From ff0daedd52bf60e17093f5ed5adbb3e5b35acf94 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 29 Jan 2024 16:34:42 +0530 Subject: [PATCH] refactor: convert sql to query builder on Payments query --- .../payment_reconciliation.py | 43 +++--- erpnext/controllers/accounts_controller.py | 125 +++++++++--------- 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 3246327864d..435837f4460 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -114,14 +114,6 @@ class PaymentReconciliation(Document): order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order" condition = self.get_payment_entry_conditions() - # pass dynamic dimension filter values to query builder - dimensions = {} - for x in self.dimensions: - dimension = x.fieldname - if self.get(dimension): - dimensions.update({dimension: self.get(dimension)}) - condition.update({"accounting_dimensions": dimensions}) - payment_entries = get_advance_payment_entries_for_regional( self.party_type, self.party, @@ -653,27 +645,32 @@ class PaymentReconciliation(Document): self.build_dimensions_filter_conditions() def get_payment_entry_conditions(self): - condition = " and company = '{0}' ".format(self.company) + conditions = [] + pe = qb.DocType("Payment Entry") + conditions.append(pe.company == self.company) if self.get("cost_center"): - condition = " and cost_center = '{0}' ".format(self.cost_center) + conditions.append(pe.cost_center == self.cost_center) - condition += ( - " and posting_date >= {0}".format(frappe.db.escape(self.from_payment_date)) - if self.from_payment_date - else "" - ) - condition += ( - " and posting_date <= {0}".format(frappe.db.escape(self.to_payment_date)) - if self.to_payment_date - else "" - ) + if self.from_payment_date: + conditions.append(pe.posting_date.gte(self.from_payment_date)) + + if self.to_payment_date: + conditions.append(pe.posting_date.lte(self.to_payment_date)) if self.minimum_payment_amount: - condition += " and unallocated_amount >= {0}".format(flt(self.minimum_payment_amount)) + conditions.append(pe.unallocated_amount.gte(flt(self.minimum_payment_amount))) + if self.maximum_payment_amount: - condition += " and unallocated_amount <= {0}".format(flt(self.maximum_payment_amount)) - return condition + conditions.append(pe.unallocated_amount.lte(flt(self.maximum_payment_amount))) + + # pass dynamic dimension filter values to payment query + for x in self.dimensions: + dimension = x.fieldname + if self.get(dimension): + conditions.append(pe[dimension] == self.get(dimension)) + + return conditions def get_journal_filter_conditions(self): conditions = [] diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index cd7b7b69529..bb87a776a1d 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -7,6 +7,8 @@ import json import frappe from frappe import _, bold, qb, throw from frappe.model.workflow import get_workflow_name, is_transition_condition_satisfied +from frappe.query_builder import Criterion +from frappe.query_builder.custom import ConstantColumn from frappe.query_builder.functions import Abs, Sum from frappe.utils import ( add_days, @@ -2541,6 +2543,9 @@ def get_advance_payment_entries( condition=None, payment_name=None, ): + pe = qb.DocType("Payment Entry") + per = qb.DocType("Payment Entry Reference") + party_account_field = "paid_from" if party_type == "Customer" else "paid_to" currency_field = ( "paid_from_account_currency" if party_type == "Customer" else "paid_to_account_currency" @@ -2551,76 +2556,74 @@ def get_advance_payment_entries( ) payment_entries_against_order, unallocated_payment_entries = [], [] - limit_cond = "limit %s" % limit if limit else "" + + if payment_name: + condition.append(pe.name.like(f"%%{payment_name}%%")) if order_list or against_all_orders: if order_list: - reference_condition = " and t2.reference_name in ({0})".format( - ", ".join(["%s"] * len(order_list)) + condition.append(per.refernce_name.isin(order_list)) + payment_entries_query = ( + qb.from_(pe) + .inner_join(per) + .on(pe.name == per.parent) + .select( + ConstantColumn("Payment Entry").as_("reference_type"), + pe.name, + pe.remarks, + per.allocated_amount.as_("amount"), + per.name.as_("reference_row"), + per.reference_name.as_("against_order"), + pe.posting_date, + pe[currency_field].as_("currency"), + pe[exchange_rate_field].as_("exchange_rate"), ) - else: - reference_condition = "" - order_list = [] - - payment_name_filter = "" - if payment_name: - payment_name_filter = " and t1.name like '%%{0}%%'".format(payment_name) - - if not condition: - condition = "" - - payment_entries_against_order = frappe.db.sql( - """ - select - 'Payment Entry' as reference_type, t1.name as reference_name, - t1.remarks, t2.allocated_amount as amount, t2.name as reference_row, - t2.reference_name as against_order, t1.posting_date, - t1.{0} as currency, t1.{5} as exchange_rate - from `tabPayment Entry` t1, `tabPayment Entry Reference` t2 - where - t1.name = t2.parent and t1.{1} = %s and t1.payment_type = %s - and t1.party_type = %s and t1.party = %s and t1.docstatus = 1 - and t2.reference_doctype = %s {2} {3} {6} - order by t1.posting_date {4} - """.format( - currency_field, - party_account_field, - reference_condition, - condition, - limit_cond, - exchange_rate_field, - payment_name_filter, - ), - [party_account, payment_type, party_type, party, order_doctype] + order_list, - as_dict=1, + .where( + (pe[party_account_field] == party_account) + & (pe.payment_type == payment_type) + & (pe.party_type == party_type) + & (pe.party == party) + & (pe.docstatus == 1) + & (per.reference_doctype == order_doctype) + ) + .where(Criterion.all(condition)) + .orderby(pe.posting_date) ) + if limit: + payment_entries_query = payment_entries_query.limit(limit) + + payment_entries_against_order = payment_entries_query.run(as_dict=1) + if include_unallocated: - payment_name_filter = "" - if payment_name: - payment_name_filter = " and name like '%%{0}%%'".format(payment_name) - - unallocated_payment_entries = frappe.db.sql( - """ - select 'Payment Entry' as reference_type, name as reference_name, posting_date, - remarks, unallocated_amount as amount, {2} as exchange_rate, {3} as currency - from `tabPayment Entry` - where - {0} = %s and party_type = %s and party = %s and payment_type = %s - and docstatus = 1 and unallocated_amount > 0 {condition} {4} - order by posting_date {1} - """.format( - party_account_field, - limit_cond, - exchange_rate_field, - currency_field, - payment_name_filter, - condition=condition or "", - ), - (party_account, party_type, party, payment_type), - as_dict=1, + unallocated_payment_query = ( + qb.from_(pe) + .select( + ConstantColumn("Payment Entry").as_("reference_type"), + pe.name.as_("reference_name"), + pe.posting_date, + pe.remarks, + pe.unallocated_amount.as_("amount"), + pe[exchange_rate_field].as_("exchange_rate"), + pe[currency_field].as_("currency"), + ) + .where( + (pe[party_account_field] == party_account) + & (pe.party_type == party_type) + & (pe.party == party) + & (pe.payment_type == payment_type) + & (pe.docstatus == 1) + & (pe.unallocated_amount.gt(0)) + ) + .where(Criterion.all(condition)) + .orderby(pe.posting_date) ) + if limit: + unallocated_payment_query = unallocated_payment_query.limit(limit) + + unallocated_payment_entries = unallocated_payment_query.run(as_dict=1) + return list(payment_entries_against_order) + list(unallocated_payment_entries)