From 713fa67b96a98e1bee905fa7755f634819703533 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 May 2023 17:54:34 +0530 Subject: [PATCH 1/6] fix: account closing balance patch --- erpnext/patches.txt | 2 +- .../patches/v14_0/update_closing_balances.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 03c7b01856..129506d941 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -326,7 +326,7 @@ erpnext.patches.v13_0.update_docs_link erpnext.patches.v15_0.update_asset_value_for_manual_depr_entries erpnext.patches.v15_0.update_gpa_and_ndb_for_assdeprsch erpnext.patches.v14_0.create_accounting_dimensions_for_closing_balance -erpnext.patches.v14_0.update_closing_balances +erpnext.patches.v14_0.update_closing_balances #05-05-2023 execute:frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) # below migration patches should always run last erpnext.patches.v14_0.migrate_gl_to_payment_ledger diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index f47e730fd2..b4cdc9faf4 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -11,6 +11,8 @@ from erpnext.accounts.utils import get_fiscal_year def execute(): + frappe.db.truncate("Account Closing Balance") + company_wise_order = {} get_opening_entries = True for pcv in frappe.db.get_all( @@ -35,7 +37,20 @@ def execute(): entry["closing_date"] = pcv_doc.posting_date entry["period_closing_voucher"] = pcv_doc.name - closing_entries = pcv_doc.get_grouped_gl_entries(get_opening_entries=get_opening_entries) + closing_entries = frappe.db.get_all( + "GL Entry", + filters={ + "is_cancelled": 0, + "voucher_type": ["!=", "Period Closing Voucher"], + "posting_date": ["<=", pcv.posting_date], + }, + fields=["*"], + ) + + for entry in closing_entries: + entry["closing_date"] = pcv_doc.posting_date + entry["period_closing_voucher"] = pcv_doc.name + make_closing_entries(gl_entries + closing_entries, voucher_name=pcv.name) company_wise_order[pcv.company].append(pcv.posting_date) get_opening_entries = False From f5cc41e1824d86996a35d45fe4ac61abbaf45347 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 10 May 2023 16:41:47 +0530 Subject: [PATCH 2/6] fix: account closing balance patch --- erpnext/patches.txt | 2 +- erpnext/patches/v14_0/update_closing_balances.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 129506d941..e158df63ff 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -326,7 +326,7 @@ erpnext.patches.v13_0.update_docs_link erpnext.patches.v15_0.update_asset_value_for_manual_depr_entries erpnext.patches.v15_0.update_gpa_and_ndb_for_assdeprsch erpnext.patches.v14_0.create_accounting_dimensions_for_closing_balance -erpnext.patches.v14_0.update_closing_balances #05-05-2023 +erpnext.patches.v14_0.update_closing_balances #10-05-2023 execute:frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) # below migration patches should always run last erpnext.patches.v14_0.migrate_gl_to_payment_ledger diff --git a/erpnext/patches/v14_0/update_closing_balances.py b/erpnext/patches/v14_0/update_closing_balances.py index b4cdc9faf4..bb108ab827 100644 --- a/erpnext/patches/v14_0/update_closing_balances.py +++ b/erpnext/patches/v14_0/update_closing_balances.py @@ -41,7 +41,7 @@ def execute(): "GL Entry", filters={ "is_cancelled": 0, - "voucher_type": ["!=", "Period Closing Voucher"], + "voucher_no": ["!=", pcv.name], "posting_date": ["<=", pcv.posting_date], }, fields=["*"], From 7a3801578cb3cf6fbaa6fc35814fc97e73820dcd Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 11 May 2023 23:17:09 +0530 Subject: [PATCH 3/6] fix: enqueue submit/cancel action for stock entry to avoid time out error --- .../stock/doctype/stock_entry/stock_entry.py | 44 ++++++++++++++++++- .../doctype/stock_entry/test_stock_entry.py | 30 ++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index cc0923f37c..e508b9043b 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -9,7 +9,17 @@ import frappe from frappe import _ from frappe.model.mapper import get_mapped_doc from frappe.query_builder.functions import Sum -from frappe.utils import cint, comma_or, cstr, flt, format_time, formatdate, getdate, nowdate +from frappe.utils import ( + cint, + comma_or, + cstr, + flt, + format_time, + formatdate, + getdate, + month_diff, + nowdate, +) import erpnext from erpnext.accounts.general_ledger import process_gl_map @@ -151,6 +161,38 @@ class StockEntry(StockController): self.reset_default_field_value("from_warehouse", "items", "s_warehouse") self.reset_default_field_value("to_warehouse", "items", "t_warehouse") + def submit(self): + if self.is_enqueue_action(): + frappe.msgprint( + _( + "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Draft stage" + ) + ) + self.queue_action("submit", timeout=2000) + else: + self._submit() + + def cancel(self): + if self.is_enqueue_action(): + frappe.msgprint( + _( + "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Submitted stage" + ) + ) + self.queue_action("cancel", timeout=2000) + else: + self._cancel() + + def is_enqueue_action(self, force=False) -> bool: + if force: + return True + + # If line items are more than 100 or record is older than 6 months + if len(self.items) > 100 or month_diff(nowdate(), self.posting_date) > 6: + return True + + return False + def on_submit(self): self.update_stock_ledger() diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index c43a1b1b81..9a748abb3b 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -5,7 +5,7 @@ import frappe from frappe.permissions import add_user_permission, remove_user_permission from frappe.tests.utils import FrappeTestCase, change_settings -from frappe.utils import add_days, flt, nowdate, nowtime, today +from frappe.utils import add_days, add_to_date, flt, nowdate, nowtime, today from erpnext.accounts.doctype.account.test_account import get_inventory_account from erpnext.stock.doctype.item.test_item import ( @@ -1707,6 +1707,34 @@ class TestStockEntry(FrappeTestCase): self.assertRaises(frappe.ValidationError, sr_doc.submit) + def test_enqueue_action(self): + item_code = "Test Enqueue Item - 001" + create_item(item_code=item_code, is_stock_item=1, valuation_rate=10) + + doc = make_stock_entry( + item_code=item_code, + posting_date=add_to_date(today(), months=-7), + posting_time="00:00:00", + purpose="Material Receipt", + qty=10, + to_warehouse="_Test Warehouse - _TC", + do_not_submit=True, + ) + + self.assertTrue(doc.is_enqueue_action()) + + doc = make_stock_entry( + item_code=item_code, + posting_date=today(), + posting_time="00:00:00", + purpose="Material Receipt", + qty=10, + to_warehouse="_Test Warehouse - _TC", + do_not_submit=True, + ) + + self.assertFalse(doc.is_enqueue_action()) + def make_serialized_item(**args): args = frappe._dict(args) From 2d6f112727185cff40662d8d5873cedb128d9218 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 12 May 2023 10:51:14 +0530 Subject: [PATCH 4/6] fix: test case --- erpnext/stock/doctype/stock_entry/stock_entry.py | 3 +++ erpnext/stock/doctype/stock_entry/test_stock_entry.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index e508b9043b..cd076d88db 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -187,6 +187,9 @@ class StockEntry(StockController): if force: return True + if frappe.flags.in_test: + return False + # If line items are more than 100 or record is older than 6 months if len(self.items) > 100 or month_diff(nowdate(), self.posting_date) > 6: return True diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 9a748abb3b..de74fda687 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1708,6 +1708,7 @@ class TestStockEntry(FrappeTestCase): self.assertRaises(frappe.ValidationError, sr_doc.submit) def test_enqueue_action(self): + frappe.flags.in_test = False item_code = "Test Enqueue Item - 001" create_item(item_code=item_code, is_stock_item=1, valuation_rate=10) @@ -1734,6 +1735,7 @@ class TestStockEntry(FrappeTestCase): ) self.assertFalse(doc.is_enqueue_action()) + frappe.flags.in_test = True def make_serialized_item(**args): From 2879cb7c280d82e879dd787c5d4a90e9f27cda14 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 12 May 2023 13:08:32 +0530 Subject: [PATCH 5/6] fix: bom item filter issue --- erpnext/manufacturing/doctype/bom/bom.js | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index f147b46ca7..8c671e2644 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -48,7 +48,6 @@ frappe.ui.form.on("BOM", { return { query: "erpnext.manufacturing.doctype.bom.bom.item_query", filters: { - "item_code": doc.item, "include_item_in_manufacturing": 1, "is_fixed_asset": 0 } From a686b8c337abe8425a041ab82e702d904f48b617 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 12 May 2023 13:47:53 +0530 Subject: [PATCH 6/6] fix: incorrect packing items --- .../doctype/sales_order/sales_order.py | 4 ++ .../doctype/sales_order/test_sales_order.py | 69 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index de63f6dec5..06467e51a6 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -620,6 +620,8 @@ def make_project(source_name, target_doc=None): @frappe.whitelist() def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False): + from erpnext.stock.doctype.packed_item.packed_item import make_packing_list + def set_missing_values(source, target): target.run_method("set_missing_values") target.run_method("set_po_nos") @@ -634,6 +636,8 @@ def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False): if target.company_address: target.update(get_fetch_values("Delivery Note", "company_address", target.company_address)) + make_packing_list(target) + def update_item(source, target, source_parent): target.base_amount = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.base_rate) target.amount = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.rate) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index ba8bbc2185..9854f159cf 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -1909,6 +1909,75 @@ class TestSalesOrder(FrappeTestCase): self.assertEqual(mr.items[0].qty, 6) + def test_packed_items_for_partial_sales_order(self): + # test Update Items with product bundle + for product_bundle in [ + "_Test Product Bundle Item Partial 1", + "_Test Product Bundle Item Partial 2", + ]: + if not frappe.db.exists("Item", product_bundle): + bundle_item = make_item(product_bundle, {"is_stock_item": 0}) + bundle_item.append( + "item_defaults", {"company": "_Test Company", "default_warehouse": "_Test Warehouse - _TC"} + ) + bundle_item.save(ignore_permissions=True) + + for product_bundle in ["_Packed Item Partial 1", "_Packed Item Partial 2"]: + if not frappe.db.exists("Item", product_bundle): + make_item(product_bundle, {"is_stock_item": 1, "stock_uom": "Nos"}) + + make_stock_entry(item=product_bundle, target="_Test Warehouse - _TC", qty=2, rate=10) + + make_product_bundle("_Test Product Bundle Item Partial 1", ["_Packed Item Partial 1"], 1) + + make_product_bundle("_Test Product Bundle Item Partial 2", ["_Packed Item Partial 2"], 1) + + so = make_sales_order( + item_code="_Test Product Bundle Item Partial 1", + warehouse="_Test Warehouse - _TC", + qty=1, + uom="Nos", + stock_uom="Nos", + conversion_factor=1, + transaction_date=nowdate(), + delivery_note=nowdate(), + do_not_submit=1, + ) + + so.append( + "items", + { + "item_code": "_Test Product Bundle Item Partial 2", + "warehouse": "_Test Warehouse - _TC", + "qty": 1, + "uom": "Nos", + "stock_uom": "Nos", + "conversion_factor": 1, + "delivery_note": nowdate(), + }, + ) + + so.save() + so.submit() + + dn = make_delivery_note(so.name) + dn.remove(dn.items[1]) + dn.save() + dn.submit() + + self.assertEqual(len(dn.items), 1) + self.assertEqual(len(dn.packed_items), 1) + self.assertEqual(dn.items[0].item_code, "_Test Product Bundle Item Partial 1") + + so.load_from_db() + + dn = make_delivery_note(so.name) + dn.save() + + self.assertEqual(len(dn.items), 1) + self.assertEqual(len(dn.packed_items), 1) + self.assertEqual(dn.items[0].item_code, "_Test Product Bundle Item Partial 2") + def automatically_fetch_payment_terms(enable=1): accounts_settings = frappe.get_doc("Accounts Settings")