From 2f4ffe137ea173c974f3111b266723f6f7bb5f9b Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 2 Feb 2023 18:40:15 +0530 Subject: [PATCH 1/3] fix: negative stock error (cherry picked from commit 6d513e2519e3c0d4ffe6a5c9b2620ab0bee1b347) # Conflicts: # erpnext/stock/stock_ledger.py --- erpnext/stock/stock_ledger.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 4d40da65935..ab06176dbfa 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -1021,7 +1021,7 @@ class update_entries_after(object): frappe.db.set_value("Bin", bin_name, updated_values) -def get_previous_sle_of_current_voucher(args, exclude_current_voucher=False): +def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_voucher=False): """get stock ledger entries filtered by specific posting datetime conditions""" args["time_format"] = "%H:%i:%s" @@ -1043,11 +1043,21 @@ def get_previous_sle_of_current_voucher(args, exclude_current_voucher=False): and warehouse = %(warehouse)s and is_cancelled = 0 {voucher_condition} +<<<<<<< HEAD and timestamp(posting_date, time_format(posting_time, %(time_format)s)) < timestamp(%(posting_date)s, time_format(%(posting_time)s, %(time_format)s)) +======= + and ( + posting_date < %(posting_date)s or + ( + posting_date = %(posting_date)s and + time_format(posting_time, %(time_format)s) {operator} time_format(%(posting_time)s, %(time_format)s) + ) + ) +>>>>>>> 6d513e2519 (fix: negative stock error) order by timestamp(posting_date, posting_time) desc, creation desc limit 1 for update""".format( - voucher_condition=voucher_condition + operator=operator, voucher_condition=voucher_condition ), args, as_dict=1, @@ -1285,7 +1295,7 @@ def get_stock_reco_qty_shift(args): stock_reco_qty_shift = flt(args.actual_qty) else: # reco is being submitted - last_balance = get_previous_sle_of_current_voucher(args, exclude_current_voucher=True).get( + last_balance = get_previous_sle_of_current_voucher(args, "<=", exclude_current_voucher=True).get( "qty_after_transaction" ) From bd1191783ba8f38a0e754f9ad4fbc90002e6be8b Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 2 Feb 2023 18:54:28 +0530 Subject: [PATCH 2/3] test: test case (cherry picked from commit 9ae7578b078fd9809ad3f04a62d7025d104b706f) --- .../doctype/stock_entry/test_stock_entry.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 4fe3cc1fdab..99de4c1844f 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1571,6 +1571,48 @@ class TestStockEntry(FrappeTestCase): self.assertRaises(BatchExpiredError, se.save) + def test_negative_stock_reco(self): + from erpnext.controllers.stock_controller import BatchExpiredError + from erpnext.stock.doctype.batch.test_batch import make_new_batch + + frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 0) + + item_code = "Test Negative Item - 001" + item_doc = create_item(item_code=item_code, is_stock_item=1, valuation_rate=10) + + make_stock_entry( + item_code=item_code, + posting_date=add_days(today(), -3), + posting_time="00:00:00", + purpose="Material Receipt", + qty=10, + to_warehouse="_Test Warehouse - _TC", + do_not_save=True, + ) + + make_stock_entry( + item_code=item_code, + posting_date=today(), + posting_time="00:00:00", + purpose="Material Receipt", + qty=8, + from_warehouse="_Test Warehouse - _TC", + do_not_save=True, + ) + + sr_doc = create_stock_reconciliation( + purpose="Stock Reconciliation", + posting_date=add_days(today(), -3), + posting_time="00:00:00", + item_code=item_code, + warehouse="_Test Warehouse - _TC", + valuation_rate=10, + qty=7, + do_not_submit=True, + ) + + self.assertRaises(frappe.ValidationError, sr_doc.submit) + def make_serialized_item(**args): args = frappe._dict(args) From a9f5be3f981ef600aec8091e56a1535f75e2d05d Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 7 Feb 2023 13:46:40 +0530 Subject: [PATCH 3/3] fix: conflicts --- erpnext/stock/stock_ledger.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index ab06176dbfa..361e00a8449 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -1043,9 +1043,6 @@ def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_vouc and warehouse = %(warehouse)s and is_cancelled = 0 {voucher_condition} -<<<<<<< HEAD - and timestamp(posting_date, time_format(posting_time, %(time_format)s)) < timestamp(%(posting_date)s, time_format(%(posting_time)s, %(time_format)s)) -======= and ( posting_date < %(posting_date)s or ( @@ -1053,7 +1050,6 @@ def get_previous_sle_of_current_voucher(args, operator="<", exclude_current_vouc time_format(posting_time, %(time_format)s) {operator} time_format(%(posting_time)s, %(time_format)s) ) ) ->>>>>>> 6d513e2519 (fix: negative stock error) order by timestamp(posting_date, posting_time) desc, creation desc limit 1 for update""".format(