Add membership to cart and recalculate cost of rest cart products

Hi to all,
Please advise if the following functionality is possible, and if so, what I can read about it.

We have (Usergroup Discounts module is used) membership subscriptions (1,6,12 month plans), user can buy any course with or without membership(there are two buttons for that), if he selects “buy with membership” we show him popup where membership plan can be selected. Let’s say he chose some kind of plan, I put in cart this plan and the course that he originally chose.

My question is: is it possible to somehow immediately recalculate the original price of that course on the fly (that is, as if he “had already bought” a subscription :slight_smile: ). Thus, we get rid of the intermediate step - “first buy a subscription, then buy at a discount” .

We want to keep the shopping path as short as possible.

Thanks in advance.

It seems it already works from the box somehow, so please skip this question :slight_smile:
Here is a screenshot for the proof:

I hurried a little :slight_smile: … everything worked as expected but when the product had already been added to the User Group Discounts group(that is it must be predefined, static). So this will be worked for all users, who added subscription to cart as well and who not. So I will correct the question a little: are there any other ways how to assign discount to cart product on the fly(depending on what else is in the basket)?
Thanks!

Hi,
Sorry to bother you again, the question is still relevant.
Can I implement with existing means or through a new module/code something conditional like the next: “if Cart has product #1(membership) that apply a discount to Product #2(course) otherwise use basic price”
?

Truthfully this is such a specific type of discount, I’ve had trouble wrapping my head around it… Certainly not possible out of the box.

I think this is something that would require a custom module that just loops over the items in the cart and adds a price adjustment to the discounted item when appropriate.

Here’s a quick example adjusted from the core on how you add a price adjustment:

        $key = 'some-unique-key-for-discount';
        $percentageDiscount = 10.00;
        /** @var \comOrderItemDiscountAdjustment $adjustment */
        $adjustment = $this->adapter->getObject('comOrderItemDiscountAdjustment', [
            'key' => $key,
            'item' => $item->get('id'),
        ]);
        if (!$adjustment) {
            $adjustment = $this->adapter->newObject('comOrderItemDiscountAdjustment');
            $adjustment->fromArray([
                'key' => $key,
                'name' => $this->adapter->lexicon('some_lexicon_for_discount'),
                'show_on_order' => true,
            ]);
        }
        $adjustment->set('price_change_percentage', $percentageDiscount);

        $item->addPriceAdjustment($adjustment, false);

The second parameter on addPriceAdjustment is wether to re-calculate the order item right away; in this example it says to not do so because this example ran inside the Commerce::EVENT_ORDERITEM_BEFORE_CALCULATE event - so re-calculating right away would cause a loop. If handled from a different event that may need to be switched to true to see effect.

When your module determines a discount should not be added, you should call $item->removePriceAdjustment($key) to remove the adjustment again.

Thanks @mhamstra, this helped a lot! And finally I’ve got what I wanted.

Glad to hear that! :slight_smile:

1 Like