mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 13:49:13 +00:00
fix: test cases of budget
This commit is contained in:
@@ -37,8 +37,6 @@
|
|||||||
"applicable_on_cumulative_expense",
|
"applicable_on_cumulative_expense",
|
||||||
"action_if_annual_exceeded_on_cumulative_expense",
|
"action_if_annual_exceeded_on_cumulative_expense",
|
||||||
"action_if_accumulated_monthly_exceeded_on_cumulative_expense",
|
"action_if_accumulated_monthly_exceeded_on_cumulative_expense",
|
||||||
"section_break_21",
|
|
||||||
"accounts",
|
|
||||||
"section_break_fpdt",
|
"section_break_fpdt",
|
||||||
"budget_distribution",
|
"budget_distribution",
|
||||||
"section_break_kkan",
|
"section_break_kkan",
|
||||||
@@ -188,18 +186,6 @@
|
|||||||
"label": "Action if Accumulated Monthly Budget Exceeded on Actual",
|
"label": "Action if Accumulated Monthly Budget Exceeded on Actual",
|
||||||
"options": "\nStop\nWarn\nIgnore"
|
"options": "\nStop\nWarn\nIgnore"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "section_break_21",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hide_border": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "accounts",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"label": "Budget Accounts",
|
|
||||||
"options": "Budget Account",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@@ -301,7 +287,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-10-26 01:09:56.367821",
|
"modified": "2025-10-28 13:02:43.456568",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Budget",
|
"name": "Budget",
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ def validate_expense_against_budget(args, expense_amount=0):
|
|||||||
budget_records = frappe.db.sql(
|
budget_records = frappe.db.sql(
|
||||||
f"""
|
f"""
|
||||||
select
|
select
|
||||||
b.name, b.{budget_against} as budget_against, b.budget_amount, b.monthly_distribution,
|
b.name, b.{budget_against} as budget_against, b.budget_amount,
|
||||||
ifnull(b.applicable_on_material_request, 0) as for_material_request,
|
ifnull(b.applicable_on_material_request, 0) as for_material_request,
|
||||||
ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
|
ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
|
||||||
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
|
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from erpnext.accounts.doctype.budget.budget import (
|
|||||||
BudgetError,
|
BudgetError,
|
||||||
get_accumulated_monthly_budget,
|
get_accumulated_monthly_budget,
|
||||||
get_actual_expense,
|
get_actual_expense,
|
||||||
|
revise_budget,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
@@ -24,7 +25,7 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
cls.make_projects()
|
cls.make_projects()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
frappe.db.set_single_value("Accounts Settings", "use_legacy_budget_controller", False)
|
frappe.db.set_single_value("Accounts Settings", "use_legacy_budget_controller", True)
|
||||||
self.company = "_Test Company"
|
self.company = "_Test Company"
|
||||||
self.fiscal_year = frappe.db.get_value("Fiscal Year", {}, "name")
|
self.fiscal_year = frappe.db.get_value("Fiscal Year", {}, "name")
|
||||||
self.account = "_Test Account Cost for Goods Sold - _TC"
|
self.account = "_Test Account Cost for Goods Sold - _TC"
|
||||||
@@ -59,7 +60,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
@@ -81,9 +83,7 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
|
|
||||||
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(budget.name, nowdate())
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
|
||||||
)
|
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Bank - _TC",
|
"_Test Bank - _TC",
|
||||||
@@ -118,7 +118,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year)
|
frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year)
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
|
|
||||||
mr = frappe.get_doc(
|
mr = frappe.get_doc(
|
||||||
@@ -162,7 +163,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year)
|
frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year)
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
po = create_purchase_order(
|
po = create_purchase_order(
|
||||||
transaction_date=nowdate(), qty=1, rate=accumulated_limit + 1, do_not_submit=True
|
transaction_date=nowdate(), qty=1, rate=accumulated_limit + 1, do_not_submit=True
|
||||||
@@ -185,7 +187,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
|
|
||||||
project = frappe.get_value("Project", {"project_name": "_Test Project"})
|
project = frappe.get_value("Project", {"project_name": "_Test Project"})
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
@@ -306,7 +309,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
@@ -339,7 +343,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
budget.name,
|
||||||
|
nowdate(),
|
||||||
)
|
)
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
@@ -393,9 +398,7 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
|
|
||||||
budget = make_budget(budget_against="Cost Center", applicable_on_cumulative_expense=True)
|
budget = make_budget(budget_against="Cost Center", applicable_on_cumulative_expense=True)
|
||||||
|
|
||||||
accumulated_limit = get_accumulated_monthly_budget(
|
accumulated_limit = get_accumulated_monthly_budget(budget.name, nowdate())
|
||||||
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
|
|
||||||
)
|
|
||||||
|
|
||||||
jv = make_journal_entry(
|
jv = make_journal_entry(
|
||||||
"_Test Account Cost for Goods Sold - _TC",
|
"_Test Account Cost for Goods Sold - _TC",
|
||||||
@@ -414,6 +417,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
)
|
)
|
||||||
po.set_missing_values()
|
po.set_missing_values()
|
||||||
|
|
||||||
|
print(">>>>>>>>>>>>>>>>>>>>>>>>")
|
||||||
|
|
||||||
self.assertRaises(BudgetError, po.submit)
|
self.assertRaises(BudgetError, po.submit)
|
||||||
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
@@ -432,7 +437,8 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
budget.fiscal_year = self.fiscal_year
|
budget.fiscal_year = self.fiscal_year
|
||||||
budget.budget_against = "Cost Center"
|
budget.budget_against = "Cost Center"
|
||||||
budget.cost_center = self.cost_center
|
budget.cost_center = self.cost_center
|
||||||
budget.append("accounts", {"account": self.account, "budget_amount": 100000})
|
budget.account = self.account
|
||||||
|
budget.budget_amount = 100000
|
||||||
|
|
||||||
start = getdate("2025-04-10")
|
start = getdate("2025-04-10")
|
||||||
end = getdate("2025-04-05")
|
end = getdate("2025-04-05")
|
||||||
@@ -482,29 +488,7 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
budget.save()
|
budget.save()
|
||||||
|
|
||||||
def test_evenly_distribute_budget(self):
|
def test_evenly_distribute_budget(self):
|
||||||
budget = frappe.new_doc("Budget")
|
budget = make_budget(budget_against="Cost Center", budget_amount=120000)
|
||||||
budget.company = self.company
|
|
||||||
budget.fiscal_year = self.fiscal_year
|
|
||||||
budget.budget_against = "Cost Center"
|
|
||||||
budget.cost_center = self.cost_center
|
|
||||||
budget.distribute_evenly = 1
|
|
||||||
budget.account = ("_Test Account Cost for Goods Sold - _TC",)
|
|
||||||
budget.budget_amount = 12000
|
|
||||||
|
|
||||||
budget.budget_start_date = getdate("2025-04-01")
|
|
||||||
budget.budget_end_date = getdate("2026-03-31")
|
|
||||||
|
|
||||||
for i in range(12):
|
|
||||||
budget.append(
|
|
||||||
"budget_distribution",
|
|
||||||
{
|
|
||||||
"start_date": add_days(getdate("2025-04-01"), 30 * i),
|
|
||||||
"end_date": add_days(getdate("2025-04-30"), 30 * i),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
budget.save()
|
|
||||||
budget.reload()
|
|
||||||
|
|
||||||
total = sum([d.amount for d in budget.budget_distribution])
|
total = sum([d.amount for d in budget.budget_distribution])
|
||||||
self.assertEqual(total, 120000)
|
self.assertEqual(total, 120000)
|
||||||
@@ -513,29 +497,26 @@ class TestBudget(ERPNextTestSuite):
|
|||||||
def test_create_revised_budget(self):
|
def test_create_revised_budget(self):
|
||||||
budget = make_budget(budget_against="Cost Center", budget_amount=120000)
|
budget = make_budget(budget_against="Cost Center", budget_amount=120000)
|
||||||
|
|
||||||
revised_name = frappe.get_doc("Budget", budget.name).revise_budget()
|
revised_name = revise_budget(budget.name)
|
||||||
|
|
||||||
revised_budget = frappe.get_doc("Budget", revised_name)
|
revised_budget = frappe.get_doc("Budget", revised_name)
|
||||||
self.assertNotEqual(budget.name, revised_budget.name)
|
self.assertNotEqual(budget.name, revised_budget.name)
|
||||||
self.assertEqual(revised_budget.budget_against, budget.budget_against)
|
self.assertEqual(revised_budget.budget_against, budget.budget_against)
|
||||||
self.assertEqual(revised_budget.accounts[0].budget_amount, budget.accounts[0].budget_amount)
|
self.assertEqual(revised_budget.budget_amount, budget.budget_amount)
|
||||||
|
|
||||||
old_budget = frappe.get_doc("Budget", budget.name)
|
old_budget = frappe.get_doc("Budget", budget.name)
|
||||||
self.assertEqual(old_budget.docstatus, 2)
|
self.assertEqual(old_budget.docstatus, 2)
|
||||||
|
|
||||||
def test_revision_preserves_distribution(self):
|
def test_revision_preserves_distribution(self):
|
||||||
budget = make_budget(budget_against="Cost Center", budget_amount=120000)
|
budget = make_budget(budget_against="Cost Center", budget_amount=120000)
|
||||||
budget.distribute_evenly = 1
|
|
||||||
budget.allocate_budget()
|
|
||||||
budget.save()
|
|
||||||
|
|
||||||
revised_name = budget.revise_budget()
|
revised_name = revise_budget(budget.name)
|
||||||
revised_budget = frappe.get_doc("Budget", revised_name)
|
revised_budget = frappe.get_doc("Budget", revised_name)
|
||||||
|
|
||||||
self.assertGreater(len(revised_budget.budget_distribution), 0)
|
self.assertGreater(len(revised_budget.budget_distribution), 0)
|
||||||
|
|
||||||
total = sum(row.amount for row in revised_budget.budget_distribution)
|
total = sum(row.amount for row in revised_budget.budget_distribution)
|
||||||
self.assertEqual(total, revised_budget.accounts[0].budget_amount)
|
self.assertEqual(total, revised_budget.budget_amount)
|
||||||
|
|
||||||
|
|
||||||
def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
|
def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
|
||||||
@@ -589,18 +570,33 @@ def make_budget(**args):
|
|||||||
|
|
||||||
budget_against = args.budget_against
|
budget_against = args.budget_against
|
||||||
cost_center = args.cost_center
|
cost_center = args.cost_center
|
||||||
|
|
||||||
fiscal_year = get_fiscal_year(nowdate())[0]
|
fiscal_year = get_fiscal_year(nowdate())[0]
|
||||||
|
|
||||||
if budget_against == "Project":
|
if budget_against == "Project":
|
||||||
project_name = "{}%".format("_Test Project/" + fiscal_year)
|
project = frappe.get_value("Project", {"project_name": "_Test Project"})
|
||||||
budget_list = frappe.get_all("Budget", fields=["name"], filters={"name": ("like", project_name)})
|
budget_list = frappe.get_all(
|
||||||
|
"Budget",
|
||||||
|
filters={
|
||||||
|
"project": project,
|
||||||
|
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||||
|
},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
cost_center_name = "{}%".format(cost_center or "_Test Cost Center - _TC/" + fiscal_year)
|
budget_list = frappe.get_all(
|
||||||
budget_list = frappe.get_all("Budget", fields=["name"], filters={"name": ("like", cost_center_name)})
|
"Budget",
|
||||||
for d in budget_list:
|
filters={
|
||||||
frappe.db.sql("delete from `tabBudget` where name = %(name)s", d)
|
"cost_center": cost_center or "_Test Cost Center - _TC",
|
||||||
frappe.db.sql("delete from `tabBudget Account` where parent = %(name)s", d)
|
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||||
|
},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
|
||||||
|
for name in budget_list:
|
||||||
|
doc = frappe.get_doc("Budget", name)
|
||||||
|
if doc.docstatus == 1:
|
||||||
|
doc.cancel()
|
||||||
|
frappe.delete_doc("Budget", name, force=True, ignore_missing=True)
|
||||||
|
|
||||||
budget = frappe.new_doc("Budget")
|
budget = frappe.new_doc("Budget")
|
||||||
|
|
||||||
@@ -609,18 +605,19 @@ def make_budget(**args):
|
|||||||
else:
|
else:
|
||||||
budget.cost_center = cost_center or "_Test Cost Center - _TC"
|
budget.cost_center = cost_center or "_Test Cost Center - _TC"
|
||||||
|
|
||||||
monthly_distribution = frappe.get_doc("Monthly Distribution", "_Test Distribution")
|
|
||||||
monthly_distribution.fiscal_year = fiscal_year
|
|
||||||
monthly_distribution.save()
|
|
||||||
|
|
||||||
budget.fiscal_year = fiscal_year
|
budget.fiscal_year = fiscal_year
|
||||||
budget.monthly_distribution = "_Test Distribution"
|
|
||||||
budget.company = "_Test Company"
|
budget.company = "_Test Company"
|
||||||
|
budget.account = "_Test Account Cost for Goods Sold - _TC"
|
||||||
|
budget.budget_amount = args.budget_amount or 200000
|
||||||
budget.applicable_on_booking_actual_expenses = 1
|
budget.applicable_on_booking_actual_expenses = 1
|
||||||
budget.action_if_annual_budget_exceeded = "Stop"
|
budget.action_if_annual_budget_exceeded = "Stop"
|
||||||
budget.action_if_accumulated_monthly_budget_exceeded = "Ignore"
|
budget.action_if_accumulated_monthly_budget_exceeded = "Ignore"
|
||||||
budget.budget_against = budget_against
|
budget.budget_against = budget_against
|
||||||
budget.append("accounts", {"account": "_Test Account Cost for Goods Sold - _TC", "budget_amount": 200000})
|
|
||||||
|
budget.budget_start_date = "2025-04-01"
|
||||||
|
budget.budget_end_date = "2026-03-31"
|
||||||
|
budget.allocation_frequency = "Monthly"
|
||||||
|
budget.distribution_type = "Amount"
|
||||||
|
|
||||||
if args.applicable_on_material_request:
|
if args.applicable_on_material_request:
|
||||||
budget.applicable_on_material_request = 1
|
budget.applicable_on_material_request = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user