feat(B09): 「여기서 세지 않는 줄」을 할 일과 갈라 냄 — 이중계상 자리
B08 이 준비공 여섯 줄을 인계에 실으면서(`93546b85`) 세 갈래가 섞여 옴 - ⚠ `blocked_kind` 가 **없는데 `in_bill=false`** 면 **막힌 줄이 아님** — 「다른 표에서 이미 섬」(벌목·지장목제거)·「이 노선엔 없음」(사방 시설). 그것을 「우리가 만들어야 하는 것」에 얹으면 사용자가 세우려 들고 **그것이 곧 이중계상**(㉠~㉦ 규칙에 걸림) - 화면 목록을 **셋으로** 가름 — 입력하면 풀리는 것(2) · 우리가 만들 것(10) · **여기서 세지 않는 줄(2)** - 검산 줄 비고에 B08 사유 문구를 그대로 실음 - 짝 시험 — 같은 `in_bill=false` 라도 사유가 다르면 갈래가 달라야 함 실측(5174, 2f940d8a): 세 무리가 각각 뜨고 검산줄 5개가 수량만 보임 검증: pytest 212 통과(신규 1), tsc 0건 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,7 +49,13 @@ SUPPLY_UNKNOWN = "unknown"
|
|||||||
SUPPLY_OWNER = "owner_supplied"
|
SUPPLY_OWNER = "owner_supplied"
|
||||||
|
|
||||||
#: 막힘 갈래를 사람 말로. **할 일이 다르므로 화면에서 갈라 보인다.**
|
#: 막힘 갈래를 사람 말로. **할 일이 다르므로 화면에서 갈라 보인다.**
|
||||||
|
#: ⚠ `blocked_kind` 가 **`None` 인데 `in_bill=False`** 면 **막힌 줄이 아니다** —
|
||||||
|
#: 「다른 표에서 이미 섬」(벌목·지장목제거)이거나 「이 노선엔 없음」(사방 시설)이다.
|
||||||
|
#: 그것을 「우리가 만들어야 하는 것」에 얹으면 **결국 이중계상으로 간다**(㉠~㉦ 규칙).
|
||||||
|
_NOT_OUR_ROW = "not_our_row"
|
||||||
|
|
||||||
_BLOCKED_LABELS = {
|
_BLOCKED_LABELS = {
|
||||||
|
_NOT_OUR_ROW: "여기서 세지 않는 줄",
|
||||||
"input_missing": "입력이 필요합니다",
|
"input_missing": "입력이 필요합니다",
|
||||||
"unit_data_missing": "원단위가 없습니다(우리가 만들 것)",
|
"unit_data_missing": "원단위가 없습니다(우리가 만들 것)",
|
||||||
"formula_missing": "전개식이 없습니다(우리가 만들 것)",
|
"formula_missing": "전개식이 없습니다(우리가 만들 것)",
|
||||||
@@ -343,7 +349,20 @@ def build_bill(
|
|||||||
# ⚠ 코드 유무보다 **먼저** 가른다. 보정량계는 공종코드가 없어서가 아니라
|
# ⚠ 코드 유무보다 **먼저** 가른다. 보정량계는 공종코드가 없어서가 아니라
|
||||||
# **검산용 줄이라서** 금액이 없는 것이다 — `missing` 으로 새면 「단가를 구해야 할
|
# **검산용 줄이라서** 금액이 없는 것이다 — `missing` 으로 새면 「단가를 구해야 할
|
||||||
# 줄」로 잘못 읽힌다.
|
# 줄」로 잘못 읽힌다.
|
||||||
result.excluded.append(_excluded_row(item))
|
row = _excluded_row(item)
|
||||||
|
result.excluded.append(row)
|
||||||
|
if item.blocked_reason:
|
||||||
|
# ⚠ 「다른 표에서 이미 섬」과 「입력이 필요함」을 **갈라** 싣는다.
|
||||||
|
kind = item.blocked_kind or _NOT_OUR_ROW
|
||||||
|
result.missing.append(
|
||||||
|
{
|
||||||
|
"name": item.display_name,
|
||||||
|
"unit": item.unit,
|
||||||
|
"quantity": str(item.quantity),
|
||||||
|
"reason": f"{_BLOCKED_LABELS.get(kind, '막힘')} — {item.blocked_reason}",
|
||||||
|
"blocked_kind": kind,
|
||||||
|
}
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
if (item.composite_parts or item.composite_not_ready) and not item.work_item_code:
|
if (item.composite_parts or item.composite_not_ready) and not item.work_item_code:
|
||||||
# 묶음 줄 — 품셈에 그 공종이 없어 **조각을 합쳐** 한 줄로 세운다
|
# 묶음 줄 — 품셈에 그 공종이 없어 **조각을 합쳐** 한 줄로 세운다
|
||||||
|
|||||||
@@ -108,7 +108,14 @@ def _composite_row(
|
|||||||
|
|
||||||
|
|
||||||
def _excluded_row(item: HandoffWorkItem) -> BillRow:
|
def _excluded_row(item: HandoffWorkItem) -> BillRow:
|
||||||
"""검산용 줄(`in_bill=false`). **수량만 보이고 단가·금액을 안 붙인다.**"""
|
"""`in_bill=false` 줄. **수량만 보이고 단가·금액을 안 붙인다.**
|
||||||
|
|
||||||
|
세 갈래가 섞여 온다 — 갈라 적지 않으면 사용자가 할 일을 못 읽는다.
|
||||||
|
· **검산용**(보정량계·무대) — 합계 검산에만 쓰는 줄
|
||||||
|
· **막힌 줄**(`blocked_kind` 있음) — 입력이나 원단위를 기다림
|
||||||
|
· ⚠ **여기서 세지 않는 줄**(`blocked_kind` 없음) — 「다른 표에서 이미 섬」·
|
||||||
|
「이 노선엔 없음」. **이것을 할 일 목록에 얹으면 결국 이중계상이 된다.**
|
||||||
|
"""
|
||||||
return BillRow(
|
return BillRow(
|
||||||
item_no="",
|
item_no="",
|
||||||
level=1,
|
level=1,
|
||||||
@@ -118,7 +125,9 @@ def _excluded_row(item: HandoffWorkItem) -> BillRow:
|
|||||||
unit=item.unit,
|
unit=item.unit,
|
||||||
quantity=item.quantity,
|
quantity=item.quantity,
|
||||||
in_bill=False,
|
in_bill=False,
|
||||||
note=item.in_bill_reason or "합계 검산용 줄 — 금액을 매기지 않습니다.",
|
note=item.blocked_reason
|
||||||
|
or item.in_bill_reason
|
||||||
|
or "합계 검산용 줄 — 금액을 매기지 않습니다.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -913,13 +913,19 @@ export async function renderB09Estimation(root: HTMLElement): Promise<void> {
|
|||||||
// (2026-09-08 메인 창 지적), 한 화면에 뜨는 줄 수를 늘리지 않는다.
|
// (2026-09-08 메인 창 지적), 한 화면에 뜨는 줄 수를 늘리지 않는다.
|
||||||
// ⚠ **할 일이 다르므로 갈라 보인다** — 「사용자가 입력하면 풀리는 것」과
|
// ⚠ **할 일이 다르므로 갈라 보인다** — 「사용자가 입력하면 풀리는 것」과
|
||||||
// 「우리가 만들어야 하는 것」. 한 목록에 섞으면 사용자가 무엇을 해야 할지 못 읽는다.
|
// 「우리가 만들어야 하는 것」. 한 목록에 섞으면 사용자가 무엇을 해야 할지 못 읽는다.
|
||||||
|
// ⚠ **세 갈래로 가른다.** 「여기서 세지 않는 줄」을 할 일 목록에 얹으면
|
||||||
|
// 사용자가 세우려 들고, 그것이 곧 이중계상이다(㉠~㉦ 규칙).
|
||||||
|
const notOurs = bill.summary.missing.filter((item) => item.blocked_kind === "not_our_row");
|
||||||
const needsInput = bill.summary.missing.filter(
|
const needsInput = bill.summary.missing.filter(
|
||||||
(item) => item.blocked_kind === "input_missing",
|
(item) => item.blocked_kind === "input_missing",
|
||||||
);
|
);
|
||||||
const rest = bill.summary.missing.filter((item) => item.blocked_kind !== "input_missing");
|
const rest = bill.summary.missing.filter(
|
||||||
|
(item) => item.blocked_kind !== "input_missing" && item.blocked_kind !== "not_our_row",
|
||||||
|
);
|
||||||
for (const [labelKey, group] of [
|
for (const [labelKey, group] of [
|
||||||
["B09_Estimation_Boq_NeedsInput", needsInput],
|
["B09_Estimation_Boq_NeedsInput", needsInput],
|
||||||
["B09_Estimation_Boq_NeedsWork", rest],
|
["B09_Estimation_Boq_NeedsWork", rest],
|
||||||
|
["B09_Estimation_Boq_NotOurs", notOurs],
|
||||||
] as Array<[keyof typeof ui_locales, typeof bill.summary.missing]>) {
|
] as Array<[keyof typeof ui_locales, typeof bill.summary.missing]>) {
|
||||||
if (group.length === 0) continue;
|
if (group.length === 0) continue;
|
||||||
const head = document.createElement("div");
|
const head = document.createElement("div");
|
||||||
|
|||||||
@@ -725,6 +725,10 @@ export const ui_locales_b2 = {
|
|||||||
"검산용 줄 — 수량만 보이고 금액을 매기지 않습니다",
|
"검산용 줄 — 수량만 보이고 금액을 매기지 않습니다",
|
||||||
"Check rows — quantity only, never priced",
|
"Check rows — quantity only, never priced",
|
||||||
],
|
],
|
||||||
|
B09_Estimation_Boq_NotOurs: [
|
||||||
|
"여기서 세지 않는 줄 (다른 표에 있거나 이 노선에 없음)",
|
||||||
|
"Counted elsewhere or not present on this route",
|
||||||
|
],
|
||||||
B09_Estimation_Boq_NeedsInput: [
|
B09_Estimation_Boq_NeedsInput: [
|
||||||
"입력하면 풀리는 것 (설계 화면에서 값을 고르면 금액이 섭니다)",
|
"입력하면 풀리는 것 (설계 화면에서 값을 고르면 금액이 섭니다)",
|
||||||
"Waiting on input — pick the value on the design screen and the amount appears",
|
"Waiting on input — pick the value on the design screen and the amount appears",
|
||||||
|
|||||||
Reference in New Issue
Block a user