Stock replenishes twice after a creditmemo (refund) is created on shipped orders.
Closed this issue · 5 comments
When I create a creditmemo (refund) on an order that is shipped, the qty are added back twice.
Version and configuration :
- Magento 2.4.3-p1
- Module version 1.2.2
- Manage stock is yes
- Indexes => inventory and cataloginventory_stock are set to "SAVE" (I have also tried with "SCHEDULE" and the same issue is present)
- Table => inventory_reservation is empty
Process :
- Create an order with a specific product
- Invoice is created automatically depending on payment
- If invoice is not created (for example banktransfer) generate invoice via Magento Admin
- Create a shipment via Magento Admin
- Create CreditMemo via Magento Admin, check "Back in stock"
- Product qty is back in stock but twice
Example : Let's say a product quantity is 115, and we order 15 qty of this product. After order creation, product quantity is set to 100.
When the order is invoiced, shipped and refunded, the order quantities are back in stock.
However :
- Expected quantity result : 115.
- Current result : 130.
When creating the shipment, I have tried shipping only some quantities, and it turns out the ordered quantity is refunded as well as the shipped quantity.
So in our previous example, the final current result is 120 because 100 base quantity after order + 15 ordered quantity refunded + 5 shipped quantity.
It seems the guilty piece of code is in the following class vendor/magento/module-inventory-source-deduction-api/Model/SourceDeductionService.php at line 87.
When getting the $sourceItem, the quantity seems to be wrong.
I think the module does not take into account the fact that the Back in stock qty is based on shipped items.
The native Magento 2 inventory module surrounds the shipment of quantities, so source deduction happens when a shipment is created, and creditmemo back in stock only happens if a shipment is created.
This module's vendor/ampersand/magento2-disable-stock-reservation/src/Observer/RestoreSourceItemQuantityOnRefundObserver.php
Observer Class works wonders if the order has not been shipped.
However, if the order has been shipped, it will take into account the module's Observer Class as well as the native SourceDeduction process when creating a creditmemo.
Which means the Back in stock function is used twice. Once by the Ampersand Module, and once by the native Magento Module.
Possible fix that I tried and seems to work is by adding this to the module's di.xml
or any other module if you're installing Ampersand_DisableStockReservation from composer :
<type name="Magento\SalesInventory\Model\Order\ReturnProcessor">
<plugin name="process_return_product_qty_on_credit_memo" disabled="true" />
</type>
@markfischmann pull requests welcome
Pull request here #93
fixed by #93