0

I already made a ticket for this on the official repository (https://github.com/magento/magento2/issues/4774), but their response was they would not implement it anytime soon. So that's why I ask my question here:

How can I calculate the FPT properly on configurable products?

Currently, in Magento 2(.0.7), when you apply FPT to a configurable product, the FPT on it's child-products is not taken into account. For example: say you got a refrigerator with a WEEE Tax of $1, and it comes in various sizes which makes the WEEE Tax of it's simple products $2, $3 and $4 respectively, it's not taken into account. Whatever you pick, Magento will take the WEEE of $1 of the configurable product.

Now I'm trying to alter this behaviour but without any luck. I tried events/observers on the add to cart events to manipulate the FPT, but without success. I tried to write a plugin that wraps itself around \Magento\Weee\Model\Tax::getProductWeeeAttributes, and this kind of works, but as soon as you add 2 configurable products that are the same ID, I just can't get the calculation right anymore.

Does anyone have any ideas/thoughts that can point me in the right direction?

Edit: In the meanwhile I figured it out, so I wrote an article about it.

0

In Magento 2 there are two mostly independent pricing calculation sub-sytems. One is used in catalog related calculations and the second one in checkout/order related calculations.

Challenge #1

For checkout/order related calculations, you can start from here: \Magento\Quote\Model\Quote\Item\AbstractItem::isChildrenCalculated

If this method will be returning true for configurable product and all it's children, you'll see taxes (including FPT) of selected child product(s) to be applied in totals (only children, tax of parent product will be ignored).

Code snippet:

public function isChildrenCalculated()
{
    if ($this->getParentItem()) {
        $calculate = $this->getParentItem()->getProduct()->getPriceType();
        if ($this->getParentItem()->getProduct()->getTypeId() == 'configurable') {
            $calculate = 0;
        }
    } else {
        $calculate = $this->getProduct()->getPriceType();
        if ($this->getProduct()->getTypeId() == 'configurable') {
            $calculate = 0;
        }
    }

    if (null !== $calculate &&
        (int)$calculate === \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD
    ) {
        return true;
    }
    return false;
}

If you need parent product FPT also to be applied, then you need to change \Magento\Weee\Model\Total\Quote\Weee::collect method. As you may notice, there is a conditional code block if ($item->getHasChildren() && $item->isChildrenCalculated()) { and if children taxes are applied, then parent product tax does not applied. You can fix that by processing parent item as well before or after children taxes being calculated:

Code snippet:

    if ($item->getHasChildren() && $item->isChildrenCalculated()) {
        foreach ($item->getChildren() as $child) {
            $this->resetItemData($child);
            $this->process($address, $total, $child);
        }
        $this->process($address, $total, $item); // calculate for parent as well
        $this->recalculateParent($item);
    } else {
        $this->process($address, $total, $item);
    }

I assume, as the most probably, it will be displayed properly only in Shopping Cart Totals section, but not in table for every line items, so you'll need to dig more into Shopping Cart line items renderers, to fix that.

Challenge #2

And as Catalog calculations concerned, you need to fix some JavaScript. First you need to find a way, how to add children taxes information to the configurable product pricing JSON object.

Code snippet: (\Magento\ConfigurableProduct\Block\Product\View\Type\Configurable::getOptionPrices method):

    protected function getOptionPrices()
    {
        $prices = [];
        foreach ($this->getAllowProducts() as $product) {
            $priceInfo = $product->getPriceInfo();

            $prices[$product->getId()] =
                [
                    'oldPrice' => [
                        'amount' => $this->_registerJsPrice(
                            $priceInfo->getPrice('regular_price')->getAmount()->getValue()
                        ),
                    ],
                    'basePrice' => [
                        'amount' => $this->_registerJsPrice(
                            $priceInfo->getPrice('final_price')->getAmount()->getBaseAmount()
                        ),
                    ],
                    'finalPrice' => [
                        'amount' => $this->_registerJsPrice(
                            $priceInfo->getPrice('final_price')->getAmount()->getValue()
                        ),
                    ],
                    'priceAdjustments' => $this->_registerJsPrice(
                            $priceInfo->getPrice('final_price')->getAmount()->getAdjustmentAmounts()
                        )
                ];
        }
        return $prices;
    }

So, then you can automatically update (Weee: XXX$) block under price block with JavaScript, since 'priceAdjustments' will be now available in JavaScript (app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js). As you may notice here the main challenge is broken modularity. Weee and Tax modules should add the information with some plugin or event. As well as JavaScript manipulations should be performed properly: you need either to have good abstraction around price adjustments, or somehow perform all manipulations not from Catalog or ConfigurableProduct modules JavaScript modules, but from Weee module. Also, I'm not sure what Weee Tax amount to be displayed on Catalog Product Listing page, but if you need to change how it works now, then it will be Challenge #3 :) I hope, this will help you to start.

  • Thanks for your answer. In the meanwhile, I already figured out a way to manipulate the WEEE functionality. Also in the Magento\Weee\Model\Total\Quote like you said, only in the process() method and the getProductWeeAttributes()-method that's invoked there. I wrote a more in-depth article in how I did this here: gielberkers.com/… – Giel Berkers Jun 24 '16 at 12:23
0

The answer of @V_Korotun brought me on the right track. The implementation of isChildrenCalculated() in module-quote\Model\Quote\Item\AbstractItem is

/**
 * Checking if there children calculated or parent item
 * when we have parent quote item and its children
 *
 * @return bool
 */
public function isChildrenCalculated()
{
    if ($this->getParentItem()) {
        $calculate = $this->getParentItem()->getProduct()->getPriceType();
    } else {
        $calculate = $this->getProduct()->getPriceType();
    }

    if (null !== $calculate &&
        (int)$calculate === \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD
    ) {
        return true;
    }
    return false;
}

Notice the call to getPriceType(). It means in effect that if you set price_type = 0 in the usual eav-way (attribute id 123 in magento2 default install) all taxes are automatically calculated by child product, not by parent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.