Help with Custom Basket Plugin and Order Price Calculation

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)
Spam and unrelated posts will be removed immediately!
User avatar
PaoloLegaspi
Posts: 35
Joined: 07 Nov 2024, 15:02

Help with Custom Basket Plugin and Order Price Calculation

Post by PaoloLegaspi » 25 Feb 2025, 00:09

Hi Aimeos Team,

I’ve created a custom basket plugin to check if an ordered product has a specific attribute configuration (type: add-on) and apply a custom discounted price + the add-on configuration price. The plugin successfully updates the ordered product price, but the order.price attribute still reflects the standard price + the add-on price instead of the discounted price.

We’re using the JSON API in our project. Any idea how I can fix this so the order.price reflects the correct discounted total?

Thanks in advance for your help!

Code: Select all

<?php

namespace Aimeos\Mshop\Plugin\Provider\Order;


class TireAddon
    extends \Aimeos\MShop\Plugin\Provider\Factory\Base
    implements \Aimeos\MShop\Plugin\Provider\Iface, \Aimeos\MShop\Plugin\Provider\Factory\Iface
{
    private array $beConfig = [
        'attribute.type' => array(
            'code' => 'attribute.type',
            'internalcode' => 'attribute.type',
            'label' => 'Attribute type code for the tire addon',
            'default' => 'add-on',
            'required' => true,
        ),
    ];

    /**
     * Checks the backend configuration attributes for validity.
     *
     * @param array $attributes Attributes added by the shop owner in the administraton interface
     * @return array An array with the attribute keys as key and an error message as values for all attributes that are
     * 	known by the provider but aren't valid
     */
    public function checkConfigBE(array $attributes): array
    {
        $errors = parent::checkConfigBE($attributes);

        return array_merge($errors, $this->checkConfig($this->beConfig, $attributes));
    }

    /**
     * Returns the configuration attribute definitions of the provider to generate a list of available fields and
     * rules for the value of each field in the administration interface.
     *
     * @return array List of attribute definitions implementing \Aimeos\Base\Critera\Attribute\Iface
     */
    public function getConfigBE(): array
    {
        return $this->getConfigItems($this->beConfig);
    }

    /**
     * Subscribes itself to a publisher
     *
     * @param \Aimeos\MShop\Order\Item\Iface $p Object implementing publisher interface
     * @return \Aimeos\MShop\Plugin\Provider\Iface Plugin object for method chaining
     */
    public function register(\Aimeos\MShop\Order\Item\Iface $p): \Aimeos\MShop\Plugin\Provider\Iface
    {
        $plugin = $this->object();

        $p->attach($plugin, 'addProduct.after');
        $p->attach($plugin, 'setProducts.after');

        return $this;
    }

    /**
     * Updates the order product item
     *
     * @param \Aimeos\MShop\Order\Item\Iface $order Order object
     * @param string $action Action name
     * @param mixed $value New value
     * @return mixed New value
     */
    public function update(\Aimeos\MShop\Order\Item\Iface $order, string $action, $value = null)
    {
        map( [$value] )->implements( \Aimeos\MShop\Order\Item\Product\Iface::class, true );

        $attributeType = $this->getConfigValue('attribute.type');
        $attributes = $value->getAttributeItem($attributeType, 'config');
        $priceSpecial = $value->get('price_special3') ?? 0.00;
        $addonPrice = $attributes ? $attributes->getPrice() : 0.00;

        if (empty($attributes) || $priceSpecial <= 0.00) {
            return $value;
        }

        $totalPrice = $priceSpecial + $addonPrice;

        $value->setPrice($value->getPrice()->setValue($totalPrice));

        return $value;
    }
}
Screenshots
Screenshot 2025-02-25 at 7.59.45 AM.png
Screenshot 2025-02-25 at 7.59.45 AM.png (66.1 KiB) Viewed 183 times
Screenshot 2025-02-25 at 8.02.26 AM.png
Screenshot 2025-02-25 at 8.02.26 AM.png (59.57 KiB) Viewed 183 times

Code: Select all

Aimeos version: Aimeos Headless 2024.10.*
Environment: Mac

User avatar
aimeos
Administrator
Posts: 8501
Joined: 01 Jan 1970, 00:00

Re: Help with Custom Basket Plugin and Order Price Calculation

Post by aimeos » 26 Feb 2025, 08:30

Only calling setPrice() on a product item doesn't cause a recalculation of the order price because the Aimeos code doesn't know that you did that. To signal that something has changed, you need to call addProduct() for the changed order product item with the same position. Also, use a static variable to avoid an infinite loop.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply