fix(b09): 경비수량금액집계표 빈 까닭 표 위 안내 — 경비 갈래 자원 없음(166-5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018jonfdxn1Xit9bdkNJpE4G
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* 값 = 서버 단독 역전개(`B09_Estimation_Summary` · GET 응답 `summary`) — 조작 중엔 안 바뀜 · [저장] 뒤 정본
|
||||
* 끝수 = 총수량 ROUND 2 · 금액 ROUND(수량 × 단가, 0) · 줄 누름 = 단가를 낸 목록표 줄
|
||||
* 경비 집계표 빈 까닭(166-5) = 산근 · 대가 어느 길도 경비 자원 줄을 안 냄(기계 → 중기 · 구역화물 → 자재)
|
||||
* ========================================================================== */
|
||||
|
||||
import type { DataRow } from "@ui/ui_template_data_table";
|
||||
@@ -26,7 +27,10 @@ const hint = (payload: Row, extra = ""): string => {
|
||||
return `${HINT}${extra}${n ? ` · 연결 없음 ${n} — 전개 안 함(연결 점검 탭)` : ""}`;
|
||||
};
|
||||
|
||||
function resourceTab(id: string, list: TabId, unitPrice: string): TabBuild {
|
||||
/** 줄이 없을 때 표 위 맨 앞 안내 */
|
||||
const EXPENSE_NONE = "경비 갈래 자원 없음 — 중기 · 자재로 셈 · 경비 로직이 들어오면 채워짐";
|
||||
|
||||
function resourceTab(id: string, list: TabId, unitPrice: string, none = ""): TabBuild {
|
||||
return ({ payload }): TabTable => {
|
||||
const rows: DataRow[] = ((payload.summary || {})[id] || []).map((r: Row) => ({ ...r }));
|
||||
const sum = rows.reduce((acc, r) => acc + (typeof r.amount === "number" ? r.amount : 0), 0);
|
||||
@@ -44,7 +48,7 @@ function resourceTab(id: string, list: TabId, unitPrice: string): TabBuild {
|
||||
rows,
|
||||
total: rows.length ? { name: "계", amount: sum } : null,
|
||||
frozen: 2,
|
||||
hint: hint(payload),
|
||||
hint: !rows.length && none ? `${none} · ${hint(payload)}` : hint(payload),
|
||||
link: (i) => (rows[i] ? { tab: list, key: String(rows[i].key) } : null),
|
||||
};
|
||||
};
|
||||
@@ -52,7 +56,7 @@ function resourceTab(id: string, list: TabId, unitPrice: string): TabBuild {
|
||||
|
||||
export const buildSumMaterial = resourceTab("sum_material", "material", "단가");
|
||||
export const buildSumLabor = resourceTab("sum_labor", "labor", "단가");
|
||||
export const buildSumExpense = resourceTab("sum_expense", "expense", "단가");
|
||||
export const buildSumExpense = resourceTab("sum_expense", "expense", "단가", EXPENSE_NONE);
|
||||
|
||||
export const buildSumMachine: TabBuild = ({ payload }): TabTable => {
|
||||
const rows: DataRow[] = ((payload.summary || {}).sum_machine || []).map((r: Row) => ({ ...r }));
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -54,7 +55,7 @@ LINES = {
|
||||
{"kind": "machine", "key": "X1", "qty": 4.295},
|
||||
{"kind": "hopyo", "key": "B", "qty": 0.5},
|
||||
{"kind": "material", "key": "M4", "qty": 0.354},
|
||||
{"kind": "expense", "key": "E16", "qty": 1.103},
|
||||
{"kind": "expense", "key": "E16", "qty": 1.103}, # 합성 줄 — 산근 · 대가는 경비 줄을 안 냄(166-5)
|
||||
]},
|
||||
"B": {"lines": [{"kind": "labor", "key": "L1", "qty": 1.658},
|
||||
{"kind": "labor", "key": "L9", "qty": 1}]},
|
||||
@@ -155,3 +156,26 @@ def test_산근_블록_역전개_엑셀_반올림():
|
||||
machine = s["sum_machine"][0] # 중기시간금액집계표 10 줄 노무비
|
||||
assert (machine["qty"], machine["labor"], machine["sum"]) == (1436.14, 79992998, None)
|
||||
assert s["unlinked"] == 3 # 토공 · 대가 전 구조물 · 수량 빈칸 = 전개 안 함
|
||||
|
||||
|
||||
# ── 166-5 경비 집계표 — 실제 블록 꼴은 경비 자원 0 → 표 위 안내 ──
|
||||
from test_155_b09_tabs import _node # noqa: E402
|
||||
|
||||
EXPENSE_NONE = "경비 갈래 자원 없음 — 중기 · 자재로 셈 · 경비 로직이 들어오면 채워짐"
|
||||
|
||||
|
||||
def _expense_tab(summary):
|
||||
return _node(
|
||||
f"\nconst t = buildSumExpense({{ payload: {{ summary: {json.dumps(summary)} }} }});"
|
||||
"\nconsole.log(JSON.stringify({ n: t.rows.length, hint: t.hint }));",
|
||||
"UI_Tabs_Summary",
|
||||
)
|
||||
|
||||
|
||||
def test_166_5_실자료_경비_0_이면_안내():
|
||||
s = compute_summary(SG_SHEETS, hopyo_lines(SG_SHEETS))
|
||||
assert s["sum_expense"] == [] # 산근 블록 꼴 = 경비 갈래 줄 없음
|
||||
out = _expense_tab(s)
|
||||
assert out["n"] == 0 and out["hint"].startswith(EXPENSE_NONE)
|
||||
filled = _expense_tab(compute_summary(SHEETS, LINES)) # 합성 경비 줄이 있으면 안내 없음
|
||||
assert filled["n"] == 1 and EXPENSE_NONE not in filled["hint"]
|
||||
|
||||
Reference in New Issue
Block a user