Action to add item to cart

Created on 12 January 2025, 2 months ago

Please only use Merge requests for contributing to this issue. Using Gitlab Please do not use patches for contributing to this project.

Problem/Motivation

I'm a bit surprised this wasn't the first action in this project -- adding an item to the user's cart!

In my scenario, I want to add a specific product to the cart when another product is added, to create a product bundle. I'm bundling an installation/configuration product with a product license -- the license product is taxable in my jurisdiction, and recurring -- but the setup is one time and not taxable. Thus two products.

I tried commerce_vado -- way too complex and confusing. I tried commerce_pado, which was closer, but still not the right fit. Promotions came the closest -- it let me auto-add supporting products -- but only at a 100% discount, and then the tax wasn't properly charged. So turning to ECA.

It looks like I can use one of the add entity to cart events, and filter for product sku. But then to add it to the cart, I have to create a commerce_order_item, populate several fields, add it to the cart entity, and possibly save? Not sure, because I got an error trying to save the model in the first attempt. Rather than repeat all that work, I want a simple action plugin to add a purchasable entity to the cart.

Steps to reproduce

Proposed resolution

Create an action plugin to add a purchasable entity to a Commerce order.

I'm going to create the initial one to have a purchasable entity field, a type field, quantity, and the cart field.

Types to include for now - a purchasable entity (usually a product_variation), an entity_id, or a sku. SKU will look up the entity by sku.

Then simply add it to the cart object supplied.

Remaining tasks

Create plugin.

User interface changes

API changes

Data model changes

Feature request
Status

Active

Version

2.1

Component

Code

Created by

🇺🇸United States freelock Seattle

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @freelock
  • Pipeline finished with Failed
    2 months ago
    Total: 150s
    #393866
  • 🇺🇸United States freelock Seattle

    Added new action plugin.

    Note that during testing, the "Add entity to cart" event got executed multiple times (twice) -- so in my initial cut, it was adding the extra product twice.

    To avoid this, I made it check the existing cart for a matching order item, and if found, it sets the quantity of that item instead of adding a new one.

    This works fine for my needs. I'm not sure if there is a good way to avoid this problem otherwise.

  • 🇮🇹Italy kopeboy Milan

    Can you provide a working example ECA model? Cause I couldn't get this to work and I'm not receiving any error messages

  • 🇮🇹Italy kopeboy Milan

    This is the ECA model with which I'm trying. I just set up a Commerce store and a single product with 1 variation with sku "VAR1".

    Nothing happens when I run the custom ECA event from the command line..

  • 🇮🇹Italy kopeboy Milan

    I tried with a different variation of ECA model as well, ie. I replaced the action to set the order token manually with one that loads the entity by Type & ID (selection Order entity type), but nothing changed.

    Maybe we can take inspiration from this module: direct_checkout_by_url

  • 🇺🇸United States freelock Seattle

    Hi,

    This action requires either a sku or a purchasable entity (product variation) to add, and an order (which is what a cart is under the hood). So you do need to load an existing order/cart to pass it in.

    I used this event: https://ecaguide.org/plugins/eca/commerce/events/eca_commerce_cart_entit... which provided a cart (order) and a product variation entity. I could then check details for the product, and if it matched, add a different product to the cart by sku.

    It does require the commerce cart and commerce order modules to be active, and the order -- so you need to get that somehow. Loading it by entity type/id should be fine -- is the one you're loading owned by the user who's executing your model? You often need to switch users if you're trying to run from drush or cron...

    Cheers,
    John

  • 🇺🇸United States nicxvan

    This looks like a great addition! Can you please take care of the PHPCS and PHPStan issues?

    Also I think this can still end up with some confusion and circular logic.

  • 🇺🇸United States freelock Seattle

    @nicxvan what circular logic do you see?

  • 🇺🇸United States nicxvan

    Sorry, I was basing that question off of your comment about duplicate events, does adding the item trigger the call a second time?

    So it works like this
    Add item A to cart
    ECA triggers
    Add item B to cart
    ECA triggers
    Set item B to quantity 1

    User then increases quantity to 2 on item B.

    Add item C
    ECA Triggers
    Set item B to quantity 1

    I'm honestly kind of stuck between adding this in the simple form you have and complicating it for a couple more scenarios.
    Maybe we need two more checkboxes:
    Checkbox 1 is multiply whether to multiply item B quantity by the quantity or just set it to the value.
    E.G. if the rule is if Item A is added add 2 of Item B, if you add 2 Item A should you get 2 or 4 of item B.
    Checkbox 2 is override whether to change the quantity of item B if it is higher than the quantity specified by the rule.
    E.G. if the rule is if Item A is added add 2 of Item B, if you add 2 Item A and you already have 5 of Item B should it be brought down to 4 or left alone.

  • 🇺🇸United States freelock Seattle

    It's not the first time I've hit circular stuff with commerce -- all the way back to Ubercart, seems like commerce events fire a lot more often than I would think necessary. My answer is idempotence -- make sure if it's called multiple times, the result is always the same.

    This is why there's a quantity field in the plugin -- each time the plugin runs, if the item is already in the cart, it updates the quantity to whatever value is in that field (which accepts a token), so you if you create a token for quantity based on other products in the cart, it can always do the right thing -- set the correct quantity on one order item.

    If the "right thing" is to add additional order items with the same sku, this plugin won't do that. It won't even detect if there is more than one order item on the order -- it just sets the quantity on the first matching one it finds (but you can specify elsewhere that multiple order items with the same sku should always be combined).

Production build 0.71.5 2024