From 4abe2e82a066326573644d0f641f9f1c400e38c4 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Mon, 17 Nov 2025 14:35:27 +0530 Subject: [PATCH] fix(patch): migrate old Budget data to new structure --- erpnext/patches.txt | 2 +- ...rate_submitted_budgets_to_new_structure.py | 102 ++++++++++++++++++ .../patches/v16_0/set_total_budget_amount.py | 16 --- 3 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 erpnext/patches/v16_0/migrate_submitted_budgets_to_new_structure.py delete mode 100644 erpnext/patches/v16_0/set_total_budget_amount.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index a894f8cb44a..7d3296fe327 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -448,4 +448,4 @@ erpnext.patches.v16_0.update_serial_batch_entries erpnext.patches.v16_0.set_company_wise_warehouses erpnext.patches.v16_0.set_valuation_method_on_companies erpnext.patches.v15_0.migrate_old_item_wise_tax_detail_data_to_table -erpnext.patches.v16_0.set_total_budget_amount +erpnext.patches.v16_0.migrate_submitted_budgets_to_new_structure diff --git a/erpnext/patches/v16_0/migrate_submitted_budgets_to_new_structure.py b/erpnext/patches/v16_0/migrate_submitted_budgets_to_new_structure.py new file mode 100644 index 00000000000..d803a852d3f --- /dev/null +++ b/erpnext/patches/v16_0/migrate_submitted_budgets_to_new_structure.py @@ -0,0 +1,102 @@ +import frappe +from frappe.utils import add_months, flt, get_first_day, get_last_day + + +def execute(): + submitted_budgets = frappe.get_all("Budget", filters={"docstatus": 1}, pluck="name") + + for old_budget in submitted_budgets: + old_bud = frappe.get_doc("Budget", old_budget) + + old_accounts = frappe.get_all( + "Budget Account", + filters={"parent": old_bud.name}, + fields=["account", "budget_amount"], + order_by="idx asc", + ) + + if not old_accounts: + continue + + old_distribution = [] + if old_bud.monthly_distribution: + old_distribution = frappe.get_all( + "Monthly Distribution Percentage", + filters={"parent": old_bud.monthly_distribution}, + fields=["percentage_allocation"], + order_by="idx asc", + ) + + if old_distribution: + percentage_list = [flt(d.percentage) for d in old_distribution] + else: + percentage_list = [100 / 12] * 12 + + fy = frappe.get_doc("Fiscal Year", old_bud.fiscal_year) + fy_start = fy.year_start_date + fy_end = fy.year_end_date + + for acc in old_accounts: + new = frappe.new_doc("Budget") + + new.company = old_bud.company + new.cost_center = old_bud.cost_center + new.project = old_bud.project + new.fiscal_year = fy.name + + new.from_fiscal_year = fy.name + new.to_fiscal_year = fy.name + new.budget_start_date = fy_start + new.budget_end_date = fy_end + + new.account = acc.account + new.budget_amount = flt(acc.budget_amount) + new.distribution_frequency = "Monthly" + + new.distribute_equally = 1 if len(set(percentage_list)) == 1 else 0 + + fields_to_copy = [ + "applicable_on_material_request", + "action_if_annual_budget_exceeded_on_mr", + "action_if_accumulated_monthly_budget_exceeded_on_mr", + "applicable_on_purchase_order", + "action_if_annual_budget_exceeded_on_po", + "action_if_accumulated_monthly_budget_exceeded_on_po", + "applicable_on_booking_actual_expenses", + "action_if_annual_budget_exceeded", + "action_if_accumulated_monthly_budget_exceeded", + "applicable_on_cumulative_expense", + "action_if_annual_exceeded_on_cumulative_expense", + "action_if_accumulated_monthly_exceeded_on_cumulative_expense", + ] + + for field in fields_to_copy: + if hasattr(old_bud, field): + new.set(field, old_bud.get(field)) + + start = fy_start + for percentage in percentage_list: + row_start = get_first_day(start) + row_end = get_last_day(start) + + new.append( + "budget_distribution", + { + "start_date": row_start, + "end_date": row_end, + "percent": percentage, + "amount": new.budget_amount * percentage / 100, + }, + ) + + start = add_months(start, 1) + + new.flags.ignore_validate = True + new.flags.ignore_mandatory = True + new.flags.ignore_links = True + new.flags.ignore_permissions = True + + new.insert(ignore_permissions=True, ignore_mandatory=True) + new.submit() + + old_bud.cancel() diff --git a/erpnext/patches/v16_0/set_total_budget_amount.py b/erpnext/patches/v16_0/set_total_budget_amount.py deleted file mode 100644 index 163f0f17274..00000000000 --- a/erpnext/patches/v16_0/set_total_budget_amount.py +++ /dev/null @@ -1,16 +0,0 @@ -import frappe - - -def execute(): - if frappe.db.has_column("Budget", "total_budget_amount"): - frappe.db.sql( - """ - UPDATE `tabBudget` b - SET b.total_budget_amount = ( - SELECT SUM(ba.budget_amount) - FROM `tabBudget Account` ba - WHERE ba.parent = b.name - ) - WHERE IFNULL(b.total_budget_amount, 0) = 0 - """ - )