From df3d0859a13b00d9aa9377dac48cfc365e557b20 Mon Sep 17 00:00:00 2001 From: Loic Oberle Date: Sat, 23 May 2026 07:59:09 +0200 Subject: [PATCH] =?UTF-8?q?refactor(sales=5Fperson=5Fwise=5Ftransaction=5F?= =?UTF-8?q?summary):=20Replace=20SQL=20with=20que=E2=80=A6=20(#55191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sales_person_wise_transaction_summary.py | 94 ++++++++++--------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py index 8966e758fc2..ceb637e8078 100644 --- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py +++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py @@ -4,7 +4,7 @@ import frappe from frappe import _, msgprint, qb -from frappe.query_builder import Criterion +from frappe.query_builder import Case, Criterion from erpnext import get_company_currency @@ -146,50 +146,60 @@ def get_columns(filters): def get_entries(filters): - date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" - if filters["doc_type"] == "Sales Order": - qty_field = "delivered_qty" - else: - qty_field = "qty" - conditions, values = get_conditions(filters, date_field) + doc_type = filters["doc_type"] - entries = frappe.db.sql( - """ - SELECT - dt.name, dt.customer, dt.territory, dt.{} as posting_date, dt_item.item_code, - st.sales_person, st.allocated_percentage, dt_item.warehouse, - CASE - WHEN dt.status = "Closed" THEN dt_item.{} * dt_item.conversion_factor - ELSE dt_item.stock_qty - END as stock_qty, - CASE - WHEN dt.status = "Closed" THEN (dt_item.base_net_rate * dt_item.{} * dt_item.conversion_factor) - ELSE dt_item.base_net_amount - END as base_net_amount, - CASE - WHEN dt.status = "Closed" THEN ((dt_item.base_net_rate * dt_item.{} * dt_item.conversion_factor) * st.allocated_percentage/100) - ELSE dt_item.base_net_amount * st.allocated_percentage/100 - END as contribution_amt - FROM - `tab{}` dt, `tab{} Item` dt_item, `tabSales Team` st - WHERE - st.parent = dt.name and dt.name = dt_item.parent and st.parenttype = {} - and dt.docstatus = 1 {} order by st.sales_person, dt.name desc - """.format( - date_field, - qty_field, - qty_field, - qty_field, - filters["doc_type"], - filters["doc_type"], - "%s", - conditions, - ), - tuple([filters["doc_type"], *values]), - as_dict=1, + date_field = "transaction_date" if doc_type == "Sales Order" else "posting_date" + qty_field = "delivered_qty" if doc_type == "Sales Order" else "qty" + + dt = frappe.qb.DocType(doc_type) + dt_item = frappe.qb.DocType(f"{doc_type} Item") + st = frappe.qb.DocType("Sales Team") + + calc_qty = dt_item[qty_field] * dt_item.conversion_factor + calc_net_amount = dt_item.base_net_rate * calc_qty + + stock_qty_case = Case().when(dt.status == "Closed", calc_qty).else_(dt_item.stock_qty).as_("stock_qty") + + base_net_amount_case = ( + Case() + .when(dt.status == "Closed", calc_net_amount) + .else_(dt_item.base_net_amount) + .as_("base_net_amount") ) - return entries + contribution_amt_case = ( + Case() + .when(dt.status == "Closed", (calc_net_amount * st.allocated_percentage / 100)) + .else_(dt_item.base_net_amount * st.allocated_percentage / 100) + .as_("contribution_amt") + ) + + query = ( + frappe.get_query(dt, filters=filters, ignore_permissions=False) + .join(dt_item) + .on(dt.name == dt_item.parent) + .join(st) + .on(dt.name == st.parent) + .select( + dt.name, + dt.customer, + dt.territory, + dt[date_field].as_("posting_date"), + dt_item.item_code, + st.sales_person, + st.allocated_percentage, + dt_item.warehouse, + stock_qty_case, + base_net_amount_case, + contribution_amt_case, + ) + .where(st.parenttype == doc_type) + .where(dt.docstatus == 1) + ) + + query = query.orderby(st.sales_person).orderby(dt.name, order=frappe.qb.desc) + + return query.run(as_dict=True) def get_conditions(filters, date_field):