feat(management): add yearly project-applied vs common admin expense split

This commit is contained in:
2026-05-04 10:01:49 +09:00
parent c13f596453
commit eab0a5bb3f
2 changed files with 70 additions and 0 deletions

View File

@@ -6172,6 +6172,16 @@
<div style={{ fontSize: 18, fontWeight: 700 }}>{yearItem.year}</div>
<div style={{ fontSize: 22, fontWeight: 700 }}>{fmtEokManagement(yearItem.total_expense || 0)}</div>
</div>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginTop: 8 }}>
<div style={{ padding: "8px 10px", border: "1px solid rgba(233, 240, 247, 0.9)", borderRadius: 10 }}>
<div className="subtle" style={{ fontSize: 11 }}>프로젝트 적용 관리비</div>
<div style={{ marginTop: 4, fontWeight: 700 }}>{fmtEokManagement(yearItem.project_applied_admin_expense || 0)}</div>
</div>
<div style={{ padding: "8px 10px", border: "1px solid rgba(233, 240, 247, 0.9)", borderRadius: 10 }}>
<div className="subtle" style={{ fontSize: 11 }}>공통관리비</div>
<div style={{ marginTop: 4, fontWeight: 700 }}>{fmtEokManagement(yearItem.common_admin_expense || 0)}</div>
</div>
</div>
<div style={{ display: "grid", gap: 8, marginTop: 14 }}>
{(yearItem.categories || []).map((category) => (
<button
@@ -6439,6 +6449,8 @@
{[
"연도",
"총 지출",
"프로젝트 적용 관리비",
"공통관리비",
"일반운영비",
"법정,의무",
"외부전문,전략",
@@ -6479,6 +6491,12 @@
<td style={{ padding: "14px", borderBottom: "1px solid var(--line)", textAlign: "right", fontWeight: 700 }}>
{fmtEokManagement(yearItem.total_expense || 0)}
</td>
<td style={{ padding: "14px", borderBottom: "1px solid var(--line)", textAlign: "right", fontWeight: 700 }}>
{fmtEokManagement(yearItem.project_applied_admin_expense || 0)}
</td>
<td style={{ padding: "14px", borderBottom: "1px solid var(--line)", textAlign: "right", fontWeight: 700 }}>
{fmtEokManagement(yearItem.common_admin_expense || 0)}
</td>
{[
"일반운영비",
"법정,의무",

View File

@@ -3441,6 +3441,8 @@ class Handler(BaseHTTPRequestHandler):
"year": year,
"income_supply": 0.0,
"total_expense": 0.0,
"project_applied_admin_expense": 0.0,
"common_admin_expense": 0.0,
"categories": {key: 0.0 for key in MANAGEMENT_ACCOUNT_CATEGORY_ORDER},
"excluded_total": 0.0,
"excluded_income_total": 0.0,
@@ -3460,6 +3462,8 @@ class Handler(BaseHTTPRequestHandler):
"year": year,
"income_supply": 0.0,
"total_expense": 0.0,
"project_applied_admin_expense": 0.0,
"common_admin_expense": 0.0,
"categories": {key: 0.0 for key in MANAGEMENT_ACCOUNT_CATEGORY_ORDER},
"excluded_total": 0.0,
"excluded_income_total": 0.0,
@@ -3483,6 +3487,52 @@ class Handler(BaseHTTPRequestHandler):
}
)
management_split_rows = conn.execute(
f"""
select
substr(coalesce(transaction_date, ''), 1, 4) as year,
coalesce(project_code, '') as project_code,
account_code_final as account_code,
coalesce(sum(case when in_out = '출금' then supply_amount else 0 end), 0) as expense_supply
from ptc_transactions
{where}
group by substr(coalesce(transaction_date, ''), 1, 4), coalesce(project_code, ''), account_code_final
having year <> ''
""",
values,
).fetchall()
for row in management_split_rows:
year = (row["year"] or "").strip() or "미상"
account_code = (row["account_code"] or "").strip()
project_code = (row["project_code"] or "").strip()
expense_supply = float(row["expense_supply"] or 0)
if not account_code or expense_supply == 0:
continue
master = ACCOUNT_MASTER.get(account_code) or {}
if master.get("project_type") != "관리":
continue
if (master.get("category") or "") == "인건비":
continue
if year not in by_year:
by_year[year] = {
"year": year,
"income_supply": 0.0,
"total_expense": 0.0,
"project_applied_admin_expense": 0.0,
"common_admin_expense": 0.0,
"categories": {key: 0.0 for key in MANAGEMENT_ACCOUNT_CATEGORY_ORDER},
"excluded_total": 0.0,
"excluded_income_total": 0.0,
"excluded_expense_total": 0.0,
"excluded_accounts": [],
}
is_project_applied = bool(project_code) and "-관리-" not in project_code
if is_project_applied:
by_year[year]["project_applied_admin_expense"] += expense_supply
else:
by_year[year]["common_admin_expense"] += expense_supply
items = []
for year in sorted(by_year.keys()):
item = by_year[year]
@@ -3490,6 +3540,8 @@ class Handler(BaseHTTPRequestHandler):
"year": item["year"],
"income_supply": item["income_supply"],
"total_expense": item["total_expense"],
"project_applied_admin_expense": item["project_applied_admin_expense"],
"common_admin_expense": item["common_admin_expense"],
"categories": [
{"name": category, "amount": item["categories"][category]}
for category in MANAGEMENT_ACCOUNT_CATEGORY_ORDER