Page 1 of 1

Problems adding coupons to order/basket

Posted: 08 Nov 2016, 14:22
by Pejka
Hello again!
I seem to have hit a roadblock, and I'm not sure why. I've been writing a coupon that gives a discount for a product of a given category, if there is a product from a different category. So after every product from category X, you get a discount after every product from category Y.
The logic behind the coupon works fine and is not the issue. The problem is that, sometimes the coupon sticks, sometimes it doesn't, but mostly it does not. I also need possibly multiple of these to be applied simultaneously, so a plugin handles the addition of the coupons like so:

Code: Select all

public function update( \Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null )
    {
        $config = $this->getItemBase()->getConfig();

        $this->context = app('\Aimeos\Shop\Base\Context')->get();
        $basket = \Aimeos\Controller\Frontend\Factory::createController( $this->context, 'basket' );

        $order_manager = \Aimeos\MShop\Factory::createManager( $this->context, 'order/base' );
        foreach(json_decode($config['values']) as $coupon_code) {
            $basket->deleteCoupon($coupon_code);
            $basket->addCoupon($coupon_code);
        }
        return true;
Now, whenever I get this to work it works without a hitch, I add more products, it adds the rebate perfectly. But, after I complete an order, or empty the basket, or, which is by far the most common, Aimeos throws the entire session out the window (logging me out of extadm in the process), it fails utterly. The coupon doesn't show up in the basket on the frontend, but if I dd($basket) in the plugin, the coupon is there, the rebate product is there, it looks like it just fails to save. I tried every combination of saving I could find thereafter, $basket->save(), $order_manager->store($basket->get()), $order_manager->setSession($basket->get()), both in and out of the foreach loop, to no avail. Sometimes when I change the way it saves it works, and I think I found the solution, but then... nothing. As if the basket were just mocking me.
What am I missing here?
Also, if I try to add the coupon regularly, be entering it from the frontend, it throws an error saying "Duplicate coupon code "NOTCHEESEBURGER"". A dump($basket->get()) or dump($order_manager->getSession()) on a different page reveals that not to be the case (products are there though).

Re: Problems adding coupons to order/basket

Posted: 08 Nov 2016, 14:43
by aimeos
From the code you've posted there are three problems:
- You have to use the passed $order parameter because this is your current basket. The Basket controller that called the method that causes your plugin to get notified cares about saving the modified basket afterwards
- You can not use the frontend controllers in a MShop plugin because they are in a layer above your own code (https://aimeos.org/docs/Developers/Software_stack). You can call objects down the software stack but not upwards. This causes the problems you've mentioned
- The configuration is already deserialized and you have to access the entries of the resulting PHP array instead. Even better, use the getConfigValue() method

Re: Problems adding coupons to order/basket

Posted: 08 Nov 2016, 15:03
by Pejka
Thanks a lot!
It seems to have worked... for now at least :D
I think I skipped past trying to use the passed $order object, since it seemed to require passing the rebate product object as a parameter...