diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index bac94f98af4..d3157e7037b 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -428,7 +428,9 @@ class SellingController(StockController): # 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 d.incoming_rate: + if not d.incoming_rate or ( + get_valuation_method(d.item_code) == "Moving Average" and self.get("is_return") + ): 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 476b4959813..a931ee2c254 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -1382,6 +1382,59 @@ class TestDeliveryNote(FrappeTestCase): self.assertAlmostEqual(dn1.items[0].incoming_rate, 250.0) + def test_sales_return_valuation_for_moving_average_case2(self): + # Make DN return + # Make Bakcdated Purchase Receipt and check DN return valuation rate + # The rate should be recalculate based on the backdated purchase receipt + frappe.flags.print_debug_messages = False + item_code = make_item( + "_Test Item Sales Return with MA Case2", + {"is_stock_item": 1, "valuation_method": "Moving Average", "stock_uom": "Nos"}, + ).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, + warehouse="_Test Warehouse - _TC", + qty=5, + rate=500, + posting_date=add_days(nowdate(), -4), + ) + + returned_dn = create_delivery_note( + is_return=1, + item_code=item_code, + return_against=dn.name, + qty=-5, + rate=500, + company=dn.company, + warehouse="_Test Warehouse - _TC", + expense_account="Cost of Goods Sold - _TC", + cost_center="Main - _TC", + posting_date=add_days(nowdate(), -1), + ) + + self.assertAlmostEqual(returned_dn.items[0].incoming_rate, 100.0) + + # Make backdated purchase receipt + make_stock_entry( + item_code=item_code, + target="_Test Warehouse - _TC", + qty=5, + basic_rate=200.0, + posting_date=add_days(nowdate(), -3), + ) + + returned_dn.reload() + self.assertAlmostEqual(returned_dn.items[0].incoming_rate, 200.0) + def create_delivery_note(**args): dn = frappe.new_doc("Delivery Note") diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 8a262497926..df1f544d7b1 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -16,6 +16,7 @@ from erpnext.stock.doctype.bin.bin import update_qty as update_bin_qty from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions from erpnext.stock.utils import ( get_incoming_outgoing_rate_for_cancel, + get_incoming_rate, get_or_make_bin, get_valuation_method, ) @@ -701,7 +702,23 @@ class update_entries_after(object): ) if self.valuation_method == "Moving Average": - rate = flt(self.data[self.args.warehouse].previous_sle.valuation_rate) + rate = get_incoming_rate( + { + "item_code": sle.item_code, + "warehouse": sle.warehouse, + "posting_date": sle.posting_date, + "posting_time": sle.posting_time, + "qty": sle.actual_qty, + "serial_no": sle.get("serial_no"), + "batch_no": sle.get("batch_no"), + "company": sle.company, + "voucher_type": sle.voucher_type, + "voucher_no": sle.voucher_no, + "allow_zero_valuation": self.allow_zero_rate, + "sle": sle.name, + } + ) + else: rate = get_rate_for_return( sle.voucher_type,