0

I am attempting to set custom prices for my products for specific customers. I am getting the prices through a third party API based on product SKU. I have to do it this way because product prices are calculated on an internal system and is quite complex. I currently have this functionality working, but it is not optimized the way I want it to be. Right now I have my own custom module created that hooks into Magento\Catalog\Model\Product in the etc/frontend/di.xml file. This is ok when the customer is viewing the product page because it only ever makes one API call, but when viewing the category pages or searching for products there can be up to 36 requests made through the API on one page load; which is obviously not ideal.

My question is -- is it possible to get all of the SKUs of the products that are going to be loaded on the page and make a single API request to get all of the custom prices at once? If it is possible, how do I do that?

Magento version is 2.4.2

Current working code

etc/frontend/di.xml

<type name="Magento\Catalog\Model\Product">
        <plugin name="customprice.product" type="Vendor\Module\Plugin\CustomPriceProduct" sortOrder="1" />
</type>

Plugin/CustomPriceProduct.php

public function afterGetPrice(Product $subject, $result) {
    if(!$this->session->getInternalID()) {
        return $result;
    }

    $sku = $subject->getData('sku');

    $data = json_encode(array(
        'assigned_no' => $this->session->getInternalID(),
        'items' => [
            array('sku' => $sku, 'order_qty' => 1)
        ]
    ));
    
    $response = $this->api->customPrices($data);
    $prices = json_decode($response['data']);
    
    if($response['code'] == 200 && count($prices)) {
        return $prices[0]->extension;
    }

    return $result;
}

1 Answer 1

0

If you are referring to a category or search result page, at some point a product collection is going to be created and there are opportunities there to get all of the SKUs. But this would likely require you to refactor how you are substituting in the custom prices, e.g. by finding some way to modify the collection, or store them in a separate data structure that is keyed to the collection and use that to render them.

You could also use an approach that scrapes the SKUs out of the page and "lazy-loads" the custom prices. E.g.:

(Edit to add: This approach could make it easier for end-users to use your API for unauthorized purposes.)

  1. Page loads with prices set to be empty in the template or hidden with CSS.
  2. JS is used to find all of the SKU values, either from existing page elements of from your own custom additions to the template, e.g. adding a data-sku property to relevant elements. (Or, you use the template to render the already-assembled list as an identifiable structure for JS to grab.)
  3. AJAX is used to send the list of SKUs to an API and receive a key/value set matching the SKU to a custom price.
  4. JS is used to populate the empty/hidden prices.
3
  • I did think about doing it that way, but I was hoping there was some point in magento where the SKUs were collected together and I could still change the price on the server side.
    – DiddleDot
    Oct 15, 2021 at 18:51
  • A plugin or observer that allows you to access the product collection after it is populated might work. Note that doing this on the server may introduce complications with cacheing, whereas using customerData or a stand-alone AJAX approach would not. If access control is an issue, having the frontend send just the SKU list to a Magento-implemented API, which uses the customer session to add customer-specific info and forward everything to an external API could work.
    – jiheison
    Oct 15, 2021 at 18:58
  • I tried a couple of other things that had potential before eventually giving up and doing it this way. There was too little documentation and not enough time for me to figure out how to do it a different way.
    – DiddleDot
    Nov 8, 2021 at 22:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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