From 88a3f65d3d250f31aeac8386fe5c8524f4864765 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Tue, 30 May 2023 16:54:28 +0530 Subject: [PATCH 1/2] fix: update `Stock Reconciliation` document while reposting (cherry picked from commit cc95cedfee3c09037a97574ca1a04b2d98c72965) --- erpnext/stock/stock_ledger.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index bdd04a06dd..2945c3d731 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -861,6 +861,8 @@ class update_entries_after(object): self.update_rate_on_purchase_receipt(sle, outgoing_rate) elif flt(sle.actual_qty) < 0 and sle.voucher_type == "Subcontracting Receipt": self.update_rate_on_subcontracting_receipt(sle, outgoing_rate) + elif sle.voucher_type == "Stock Reconciliation": + self.update_rate_on_stock_reconciliation(sle) def update_rate_on_stock_entry(self, sle, outgoing_rate): frappe.db.set_value("Stock Entry Detail", sle.voucher_detail_no, "basic_rate", outgoing_rate) @@ -928,6 +930,38 @@ class update_entries_after(object): for d in scr.items: d.db_update() + def update_rate_on_stock_reconciliation(self, sle): + if not sle.serial_no and not sle.batch_no: + sr = frappe.get_doc("Stock Reconciliation", sle.voucher_no, for_update=True) + + for item in sr.items: + # Skip for Serial and Batch Items + if item.serial_no or item.batch_no: + continue + + previous_sle = get_previous_sle( + { + "item_code": item.item_code, + "warehouse": item.warehouse, + "posting_date": sr.posting_date, + "posting_time": sr.posting_time, + "sle": sle.name, + } + ) + + item.current_qty = previous_sle.get("qty_after_transaction") or 0.0 + item.current_valuation_rate = previous_sle.get("valuation_rate") or 0.0 + item.current_amount = flt(item.current_qty) * flt(item.current_valuation_rate) + + item.amount = flt(item.qty) * flt(item.valuation_rate) + item.amount_difference = item.amount - item.current_amount + else: + sr.difference_amount = sum([item.amount_difference for item in sr.items]) + sr.db_update() + + for item in sr.items: + item.db_update() + def get_serialized_values(self, sle): incoming_rate = flt(sle.incoming_rate) actual_qty = flt(sle.actual_qty) From 0fa56bcdce0b253f6d9fe26b25ffc906ceabbb6f Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Tue, 30 May 2023 21:25:41 +0530 Subject: [PATCH 2/2] test: add test case for update stock reconciliation doc (cherry picked from commit 5c9506c8ca26899536be823755f1bbb747716e01) --- .../test_stock_reconciliation.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 2e5d2c3aaf..621b9df124 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -751,6 +751,50 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): self.assertEqual(flt(sle[0].qty_after_transaction), flt(50.0)) + def test_update_stock_reconciliation_while_reposting(self): + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + + item_code = self.make_item().name + warehouse = "_Test Warehouse - _TC" + + # Stock Value => 100 * 100 = 10000 + se = make_stock_entry( + item_code=item_code, + target=warehouse, + qty=100, + basic_rate=100, + posting_time="10:00:00", + ) + + # Stock Value => 100 * 200 = 20000 + # Value Change => 20000 - 10000 = 10000 + sr1 = create_stock_reconciliation( + item_code=item_code, + warehouse=warehouse, + qty=100, + rate=200, + posting_time="12:00:00", + ) + self.assertEqual(sr1.difference_amount, 10000) + + # Stock Value => 50 * 50 = 2500 + # Value Change => 2500 - 10000 = -7500 + sr2 = create_stock_reconciliation( + item_code=item_code, + warehouse=warehouse, + qty=50, + rate=50, + posting_time="11:00:00", + ) + self.assertEqual(sr2.difference_amount, -7500) + + sr1.load_from_db() + self.assertEqual(sr1.difference_amount, 17500) + + sr2.cancel() + sr1.load_from_db() + self.assertEqual(sr1.difference_amount, 10000) + def create_batch_item_with_batch(item_name, batch_id): batch_item_doc = create_item(item_name, is_stock_item=1)