From 6d513e2519e3c0d4ffe6a5c9b2620ab0bee1b347 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 2 Feb 2023 18:40:15 +0530 Subject: [PATCH 1/9] fix: negative stock error --- erpnext/stock/stock_ledger.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 5d75bfd05a..30e75bff3d 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -1050,7 +1050,7 @@ class update_entries_after(object): frappe.db.set_value("Bin", bin_name, updated_values, update_modified=True) -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" @@ -1076,13 +1076,13 @@ def get_previous_sle_of_current_voucher(args, exclude_current_voucher=False): posting_date < %(posting_date)s or ( posting_date = %(posting_date)s and - time_format(posting_time, %(time_format)s) < time_format(%(posting_time)s, %(time_format)s) + time_format(posting_time, %(time_format)s) {operator} time_format(%(posting_time)s, %(time_format)s) ) ) 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, @@ -1375,7 +1375,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 9ae7578b078fd9809ad3f04a62d7025d104b706f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 2 Feb 2023 18:54:28 +0530 Subject: [PATCH 2/9] test: test case --- .../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 b574b718fe..4e4fe758b5 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1614,6 +1614,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 d7a665cb8478c72efbb7046ec1432eaa04ecc247 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Sun, 29 Jan 2023 11:52:25 +0530 Subject: [PATCH 3/9] chore: column width in `Warehouse wise Item Balance Age and Value` report --- .../warehouse_wise_item_balance_age_and_value.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py index b5c6764224..55454ded71 100644 --- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py +++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py @@ -89,10 +89,10 @@ def get_columns(filters): """return columns""" columns = [ - _("Item") + ":Link/Item:180", - _("Item Group") + "::100", + _("Item") + ":Link/Item:150", + _("Item Group") + "::120", _("Value") + ":Currency:120", - _("Age") + ":Float:80", + _("Age") + ":Float:120", ] return columns @@ -123,7 +123,7 @@ def get_warehouse_list(filters): def add_warehouse_column(columns, warehouse_list): if len(warehouse_list) > 1: - columns += [_("Total Qty") + ":Int:90"] + columns += [_("Total Qty") + ":Int:120"] for wh in warehouse_list: - columns += [_(wh.name) + ":Int:120"] + columns += [_(wh.name) + ":Int:100"] From 56356ffbb9302d36c6b206102fda94fc5997f2a6 Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Sun, 29 Jan 2023 12:22:01 +0530 Subject: [PATCH 4/9] chore: add `Item Name` column in `Warehouse wise Item Balance Age and Value` report --- .../warehouse_wise_item_balance_age_and_value.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py index 55454ded71..abbb33b2f1 100644 --- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py +++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py @@ -62,7 +62,7 @@ def execute(filters=None): continue total_stock_value = sum(item_value[(item, item_group)]) - row = [item, item_group, total_stock_value] + row = [item, item_map[item]["item_name"], item_group, total_stock_value] fifo_queue = item_ageing[item]["fifo_queue"] average_age = 0.00 @@ -90,6 +90,7 @@ def get_columns(filters): columns = [ _("Item") + ":Link/Item:150", + _("Item Name") + ":Link/Item:150", _("Item Group") + "::120", _("Value") + ":Currency:120", _("Age") + ":Float:120", From ce8a1086a7b4cc3c6f0a9d460fe7abd742faa5d8 Mon Sep 17 00:00:00 2001 From: developsessions Date: Fri, 3 Feb 2023 11:30:29 +0100 Subject: [PATCH 5/9] fix: default due_date was wrong calculated on template "_Test Payment Term Template 1" (last day of next month) --- erpnext/accounts/party.py | 2 +- erpnext/buying/doctype/purchase_order/test_purchase_order.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index b6eb3edbda..01cfb58dec 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -550,7 +550,7 @@ def get_due_date_from_template(template_name, posting_date, bill_date): elif term.due_date_based_on == "Day(s) after the end of the invoice month": due_date = max(due_date, add_days(get_last_day(due_date), term.credit_days)) else: - due_date = max(due_date, add_months(get_last_day(due_date), term.credit_months)) + due_date = max(due_date, get_last_day(add_months(due_date, term.credit_months))) return due_date diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index f0360b27dc..3c08d53288 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -23,6 +23,7 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( make_purchase_invoice as make_pi_from_pr, ) +from erpnext.accounts.party import get_due_date_from_template class TestPurchaseOrder(FrappeTestCase): @@ -685,6 +686,10 @@ class TestPurchaseOrder(FrappeTestCase): else: raise Exception + def test_default_payment_terms(self): + due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03") + self.assertEqual(due_date, "2023-03-31") + def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self): po = create_purchase_order(do_not_save=1) po.payment_terms_template = "_Test Payment Term Template" From c80aaad437e5b080d9bd929cbd5d22afcbbe77c6 Mon Sep 17 00:00:00 2001 From: developsessions Date: Fri, 3 Feb 2023 13:55:36 +0100 Subject: [PATCH 6/9] style: lint wrong from position --- erpnext/buying/doctype/purchase_order/test_purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 3c08d53288..14c54e92fa 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -10,6 +10,7 @@ from frappe.utils import add_days, flt, getdate, nowdate from frappe.utils.data import today from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry +from erpnext.accounts.party import get_due_date_from_template from erpnext.buying.doctype.purchase_order.purchase_order import make_inter_company_sales_order from erpnext.buying.doctype.purchase_order.purchase_order import ( make_purchase_invoice as make_pi_from_po, @@ -23,7 +24,6 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( make_purchase_invoice as make_pi_from_pr, ) -from erpnext.accounts.party import get_due_date_from_template class TestPurchaseOrder(FrappeTestCase): From be1f94199681a785173fef20be5ce9cc6932c134 Mon Sep 17 00:00:00 2001 From: developsessions Date: Fri, 3 Feb 2023 14:50:44 +0100 Subject: [PATCH 7/9] fix: Add missing 1 required positional argument: 'bill_date' --- erpnext/buying/doctype/purchase_order/test_purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 14c54e92fa..f3881bd2ec 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -687,7 +687,7 @@ class TestPurchaseOrder(FrappeTestCase): raise Exception def test_default_payment_terms(self): - due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03") + due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03", None) self.assertEqual(due_date, "2023-03-31") def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self): From 9d0096ad9ea17565d8ba692bb1c36ad7a64e96d5 Mon Sep 17 00:00:00 2001 From: developsessions Date: Fri, 3 Feb 2023 21:21:43 +0100 Subject: [PATCH 8/9] fix: failed test, convert date time to string --- erpnext/buying/doctype/purchase_order/test_purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index f3881bd2ec..4615b695d1 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -687,7 +687,7 @@ class TestPurchaseOrder(FrappeTestCase): raise Exception def test_default_payment_terms(self): - due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03", None) + due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03", None).strftime("%Y-%m-%d") self.assertEqual(due_date, "2023-03-31") def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self): From c8cd351b39e57295fb477b70c29dba14c13bb4dd Mon Sep 17 00:00:00 2001 From: developsessions Date: Sat, 4 Feb 2023 09:12:29 +0100 Subject: [PATCH 9/9] style: apply results of lint run --- erpnext/buying/doctype/purchase_order/test_purchase_order.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 4615b695d1..920486a78e 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -687,7 +687,9 @@ class TestPurchaseOrder(FrappeTestCase): raise Exception def test_default_payment_terms(self): - due_date = get_due_date_from_template("_Test Payment Term Template 1", "2023-02-03", None).strftime("%Y-%m-%d") + due_date = get_due_date_from_template( + "_Test Payment Term Template 1", "2023-02-03", None + ).strftime("%Y-%m-%d") self.assertEqual(due_date, "2023-03-31") def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self):