From e047e1eb15e5f19cf741b8f59af34a31bdfa1dc2 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Sun, 14 Apr 2024 17:03:22 +0530 Subject: [PATCH] feat: show expense breakup (cherry picked from commit 59292a09c4bdf79341c37c00edc177f401404f4f) --- erpnext/accounts/doctype/budget/budget.py | 133 ++++++++++++++++++---- 1 file changed, 109 insertions(+), 24 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index b0fddbd9365..3171a7cea06 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -219,12 +219,18 @@ def validate_expense_against_budget(args, expense_amount=0): def validate_budget_records(args, budget_records, expense_amount): for budget in budget_records: if flt(budget.budget_amount): - amount = expense_amount or get_amount(args, budget) yearly_action, monthly_action = get_actions(args, budget) + args["for_material_request"] = budget.for_material_request + args["for_purchase_order"] = budget.for_purchase_order if yearly_action in ("Stop", "Warn"): compare_expense_with_budget( - args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount + args, + flt(budget.budget_amount), + _("Annual"), + yearly_action, + budget.budget_against, + expense_amount, ) if monthly_action in ["Stop", "Warn"]: @@ -240,18 +246,28 @@ def validate_budget_records(args, budget_records, expense_amount): _("Accumulated Monthly"), monthly_action, budget.budget_against, - amount, + expense_amount, ) def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0): - actual_expense = get_actual_expense(args) - total_expense = actual_expense + amount + args.actual_expense = get_actual_expense(args) + args.requested_amount, args.ordered_amount = 0, 0 + if not amount: + args.requested_amount, args.ordered_amount = get_requested_amount(args), get_ordered_amount(args) + + if args.get("doctype") == "Material Request" and args.for_material_request: + amount = args.requested_amount + args.ordered_amount + + elif args.get("doctype") == "Purchase Order" and args.for_purchase_order: + amount = args.ordered_amount + + total_expense = args.actual_expense + amount if total_expense > budget_amount: - if actual_expense > budget_amount: + if args.actual_expense > budget_amount: error_tense = _("is already") - diff = actual_expense - budget_amount + diff = args.actual_expense - budget_amount else: error_tense = _("will be") diff = total_expense - budget_amount @@ -268,6 +284,8 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_ frappe.bold(fmt_money(diff, currency=currency)), ) + msg += get_expense_breakup(args, currency, budget_against) + if frappe.flags.exception_approver_role and frappe.flags.exception_approver_role in frappe.get_roles( frappe.session.user ): @@ -279,6 +297,85 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_ frappe.msgprint(msg, indicator="orange", title=_("Budget Exceeded")) +def get_expense_breakup(args, currency, budget_against): + msg = "
Total Expenses booked through - " + + return msg + + def get_actions(args, budget): yearly_action = budget.action_if_annual_budget_exceeded monthly_action = budget.action_if_accumulated_monthly_budget_exceeded @@ -294,21 +391,9 @@ def get_actions(args, budget): return yearly_action, monthly_action -def get_amount(args, budget): - amount = 0 - - if args.get("doctype") == "Material Request" and budget.for_material_request: - amount = get_requested_amount(args, budget) + get_ordered_amount(args, budget) - - elif args.get("doctype") == "Purchase Order" and budget.for_purchase_order: - amount = get_ordered_amount(args, budget) - - return amount - - -def get_requested_amount(args, budget): +def get_requested_amount(args): item_code = args.get("item_code") - condition = get_other_condition(args, budget, "Material Request") + condition = get_other_condition(args, "Material Request") data = frappe.db.sql( """ select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount @@ -322,9 +407,9 @@ def get_requested_amount(args, budget): return data[0][0] if data else 0 -def get_ordered_amount(args, budget): +def get_ordered_amount(args): item_code = args.get("item_code") - condition = get_other_condition(args, budget, "Purchase Order") + condition = get_other_condition(args, "Purchase Order") data = frappe.db.sql( f""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount @@ -338,7 +423,7 @@ def get_ordered_amount(args, budget): return data[0][0] if data else 0 -def get_other_condition(args, budget, for_doc): +def get_other_condition(args, for_doc): condition = "expense_account = '%s'" % (args.expense_account) budget_against_field = args.get("budget_against_field")