diff --git a/PTC/management_dashboard_preview.html b/PTC/management_dashboard_preview.html
index 60e9aa5..3c0cd08 100644
--- a/PTC/management_dashboard_preview.html
+++ b/PTC/management_dashboard_preview.html
@@ -1921,6 +1921,7 @@
const [companyAccountDetailModalLoading, setCompanyAccountDetailModalLoading] = useState(false);
const [lifecycleBreakdownModal, setLifecycleBreakdownModal] = useState(null);
const [lifecycleProjectTotalModal, setLifecycleProjectTotalModal] = useState(null);
+ const [lifecycleProjectTotalGroup, setLifecycleProjectTotalGroup] = useState("공통배분분");
const [lifecycleAccountDetailModal, setLifecycleAccountDetailModal] = useState(null);
const [lifecycleAccountDetailModalLoading, setLifecycleAccountDetailModalLoading] = useState(false);
const [lifecycleAllocationModal, setLifecycleAllocationModal] = useState(null);
@@ -5397,16 +5398,48 @@
className="button-muted"
style={{ height: 30, padding: "0 10px", borderRadius: 9, fontSize: 12 }}
onClick={() => {
- const allocationAccount = (lifecycleBreakdownModal.accounts || []).find(
- (acc) => Array.isArray(acc.allocation_details) && acc.allocation_details.length
- ) || (lifecycleBreakdownModal.accounts || [])[0] || {};
+ const accounts = Array.isArray(lifecycleBreakdownModal.accounts) ? lifecycleBreakdownModal.accounts : [];
+ const allocationMode =
+ (accounts.find((acc) => (acc.allocation_mode || "").trim()) || {}).allocation_mode || "";
+ const aggregatedByYearMonth = {};
+ accounts.forEach((acc) => {
+ const rows = Array.isArray(acc.allocation_details) ? acc.allocation_details : [];
+ rows.forEach((row) => {
+ const key = String(row.year_month || "");
+ if (!aggregatedByYearMonth[key]) {
+ aggregatedByYearMonth[key] = {
+ year_month: key,
+ source_amount: 0,
+ project_basis_amount: Number(row.project_basis_amount || 0),
+ total_basis_amount: Number(row.total_basis_amount || 0),
+ display_project_basis_amount: Number(row.display_project_basis_amount ?? row.project_basis_amount ?? 0),
+ display_total_basis_amount: Number(row.display_total_basis_amount ?? row.total_basis_amount ?? 0),
+ allocated_amount: 0,
+ };
+ }
+ aggregatedByYearMonth[key].source_amount += Number(row.source_amount || 0);
+ aggregatedByYearMonth[key].allocated_amount += Number(row.allocated_amount || 0);
+ });
+ });
+ const aggregatedAllocationDetails = Object.values(aggregatedByYearMonth).sort((a, b) =>
+ String(a.year_month || "").localeCompare(String(b.year_month || ""))
+ );
+ const sharedProjects = (Array.isArray(lifecycleBreakdownModal.projects) ? lifecycleBreakdownModal.projects : [])
+ .map((project) => ({ ...project }))
+ .filter((project) => Number(project.shared_expense_supply || 0) > 0);
+ const directTotal = sharedProjects.reduce((sum, project) => sum + Number(project.direct_expense_supply || 0), 0);
+ const sharedTotal = sharedProjects.reduce((sum, project) => sum + Number(project.shared_expense_supply || 0), 0);
setLifecycleProjectTotalModal({
label: lifecycleBreakdownModal.label || "",
- total_amount: Number(lifecycleBreakdownModal.expense_supply || 0),
- projects: Array.isArray(lifecycleBreakdownModal.projects) ? lifecycleBreakdownModal.projects.map((project) => ({ ...project })) : [],
- allocation_mode: allocationAccount.allocation_mode || "",
- allocation_details: Array.isArray(allocationAccount.allocation_details) ? allocationAccount.allocation_details.map((row) => ({ ...row })) : [],
+ total_amount: directTotal + sharedTotal,
+ direct_total: directTotal,
+ shared_total: sharedTotal,
+ projects: sharedProjects,
+ accounts: Array.isArray(lifecycleBreakdownModal.accounts) ? lifecycleBreakdownModal.accounts.map((account) => ({ ...account })) : [],
+ allocation_mode: allocationMode,
+ allocation_details: aggregatedAllocationDetails,
});
+ setLifecycleProjectTotalGroup("공통배분분");
}}
>
상세보기
@@ -5415,31 +5448,66 @@
연결된 프로젝트들 중 이 항목에 반영된 지출 금액입니다.
{(lifecycleBreakdownModal.projects || []).length ? (
- (lifecycleBreakdownModal.projects || []).map((item) => (
-
{
+ const projects = Array.isArray(lifecycleBreakdownModal.projects) ? lifecycleBreakdownModal.projects : [];
+ const roleAmount = {
+ 영업: 0,
+ 설계: 0,
+ 시공: 0,
+ };
+ const roleCodes = {
+ 영업: new Set(),
+ 설계: new Set(),
+ 시공: new Set(),
+ };
+ let sharedAmount = 0;
+ projects.forEach((project) => {
+ const role = (project.project_type || "").trim();
+ const direct = Number(project.direct_expense_supply || 0);
+ const shared = Number(project.shared_expense_supply || 0);
+ const projectCode = (project.project_code || "").trim();
+ if (roleAmount[role] !== undefined) {
+ roleAmount[role] += direct;
+ if (projectCode) roleCodes[role].add(projectCode);
+ }
+ sharedAmount += shared;
+ });
+ const groupedRows = [
+ { key: "영업", label: "영업", amount: roleAmount.영업, showWhenZero: false, codes: Array.from(roleCodes.영업) },
+ { key: "설계", label: "설계", amount: roleAmount.설계, showWhenZero: false, codes: Array.from(roleCodes.설계) },
+ { key: "시공", label: "시공", amount: roleAmount.시공, showWhenZero: true, codes: Array.from(roleCodes.시공) },
+ { key: "공통배분분", label: "공통배분분", amount: sharedAmount, showWhenZero: true, codes: [] },
+ ].filter((row) => row.showWhenZero || row.amount > 0);
+ return groupedRows.map((item) => (
+
- ))
+
+ {fmt(item.amount || 0)}원
+
+
+ ));
+ })()
) : (
표시할 프로젝트가 없습니다.
)}
@@ -5448,10 +5516,28 @@
계정별 금액
- 이 항목에 포함된 계정 기준 합계입니다.
+
+ {lifecycleProjectTotalGroup === "설계" || lifecycleProjectTotalGroup === "시공"
+ ? `${lifecycleProjectTotalGroup} 직접분 계정 기준 합계입니다.`
+ : lifecycleProjectTotalGroup === "공통배분분"
+ ? "공통배분분 계정 기준 합계입니다."
+ : "이 항목에 포함된 계정 기준 합계입니다."}
+
{(lifecycleBreakdownModal.accounts || []).length ? (
- (lifecycleBreakdownModal.accounts || []).map((item) => (
+ (() => {
+ const roleField =
+ lifecycleProjectTotalGroup === "설계" ? "direct_design_expense_supply"
+ : lifecycleProjectTotalGroup === "시공" ? "direct_construction_expense_supply"
+ : lifecycleProjectTotalGroup === "영업" ? "direct_sales_expense_supply"
+ : "shared_expense_supply";
+ const filtered = (lifecycleBreakdownModal.accounts || [])
+ .map((item) => ({ ...item, __role_amount: Number(item?.[roleField] || 0) }))
+ .filter((item) => item.__role_amount > 0);
+ if (!filtered.length) {
+ return
표시할 계정이 없습니다.
;
+ }
+ return filtered.map((item) => (
)}
- {fmt(item.expense_supply || 0)}원
+ {fmt(item.__role_amount || 0)}원
- ))
+ ));
+ })()
) : (
표시할 계정이 없습니다.
)}
@@ -6843,20 +6932,22 @@
계정 상세를 불러오는 중입니다.
) : lifecycleAccountDetailModal.detail?.summary ? (
<>
+ {(() => {
+ const summaryAmount = Number(lifecycleAccountDetailModal.detail?.summary?.expense_supply_sum || 0);
+ const selectedAmount = Number(lifecycleAccountDetailModal.allocation_result_amount || 0);
+ const effectiveAccountAmount = selectedAmount > 0 ? selectedAmount : summaryAmount;
+ const effectiveTxnCount = Number(lifecycleAccountDetailModal.detail?.summary?.txn_count || 0);
+ return (
지출 합계
- {fmt(
- Number(lifecycleAccountDetailModal.allocation_result_amount || 0) > 0
- ? Number(lifecycleAccountDetailModal.allocation_result_amount || 0)
- : Number(lifecycleAccountDetailModal.detail.summary.expense_supply_sum || 0)
- )}원
+ {fmt(effectiveAccountAmount)}원
거래 건수
-
{fmt(lifecycleAccountDetailModal.detail.summary.txn_count || 0)}건
+
{fmt(effectiveTxnCount)}건
기간
@@ -6867,8 +6958,10 @@
+ );
+ })()}
- {((lifecycleAccountDetailModal.bucket_label || "") === "인건비" || (lifecycleAccountDetailModal.bucket_label || "") === "관리비") && (
+ {Boolean(lifecycleAccountDetailModal.show_allocation_formula) && (
배부 계산식
@@ -7011,9 +7104,11 @@
{fmt(
- (lifecycleAccountDetailModal.account_code || "").startsWith("SHARED_")
- ? Number(lifecycleAccountDetailModal.allocation_result_amount || 0)
- : Number(lifecycleAccountDetailModal.detail?.summary?.expense_supply_sum || 0)
+ (() => {
+ const summaryAmount = Number(lifecycleAccountDetailModal.detail?.summary?.expense_supply_sum || 0);
+ const selectedAmount = Number(lifecycleAccountDetailModal.allocation_result_amount || 0);
+ return selectedAmount > 0 ? selectedAmount : summaryAmount;
+ })()
)}원
@@ -7038,13 +7133,16 @@
{lifecycleProjectTotalModal.label || "전체"} 프로젝트별 상세
-
연결 프로젝트 기준 전체 금액 내역입니다.
+
연결 프로젝트 기준 공통배분분 내역입니다.
-
+
합계 금액
{fmt(lifecycleProjectTotalModal.total_amount || 0)}원
+
+ 직접분 {fmt(lifecycleProjectTotalModal.direct_total || 0)}원 · 공통배분분 {fmt(lifecycleProjectTotalModal.shared_total || 0)}원
+
배부 계산식
@@ -7095,11 +7193,16 @@
{item.project_code || "-"} · {item.project_type || "미지정"} · {item.construction_family || "종류미지정"} · {item.construction_method || "공법미지정"}
- {fmt(item.expense_supply || 0)}원
+
+
{fmt(item.expense_supply || 0)}원
+
+ 직접분 {fmt(item.direct_expense_supply || 0)}원 · 공통배분분 {fmt(item.shared_expense_supply || 0)}원
+
+
))
) : (
- 표시할 프로젝트가 없습니다.
+ 표시할 공통배분 프로젝트가 없습니다.
)}