fix: skip PO items with invoice-created receipts in billing repair patch

A Purchase Receipt row created from a Purchase Invoice carries both
purchase_order_item and purchase_invoice_item, and its billed_amt is pinned
to the row amount by update_billing_status. Redistributing the PO-invoiced
pool over such rows zeroes the invoice-created receipt and flips it from
Completed to To Bill, so the repair leaves those PO Items untouched.

(cherry picked from commit ace4230f97)
This commit is contained in:
Mihir Kandoi
2026-08-11 18:16:38 +05:30
parent fa733e691b
commit 9139994686

View File

@@ -25,6 +25,11 @@ def execute():
def get_affected_purchase_order_items() -> list[str]:
purchase_order_items = get_candidate_purchase_order_items()
if purchase_order_items:
purchase_order_items = exclude_purchase_order_items_with_invoice_created_receipts(
purchase_order_items
)
if not purchase_order_items:
return []
@@ -55,6 +60,21 @@ def get_affected_purchase_order_items() -> list[str]:
]
def exclude_purchase_order_items_with_invoice_created_receipts(purchase_order_items: list[str]) -> list[str]:
invoice_created_receipt_items = set(
frappe.get_all(
"Purchase Receipt Item",
filters={
"purchase_order_item": ("in", purchase_order_items),
"purchase_invoice_item": ("is", "set"),
"docstatus": 1,
},
pluck="purchase_order_item",
)
)
return [item for item in purchase_order_items if item not in invoice_created_receipt_items]
def get_candidate_purchase_order_items() -> list[str]:
purchase_receipt = frappe.qb.DocType("Purchase Receipt")
purchase_receipt_item = frappe.qb.DocType("Purchase Receipt Item")