1

I'd like to replace the error message in this magento core function.

vendor/magento/module-inventory-sales/Model/IsProductSalableCondition/BackOrderNotifyCustomerCondition.php

public function execute(string $sku, int $stockId, float $requestedQty): ProductSalableResultInterface
    {
        $stockItemConfiguration = $this->getStockItemConfiguration->execute($sku, $stockId);

        if ($stockItemConfiguration->isManageStock()
            && $stockItemConfiguration->getBackorders() === StockItemConfigurationInterface::BACKORDERS_YES_NOTIFY
        ) {
            $stockItemData = $this->getStockItemData->execute($sku, $stockId);
            if (null === $stockItemData) {
                return $this->productSalableResultFactory->create(['errors' => []]);
            }

            $salableQty = $this->getProductSalableQty->execute($sku, $stockId);
            $backOrderQty = $requestedQty - $salableQty;
            $displayQty = $this->getDisplayQty($backOrderQty, $salableQty, $requestedQty);

            if ($displayQty > 0) {
                $errors = [
                    $this->productSalabilityErrorFactory->create([
                            'code' => 'back_order-not-enough',
                            /*'message' => __(
                                'We don\'t have as many quantity as you requested, '
                                . 'but we\'ll back order the remaining %1.',
                                $displayQty * 1
                            )])*/
                            'message' => __(
                                'We don\'t have as many quantity as you requested, '
                                . 'but we\'ll back order the remaining %1.',
                                $displayQty * 1
                            )])
                ];
                return $this->productSalableResultFactory->create(['errors' => $errors]);
            }
        }

So I created a custom plugin, but I don't understand how around() method would replace error message, since the original method will be executed in $proceed(). Can you help me?

namespace Mymodule\BackorderCustom\Plugin\Magento\InventorySales\Model\IsProductSalableCondition;

class BackOrderNotifyCustomerCondition
{

    public function aroundExecute(
        \Magento\InventorySales\Model\IsProductSalableCondition\BackOrderNotifyCustomerCondition $subject,
        \Closure $proceed
    ) {
        // plugin code
        $result = $proceed();
        return $result;
    }
}
1
  • my answer is helpfull or not? still anything remain into this one? Commented May 1 at 5:16

3 Answers 3

3

According to magento coding standard practice,

When you want to modify the result, then instead of Around plugin, You need to use After Plugin.

public function afterExecute($subject, $result)
{
    return "MODIFY RESULT";
}
2
  • After long thought I think your way is the best kuddos ! we can test if($result->getErrors() contains an element with ->getCode() == "back_order-not-enough") then modify it before returning tada
    – medmek
    Commented Apr 22 at 19:57
  • 1
    If answer help you, please accept it as solution and upvote, so it help other in community. Commented Apr 23 at 4:14
1

A plugin is more to modify what is done before or after a method. If you want to modify what the method does by itself, then what you are looking for isn't a plugin but a preference.

And yes i'm already hearing an army of people saying preference is bad, cause multiple module can use a preference and that's adding potential maitainance cost in the future. That's true.

Although in that kind of case to me using a preference makes much more sense than using a plugin.

Also some class have private methods / variables which makes them impossible to work with plugins.

1

Since you want to modify something in the middle $errors

(not the inputs string $sku, int $stockId, float $requestedQty , so no before plugin)

(not the output $this->productSalableResultFactory->create(['errors' => $errors]) because you don't (want to) know what's really happening in ->create so no after plugin)-

I'd advise an around plugin or a i18n phrase definition to override (in CSV).

A preference in this case seems too broad, not specific to a function, unless you anticipate other changes in other functions in the same class.

I'd do it by not calling the proceed() and reusing the code, but when I tried it :

namespace Mymodule\BackorderCustom\Plugin\Magento\InventorySales\Model\IsProductSalableCondition;

class BackOrderNotifyCustomerCondition
{

    public function aroundExecute(
        \Magento\InventorySales\Model\IsProductSalableCondition\BackOrderNotifyCustomerCondition $subject,
        \Closure $proceed
        string $sku, int $stockId, float $requestedQty //same arguments as overridden function
    ) {
        $stockItemConfiguration = $subject->getStockItemConfiguration->execute($sku, $stockId);

        if ($stockItemConfiguration->isManageStock()
        ...
        return $subject->productSalableResultFactory->create(['errors' => []]);
    }
}

PHPStrom notifies me that ->getStockItemConfiguration private for example.

So I think in the end CSV is good practice enough : try to override this in your module :

//FILE vendor/magento/module-inventory-sales/i18n/en_US.csv
"We don't have as many quantity as you requested, but we'll back order the remaining %1.","We don't have as many quantity as you requested, but we'll back order the remaining %1."

Otherwise there's preference or I guess using Dependency Injection on \Magento\InventorySales\Model\IsProductSalableForRequestedQtyCondition\ProductSalableResult by specifying what should be in the array $errors (I didn't try it)

EDIT : changed my mind thanks to @Dhiren Vasoya answer, better go with after plugin, because now I understand that we can re-create the result with productSalableResultFactory->create(['errors' => $newCustomErrors])

2
  • en_US.csv this file use for language translator, not actual message change. Commented Apr 22 at 13:16
  • depends on the change IMO, eg OK with csv : "We don't have as many quantity as you requested, but we'll back order the remaining %1.","We don't have the requested quantity yet, but we'll back order the remaining %1." eg Not OK with csv : "We don't have as many quantity as you requested, but we'll back order the remaining %1.","The product is out of stock." (Cosmetic vs Meaning) But careful if the phrase is used elsewhere.
    – medmek
    Commented Apr 22 at 19:28

Your Answer

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

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