Merge pull request #33722 from rohitwaghchaure/purchase-invoice-performance-issue

fix: purchase invoice performance issue
This commit is contained in:
rohitwaghchaure 2023-02-20 12:47:07 +05:30 committed by GitHub
commit 3871cf7110
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 21 deletions

View File

@ -5,6 +5,7 @@
import frappe import frappe
from frappe import _, throw from frappe import _, throw
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe.query_builder.functions import Sum
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
import erpnext import erpnext
@ -1465,19 +1466,16 @@ class PurchaseInvoice(BuyingController):
def update_billing_status_in_pr(self, update_modified=True): def update_billing_status_in_pr(self, update_modified=True):
updated_pr = [] updated_pr = []
po_details = [] po_details = []
pr_details_billed_amt = self.get_pr_details_billed_amt()
for d in self.get("items"): for d in self.get("items"):
if d.pr_detail: if d.pr_detail:
billed_amt = frappe.db.sql(
"""select sum(amount) from `tabPurchase Invoice Item`
where pr_detail=%s and docstatus=1""",
d.pr_detail,
)
billed_amt = billed_amt and billed_amt[0][0] or 0
frappe.db.set_value( frappe.db.set_value(
"Purchase Receipt Item", "Purchase Receipt Item",
d.pr_detail, d.pr_detail,
"billed_amt", "billed_amt",
billed_amt, flt(pr_details_billed_amt.get(d.pr_detail)),
update_modified=update_modified, update_modified=update_modified,
) )
updated_pr.append(d.purchase_receipt) updated_pr.append(d.purchase_receipt)
@ -1493,6 +1491,24 @@ class PurchaseInvoice(BuyingController):
pr_doc = frappe.get_doc("Purchase Receipt", pr) pr_doc = frappe.get_doc("Purchase Receipt", pr)
update_billing_percentage(pr_doc, update_modified=update_modified) update_billing_percentage(pr_doc, update_modified=update_modified)
def get_pr_details_billed_amt(self):
# Get billed amount based on purchase receipt item reference (pr_detail) in purchase invoice
pr_details_billed_amt = {}
pr_details = [d.get("pr_detail") for d in self.get("items") if d.get("pr_detail")]
if pr_details:
doctype = frappe.qb.DocType("Purchase Invoice Item")
query = (
frappe.qb.from_(doctype)
.select(doctype.pr_detail, Sum(doctype.amount))
.where(doctype.pr_detail.isin(pr_details) & doctype.docstatus == 1)
.groupby(doctype.pr_detail)
)
pr_details_billed_amt = frappe._dict(query.run(as_list=1))
return pr_details_billed_amt
def on_recurring(self, reference_doc, auto_repeat_doc): def on_recurring(self, reference_doc, auto_repeat_doc):
self.due_date = None self.due_date = None

View File

@ -887,18 +887,10 @@ def update_billing_percentage(pr_doc, update_modified=True):
# Update Billing % based on pending accepted qty # Update Billing % based on pending accepted qty
total_amount, total_billed_amount = 0, 0 total_amount, total_billed_amount = 0, 0
for item in pr_doc.items: item_wise_returned_qty = get_item_wise_returned_qty(pr_doc)
return_data = frappe.get_all(
"Purchase Receipt",
fields=["sum(abs(`tabPurchase Receipt Item`.qty)) as qty"],
filters=[
["Purchase Receipt", "docstatus", "=", 1],
["Purchase Receipt", "is_return", "=", 1],
["Purchase Receipt Item", "purchase_receipt_item", "=", item.name],
],
)
returned_qty = return_data[0].qty if return_data else 0 for item in pr_doc.items:
returned_qty = flt(item_wise_returned_qty.get(item.name))
returned_amount = flt(returned_qty) * flt(item.rate) returned_amount = flt(returned_qty) * flt(item.rate)
pending_amount = flt(item.amount) - returned_amount pending_amount = flt(item.amount) - returned_amount
total_billable_amount = pending_amount if item.billed_amt <= pending_amount else item.billed_amt total_billable_amount = pending_amount if item.billed_amt <= pending_amount else item.billed_amt
@ -915,6 +907,27 @@ def update_billing_percentage(pr_doc, update_modified=True):
pr_doc.notify_update() pr_doc.notify_update()
def get_item_wise_returned_qty(pr_doc):
items = [d.name for d in pr_doc.items]
return frappe._dict(
frappe.get_all(
"Purchase Receipt",
fields=[
"`tabPurchase Receipt Item`.purchase_receipt_item",
"sum(abs(`tabPurchase Receipt Item`.qty)) as qty",
],
filters=[
["Purchase Receipt", "docstatus", "=", 1],
["Purchase Receipt", "is_return", "=", 1],
["Purchase Receipt Item", "purchase_receipt_item", "in", items],
],
group_by="`tabPurchase Receipt Item`.purchase_receipt_item",
as_list=1,
)
)
@frappe.whitelist() @frappe.whitelist()
def make_purchase_invoice(source_name, target_doc=None): def make_purchase_invoice(source_name, target_doc=None):
from erpnext.accounts.party import get_payment_terms_template from erpnext.accounts.party import get_payment_terms_template

View File

@ -859,7 +859,8 @@
"label": "Purchase Receipt Item", "label": "Purchase Receipt Item",
"no_copy": 1, "no_copy": 1,
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1,
"search_index": 1
}, },
{ {
"collapsible": 1, "collapsible": 1,
@ -974,7 +975,8 @@
"label": "Purchase Invoice Item", "label": "Purchase Invoice Item",
"no_copy": 1, "no_copy": 1,
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1,
"search_index": 1
}, },
{ {
"fieldname": "product_bundle", "fieldname": "product_bundle",
@ -1010,7 +1012,7 @@
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2022-11-02 12:49:28.746701", "modified": "2023-01-18 15:48:58.114923",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Purchase Receipt Item", "name": "Purchase Receipt Item",