From 0ba6e60608b2f00d3ab68b6c837994f17e7df8d0 Mon Sep 17 00:00:00 2001 From: mahsem <137205921+mahsem@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:24:23 +0100 Subject: [PATCH 01/22] fix: add doc.status to translation from POS --- erpnext/selling/page/point_of_sale/pos_past_order_summary.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js index 4a2d8911d1a..ed6e6e02dcc 100644 --- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js +++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js @@ -85,7 +85,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
${doc.name}
- ${doc.status} + ${__(doc.status)}
`; } From 328b9e7d9e59b1f7e188d7ad211158806022372d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Di=C3=B3genes=20Souza?= <103958767+devdiogenes@users.noreply.github.com> Date: Fri, 13 Dec 2024 03:26:55 -0300 Subject: [PATCH 02/22] fix: Wrong allocated_amount for sales_team in gross_profit report (#42989) * fix: Wrong allocated_amount for sales_team in gross_profit report * style: Removes whitespaces --------- Co-authored-by: ruthra kumar --- erpnext/accounts/report/gross_profit/gross_profit.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index c59a3bd2a7a..647490dcc90 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -790,7 +790,10 @@ class GrossProfitGenerator: """ if self.filters.group_by == "Sales Person": - sales_person_cols = ", sales.sales_person, sales.allocated_amount, sales.incentives" + sales_person_cols = """, sales.sales_person, + sales.allocated_percentage * `tabSales Invoice Item`.base_net_amount / 100 as allocated_amount, + sales.incentives + """ sales_team_table = "left join `tabSales Team` sales on sales.parent = `tabSales Invoice`.name" else: sales_person_cols = "" From fdfbb577794fa6af0d3b148555d4d518632f72b9 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Thu, 12 Dec 2024 15:15:07 +0530 Subject: [PATCH 03/22] fix: remove invalid filter in Account Receivable report --- .../report/accounts_receivable/accounts_receivable.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 49dce0e299b..1d67109d68d 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -551,9 +551,7 @@ class ReceivablePayableReport: self.append_payment_term(row, d, term) def append_payment_term(self, row, d, term): - if ( - self.filters.get("customer") or self.filters.get("supplier") - ) and d.currency == d.party_account_currency: + if d.currency == d.party_account_currency: invoiced = d.payment_amount else: invoiced = d.base_payment_amount From 47c7356b38447ec70391cb329a972deedbfee0bf Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:18:04 +0530 Subject: [PATCH 04/22] fix: switched asset terminology from cost to value --- .../asset_depreciations_and_balances.py | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py index cdd5baf3240..bec5d128f0a 100644 --- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py +++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py @@ -28,15 +28,14 @@ def get_group_by_asset_category_data(filters): for asset_category in asset_categories: row = frappe._dict() - # row.asset_category = asset_category row.update(asset_category) - row.cost_as_on_to_date = ( - flt(row.cost_as_on_from_date) - + flt(row.cost_of_new_purchase) - - flt(row.cost_of_sold_asset) - - flt(row.cost_of_scrapped_asset) - - flt(row.cost_of_capitalized_asset) + row.value_as_on_to_date = ( + flt(row.value_as_on_from_date) + + flt(row.value_of_new_purchase) + - flt(row.value_of_sold_asset) + - flt(row.value_of_scrapped_asset) + - flt(row.value_of_capitalized_asset) ) row.update( @@ -53,11 +52,11 @@ def get_group_by_asset_category_data(filters): - flt(row.depreciation_eliminated_during_the_period) ) - row.net_asset_value_as_on_from_date = flt(row.cost_as_on_from_date) - flt( + row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt( row.accumulated_depreciation_as_on_from_date ) - row.net_asset_value_as_on_to_date = flt(row.cost_as_on_to_date) - flt( + row.net_asset_value_as_on_to_date = flt(row.value_as_on_to_date) - flt( row.accumulated_depreciation_as_on_to_date ) @@ -85,12 +84,12 @@ def get_asset_categories_for_grouped_by_category(filters): end else 0 - end), 0) as cost_as_on_from_date, + end), 0) as value_as_on_from_date, ifnull(sum(case when a.purchase_date >= %(from_date)s then a.gross_purchase_amount else 0 - end), 0) as cost_of_new_purchase, + end), 0) as value_of_new_purchase, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -101,7 +100,7 @@ def get_asset_categories_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_sold_asset, + end), 0) as value_of_sold_asset, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -112,7 +111,7 @@ def get_asset_categories_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_scrapped_asset, + end), 0) as value_of_scrapped_asset, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -123,7 +122,7 @@ def get_asset_categories_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_capitalized_asset + end), 0) as value_of_capitalized_asset from `tabAsset` a where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} and not exists( @@ -164,12 +163,12 @@ def get_asset_details_for_grouped_by_category(filters): end else 0 - end), 0) as cost_as_on_from_date, + end), 0) as value_as_on_from_date, ifnull(sum(case when a.purchase_date >= %(from_date)s then a.gross_purchase_amount else 0 - end), 0) as cost_of_new_purchase, + end), 0) as value_of_new_purchase, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -180,7 +179,7 @@ def get_asset_details_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_sold_asset, + end), 0) as value_of_sold_asset, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -191,7 +190,7 @@ def get_asset_details_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_scrapped_asset, + end), 0) as value_of_scrapped_asset, ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then @@ -202,7 +201,7 @@ def get_asset_details_for_grouped_by_category(filters): end else 0 - end), 0) as cost_of_capitalized_asset + end), 0) as value_of_capitalized_asset from `tabAsset` a where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition} and not exists( @@ -232,15 +231,14 @@ def get_group_by_asset_data(filters): for asset_detail in asset_details: row = frappe._dict() - # row.asset_category = asset_category row.update(asset_detail) - row.cost_as_on_to_date = ( - flt(row.cost_as_on_from_date) - + flt(row.cost_of_new_purchase) - - flt(row.cost_of_sold_asset) - - flt(row.cost_of_scrapped_asset) - - flt(row.cost_of_capitalized_asset) + row.value_as_on_to_date = ( + flt(row.value_as_on_from_date) + + flt(row.value_of_new_purchase) + - flt(row.value_of_sold_asset) + - flt(row.value_of_scrapped_asset) + - flt(row.value_of_capitalized_asset) ) row.update(next(asset for asset in assets if asset["asset"] == asset_detail.get("name", ""))) @@ -251,11 +249,11 @@ def get_group_by_asset_data(filters): - flt(row.depreciation_eliminated_during_the_period) ) - row.net_asset_value_as_on_from_date = flt(row.cost_as_on_from_date) - flt( + row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt( row.accumulated_depreciation_as_on_from_date ) - row.net_asset_value_as_on_to_date = flt(row.cost_as_on_to_date) - flt( + row.net_asset_value_as_on_to_date = flt(row.value_as_on_to_date) - flt( row.accumulated_depreciation_as_on_to_date ) @@ -446,38 +444,38 @@ def get_columns(filters): columns += [ { - "label": _("Cost as on") + " " + formatdate(filters.day_before_from_date), - "fieldname": "cost_as_on_from_date", + "label": _("Value as on") + " " + formatdate(filters.day_before_from_date), + "fieldname": "value_as_on_from_date", "fieldtype": "Currency", "width": 140, }, { - "label": _("Cost of New Purchase"), - "fieldname": "cost_of_new_purchase", + "label": _("Value of New Purchase"), + "fieldname": "value_of_new_purchase", "fieldtype": "Currency", "width": 140, }, { - "label": _("Cost of Sold Asset"), - "fieldname": "cost_of_sold_asset", + "label": _("Value of Sold Asset"), + "fieldname": "value_of_sold_asset", "fieldtype": "Currency", "width": 140, }, { - "label": _("Cost of Scrapped Asset"), - "fieldname": "cost_of_scrapped_asset", + "label": _("Value of Scrapped Asset"), + "fieldname": "value_of_scrapped_asset", "fieldtype": "Currency", "width": 140, }, { - "label": _("Cost of New Capitalized Asset"), - "fieldname": "cost_of_capitalized_asset", + "label": _("Value of New Capitalized Asset"), + "fieldname": "value_of_capitalized_asset", "fieldtype": "Currency", "width": 140, }, { - "label": _("Cost as on") + " " + formatdate(filters.to_date), - "fieldname": "cost_as_on_to_date", + "label": _("Value as on") + " " + formatdate(filters.to_date), + "fieldname": "value_as_on_to_date", "fieldtype": "Currency", "width": 140, }, From 78d7d7148f2443e48b4feb088c70522f62b6040f Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 16 Dec 2024 16:14:02 +0530 Subject: [PATCH 05/22] fix: broken CI - always install wkhtmltopdf - remove specific version on mariadb-client (cherry picked from commit eb1e36ca227480d8414b912a88cf440cfe0b7cd3) --- .github/helper/install.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/helper/install.sh b/.github/helper/install.sh index 915a4637999..30389734429 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -6,7 +6,7 @@ cd ~ || exit sudo apt update sudo apt remove mysql-server mysql-client -sudo apt install libcups2-dev redis-server mariadb-client-10.6 +sudo apt install libcups2-dev redis-server mariadb-client pip install frappe-bench @@ -44,13 +44,9 @@ fi install_whktml() { - if [ "$(lsb_release -rs)" = "22.04" ]; then - wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - sudo apt install /tmp/wkhtmltox.deb - else - echo "Please update this script to support wkhtmltopdf for $(lsb_release -ds)" - exit 1 - fi + wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb + sudo apt install /tmp/wkhtmltox.deb + } install_whktml & wkpid=$! From 158a4803ca2d0645387fc1b1b9040352b2328e9f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:04:40 +0530 Subject: [PATCH 06/22] fix: unsupported operand type (backport #44722) (#44723) fix: unsupported operand type (#44722) (cherry picked from commit 95da0913f6016c0f0c23b99712afa88fa87c74af) Co-authored-by: rohitwaghchaure --- .../serial_and_batch_bundle/serial_and_batch_bundle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index dc2071b9ee0..30538049e6c 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -505,9 +505,9 @@ class SerialandBatchBundle(Document): elif (d.incoming_rate == rate) and d.qty and d.stock_value_difference: continue - d.incoming_rate = rate + d.incoming_rate = flt(rate) if d.qty: - d.stock_value_difference = d.qty * d.incoming_rate + d.stock_value_difference = flt(d.qty) * d.incoming_rate if save: d.db_set( From 8940747161ca368e8ebab8f0eae199a70f09c3cf Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:04:54 +0530 Subject: [PATCH 07/22] fix: delink SABB from cancelled SLEs (backport #44691) (#44719) fix: delink SABB from cancelled SLEs (#44691) (cherry picked from commit 5f539619bc6f6ae713c8b82aba5b580345d47728) Co-authored-by: rohitwaghchaure --- .../pos_invoice_merge_log.py | 36 +++++++++++++++++++ .../serial_and_batch_bundle.py | 2 ++ 2 files changed, 38 insertions(+) diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index 5bb43b3fa72..b9bf145c728 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -132,6 +132,7 @@ class POSInvoiceMergeLog(Document): self.update_pos_invoices(pos_invoice_docs) self.serial_and_batch_bundle_reference_for_pos_invoice() self.cancel_linked_invoices() + self.delink_serial_and_batch_bundle() def process_merging_into_sales_invoice(self, data): sales_invoice = self.get_new_sales_invoice() @@ -319,6 +320,38 @@ class POSInvoiceMergeLog(Document): for table_name in ["items", "packed_items"]: pos_invoice.set_serial_and_batch_bundle(table_name) + def delink_serial_and_batch_bundle(self): + bundles = self.get_serial_and_batch_bundles() + if not bundles: + return + + sle_table = frappe.qb.DocType("Stock Ledger Entry") + query = ( + frappe.qb.update(sle_table) + .set(sle_table.serial_and_batch_bundle, None) + .where(sle_table.serial_and_batch_bundle.isin(bundles) & sle_table.is_cancelled == 1) + ) + + query.run() + + def get_serial_and_batch_bundles(self): + pos_invoices = [] + for d in self.pos_invoices: + pos_invoices.append(d.pos_invoice) + + if pos_invoices: + return frappe.get_all( + "POS Invoice Item", + filters={ + "docstatus": 1, + "parent": ["in", pos_invoices], + "serial_and_batch_bundle": ["is", "set"], + }, + pluck="serial_and_batch_bundle", + ) + + return [] + def cancel_linked_invoices(self): for si_name in [self.consolidated_invoice, self.consolidated_credit_note]: if not si_name: @@ -503,6 +536,9 @@ def cancel_merge_logs(merge_logs, closing_entry=None): try: for log in merge_logs: merge_log = frappe.get_doc("POS Invoice Merge Log", log) + if merge_log.docstatus == 2: + continue + merge_log.flags.ignore_permissions = True merge_log.cancel() diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 30538049e6c..f96a6760bec 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -519,6 +519,8 @@ class SerialandBatchBundle(Document): if not self.voucher_no or self.voucher_no != row.parent: values_to_set["voucher_no"] = row.parent + self.db_set("is_cancelled", 0) + if self.voucher_type != parent.doctype: values_to_set["voucher_type"] = parent.doctype From 7665eac277a1128eb686f97d3038fdd5d27c1063 Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Wed, 11 Dec 2024 12:15:56 +0530 Subject: [PATCH 08/22] feat: change type link to multiselect (cherry picked from commit 4de180feeea20a2f0a2c9c4ba794f1db55f82ed8) --- .../process_statement_of_accounts.json | 6 ++-- .../process_statement_of_accounts.py | 7 ++-- .../__init__.py | 0 .../process_statement_of_accounts_cc.json | 32 +++++++++++++++++++ .../process_statement_of_accounts_cc.py | 23 +++++++++++++ 5 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 erpnext/accounts/doctype/process_statement_of_accounts_cc/__init__.py create mode 100644 erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.json create mode 100644 erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.py diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json index 763607c22a1..ed9a4d84f53 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json @@ -244,9 +244,9 @@ }, { "fieldname": "cc_to", - "fieldtype": "Link", + "fieldtype": "Table MultiSelect", "label": "CC To", - "options": "User" + "options": "Process Statement Of Accounts CC" }, { "default": "1", @@ -400,7 +400,7 @@ } ], "links": [], - "modified": "2024-10-18 17:51:39.108481", + "modified": "2024-12-11 12:11:13.543134", "modified_by": "Administrator", "module": "Accounts", "name": "Process Statement Of Accounts", diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py index bf1c8c0b66e..6910559b8b4 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py @@ -31,6 +31,9 @@ class ProcessStatementOfAccounts(Document): if TYPE_CHECKING: from frappe.types import DF + from erpnext.accounts.doctype.process_statement_of_accounts_cc.process_statement_of_accounts_cc import ( + ProcessStatementOfAccountsCC, + ) from erpnext.accounts.doctype.process_statement_of_accounts_customer.process_statement_of_accounts_customer import ( ProcessStatementOfAccountsCustomer, ) @@ -41,7 +44,7 @@ class ProcessStatementOfAccounts(Document): ageing_based_on: DF.Literal["Due Date", "Posting Date"] based_on_payment_terms: DF.Check body: DF.TextEditor | None - cc_to: DF.Link | None + cc_to: DF.TableMultiSelect[ProcessStatementOfAccountsCC] collection_name: DF.DynamicLink | None company: DF.Link cost_center: DF.TableMultiSelect[PSOACostCenter] @@ -324,7 +327,7 @@ def get_recipients_and_cc(customer, doc): cc = [] if doc.cc_to != "": try: - cc = [frappe.get_value("User", doc.cc_to, "email")] + cc = [frappe.get_value("User", user.cc, "email") for user in doc.cc_to] except Exception: pass diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_cc/__init__.py b/erpnext/accounts/doctype/process_statement_of_accounts_cc/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.json b/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.json new file mode 100644 index 00000000000..c6103048b50 --- /dev/null +++ b/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.json @@ -0,0 +1,32 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-12-11 12:10:04.654593", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "cc" + ], + "fields": [ + { + "fieldname": "cc", + "fieldtype": "Link", + "in_list_view": 1, + "label": "CC", + "options": "User" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-12-11 12:10:39.772598", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Process Statement Of Accounts CC", + "owner": "Administrator", + "permissions": [], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.py b/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.py new file mode 100644 index 00000000000..a500b6c89a7 --- /dev/null +++ b/erpnext/accounts/doctype/process_statement_of_accounts_cc/process_statement_of_accounts_cc.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class ProcessStatementOfAccountsCC(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + cc: DF.Link | None + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + # end: auto-generated types + + pass From df9bc33f34c67ee0200be5e29bb99da09dab34ff Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Wed, 11 Dec 2024 12:17:18 +0530 Subject: [PATCH 09/22] fix: update cc_to multiselect in process statement of accounts (cherry picked from commit 2a6be127ef399566327cdbbc5305e51543ef7a36) # Conflicts: # erpnext/patches.txt --- erpnext/patches.txt | 5 +++++ .../update_cc_in_process_statement_of_accounts.py | 11 +++++++++++ 2 files changed, 16 insertions(+) create mode 100644 erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index a916478d4b3..fae3c93e722 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -383,5 +383,10 @@ erpnext.patches.v14_0.update_currency_exchange_settings_for_frankfurter erpnext.patches.v15_0.update_task_assignee_email_field_in_asset_maintenance_log erpnext.patches.v15_0.update_sub_voucher_type_in_gl_entries erpnext.patches.v14_0.update_stock_uom_in_work_order_item +<<<<<<< HEAD erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no +======= +erpnext.patches.v15_0.enable_allow_existing_serial_no +erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts +>>>>>>> 2a6be127ef (fix: update cc_to multiselect in process statement of accounts) diff --git a/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py new file mode 100644 index 00000000000..8b9ec0b9d3a --- /dev/null +++ b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py @@ -0,0 +1,11 @@ +import frappe + + +def execute(): + data = frappe.db.sql( + """SELECT name, cc_to FROM `tabProcess Statement Of Accounts` WHERE cc_to IS NOT NULL""", as_dict=True + ) + for d in data: + doc = frappe.get_doc("Process Statement Of Accounts", d.name) + doc.append("cc_to", {"cc": d.cc_to}) + doc.save() From 082fd27938c4bc5e7fa2eb62dcc81f08cdca173b Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Mon, 16 Dec 2024 11:26:49 +0530 Subject: [PATCH 10/22] refactor: convert sql query to query builder (cherry picked from commit 494ac04f8e189d19cfe7ee81bc6f4429ee136f8a) --- .../update_cc_in_process_statement_of_accounts.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py index 8b9ec0b9d3a..016aa8f14ea 100644 --- a/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py +++ b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py @@ -1,10 +1,16 @@ import frappe +from frappe import qb def execute(): - data = frappe.db.sql( - """SELECT name, cc_to FROM `tabProcess Statement Of Accounts` WHERE cc_to IS NOT NULL""", as_dict=True - ) + process_statement_of_accounts = qb.DocType("Process Statement Of Accounts") + + data = ( + frappe.qb.from_(process_statement_of_accounts) + .select(process_statement_of_accounts.name, process_statement_of_accounts.cc_to) + .where(process_statement_of_accounts.cc_to.isnotnull()) + ).run(as_dict=True) + for d in data: doc = frappe.get_doc("Process Statement Of Accounts", d.name) doc.append("cc_to", {"cc": d.cc_to}) From 5b4eb5ea9aa97b1fc03e4b27a6561e2aab76a24e Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Mon, 16 Dec 2024 11:55:34 +0530 Subject: [PATCH 11/22] chore: remove irrelevant import (cherry picked from commit 5401cf964704a4e540f942771882c54a94d6fc08) --- .../v15_0/update_cc_in_process_statement_of_accounts.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py index 016aa8f14ea..75aa8b9faf1 100644 --- a/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py +++ b/erpnext/patches/v15_0/update_cc_in_process_statement_of_accounts.py @@ -1,9 +1,8 @@ import frappe -from frappe import qb def execute(): - process_statement_of_accounts = qb.DocType("Process Statement Of Accounts") + process_statement_of_accounts = frappe.qb.DocType("Process Statement Of Accounts") data = ( frappe.qb.from_(process_statement_of_accounts) From 632a45d82e60ba4179d8f6c9a36e511e97de9193 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:31:38 +0530 Subject: [PATCH 12/22] fix: handle zero salvage value case --- erpnext/assets/doctype/asset/asset.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 05d575ac822..dbef3d096c7 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -805,6 +805,9 @@ class Asset(AccountsController): return args.get("rate_of_depreciation") if self.flags.increase_in_asset_value_due_to_repair: + if not flt(args.get("expected_value_after_useful_life")): + return args.get("rate_of_depreciation") + value = flt(args.get("expected_value_after_useful_life")) / flt( args.get("value_after_depreciation") ) From f9a904c58423074fed8013a20f130d88f6e2f0d8 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 17 Dec 2024 11:38:37 +0530 Subject: [PATCH 13/22] chore: resolve conflict --- erpnext/patches.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index fae3c93e722..7e03ef9394c 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -383,10 +383,6 @@ erpnext.patches.v14_0.update_currency_exchange_settings_for_frankfurter erpnext.patches.v15_0.update_task_assignee_email_field_in_asset_maintenance_log erpnext.patches.v15_0.update_sub_voucher_type_in_gl_entries erpnext.patches.v14_0.update_stock_uom_in_work_order_item -<<<<<<< HEAD erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no -======= -erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts ->>>>>>> 2a6be127ef (fix: update cc_to multiselect in process statement of accounts) From ed42ed04d262a492291a4720a8af6a32661f993e Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:36:30 +0530 Subject: [PATCH 14/22] fix: make rate of depreciation mandatory --- erpnext/assets/doctype/asset/asset.py | 6 +++--- .../doctype/asset_finance_book/asset_finance_book.json | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index dbef3d096c7..243ad009050 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -804,10 +804,10 @@ class Asset(AccountsController): ): return args.get("rate_of_depreciation") - if self.flags.increase_in_asset_value_due_to_repair: - if not flt(args.get("expected_value_after_useful_life")): - return args.get("rate_of_depreciation") + if args.get("rate_of_depreciation") and not flt(args.get("expected_value_after_useful_life")): + return args.get("rate_of_depreciation") + if self.flags.increase_in_asset_value_due_to_repair: value = flt(args.get("expected_value_after_useful_life")) / flt( args.get("value_after_depreciation") ) diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json index c269948b742..b86028a7621 100644 --- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json +++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json @@ -86,7 +86,8 @@ "description": "In Percentage", "fieldname": "rate_of_depreciation", "fieldtype": "Percent", - "label": "Rate of Depreciation" + "label": "Rate of Depreciation (%)", + "mandatory_depends_on": "eval:doc.depreciation_method == 'Written Down Value'" }, { "fieldname": "salvage_value_percentage", @@ -117,7 +118,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-05-21 15:48:20.907250", + "modified": "2024-12-13 12:11:03.743209", "modified_by": "Administrator", "module": "Assets", "name": "Asset Finance Book", From 8aec13115c28c5e28679f69ad2cb9ceae3d09cd6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:29:42 +0530 Subject: [PATCH 15/22] fix: pos invoice return reference missing (backport #44720) (#44729) fix: pos invoice return reference missing (#44720) (cherry picked from commit 852596dbe60664f07ad2862ce445ba0729153a73) Co-authored-by: rohitwaghchaure --- .../pos_invoice_merge_log.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py index b9bf145c728..761ed8d804e 100644 --- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py +++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py @@ -117,12 +117,12 @@ class POSInvoiceMergeLog(Document): sales = [d for d in pos_invoice_docs if d.get("is_return") == 0] sales_invoice, credit_note = "", "" - if returns: - credit_note = self.process_merging_into_credit_note(returns) - if sales: sales_invoice = self.process_merging_into_sales_invoice(sales) + if returns: + credit_note = self.process_merging_into_credit_note(returns, sales_invoice) + self.save() # save consolidated_sales_invoice & consolidated_credit_note ref in merge log self.update_pos_invoices(pos_invoice_docs, sales_invoice, credit_note) @@ -140,8 +140,13 @@ class POSInvoiceMergeLog(Document): sales_invoice.is_consolidated = 1 sales_invoice.set_posting_time = 1 - sales_invoice.posting_date = getdate(self.posting_date) - sales_invoice.posting_time = get_time(self.posting_time) + + if not sales_invoice.posting_date: + sales_invoice.posting_date = getdate(self.posting_date) + + if not sales_invoice.posting_time: + sales_invoice.posting_time = get_time(self.posting_time) + sales_invoice.save() sales_invoice.submit() @@ -149,12 +154,14 @@ class POSInvoiceMergeLog(Document): return sales_invoice.name - def process_merging_into_credit_note(self, data): + def process_merging_into_credit_note(self, data, sales_invoice): credit_note = self.get_new_sales_invoice() credit_note.is_return = 1 credit_note = self.merge_pos_invoice_into(credit_note, data) + credit_note.return_against = sales_invoice + credit_note.is_consolidated = 1 credit_note.set_posting_time = 1 credit_note.posting_date = getdate(self.posting_date) @@ -181,6 +188,10 @@ class POSInvoiceMergeLog(Document): for doc in data: map_doc(doc, invoice, table_map={"doctype": invoice.doctype}) + if doc.get("posting_date"): + invoice.posting_date = getdate(doc.posting_date) + invoice.posting_time = get_time(doc.posting_time) + if doc.redeem_loyalty_points: invoice.loyalty_redemption_account = doc.loyalty_redemption_account invoice.loyalty_redemption_cost_center = doc.loyalty_redemption_cost_center @@ -298,6 +309,8 @@ class POSInvoiceMergeLog(Document): sales_invoice = frappe.new_doc("Sales Invoice") sales_invoice.customer = self.customer sales_invoice.is_pos = 1 + sales_invoice.posting_date = None + sales_invoice.posting_time = None return sales_invoice From 8ba7424996136209c32b60593219e33fa330e8f7 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:48:18 +0530 Subject: [PATCH 16/22] fix: purchase return entry issue (backport #44721) (#44737) fix: purchase return entry issue (#44721) (cherry picked from commit 1f5d7072e7644aead90743e8316097bf1d0d4afb) Co-authored-by: rohitwaghchaure --- .../controllers/sales_and_purchase_return.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 696d404d16d..5c8f5a6fbd7 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -76,16 +76,13 @@ def validate_return_against(doc): def validate_returned_items(doc): valid_items = frappe._dict() - select_fields = "item_code, qty, stock_qty, rate, parenttype, conversion_factor" + select_fields = "item_code, qty, stock_qty, rate, parenttype, conversion_factor, name" if doc.doctype != "Purchase Invoice": select_fields += ",serial_no, batch_no" if doc.doctype in ["Purchase Invoice", "Purchase Receipt", "Subcontracting Receipt"]: select_fields += ",rejected_qty, received_qty" - if doc.doctype in ["Purchase Receipt", "Purchase Invoice"]: - select_fields += ",name" - for d in frappe.db.sql( f"""select {select_fields} from `tab{doc.doctype} Item` where parent = %s""", doc.return_against, @@ -113,11 +110,13 @@ def validate_returned_items(doc): for d in doc.get("items"): key = d.item_code raise_exception = False - if doc.doctype in ["Purchase Receipt", "Purchase Invoice"]: + if doc.doctype in ["Purchase Receipt", "Purchase Invoice", "Sales Invoice"]: field = frappe.scrub(doc.doctype) + "_item" if d.get(field): key = (d.item_code, d.get(field)) raise_exception = True + elif doc.doctype == "Delivery Note": + key = (d.item_code, d.get("dn_detail")) if d.item_code and (flt(d.qty) < 0 or flt(d.get("received_qty")) < 0): if key not in valid_items: @@ -129,7 +128,7 @@ def validate_returned_items(doc): ) else: ref = valid_items.get(key, frappe._dict()) - validate_quantity(doc, d, ref, valid_items, already_returned_items) + validate_quantity(doc, key, d, ref, valid_items, already_returned_items) if ( ref.rate @@ -159,7 +158,7 @@ def validate_returned_items(doc): frappe.throw(_("Atleast one item should be entered with negative quantity in return document")) -def validate_quantity(doc, args, ref, valid_items, already_returned_items): +def validate_quantity(doc, key, args, ref, valid_items, already_returned_items): fields = ["stock_qty"] if doc.doctype in ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"]: if not args.get("return_qty_from_rejected_warehouse"): @@ -167,7 +166,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items): else: fields.extend(["received_qty"]) - already_returned_data = already_returned_items.get(args.item_code) or {} + already_returned_data = already_returned_items.get(key) or {} company_currency = erpnext.get_company_currency(doc.company) stock_qty_precision = get_field_precision( @@ -253,15 +252,20 @@ def get_already_returned_items(doc): column += """, sum(abs(child.rejected_qty) * child.conversion_factor) as rejected_qty, sum(abs(child.received_qty) * child.conversion_factor) as received_qty""" + field = ( + frappe.scrub(doc.doctype) + "_item" + if doc.doctype in ["Purchase Invoice", "Purchase Receipt", "Sales Invoice"] + else "dn_detail" + ) data = frappe.db.sql( f""" - select {column} + select {column}, {field} from `tab{doc.doctype} Item` child, `tab{doc.doctype}` par where child.parent = par.name and par.docstatus = 1 and par.is_return = 1 and par.return_against = %s - group by item_code + group by item_code, {field} """, doc.return_against, as_dict=1, @@ -271,7 +275,7 @@ def get_already_returned_items(doc): for d in data: items.setdefault( - d.item_code, + (d.item_code, d.get(field)), frappe._dict( { "qty": d.get("qty"), From a8f739370610c21e8643526eb14c8055dbe0563a Mon Sep 17 00:00:00 2001 From: venkat102 Date: Fri, 13 Dec 2024 11:22:17 +0530 Subject: [PATCH 17/22] fix: set company bank account if default account not set in mode of payment (cherry picked from commit 91c7e3d5f3168736f40973816594a57e36d0f625) --- .../doctype/payment_entry/payment_entry.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index f2d11ba9ff3..8fd5f00b583 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -1328,6 +1328,24 @@ frappe.ui.form.on("Payment Entry", { if (r.message) { if (!frm.doc.mode_of_payment) { frm.set_value(field, r.message.account); + } else { + frappe.call({ + method: "frappe.client.get_value", + args: { + doctype: "Mode of Payment Account", + filters: { + parent: frm.doc.mode_of_payment, + company: frm.doc.company, + }, + fieldname: "default_account", + parent: "Mode of Payment", + }, + callback: function (res) { + if (!res.message.default_account) { + frm.set_value(field, r.message.account); + } + }, + }); } frm.set_value("bank", r.message.bank); frm.set_value("bank_account_no", r.message.bank_account_no); From db3a87c837bbccab59e3cc30e132aaa5b72bc66b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 17 Dec 2024 17:43:31 +0530 Subject: [PATCH 18/22] fix: allow all dispatch address for drop ship invoice --- erpnext/public/js/queries.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js index fd5b7603844..46958092199 100644 --- a/erpnext/public/js/queries.js +++ b/erpnext/public/js/queries.js @@ -99,9 +99,12 @@ $.extend(erpnext.queries, { }, dispatch_address_query: function (doc) { + var filters = { link_doctype: "Company", link_name: doc.company || "" }; + var is_drop_ship = doc.items.some((item) => item.delivered_by_supplier); + if (is_drop_ship) filters = {}; return { query: "frappe.contacts.doctype.address.address.address_query", - filters: { link_doctype: "Company", link_name: doc.company || "" }, + filters: filters, }; }, From 83aeb2e4754700467508533a7d4d736dbdfe489a Mon Sep 17 00:00:00 2001 From: ljain112 Date: Fri, 13 Dec 2024 13:46:15 +0530 Subject: [PATCH 19/22] fix: User permissions in financial statements (cherry picked from commit a626372d660a061de4594f92efaeac0a45d4bd57) --- erpnext/accounts/report/financial_statements.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 73e49983fb2..a12b217d1be 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -527,7 +527,16 @@ def get_accounting_entries( account_filter_query = get_account_filter_query(root_lft, root_rgt, root_type, gl_entry) query = query.where(ExistsCriterion(account_filter_query)) - entries = query.run(as_dict=True) + query = query.get_sql() + + from frappe.desk.reportview import build_match_conditions + + match_conditions = build_match_conditions(doctype) + + if match_conditions: + query += "and" + match_conditions + + entries = frappe.db.sql(query, as_dict=True) return entries From 40a8ed85711f86e95f8d5eca23ca6d3a77c74084 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Tue, 17 Dec 2024 18:49:38 +0530 Subject: [PATCH 20/22] fix: using query.walk() for escaping (cherry picked from commit 5ea131c763633e1c93abddcbcd551d6d10df7336) --- erpnext/accounts/report/financial_statements.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index a12b217d1be..918bafa169a 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -527,8 +527,6 @@ def get_accounting_entries( account_filter_query = get_account_filter_query(root_lft, root_rgt, root_type, gl_entry) query = query.where(ExistsCriterion(account_filter_query)) - query = query.get_sql() - from frappe.desk.reportview import build_match_conditions match_conditions = build_match_conditions(doctype) @@ -536,9 +534,9 @@ def get_accounting_entries( if match_conditions: query += "and" + match_conditions - entries = frappe.db.sql(query, as_dict=True) + query, params = query.walk() - return entries + return frappe.db.sql(query, params, as_dict=True) def get_account_filter_query(root_lft, root_rgt, root_type, gl_entry): From f1a5000872d0a3dc79f271afbe7a4d045282635f Mon Sep 17 00:00:00 2001 From: venkat102 Date: Sun, 15 Dec 2024 22:55:24 +0530 Subject: [PATCH 21/22] fix: update discount when pricing rule is changed (cherry picked from commit 8338d1d5b45dc20049130d96546fad002a64ba99) --- erpnext/accounts/doctype/pricing_rule/pricing_rule.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 73cb2483811..385cc1a685e 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -415,6 +415,8 @@ def get_pricing_rule_for_item(args, doc=None, for_validate=False): "parent": args.parent, "parenttype": args.parenttype, "child_docname": args.get("child_docname"), + "discount_percentage": 0.0, + "discount_amount": 0, } ) From 3ac801c884f93b1008adc126e31f73d6820575b1 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 18 Dec 2024 10:41:24 +0530 Subject: [PATCH 22/22] fix: duplicate Use Multi-Level BOM checkbox (#44757) --- erpnext/manufacturing/doctype/bom/bom.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index fe498ca32f9..4b52859cabd 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -255,15 +255,6 @@ frappe.ui.form.on("BOM", { }); } - if (!skip_qty_field) { - fields.push({ - fieldtype: "Check", - label: __("Use Multi-Level BOM"), - fieldname: "use_multi_level_bom", - default: 1, - }); - } - if (!skip_qty_field) { fields.push({ fieldtype: "Float",