fix: incoming rate for sales return with Moving Average valuation method (backport #38849) (#38863)
* fix: incoming rate for sales return with Moving Average valuation method (#38849)
(cherry picked from commit 7fdac62393ee1e96969cca38a4ce0c07993dce7e)
# Conflicts:
# erpnext/stock/doctype/delivery_note/test_delivery_note.py
* chore: fix conflicts
---------
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index e8bae8c..4489d60 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -12,7 +12,7 @@
from erpnext.controllers.stock_controller import StockController
from erpnext.stock.doctype.item.item import set_item_default
from erpnext.stock.get_item_details import get_bin_details, get_conversion_factor
-from erpnext.stock.utils import get_incoming_rate
+from erpnext.stock.utils import get_incoming_rate, get_valuation_method
class SellingController(StockController):
@@ -432,11 +432,13 @@
items = self.get("items") + (self.get("packed_items") or [])
for d in items:
- if not self.get("return_against"):
+ if not self.get("return_against") or (
+ get_valuation_method(d.item_code) == "Moving Average" and self.get("is_return")
+ ):
# Get incoming rate based on original item cost based on valuation method
qty = flt(d.get("stock_qty") or d.get("actual_qty"))
- if not (self.get("is_return") and d.incoming_rate):
+ if not d.incoming_rate:
d.incoming_rate = get_incoming_rate(
{
"item_code": d.item_code,
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 3a58122..da8ee02 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -1375,6 +1375,56 @@
dn.reload()
self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Delivered")
+ def test_sales_return_valuation_for_moving_average(self):
+ item_code = make_item(
+ "_Test Item Sales Return with MA", {"is_stock_item": 1, "valuation_method": "Moving Average"}
+ ).name
+
+ make_stock_entry(
+ item_code=item_code,
+ target="_Test Warehouse - _TC",
+ qty=5,
+ basic_rate=100.0,
+ posting_date=add_days(nowdate(), -5),
+ )
+ dn = create_delivery_note(
+ item_code=item_code, qty=5, rate=500, posting_date=add_days(nowdate(), -4)
+ )
+ self.assertEqual(dn.items[0].incoming_rate, 100.0)
+
+ make_stock_entry(
+ item_code=item_code,
+ target="_Test Warehouse - _TC",
+ qty=5,
+ basic_rate=200.0,
+ posting_date=add_days(nowdate(), -3),
+ )
+ make_stock_entry(
+ item_code=item_code,
+ target="_Test Warehouse - _TC",
+ qty=5,
+ basic_rate=300.0,
+ posting_date=add_days(nowdate(), -2),
+ )
+
+ dn1 = create_delivery_note(
+ is_return=1,
+ item_code=item_code,
+ return_against=dn.name,
+ qty=-5,
+ rate=500,
+ company=dn.company,
+ expense_account="Cost of Goods Sold - _TC",
+ cost_center="Main - _TC",
+ do_not_submit=1,
+ posting_date=add_days(nowdate(), -1),
+ )
+
+ # (300 * 5) + (200 * 5) = 2500
+ # 2500 / 10 = 250
+
+ self.assertAlmostEqual(dn1.items[0].incoming_rate, 250.0)
+
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")