From d40e660a527c5329dd8b1bdf148ed8bf8b097c39 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Nov 2025 12:55:10 +0530 Subject: [PATCH] fix: use qb for functions --- .../bank_statement_import.py | 3 ++- .../opening_invoice_creation_tool.py | 2 +- .../opportunity_summary_by_sales_stage.py | 2 +- .../sales_pipeline_analytics.py | 2 +- erpnext/manufacturing/doctype/bom/bom.py | 17 ++++++++++------- .../bom_operations_time/bom_operations_time.py | 2 +- ...stock_ledger_entries_for_target_warehouse.py | 2 +- .../setup/doctype/email_digest/email_digest.py | 2 +- erpnext/stock/doctype/warehouse/warehouse.py | 6 +++++- 9 files changed, 23 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py index 28915c8e6d0..0a291d3668e 100644 --- a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py +++ b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py @@ -14,6 +14,7 @@ import openpyxl from frappe import _ from frappe.core.doctype.data_import.data_import import DataImport from frappe.core.doctype.data_import.importer import Importer, ImportFile +from frappe.query_builder.functions import Count from frappe.utils.background_jobs import enqueue from frappe.utils.file_manager import get_file, save_file from frappe.utils.xlsxutils import ILLEGAL_CHARACTERS_RE, handle_html @@ -371,7 +372,7 @@ def get_import_status(docname): logs = frappe.get_all( "Data Import Log", - fields=["count(*) as count", "success"], + fields=[{"COUNT": "*", "as": "count"}, "success"], filters={"data_import": docname}, group_by="success", ) diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index be545ac980b..bab64406bd0 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -71,7 +71,7 @@ class OpeningInvoiceCreationTool(Document): max_count = {} fields = [ "company", - "count(name) as total_invoices", + {"COUNT": "*", "as": "total_invoices"}, "sum(outstanding_amount) as outstanding_amount", ] companies = frappe.get_all("Company", fields=["name as company", "default_currency as currency"]) diff --git a/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py index 370d3a85333..d2fc4ca849b 100644 --- a/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py +++ b/erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py @@ -74,7 +74,7 @@ class OpportunitySummaryBySalesStage: }[self.filters.get("based_on")] data_based_on = { - "Number": "count(name) as count", + "Number": {"COUNT": "*", "as": "count"}, "Amount": "opportunity_amount as amount", }[self.filters.get("data_based_on")] diff --git a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py index 217d9ca31be..0bb050a6fe2 100644 --- a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py +++ b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py @@ -74,7 +74,7 @@ class SalesPipelineAnalytics: ] self.data_based_on = { - "Number": "count(name) as count", + "Number": {"COUNT": "*", "as": "count"}, "Amount": "opportunity_amount as amount", }[self.filters.get("based_on")] diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index a484361dd0a..8a7e8d4571f 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -10,6 +10,8 @@ import frappe from frappe import _, bold from frappe.core.doctype.version.version import get_diff from frappe.model.mapper import get_mapped_doc +from frappe.query_builder import Field +from frappe.query_builder.functions import Count, IfNull, Sum from frappe.utils import cint, cstr, flt, get_link_to_form, parse_json, today from frappe.website.website_generator import WebsiteGenerator @@ -1191,7 +1193,6 @@ def get_valuation_rate(data): 2) If no value, get last valuation rate from SLE 3) If no value, get valuation rate from Item """ - from frappe.query_builder.functions import Count, IfNull, Sum from pypika import Case item_code, company = data.get("item_code"), data.get("company") @@ -1482,7 +1483,10 @@ def add_non_stock_items_cost(stock_entry, work_order, expense_account, job_card= non_stock_items = frappe.get_all( "Item", fields="name", - filters={"name": ("in", list(items.keys())), "ifnull(is_stock_item, 0)": 0}, + filters=[ + ["name", "in", list(items.keys())], + [IfNull(Field("is_stock_item"), 0), "=", 0], + ], as_list=1, ) @@ -1601,8 +1605,6 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None, job_ ) def get_max_operation_quantity(): - from frappe.query_builder.functions import Sum - table = frappe.qb.DocType("Job Card") query = ( frappe.qb.from_(table) @@ -1617,8 +1619,6 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None, job_ return min([d.qty for d in query.run(as_dict=True)], default=0) def get_utilised_corrective_cost(): - from frappe.query_builder.functions import Sum - table = frappe.qb.DocType("Stock Entry") subquery = ( frappe.qb.from_(table) @@ -1728,7 +1728,10 @@ def item_query(doctype, txt, searchfield, start, page_len, filters): if not searchfields: searchfields = ["name"] - query_filters = {"disabled": 0, "ifnull(end_of_life, '3099-12-31')": (">", today())} + query_filters = [ + ["disabled", "=", 0], + [IfNull(Field("end_of_life"), "3099-12-31"), ">", today()], + ] or_cond_filters = {} if txt: diff --git a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py index 92c69cf3e0a..3e1a905915f 100644 --- a/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py +++ b/erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py @@ -80,7 +80,7 @@ def get_filtered_data(filters): def get_bom_count(bom_data): data = frappe.get_all( "BOM Item", - fields=["count(name) as count", "bom_no"], + fields=[{"COUNT": "*", "as": "count"}, "bom_no"], filters={"bom_no": ("in", bom_data)}, group_by="bom_no", ) diff --git a/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py index 69ddb603d7d..83fa2cef8eb 100644 --- a/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py +++ b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py @@ -8,7 +8,7 @@ import frappe def execute(): warehouse_perm = frappe.get_all( "User Permission", - fields=["count(*) as p_count", "is_default", "user"], + fields=[{"COUNT": "*", "as": "p_count"}, "is_default", "user"], filters={"allow": "Warehouse"}, group_by="user", ) diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py index ba837c6d9dc..b7d80af85f5 100644 --- a/erpnext/setup/doctype/email_digest/email_digest.py +++ b/erpnext/setup/doctype/email_digest/email_digest.py @@ -799,7 +799,7 @@ class EmailDigest(Document): "status": ["not in", ("Cancelled")], "company": self.company, }, - fields=["count(*) as count", "sum(grand_total) as grand_total"], + fields=[{"COUNT": "*", "as": "count"}, "sum(grand_total) as grand_total"], ) def get_from_to_date(self): diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 63a2f209d02..8fabedfa49c 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -7,6 +7,8 @@ import json import frappe from frappe import _, throw from frappe.contacts.address_and_contact import load_address_and_contact +from frappe.query_builder import Field +from frappe.query_builder.functions import IfNull from frappe.utils import cint from frappe.utils.caching import request_cache from frappe.utils.nestedset import NestedSet @@ -197,10 +199,12 @@ def get_children(doctype, parent=None, company=None, is_root=False, include_disa include_disabled = json.loads(include_disabled) fields = ["name as value", "is_group as expandable"] + filters = [ - ["ifnull(`parent_warehouse`, '')", "=", parent], + [IfNull(Field("parent_warehouse"), ""), "=", parent], ["company", "in", (company, None, "")], ] + if frappe.db.has_column(doctype, "disabled") and not include_disabled: filters.append(["disabled", "=", False])