fix(controllers): compute budget requested amount per row

get_requested_amount multiplied the pooled pending qty of all matching Material Request items by a single Max(rate), fabricating the total whenever rates differ and biasing it upward - making false Budget Exceeded stops more likely. Sum (stock_qty - ordered_qty) * rate per row instead, matching get_ordered_amount.
This commit is contained in:
Mihir Kandoi
2026-07-05 15:09:49 +05:30
parent 17851ceaae
commit e52b1d6cff

View File

@@ -3,7 +3,7 @@ from collections import OrderedDict
import frappe
from frappe import _, qb
from frappe.query_builder import Criterion
from frappe.query_builder.functions import IfNull, Max, Sum
from frappe.query_builder.functions import IfNull, Sum
from frappe.utils import fmt_money
from erpnext.accounts.doctype.budget.budget import BudgetError, get_accumulated_monthly_budget
@@ -260,10 +260,10 @@ class BudgetValidation:
qb.from_(mr)
.inner_join(mri)
.on(mr.name == mri.parent)
# rate is outside the Sum (no GROUP BY -> implicit aggregate); Max() keeps it valid on
# postgres and matches MySQL's arbitrary single-rate choice for this aggregate.
.select(
(Sum(IfNull(mri.stock_qty, 0) - IfNull(mri.ordered_qty, 0)) * Max(mri.rate)).as_("amount")
Sum((IfNull(mri.stock_qty, 0) - IfNull(mri.ordered_qty, 0)) * IfNull(mri.rate, 0)).as_(
"amount"
)
)
.where(Criterion.all(conditions))
.run(as_dict=True)