From af26ac96e98d7ec6791676fb2bd6860a6332fcd9 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 29 Mar 2024 17:22:48 +0530 Subject: [PATCH 1/3] fix: do not add actual expense twice for validating budget --- erpnext/accounts/doctype/budget/budget.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index b585f409e14..07e8d853da4 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -303,12 +303,10 @@ 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) + get_actual_expense(args) - ) + 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) + get_actual_expense(args) + amount = get_ordered_amount(args, budget) return amount From 59292a09c4bdf79341c37c00edc177f401404f4f Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Sun, 14 Apr 2024 17:03:22 +0530 Subject: [PATCH 2/3] feat: show expense breakup --- 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 07e8d853da4..337face2df2 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -224,12 +224,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"]: @@ -245,18 +251,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 @@ -273,6 +289,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 ): @@ -284,6 +302,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 @@ -299,21 +396,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 @@ -327,9 +412,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 @@ -343,7 +428,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") From 9a12376e29d32ff7acfcd187d8ae52c2eeb323e9 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Sun, 14 Apr 2024 17:06:01 +0530 Subject: [PATCH 3/3] refactor: show list for expense breakup --- erpnext/accounts/doctype/budget/budget.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index 337face2df2..145480138d6 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -256,8 +256,7 @@ def validate_budget_records(args, budget_records, expense_amount): def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0): - args.actual_expense = get_actual_expense(args) - args.requested_amount, args.ordered_amount = 0, 0 + args.actual_expense, args.requested_amount, args.ordered_amount = get_actual_expense(args), 0, 0 if not amount: args.requested_amount, args.ordered_amount = get_requested_amount(args), get_ordered_amount(args) @@ -373,11 +372,9 @@ def get_expense_breakup(args, currency, budget_against): ) + " - " + frappe.bold(fmt_money(args.ordered_amount, currency=currency)) - + "" + + "" ) - msg += "" - return msg