diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index d740f3c6fc7656d9d71ec2d332f63db1165df8ca..0a3b12df14e23e9988c37b260f331a85df009961 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -717,6 +717,9 @@ class StockController(AccountsController): row.db_set("rejected_serial_and_batch_bundle", None) + if row.get("current_serial_and_batch_bundle"): + row.db_set("current_serial_and_batch_bundle", None) + def set_serial_and_batch_bundle(self, table_name=None, ignore_validate=False): if not table_name: table_name = "items" diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 1cb9fd64a817f207a63d5f555fd45bb17d2e5ee7..13e9a41c5b35b21666d25ff91945854a47d292cc 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -135,7 +135,11 @@ class StockReconciliation(StockController): for item in self.items: if not item.reconcile_all_serial_batch and item.serial_and_batch_bundle: bundle = self.get_bundle_for_specific_serial_batch(item) - item.current_serial_and_batch_bundle = bundle + item.current_serial_and_batch_bundle = bundle.name + item.current_valuation_rate = abs(bundle.avg_rate) + + if not item.valuation_rate: + item.valuation_rate = item.current_valuation_rate continue if not save and item.use_serial_batch_fields: @@ -253,7 +257,12 @@ class StockReconciliation(StockController): from erpnext.stock.serial_batch_bundle import SerialBatchCreation if row.current_serial_and_batch_bundle and not self.has_change_in_serial_batch(row): - return row.current_serial_and_batch_bundle + return frappe._dict( + { + "name": row.current_serial_and_batch_bundle, + "avg_rate": row.current_valuation_rate, + } + ) cls_obj = SerialBatchCreation( { @@ -287,12 +296,11 @@ class StockReconciliation(StockController): total_current_qty += current_qty entry.qty = current_qty * -1 - reco_obj.flags.ignore_validate = True reco_obj.save() row.current_qty = total_current_qty - return reco_obj.name + return reco_obj def has_change_in_serial_batch(self, row) -> bool: bundles = {row.serial_and_batch_bundle: [], row.current_serial_and_batch_bundle: []} @@ -687,7 +695,7 @@ class StockReconciliation(StockController): for d in serial_nos: frappe.db.set_value("Serial No", d, "purchase_rate", valuation_rate) - def get_sle_for_items(self, row, serial_nos=None): + def get_sle_for_items(self, row, serial_nos=None, current_bundle=True): """Insert Stock Ledger Entries""" if not serial_nos and row.serial_no: @@ -721,7 +729,7 @@ class StockReconciliation(StockController): has_dimensions = True if self.docstatus == 2 and (not row.batch_no or not row.serial_and_batch_bundle): - if row.current_qty: + if row.current_qty and current_bundle: data.actual_qty = -1 * row.current_qty data.qty_after_transaction = flt(row.current_qty) data.previous_qty_after_transaction = flt(row.qty) @@ -753,6 +761,8 @@ class StockReconciliation(StockController): has_serial_no = False for row in self.items: sl_entries.append(self.get_sle_for_items(row)) + if row.serial_and_batch_bundle and row.current_serial_and_batch_bundle: + sl_entries.append(self.get_sle_for_items(row, current_bundle=False)) if sl_entries: if has_serial_no: diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index cec6e04267929709fbf0b6f024e5c4178079ad4e..915bced7d29ffa75d73286267ad4b7f0b94e54a6 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -1110,6 +1110,8 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): ) sr.reload() + + self.assertTrue(sr.items[0].current_valuation_rate) current_sabb = sr.items[0].current_serial_and_batch_bundle doc = frappe.get_doc("Serial and Batch Bundle", current_sabb) for row in doc.entries: @@ -1119,6 +1121,18 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): batch_qty = get_batch_qty(batches[0].batch_no, warehouse, item.name) self.assertEqual(batch_qty, 100) + for row in frappe.get_all("Repost Item Valuation", filters={"voucher_no": sr.name}): + rdoc = frappe.get_doc("Repost Item Valuation", row.name) + rdoc.cancel() + rdoc.delete() + + sr.cancel() + + for row in frappe.get_all( + "Serial and Batch Bundle", fields=["docstatus"], filters={"voucher_no": sr.name} + ): + self.assertEqual(row.docstatus, 2) + def test_not_reconcile_all_serial_nos(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.utils import get_incoming_rate