mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-13 03:45:08 +00:00
perf: Use lazy loaded documents (#48017)
* perf: Use lazy docs for status updaters and similar use cases * perf: lazy load documents while reposting
This commit is contained in:
@@ -498,7 +498,7 @@ class PaymentEntry(AccountsController):
|
||||
def delink_advance_entry_references(self):
|
||||
for reference in self.references:
|
||||
if reference.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
doc = frappe.get_doc(reference.reference_doctype, reference.reference_name)
|
||||
doc = frappe.get_lazy_doc(reference.reference_doctype, reference.reference_name)
|
||||
doc.delink_advance_entries(self.name)
|
||||
|
||||
def set_missing_values(self):
|
||||
@@ -661,7 +661,7 @@ class PaymentEntry(AccountsController):
|
||||
if not frappe.db.exists(d.reference_doctype, d.reference_name):
|
||||
frappe.throw(_("{0} {1} does not exist").format(d.reference_doctype, d.reference_name))
|
||||
|
||||
ref_doc = frappe.get_doc(d.reference_doctype, d.reference_name)
|
||||
ref_doc = frappe.get_lazy_doc(d.reference_doctype, d.reference_name)
|
||||
|
||||
if d.reference_doctype != "Journal Entry":
|
||||
if self.party != ref_doc.get(scrub(self.party_type)):
|
||||
@@ -1785,7 +1785,7 @@ class PaymentEntry(AccountsController):
|
||||
)
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount and d.reference_doctype in advance_payment_doctypes:
|
||||
frappe.get_doc(
|
||||
frappe.get_lazy_doc(
|
||||
d.reference_doctype, d.reference_name, for_update=True
|
||||
).set_total_advance_paid()
|
||||
|
||||
@@ -2865,7 +2865,7 @@ def get_reference_details(
|
||||
):
|
||||
total_amount = outstanding_amount = exchange_rate = account = None
|
||||
|
||||
ref_doc = frappe.get_doc(reference_doctype, reference_name)
|
||||
ref_doc = frappe.get_lazy_doc(reference_doctype, reference_name)
|
||||
company_currency = ref_doc.get("company_currency") or erpnext.get_company_currency(ref_doc.company)
|
||||
|
||||
# Only applies for Reverse Payment Entries
|
||||
|
||||
@@ -749,7 +749,7 @@ class PurchaseInvoice(BuyingController):
|
||||
self.update_status_updater_args()
|
||||
self.update_prevdoc_status()
|
||||
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total
|
||||
)
|
||||
|
||||
@@ -1718,7 +1718,7 @@ class PurchaseInvoice(BuyingController):
|
||||
res = frappe.qb.from_(pj).select(pj.total_purchase_cost).where(pj.name == proj).for_update().run()
|
||||
current_purchase_cost = res and res[0][0] or 0
|
||||
# frappe.db.set_value("Project", proj, "total_purchase_cost", current_purchase_cost + value)
|
||||
project_doc = frappe.get_doc("Project", proj)
|
||||
project_doc = frappe.get_lazy_doc("Project", proj)
|
||||
project_doc.total_purchase_cost = current_purchase_cost + value
|
||||
project_doc.calculate_gross_margin()
|
||||
project_doc.db_update()
|
||||
@@ -1790,7 +1790,7 @@ class PurchaseInvoice(BuyingController):
|
||||
for pr in set(updated_pr):
|
||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_billing_percentage
|
||||
|
||||
pr_doc = frappe.get_doc("Purchase Receipt", pr)
|
||||
pr_doc = frappe.get_lazy_doc("Purchase Receipt", pr)
|
||||
update_billing_percentage(
|
||||
pr_doc, update_modified=update_modified, adjust_incoming_rate=adjust_incoming_rate
|
||||
)
|
||||
@@ -2046,21 +2046,21 @@ def make_stock_entry(source_name, target_doc=None):
|
||||
@frappe.whitelist()
|
||||
def change_release_date(name, release_date=None):
|
||||
if frappe.db.exists("Purchase Invoice", name):
|
||||
pi = frappe.get_doc("Purchase Invoice", name)
|
||||
pi = frappe.get_lazy_doc("Purchase Invoice", name)
|
||||
pi.db_set("release_date", release_date)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def unblock_invoice(name):
|
||||
if frappe.db.exists("Purchase Invoice", name):
|
||||
pi = frappe.get_doc("Purchase Invoice", name)
|
||||
pi = frappe.get_lazy_doc("Purchase Invoice", name)
|
||||
pi.unblock_invoice()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def block_invoice(name, release_date, hold_comment=None):
|
||||
if frappe.db.exists("Purchase Invoice", name):
|
||||
pi = frappe.get_doc("Purchase Invoice", name)
|
||||
pi = frappe.get_lazy_doc("Purchase Invoice", name)
|
||||
pi.block_invoice(hold_comment, release_date)
|
||||
|
||||
|
||||
|
||||
@@ -448,7 +448,7 @@ class SalesInvoice(SellingController):
|
||||
self.validate_pos_paid_amount()
|
||||
|
||||
if not self.auto_repeat:
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total, self
|
||||
)
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ def get_balance_on(
|
||||
report_type = ""
|
||||
|
||||
if cost_center and report_type == "Profit and Loss":
|
||||
cc = frappe.get_doc("Cost Center", cost_center)
|
||||
cc = frappe.get_lazy_doc("Cost Center", cost_center)
|
||||
if cc.is_group:
|
||||
cond.append(
|
||||
f""" exists (
|
||||
@@ -555,7 +555,7 @@ def reconcile_against_document(
|
||||
# update advance paid in Advance Receivable/Payable doctypes
|
||||
if update_advance_paid:
|
||||
for t, n in update_advance_paid:
|
||||
frappe.get_doc(t, n).set_total_advance_paid()
|
||||
frappe.get_lazy_doc(t, n).set_total_advance_paid()
|
||||
|
||||
frappe.flags.ignore_party_validation = False
|
||||
|
||||
@@ -1467,7 +1467,7 @@ def repost_gle_for_stock_vouchers(
|
||||
|
||||
for voucher_type, voucher_no in stock_vouchers_chunk:
|
||||
existing_gle = gle.get((voucher_type, voucher_no), [])
|
||||
voucher_obj = frappe.get_doc(voucher_type, voucher_no)
|
||||
voucher_obj = frappe.get_lazy_doc(voucher_type, voucher_no)
|
||||
# Some transactions post credit as negative debit, this is handled while posting GLE
|
||||
# but while comparing we need to make sure it's flipped so comparisons are accurate
|
||||
expected_gle = toggle_debit_credit_if_negative(voucher_obj.get_gl_entries(warehouse_account))
|
||||
@@ -1891,7 +1891,7 @@ def update_voucher_outstanding(voucher_type, voucher_no, account, party_type, pa
|
||||
and voucher_outstanding
|
||||
):
|
||||
outstanding = voucher_outstanding[0]
|
||||
ref_doc = frappe.get_doc(voucher_type, voucher_no)
|
||||
ref_doc = frappe.get_lazy_doc(voucher_type, voucher_no)
|
||||
outstanding_amount = flt(
|
||||
outstanding["outstanding_in_account_currency"], ref_doc.precision("outstanding_amount")
|
||||
)
|
||||
|
||||
@@ -498,7 +498,7 @@ class PurchaseOrder(BuyingController):
|
||||
self.validate_budget()
|
||||
self.update_reserved_qty_for_subcontract()
|
||||
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total
|
||||
)
|
||||
|
||||
@@ -594,7 +594,7 @@ class PurchaseOrder(BuyingController):
|
||||
sales_orders_to_update.append(item.sales_order)
|
||||
|
||||
for so_name in sales_orders_to_update:
|
||||
so = frappe.get_doc("Sales Order", so_name)
|
||||
so = frappe.get_lazy_doc("Sales Order", so_name)
|
||||
so.update_delivery_status()
|
||||
so.set_status(update=True)
|
||||
so.notify_update()
|
||||
@@ -725,7 +725,7 @@ def close_or_unclose_purchase_orders(names, status):
|
||||
|
||||
names = json.loads(names)
|
||||
for name in names:
|
||||
po = frappe.get_doc("Purchase Order", name)
|
||||
po = frappe.get_lazy_doc("Purchase Order", name)
|
||||
if po.docstatus == 1:
|
||||
if status == "Closed":
|
||||
if po.status not in ("Cancelled", "Closed") and (
|
||||
@@ -902,7 +902,7 @@ def get_list_context(context=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_status(status, name):
|
||||
po = frappe.get_doc("Purchase Order", name)
|
||||
po = frappe.get_lazy_doc("Purchase Order", name)
|
||||
po.update_status(status)
|
||||
po.update_delivered_qty_in_sales_order()
|
||||
|
||||
|
||||
@@ -150,10 +150,7 @@ class AccountsController(TransactionBase):
|
||||
supplier = None
|
||||
|
||||
if supplier_name:
|
||||
supplier = frappe.get_doc(
|
||||
"Supplier",
|
||||
supplier_name,
|
||||
)
|
||||
supplier = frappe.get_lazy_doc("Supplier", supplier_name)
|
||||
|
||||
if supplier and supplier.on_hold:
|
||||
if (is_buying_invoice and supplier.hold_type in ["All", "Invoices"]) or (
|
||||
@@ -3918,7 +3915,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
if parent_doctype == "Sales Order":
|
||||
make_packing_list(parent)
|
||||
parent.set_gross_profit()
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
parent.doctype, parent.company, parent.base_grand_total
|
||||
)
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ class BudgetValidation:
|
||||
def get_dimensions(self):
|
||||
self.dimensions = []
|
||||
for _x in frappe.db.get_all("Accounting Dimension"):
|
||||
self.dimensions.append(frappe.get_doc("Accounting Dimension", _x.name))
|
||||
self.dimensions.append(frappe.get_lazy_doc("Accounting Dimension", _x.name))
|
||||
self.dimensions.extend(
|
||||
[
|
||||
{"fieldname": "cost_center", "document_type": "Cost Center"},
|
||||
|
||||
@@ -793,7 +793,7 @@ class BuyingController(SubcontractingController):
|
||||
|
||||
for po, po_item_rows in po_map.items():
|
||||
if po and po_item_rows:
|
||||
po_obj = frappe.get_doc("Purchase Order", po)
|
||||
po_obj = frappe.get_lazy_doc("Purchase Order", po)
|
||||
|
||||
if po_obj.status in ["Closed", "Cancelled"]:
|
||||
frappe.throw(
|
||||
|
||||
@@ -123,7 +123,7 @@ class SellingController(StockController):
|
||||
|
||||
def remove_shipping_charge(self):
|
||||
if self.shipping_rule:
|
||||
shipping_rule = frappe.get_doc("Shipping Rule", self.shipping_rule)
|
||||
shipping_rule = frappe.get_last_doc("Shipping Rule", self.shipping_rule)
|
||||
existing_shipping_charge = self.get(
|
||||
"taxes",
|
||||
{
|
||||
@@ -463,7 +463,7 @@ class SellingController(StockController):
|
||||
|
||||
for so, so_item_rows in so_map.items():
|
||||
if so and so_item_rows:
|
||||
sales_order = frappe.get_doc("Sales Order", so)
|
||||
sales_order = frappe.get_lazy_doc("Sales Order", so)
|
||||
|
||||
if (sales_order.status == "Closed" and not self.is_return) or sales_order.status in [
|
||||
"Cancelled"
|
||||
|
||||
@@ -559,7 +559,7 @@ class StatusUpdater(Document):
|
||||
)
|
||||
|
||||
if update_data:
|
||||
target = frappe.get_doc(args["target_parent_dt"], args["name"])
|
||||
target = frappe.get_lazy_doc(args["target_parent_dt"], args["name"])
|
||||
target.update(update_data) # status calculus might depend on it
|
||||
status = target.get_status()
|
||||
if status.get("status"):
|
||||
@@ -619,7 +619,7 @@ class StatusUpdater(Document):
|
||||
|
||||
per_billed = safe_div(min(ref_doc_qty, billed_qty), ref_doc_qty) * 100
|
||||
|
||||
ref_doc = frappe.get_doc(ref_dt, ref_dn)
|
||||
ref_doc = frappe.get_lazy_doc(ref_dt, ref_dn)
|
||||
|
||||
ref_doc.db_set("per_billed", per_billed)
|
||||
|
||||
|
||||
@@ -1444,7 +1444,7 @@ class StockController(AccountsController):
|
||||
@frappe.whitelist()
|
||||
def show_accounting_ledger_preview(company, doctype, docname):
|
||||
filters = frappe._dict(company=company, include_dimensions=1)
|
||||
doc = frappe.get_doc(doctype, docname)
|
||||
doc = frappe.get_lazy_doc(doctype, docname)
|
||||
doc.run_method("before_gl_preview")
|
||||
|
||||
gl_columns, gl_data = get_accounting_ledger_preview(doc, filters)
|
||||
@@ -1457,7 +1457,7 @@ def show_accounting_ledger_preview(company, doctype, docname):
|
||||
@frappe.whitelist()
|
||||
def show_stock_ledger_preview(company, doctype, docname):
|
||||
filters = frappe._dict(company=company)
|
||||
doc = frappe.get_doc(doctype, docname)
|
||||
doc = frappe.get_lazy_doc(doctype, docname)
|
||||
doc.run_method("before_sl_preview")
|
||||
|
||||
sl_columns, sl_data = get_stock_ledger_preview(doc, filters)
|
||||
|
||||
@@ -284,7 +284,7 @@ class Quotation(SellingController):
|
||||
|
||||
def on_submit(self):
|
||||
# Check for Approving Authority
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total, self
|
||||
)
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ class SalesOrder(SellingController):
|
||||
self.check_credit_limit()
|
||||
self.update_reserved_qty()
|
||||
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total, self
|
||||
)
|
||||
self.update_project()
|
||||
@@ -487,7 +487,7 @@ class SalesOrder(SellingController):
|
||||
return
|
||||
|
||||
if self.project:
|
||||
project = frappe.get_doc("Project", self.project)
|
||||
project = frappe.get_lazy_doc("Project", self.project)
|
||||
project.update_sales_amount()
|
||||
project.db_update()
|
||||
|
||||
@@ -825,7 +825,7 @@ def close_or_unclose_sales_orders(names, status):
|
||||
|
||||
names = json.loads(names)
|
||||
for name in names:
|
||||
so = frappe.get_doc("Sales Order", name)
|
||||
so = frappe.get_lazy_doc("Sales Order", name)
|
||||
if so.docstatus == 1:
|
||||
if status == "Closed":
|
||||
if so.status not in ("Cancelled", "Closed") and (
|
||||
|
||||
@@ -639,7 +639,7 @@ class DeliveryNote(SellingController):
|
||||
updated_delivery_notes += update_billed_amount_based_on_so(d.so_detail, update_modified)
|
||||
|
||||
for dn in set(updated_delivery_notes):
|
||||
dn_doc = self if (dn == self.name) else frappe.get_doc("Delivery Note", dn)
|
||||
dn_doc = self if (dn == self.name) else frappe.get_lazy_doc("Delivery Note", dn)
|
||||
dn_doc.update_billing_percentage(update_modified=update_modified)
|
||||
|
||||
self.load_from_db()
|
||||
@@ -1102,7 +1102,7 @@ def make_sales_return(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_delivery_note_status(docname, status):
|
||||
dn = frappe.get_doc("Delivery Note", docname)
|
||||
dn = frappe.get_lazy_doc("Delivery Note", docname)
|
||||
dn.update_status(status)
|
||||
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ class PurchaseReceipt(BuyingController):
|
||||
super().on_submit()
|
||||
|
||||
# Check for Approving Authority
|
||||
frappe.get_doc("Authorization Control").validate_approving_authority(
|
||||
frappe.get_cached_doc("Authorization Control").validate_approving_authority(
|
||||
self.doctype, self.company, self.base_grand_total
|
||||
)
|
||||
|
||||
@@ -942,7 +942,7 @@ class PurchaseReceipt(BuyingController):
|
||||
updated_pr += update_billed_amount_based_on_po(po_details, update_modified, self)
|
||||
|
||||
for pr in set(updated_pr):
|
||||
pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr)
|
||||
pr_doc = self if (pr == self.name) else frappe.get_lazy_doc("Purchase Receipt", pr)
|
||||
update_billing_percentage(pr_doc, update_modified=update_modified)
|
||||
|
||||
def reserve_stock(self):
|
||||
@@ -980,7 +980,7 @@ class PurchaseReceipt(BuyingController):
|
||||
)
|
||||
|
||||
for so, items_details in so_items_details_map.items():
|
||||
so_doc = frappe.get_doc("Sales Order", so)
|
||||
so_doc = frappe.get_lazy_doc("Sales Order", so)
|
||||
so_doc.create_stock_reservation_entries(
|
||||
items_details=items_details,
|
||||
from_voucher_type="Purchase Receipt",
|
||||
@@ -1463,7 +1463,7 @@ def make_purchase_return(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_purchase_receipt_status(docname, status):
|
||||
pr = frappe.get_doc("Purchase Receipt", docname)
|
||||
pr = frappe.get_lazy_doc("Purchase Receipt", docname)
|
||||
pr.update_status(status)
|
||||
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ def _get_directly_dependent_vouchers(doc):
|
||||
warehouses = set()
|
||||
|
||||
if doc.based_on == "Transaction":
|
||||
ref_doc = frappe.get_doc(doc.voucher_type, doc.voucher_no)
|
||||
ref_doc = frappe.get_lazy_doc(doc.voucher_type, doc.voucher_no)
|
||||
doc_items, doc_warehouses = ref_doc.get_items_and_warehouses()
|
||||
items.update(doc_items)
|
||||
warehouses.update(doc_warehouses)
|
||||
|
||||
@@ -1225,7 +1225,7 @@ class update_entries_after:
|
||||
return False
|
||||
|
||||
def recalculate_amounts_in_stock_entry(self, voucher_no, voucher_detail_no):
|
||||
stock_entry = frappe.get_doc("Stock Entry", voucher_no, for_update=True)
|
||||
stock_entry = frappe.get_lazy_doc("Stock Entry", voucher_no, for_update=True)
|
||||
stock_entry.calculate_rate_and_amount(reset_outgoing_rate=False, raise_error_if_no_rate=False)
|
||||
stock_entry.db_update()
|
||||
for d in stock_entry.items:
|
||||
@@ -1268,7 +1268,7 @@ class update_entries_after:
|
||||
|
||||
# Recalculate subcontracted item's rate in case of subcontracted purchase receipt/invoice
|
||||
if frappe.get_cached_value(sle.voucher_type, sle.voucher_no, "is_subcontracted"):
|
||||
doc = frappe.get_doc(sle.voucher_type, sle.voucher_no)
|
||||
doc = frappe.get_lazy_doc(sle.voucher_type, sle.voucher_no)
|
||||
doc.update_valuation_rate(reset_outgoing_rate=False)
|
||||
for d in doc.items + doc.supplied_items:
|
||||
d.db_update()
|
||||
@@ -1283,7 +1283,7 @@ class update_entries_after:
|
||||
{"rate": outgoing_rate, "amount": abs(sle.actual_qty) * outgoing_rate},
|
||||
)
|
||||
|
||||
scr = frappe.get_doc("Subcontracting Receipt", sle.voucher_no, for_update=True)
|
||||
scr = frappe.get_lazy_doc("Subcontracting Receipt", sle.voucher_no, for_update=True)
|
||||
scr.calculate_items_qty_and_amount()
|
||||
scr.db_update()
|
||||
for d in scr.items:
|
||||
@@ -1291,7 +1291,7 @@ class update_entries_after:
|
||||
|
||||
def update_rate_on_stock_reconciliation(self, sle):
|
||||
if not sle.serial_no and not sle.batch_no:
|
||||
sr = frappe.get_doc("Stock Reconciliation", sle.voucher_no, for_update=True)
|
||||
sr = frappe.get_lazy_doc("Stock Reconciliation", sle.voucher_no, for_update=True)
|
||||
|
||||
for item in sr.items:
|
||||
# Skip for Serial and Batch Items
|
||||
|
||||
Reference in New Issue
Block a user