From d2d28c9e0361f46ce5afc093e686a906c14546c4 Mon Sep 17 00:00:00 2001 From: Loic Oberle Date: Wed, 3 Jun 2026 11:49:24 +0200 Subject: [PATCH] refactor(accounting): replace sql with qb in diverse accounting-related files (#55416) --- .../accounting_dimension.py | 40 +++++++------- .../accounting_dimension_filter.py | 55 +++++++++++-------- .../accounting_period/accounting_period.py | 26 ++++----- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py index d43f333b50c..5b0e3bf939b 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py @@ -198,21 +198,9 @@ def add_dimension_to_budget_doctype(df, doc): def delete_accounting_dimension(doc): doclist = get_doctypes_with_dimensions() - frappe.db.sql( - """ - DELETE FROM `tabCustom Field` - WHERE fieldname = {} - AND dt IN ({})""".format("%s", ", ".join(["%s"] * len(doclist))), # nosec - tuple([doc.fieldname, *doclist]), - ) + frappe.db.delete("Custom Field", filters={"fieldname": doc.fieldname, "dt": ["in", doclist]}) - frappe.db.sql( - """ - DELETE FROM `tabProperty Setter` - WHERE field_name = {} - AND doc_type IN ({})""".format("%s", ", ".join(["%s"] * len(doclist))), # nosec - tuple([doc.fieldname, *doclist]), - ) + frappe.db.delete("Property Setter", filters={"field_name": doc.fieldname, "doc_type": ["in", doclist]}) budget_against_property = frappe.get_doc("Property Setter", "Budget-budget_against-options") value_list = budget_against_property.value.split("\n")[3:] @@ -273,13 +261,27 @@ def get_accounting_dimensions(as_list=True): def get_checks_for_pl_and_bs_accounts(): - return frappe.db.sql( - """SELECT p.label, p.disabled, p.fieldname, c.default_dimension, c.company, c.mandatory_for_pl, c.mandatory_for_bs - FROM `tabAccounting Dimension`p ,`tabAccounting Dimension Detail` c - WHERE p.name = c.parent AND p.disabled = 0""", - as_dict=1, + AccountingDimension = frappe.qb.DocType("Accounting Dimension") + AccountingDimensionDetail = frappe.qb.DocType("Accounting Dimension Detail") + + query = ( + frappe.qb.from_(AccountingDimension) + .join(AccountingDimensionDetail) + .on(AccountingDimension.name == AccountingDimensionDetail.parent) + .select( + AccountingDimension.label, + AccountingDimension.disabled, + AccountingDimension.fieldname, + AccountingDimensionDetail.default_dimension, + AccountingDimensionDetail.company, + AccountingDimensionDetail.mandatory_for_pl, + AccountingDimensionDetail.mandatory_for_bs, + ) + .where(AccountingDimension.disabled == 0) ) + return query.run(as_dict=1) + def get_dimension_with_children(doctype, dimensions): if isinstance(dimensions, str): diff --git a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py index 7846f11d91e..631e9a3acc0 100644 --- a/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py +++ b/erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py @@ -43,18 +43,19 @@ class AccountingDimensionFilter(Document): self.validate_applicable_accounts() def validate_applicable_accounts(self): - accounts = frappe.db.sql( - """ - SELECT a.applicable_on_account as account - FROM `tabApplicable On Account` a, `tabAccounting Dimension Filter` d - WHERE d.name = a.parent - and d.name != %s - and d.accounting_dimension = %s - """, - (self.name, self.accounting_dimension), - as_dict=1, + ApplicableOnAccount = frappe.qb.DocType("Applicable On Account") + AccountingDimensionFilter = frappe.qb.DocType("Accounting Dimension Filter") + + query = ( + frappe.qb.from_(ApplicableOnAccount) + .join(AccountingDimensionFilter) + .on(AccountingDimensionFilter.name == ApplicableOnAccount.parent) + .select(ApplicableOnAccount.applicable_on_account.as_("account")) + .where(AccountingDimensionFilter.name != self.name) + .where(AccountingDimensionFilter.accounting_dimension == self.accounting_dimension) ) + accounts = query.run(as_dict=1) account_list = [d.account for d in accounts] for account in self.get("accounts"): @@ -69,22 +70,28 @@ class AccountingDimensionFilter(Document): def get_dimension_filter_map(): - filters = frappe.db.sql( - """ - SELECT - a.applicable_on_account, d.dimension_value, p.accounting_dimension, - p.allow_or_restrict, p.fieldname, a.is_mandatory - FROM - `tabApplicable On Account` a, - `tabAccounting Dimension Filter` p - LEFT JOIN `tabAllowed Dimension` d ON d.parent = p.name - WHERE - p.name = a.parent - AND p.disabled = 0 - """, - as_dict=1, + ApplicableOnAccount = frappe.qb.DocType("Applicable On Account") + AccountingDimensionFilter = frappe.qb.DocType("Accounting Dimension Filter") + AllowedDimension = frappe.qb.DocType("Allowed Dimension") + + query = ( + frappe.qb.from_(AccountingDimensionFilter) + .join(ApplicableOnAccount) + .on(AccountingDimensionFilter.name == ApplicableOnAccount.parent) + .left_join(AllowedDimension) + .on(AllowedDimension.parent == AccountingDimensionFilter.name) + .select( + ApplicableOnAccount.applicable_on_account, + AllowedDimension.dimension_value, + AccountingDimensionFilter.accounting_dimension, + AccountingDimensionFilter.allow_or_restrict, + AccountingDimensionFilter.fieldname, + ApplicableOnAccount.is_mandatory, + ) + .where(AccountingDimensionFilter.disabled == 0) ) + filters = query.run(as_dict=1) dimension_filter_map = {} for f in filters: diff --git a/erpnext/accounts/doctype/accounting_period/accounting_period.py b/erpnext/accounts/doctype/accounting_period/accounting_period.py index 16a29bf4591..f1ea837f934 100644 --- a/erpnext/accounts/doctype/accounting_period/accounting_period.py +++ b/erpnext/accounts/doctype/accounting_period/accounting_period.py @@ -46,23 +46,19 @@ class AccountingPeriod(Document): self.name = " - ".join([self.period_name, company_abbr]) def validate_overlap(self): - existing_accounting_period = frappe.db.sql( - """select name from `tabAccounting Period` - where ( - (%(start_date)s between start_date and end_date) - or (%(end_date)s between start_date and end_date) - or (start_date between %(start_date)s and %(end_date)s) - or (end_date between %(start_date)s and %(end_date)s) - ) and name!=%(name)s and company=%(company)s""", - { - "start_date": self.start_date, - "end_date": self.end_date, - "name": self.name, - "company": self.company, - }, - as_dict=True, + AccountingPeriod = frappe.qb.DocType("Accounting Period") + + query = ( + frappe.qb.from_(AccountingPeriod) + .select(AccountingPeriod.name) + .where(AccountingPeriod.start_date <= self.end_date) + .where(AccountingPeriod.end_date >= self.start_date) + .where(AccountingPeriod.name != self.name) + .where(AccountingPeriod.company == self.company) ) + existing_accounting_period = query.run(as_dict=True) + if len(existing_accounting_period) > 0: frappe.throw( _("Accounting Period overlaps with {0}").format(existing_accounting_period[0].get("name")),