How to configure and adapt Aimeos based shops as developer
Forum rules: Always add your Aimeos and PHP version as well as your environment (Linux/Mac/Win)
#3612 by Pejka
08 Nov 2016, 14:22
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 allpublic 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).
#3614 by aimeos
08 Nov 2016, 14:43
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
#3616 by Pejka
08 Nov 2016, 15:03
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...