1

UPDATE

After a lot of debugging I found out that the plugin is loaded on the product detail page but not in the checkout. It seems that the checkout gets the values from somewhere before so that is why the price is correct initially. But if Javascript is triggered it goes through the module loading process again and there the plugin is not loaded. Thus the original magento database price is loaded.

The problem seems to be in var/generation/Magento/Catalog/Model/Product/Interceptor.php in function getPrice. There they fetch $pluginInfo and this contains an array with my plugin. But only on the product detail page. In the checkout this array is always null and therefor it only calls parent::getPrice().

I wonder why my plugin is not loaded in the checkout?

Here is how I setup the plugin:

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    '<vendor>_<plugin>',
    __DIR__
);

di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\Product" shared="false">
        <plugin
                name="<vendor>_<plugin>_productplugin"
                type="\<vendor>\<plugin>\Plugin\Product\ProductPlugin"
                disabled="false"
                sortOrder="999" />
    </type>
</config>

app/code/<vendor>/<plugin>/Plugin/Product/ProductPlugin.php

<?php

namespace <vendor>\<plugin>\Plugin\Product;

class ProductPlugin
{
    public function afterGetPrice($product, $proceed) : float
    {
        return 111.55;
    }

}

OLD INFO

I already build a mage2-module with a plugin for Magento\Catalog\Model\Product and created an afterGetPrice() method. This works fine for:

  • product detail page
  • checkout/cart product listing on the left

But the problem is that the widget/sidebar summary component at the checkout on the right side of the e.g. Luma theme shows the right prices for a short moment, than an ajax request to the Magento REST-API changes all prices to the normal Magento product prices so the plugin does not work here.

Before everything is ok and can be checkt via console:

window.checkoutConfig;

quoteData and totalsData have got the proper prices. Later they will be updated by the response of totals-information.

I think these endpoints could be used for this action depending on the situation:

POST   /V1/carts/:cartId/totals-information
POST   /V1/guest-carts/:cartId/totals-information
POST   /V1/carts/mine/totals-information

<preference for="Magento\Checkout\Api\Data\TotalsInformationInterface" type="Magento\Checkout\Model\TotalsInformation" />
<preference for="Magento\Checkout\Api\GuestTotalsInformationManagementInterface" type="Magento\Checkout\Model\GuestTotalsInformationManagement" />
<preference for="Magento\Checkout\Api\TotalsInformationManagementInterface" type="Magento\Checkout\Model\TotalsInformationManagement" />

In my own theme no such reloading takes place but in step 2 of the onepage checkout the prices are also wrong.

How can I achieve to overwrite the prices in the frontend with my own prices and in case of no data with the original price, like the afterGetPrice() function does?

Here you can see the process in screenshots:

  1. first it loads the page with the correct price (sorry it's german language) enter image description here

  2. then it reloads the summary box enter image description here

  3. after the refresh the price is the magento price without the afterGetPrice() method being runenter image description here

2

The problem is that I placed the di.xml into the frontend subfolder, thinking that this defines the area the plugin applies to. But reading the docu ( http://devdocs.magento.com/guides/v2.1/architecture/archi_perspectives/components/modules/mod_and_areas.html )

Magento area types

Magento is organized into these main areas:

Magento Admin (adminhtml): entry point for this area is index.php or pub/index.php. The Admin panel area includes the code needed for store management. The /app/design/adminhtml directory contains all the code for components you’ll see while working in the Admin panel.

Storefront (frontend): entry point for this area is index.php or pub/index.php. The storefront (or frontend) contains template and layout files that define the appearance of your storefront.

Basic (base): used as a fallback for files absent in adminhtml and frontend areas.

again it seems that frontend refers only to display purposes but not saving or anything.

  • 1
    Hi. How did you solve this in the end? I have my di.xml in etc/adminhtml, etc/frontend & the base folder (etc). But the side column in the cart is still getting the price from the DB, and not my dynamic price. Price is displaying correctly in catalog. It's just the side bar and checkout! – sulman Sep 14 '17 at 15:02
  • Nice man you saved lots of time for me – Vaibhav Ahalpara Nov 8 '17 at 10:50
0

Perhaps it's too late, but in magento 2, you can use event named : "controller_action_catalog_product_save_entity_after" in order to do action after product saved

Will

  • That will not work for the usecase I think as it works on the catalog which is not expected. – steros May 7 at 22:24
-1

After a lot of debugging I found out that the plugin is loaded on the product detail page but not in the checkout. It seems that the checkout gets the values from somewhere before so that is why the price is correct initially. But if Javascript is triggered it goes through the module loading process again and there the plugin is not loaded. Thus the original magento database price is loaded.

The problem seems to be in var/generation/Magento/Catalog/Model/Product/Interceptor.php in function getPrice. There they fetch $pluginInfo and this contains an array with my plugin. But only on the product detail page. In the checkout this array is always null and therefor it only calls parent::getPrice().

I wonder why my plugin is not loaded in the checkout?

Here is how I setup the plugin:

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    '<vendor>_<plugin>',
    __DIR__
);

di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\Product" shared="false">
        <plugin
                name="<vendor>_<plugin>_productplugin"
                type="\<vendor>\<plugin>\Plugin\Product\ProductPlugin"
                disabled="false"
                sortOrder="999" />
    </type>
</config>

app/code/<vendor>/<plugin>/Plugin/Product/ProductPlugin.php

<?php

namespace <vendor>\<plugin>\Plugin\Product;

class ProductPlugin
{
    public function afterGetPrice($product, $proceed) : float
    {
        return 111.55;
    }

}
  • sorry what is the idea behind "copying" my findings? – steros May 11 '17 at 17:03
-1

a litte late, but if anyone has the same problem, you also need to add an afterGetFinalPrice() method. This is what get called here. You can add that to your Product Plugin.

  • What version are you working with? I can't recall the need for this. – steros May 7 at 22:26

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.