mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-28 22:28:24 +00:00
Convert raw `frappe.db.sql` in the Setup, Utilities, Templates and Regional areas to `frappe.qb` / the ORM so the same code runs on MariaDB and Postgres. Behaviour is preserved on MariaDB; the conversions also make these paths valid under Postgres' stricter SQL (GROUP BY, case-sensitivity, reserved words). Conversions of note (behaviour kept identical to the MariaDB original): - email_digest: ToDo ordering replicated with a CASE that mirrors MySQL `field(priority,'High','Medium','Low')` (unknown/NULL -> 0, sorts first), NULL-date-first and a `name` tie-break for a deterministic LIMIT. - company.get_all_transactions_annual_history: the cross-DocType UNION + GROUP BY is replaced by one grouped query per DocType merged with a Counter, so two different DocTypes sharing a transaction_date still collapse into one bucket. - templates/utils.send_message: contact lookup wraps both sides in LOWER() to keep MariaDB's case-insensitive email match on case-sensitive Postgres. - regional/irs_1099 & uae_vat_201: address ranking and emirate aggregation rebuilt with CASE/aggregate selects that satisfy Postgres GROUP BY, with a deterministic tie-break on the LIMIT-1 address lookups. - utilities/product.get_item_codes_by_attributes: numeric attribute values are cast with cstr() so Postgres doesn't reject `varchar = numeric`. Tests (run on both MariaDB and Postgres, --lightmode): - New: company merge test, authorization_rule duplicate-check, youtube report, templates/utils, and utilities/templates page reports (partners, rfq, material_request_info, product, utilities __init__). - Existing suites kept green: company, email_digest, transaction_deletion_record, irs_1099, uae_vat_201. Deferred (tracked separately): - setup/doctype/authorization_control.py still has raw `.format()` SELECTs; left for its own PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# License: GNU General Public License v3. See license.txt
|
|
|
|
|
|
import frappe
|
|
from frappe import _
|
|
from frappe.utils import flt
|
|
|
|
|
|
def get_context(context):
|
|
context.no_cache = 1
|
|
context.show_sidebar = True
|
|
context.doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
|
|
if hasattr(context.doc, "set_indicator"):
|
|
context.doc.set_indicator()
|
|
|
|
context.parents = frappe.form_dict.parents
|
|
context.title = frappe.form_dict.name
|
|
|
|
if not frappe.has_website_permission(context.doc):
|
|
frappe.throw(_("Not Permitted"), frappe.PermissionError)
|
|
|
|
default_print_format = frappe.db.get_value(
|
|
"Property Setter",
|
|
dict(property="default_print_format", doc_type=frappe.form_dict.doctype),
|
|
"value",
|
|
)
|
|
if default_print_format:
|
|
context.print_format = default_print_format
|
|
else:
|
|
context.print_format = "Standard"
|
|
context.doc.items = get_more_items_info(context.doc.items, context.doc.name)
|
|
|
|
|
|
def get_more_items_info(items, material_request):
|
|
for item in items:
|
|
item.customer_provided = frappe.get_value("Item", item.item_code, "is_customer_provided_item")
|
|
wo = frappe.qb.DocType("Work Order")
|
|
wo_item = frappe.qb.DocType("Work Order Item")
|
|
item.work_orders = (
|
|
frappe.qb.from_(wo_item)
|
|
.inner_join(wo)
|
|
.on(wo_item.parent == wo.name)
|
|
.select(wo.name, wo.status, wo_item.consumed_qty)
|
|
.where(
|
|
(wo_item.item_code == item.item_code)
|
|
& (wo_item.consumed_qty == 0)
|
|
& (wo.status.notin(["Completed", "Cancelled", "Stopped"]))
|
|
)
|
|
.orderby(wo.name)
|
|
.run(as_dict=1)
|
|
)
|
|
item.delivered_qty = flt(
|
|
frappe.get_all(
|
|
"Stock Entry Detail",
|
|
filters={
|
|
"material_request": material_request,
|
|
"item_code": item.item_code,
|
|
"docstatus": 1,
|
|
},
|
|
fields=[{"SUM": "transfer_qty", "as": "transfer_qty"}],
|
|
)[0].transfer_qty
|
|
)
|
|
return items
|