From eabb956acadfef7f69e72a160a86e4963d6e7393 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:44:50 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20reposting=20not=20fixing=20valuation=20r?= =?UTF-8?q?ate=20for=20sales=20return=20using=20movin=E2=80=A6=20(backport?= =?UTF-8?q?=20#38895)=20(backport=20#38897)=20(#38901)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: reposting not fixing valuation rate for sales return using movin… (backport #38895) (#38897) * fix: reposting not fixing valuation rate for sales return using movin… (#38895) fix: reposting not fixing valuation rate for sales return using moving average method (cherry picked from commit 3a668bbe9694fdd6e8265869c6943e42f889ac41) # Conflicts: # erpnext/stock/stock_ledger.py * chore: fix conflicts --------- Co-authored-by: rohitwaghchaure (cherry picked from commit 07175367d8158355e5f699c7c66a2a6743a85c29) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/controllers/selling_controller.py | 4 +- .../delivery_note/test_delivery_note.py | 53 +++++++++++++++++++ erpnext/stock/stock_ledger.py | 34 +++++++++--- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 4489d60131..919e459c9e 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -438,7 +438,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 da8ee022f9..933be53b07 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -1425,6 +1425,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 9142a27f4c..b19a34a354 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -25,6 +25,7 @@ from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry impor ) from erpnext.stock.utils import ( get_incoming_outgoing_rate_for_cancel, + get_incoming_rate, get_or_make_bin, get_stock_balance, get_valuation_method, @@ -841,14 +842,33 @@ class update_entries_after(object): get_rate_for_return, # don't move this import to top ) - rate = get_rate_for_return( - sle.voucher_type, - sle.voucher_no, - sle.item_code, - voucher_detail_no=sle.voucher_detail_no, - sle=sle, - ) + if self.valuation_method == "Moving Average": + 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"), + "serial_and_batch_bundle": sle.get("serial_and_batch_bundle"), + "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, + sle.voucher_no, + sle.item_code, + voucher_detail_no=sle.voucher_detail_no, + sle=sle, + ) elif ( sle.voucher_type in ["Purchase Receipt", "Purchase Invoice"] and sle.voucher_detail_no