Make lifecycle allocation formulas account-specific

This commit is contained in:
2026-05-04 14:10:54 +09:00
parent b2134d7515
commit 79b3fd646e

View File

@@ -1210,6 +1210,8 @@ def calculate_monthly_shared_distribution(
common_overall_basis_total = 0.0
labor_allocation_details: list[dict] = []
common_allocation_details: list[dict] = []
labor_account_allocation_details: dict[str, list[dict]] = defaultdict(list)
common_account_allocation_details: dict[str, list[dict]] = defaultdict(list)
labor_account_allocated: dict[str, float] = defaultdict(float)
common_account_allocated: dict[str, float] = defaultdict(float)
for ym in candidate_months:
@@ -1265,7 +1267,21 @@ def calculate_monthly_shared_distribution(
}
)
for account_code, account_amount in (labor_pool_accounts_by_month.get(ym) or {}).items():
labor_account_allocated[account_code] += float(account_amount or 0.0) * ratio
account_amount_value = float(account_amount or 0.0)
allocated_value = account_amount_value * ratio
labor_account_allocated[account_code] += allocated_value
labor_account_allocation_details[account_code].append(
{
"year_month": ym,
"source_amount": account_amount_value,
"project_basis_amount": base_value,
"total_basis_amount": total_value,
"display_project_basis_amount": display_project_basis_amount,
"display_total_basis_amount": display_total_basis_amount,
"used_equal_split": used_equal_split,
"allocated_amount": allocated_value,
}
)
if common_pool:
common_allocation_details.append(
{
@@ -1280,7 +1296,21 @@ def calculate_monthly_shared_distribution(
}
)
for account_code, account_amount in (common_pool_accounts_by_month.get(ym) or {}).items():
common_account_allocated[account_code] += float(account_amount or 0.0) * ratio
account_amount_value = float(account_amount or 0.0)
allocated_value = account_amount_value * ratio
common_account_allocated[account_code] += allocated_value
common_account_allocation_details[account_code].append(
{
"year_month": ym,
"source_amount": account_amount_value,
"project_basis_amount": base_value,
"total_basis_amount": total_value,
"display_project_basis_amount": display_project_basis_amount,
"display_total_basis_amount": display_total_basis_amount,
"used_equal_split": used_equal_split,
"allocated_amount": allocated_value,
}
)
return {
"labor_shared": labor_shared,
@@ -1295,6 +1325,8 @@ def calculate_monthly_shared_distribution(
"common_allocation_details": common_allocation_details,
"labor_account_allocated": dict(labor_account_allocated),
"common_account_allocated": dict(common_account_allocated),
"labor_account_allocation_details": dict(labor_account_allocation_details),
"common_account_allocation_details": dict(common_account_allocation_details),
}
@@ -1556,6 +1588,7 @@ def build_project_lifecycle_cost(
project_entry["shared_expense_supply"] += labor_shared
project_entry["expense_supply"] += labor_shared
labor_account_allocated = monthly_shared.get("labor_account_allocated") or {}
labor_account_allocation_details = monthly_shared.get("labor_account_allocation_details") or {}
if labor_account_allocated:
for shared_code, shared_amount in labor_account_allocated.items():
shared_code_str = (shared_code or "").strip()
@@ -1580,11 +1613,13 @@ def build_project_lifecycle_cost(
)
account_entry["shared_expense_supply"] += shared_amount_value
account_entry["expense_supply"] += shared_amount_value
account_entry["allocation_source_amount"] = float(monthly_shared.get("labor_source_total") or 0.0)
account_entry["allocation_source_amount"] = float(
sum(float(row.get("source_amount") or 0.0) for row in (labor_account_allocation_details.get(shared_code_str) or []))
)
account_entry["allocation_project_basis_amount"] = float(monthly_shared.get("labor_project_basis_total") or 0.0)
account_entry["allocation_total_basis_amount"] = float(monthly_shared.get("labor_overall_basis_total") or 0.0)
account_entry["allocation_mode"] = common_allocation_mode
account_entry["allocation_details"] = list(monthly_shared.get("labor_allocation_details") or [])
account_entry["allocation_details"] = list(labor_account_allocation_details.get(shared_code_str) or [])
else:
account_entry = breakdown_account_maps["인건비"].setdefault(
"SHARED_LABOR",
@@ -1631,6 +1666,7 @@ def build_project_lifecycle_cost(
project_entry["shared_expense_supply"] += common_shared
project_entry["expense_supply"] += common_shared
common_account_allocated = monthly_shared.get("common_account_allocated") or {}
common_account_allocation_details = monthly_shared.get("common_account_allocation_details") or {}
if common_account_allocated:
for shared_code, shared_amount in common_account_allocated.items():
shared_code_str = (shared_code or "").strip()
@@ -1655,11 +1691,13 @@ def build_project_lifecycle_cost(
)
account_entry["shared_expense_supply"] += shared_amount_value
account_entry["expense_supply"] += shared_amount_value
account_entry["allocation_source_amount"] = float(monthly_shared.get("common_source_total") or 0.0)
account_entry["allocation_source_amount"] = float(
sum(float(row.get("source_amount") or 0.0) for row in (common_account_allocation_details.get(shared_code_str) or []))
)
account_entry["allocation_project_basis_amount"] = float(monthly_shared.get("common_project_basis_total") or 0.0)
account_entry["allocation_total_basis_amount"] = float(monthly_shared.get("common_overall_basis_total") or 0.0)
account_entry["allocation_mode"] = common_allocation_mode
account_entry["allocation_details"] = list(monthly_shared.get("common_allocation_details") or [])
account_entry["allocation_details"] = list(common_account_allocation_details.get(shared_code_str) or [])
else:
account_entry = breakdown_account_maps["관리비"].setdefault(
"SHARED_COMMON",
@@ -1886,6 +1924,17 @@ def build_lifecycle_account_detail(
allocation_project_basis_amount = float(monthly_shared.get("common_project_basis_total") or 0.0)
allocation_total_basis_amount = float(monthly_shared.get("common_overall_basis_total") or 0.0)
allocation_details = list(monthly_shared.get("common_allocation_details") or [])
else:
allocation_mode = fetch_lifecycle_common_allocation_mode(conn, base_project_code)
monthly_shared = calculate_monthly_shared_distribution(conn, base_project_code, allocation_mode)
labor_detail_map = monthly_shared.get("labor_account_allocation_details") or {}
common_detail_map = monthly_shared.get("common_account_allocation_details") or {}
account_rows = labor_detail_map.get(account_code) or common_detail_map.get(account_code) or []
if account_rows:
allocation_details = list(account_rows)
allocation_source_amount = float(sum(float(row.get("source_amount") or 0.0) for row in account_rows))
allocation_project_basis_amount = float(sum(float(row.get("project_basis_amount") or 0.0) for row in account_rows))
allocation_total_basis_amount = float(sum(float(row.get("total_basis_amount") or 0.0) for row in account_rows))
return {
"summary": summary,