diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 0eafe4323a2..fb8e63c37b7 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -895,7 +895,7 @@ class update_entries_after: # Only run in reposting self.get_serialized_values(sle) self.wh_data.qty_after_transaction += flt(sle.actual_qty) - if sle.voucher_type == "Stock Reconciliation" and not sle.batch_no: + if sle.voucher_type == "Stock Reconciliation" and not sle.batch_no and has_correct_data(sle): self.wh_data.qty_after_transaction = sle.qty_after_transaction self.wh_data.stock_value = flt(self.wh_data.qty_after_transaction) * flt( @@ -2470,3 +2470,28 @@ def get_incoming_rate_for_serial_and_batch(item_code, row, sn_obj, company): @frappe.request_cache def is_repack_entry(stock_entry_id): return frappe.get_cached_value("Stock Entry", stock_entry_id, "purpose") == "Repack" + + +def has_correct_data(sle): + previous_sle = get_previous_sle( + { + "item_code": sle.item_code, + "warehouse": sle.warehouse, + "posting_date": sle.posting_date, + "posting_time": sle.posting_time, + "creation": sle.creation, + "sle": sle.name, + } + ) + + if not previous_sle: + return True + + previous_qty = previous_sle.get("qty_after_transaction") or 0 + if previous_qty and not frappe.db.get_value( + "Stock Ledger Entry", + {"voucher_detail_no": sle.voucher_detail_no, "is_cancelled": 0, "actual_qty": ("<", 0)}, + ): + return False + + return True