From 804edad233d9e18b3a73a13572692e06c457b778 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 3 Jul 2025 15:41:14 +0530 Subject: [PATCH] refactor: build and pass match conditions as qb criterion (cherry picked from commit 7efeed54de47a0b52b1a8081ea2aee7c2831277d) # Conflicts: # erpnext/accounts/report/accounts_receivable/accounts_receivable.py # erpnext/accounts/utils.py --- .../accounts_receivable.py | 27 ++++++++- erpnext/accounts/utils.py | 55 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index b982b7f21d6..f016ef848d9 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -9,8 +9,11 @@ from frappe import _, qb, query_builder, scrub <<<<<<< HEAD ======= from frappe.database.schema import get_definition +<<<<<<< HEAD from frappe.desk.reportview import build_match_conditions >>>>>>> 9d0ebe3427 (refactor: dynamic DB field types) +======= +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion) from frappe.query_builder import Criterion from frappe.query_builder.functions import Date, Substring, Sum from frappe.utils import cint, cstr, flt, getdate, nowdate @@ -19,7 +22,16 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_accounting_dimensions, get_dimension_with_children, ) +<<<<<<< HEAD from erpnext.accounts.utils import get_currency_precision +======= +from erpnext.accounts.utils import ( + build_qb_match_conditions, + get_advance_payment_doctypes, + get_currency_precision, + get_party_types_from_account_type, +) +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion) # This report gives a summary of all Outstanding Invoices considering the following @@ -136,8 +148,12 @@ class ReceivablePayableReport: self.build_data() def fetch_ple_in_buffered_cursor(self): +<<<<<<< HEAD query, param = self.ple_query.walk() self.ple_entries = frappe.db.sql(query, param, as_dict=True) +======= + self.ple_entries = self.ple_query.run(as_dict=True) +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion) for ple in self.ple_entries: self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding @@ -150,9 +166,12 @@ class ReceivablePayableReport: def fetch_ple_in_unbuffered_cursor(self): self.ple_entries = [] +<<<<<<< HEAD query, param = self.ple_query.walk() +======= +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion) with frappe.db.unbuffered_cursor(): - for ple in frappe.db.sql(query, param, as_dict=True, as_iterator=True): + for ple in self.ple_query.run(as_dict=True, as_iterator=True): self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding self.ple_entries.append(ple) @@ -930,6 +949,12 @@ class ReceivablePayableReport: else: query = query.select(ple.remarks) +<<<<<<< HEAD +======= + if match_conditions := build_qb_match_conditions("Payment Ledger Entry"): + query = query.where(Criterion.all(match_conditions)) + +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion) if self.filters.get("group_by_party"): query = query.orderby(self.ple.party, self.ple.posting_date) else: diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index af760519054..9c0d0636525 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Optional import frappe import frappe.defaults from frappe import _, qb, throw +from frappe.desk.reportview import build_match_conditions from frappe.model.meta import get_field_precision from frappe.query_builder import AliasedQuery, Criterion, Table from frappe.query_builder.functions import Round, Sum @@ -2191,3 +2192,57 @@ def run_ledger_health_checks(): doc.general_and_payment_ledger_mismatch = True doc.checked_on = run_date doc.save() +<<<<<<< HEAD +======= + + +def sync_auto_reconcile_config(auto_reconciliation_job_trigger: int = 15): + auto_reconciliation_job_trigger = auto_reconciliation_job_trigger or frappe.get_single_value( + "Accounts Settings", "auto_reconciliation_job_trigger" + ) + method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs" + + sch_event = frappe.get_doc( + "Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method} + ) + if frappe.db.get_value("Scheduled Job Type", {"method": method}): + frappe.get_doc( + "Scheduled Job Type", + { + "method": method, + }, + ).update( + { + "cron_format": f"0/{auto_reconciliation_job_trigger} * * * *", + "scheduler_event": sch_event.name, + } + ).save() + else: + frappe.get_doc( + { + "doctype": "Scheduled Job Type", + "method": method, + "scheduler_event": sch_event.name, + "cron_format": f"0/{auto_reconciliation_job_trigger} * * * *", + "create_log": True, + "stopped": False, + "frequency": "Cron", + } + ).save() + + +def build_qb_match_conditions(doctype, user=None) -> list: + match_filters = build_match_conditions(doctype, user, False) + criterion = [] + if match_filters: + from frappe import qb + + _dt = qb.DocType(doctype) + + for filter in match_filters: + for d, names in filter.items(): + fieldname = d.lower().replace(" ", "_") + criterion.append(_dt[fieldname].isin(names)) + + return criterion +>>>>>>> 7efeed54de (refactor: build and pass match conditions as qb criterion)