main_laptop_1 -> main byeonghap (4 hwangyeong 585 commits) #12

Merged
eomsangdon merged 585 commits from main_laptop_1 into main 2026-09-08 17:26:30 +09:00
5 changed files with 48 additions and 11 deletions
Showing only changes of commit b680141d2c - Show all commits
@@ -49,7 +49,13 @@ SUPPLY_UNKNOWN = "unknown"
SUPPLY_OWNER = "owner_supplied"
#: 막힘 갈래를 사람 말로. **할 일이 다르므로 화면에서 갈라 보인다.**
#: ⚠ `blocked_kind` 가 **`None` 인데 `in_bill=False`** 면 **막힌 줄이 아니다** —
#: 「다른 표에서 이미 섬」(벌목·지장목제거)이거나 「이 노선엔 없음」(사방 시설)이다.
#: 그것을 「우리가 만들어야 하는 것」에 얹으면 **결국 이중계상으로 간다**(㉠~㉦ 규칙).
_NOT_OUR_ROW = "not_our_row"
_BLOCKED_LABELS = {
_NOT_OUR_ROW: "여기서 세지 않는 줄",
"input_missing": "입력이 필요합니다",
"unit_data_missing": "원단위가 없습니다(우리가 만들 것)",
"formula_missing": "전개식이 없습니다(우리가 만들 것)",
@@ -343,7 +349,20 @@ def build_bill(
# ⚠ 코드 유무보다 **먼저** 가른다. 보정량계는 공종코드가 없어서가 아니라
# **검산용 줄이라서** 금액이 없는 것이다 — `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
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:
"""검산용 줄(`in_bill=false`). **수량만 보이고 단가·금액을 안 붙인다.**"""
"""`in_bill=false`. **수량만 보이고 단가·금액을 안 붙인다.**
세 갈래가 섞여 온다 — 갈라 적지 않으면 사용자가 할 일을 못 읽는다.
· **검산용**(보정량계·무대) — 합계 검산에만 쓰는 줄
· **막힌 줄**(`blocked_kind` 있음) — 입력이나 원단위를 기다림
· ⚠ **여기서 세지 않는 줄**(`blocked_kind` 없음) — 「다른 표에서 이미 섬」·
「이 노선엔 없음」. **이것을 할 일 목록에 얹으면 결국 이중계상이 된다.**
"""
return BillRow(
item_no="",
level=1,
@@ -118,7 +125,9 @@ def _excluded_row(item: HandoffWorkItem) -> BillRow:
unit=item.unit,
quantity=item.quantity,
in_bill=False,
note=item.in_bill_reason or "합계 검산용 줄 — 금액을 매기지 않습니다.",
note=item.blocked_reason
or item.in_bill_reason
or "합계 검산용 줄 — 금액을 매기지 않습니다.",
)
+7 -1
View File
@@ -913,13 +913,19 @@ export async function renderB09Estimation(root: HTMLElement): Promise<void> {
// (2026-09-08 메인 창 지적), 한 화면에 뜨는 줄 수를 늘리지 않는다.
// ⚠ **할 일이 다르므로 갈라 보인다** — 「사용자가 입력하면 풀리는 것」과
// 「우리가 만들어야 하는 것」. 한 목록에 섞으면 사용자가 무엇을 해야 할지 못 읽는다.
// ⚠ **세 갈래로 가른다.** 「여기서 세지 않는 줄」을 할 일 목록에 얹으면
// 사용자가 세우려 들고, 그것이 곧 이중계상이다(㉠~㉦ 규칙).
const notOurs = bill.summary.missing.filter((item) => item.blocked_kind === "not_our_row");
const needsInput = bill.summary.missing.filter(
(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 [
["B09_Estimation_Boq_NeedsInput", needsInput],
["B09_Estimation_Boq_NeedsWork", rest],
["B09_Estimation_Boq_NotOurs", notOurs],
] as Array<[keyof typeof ui_locales, typeof bill.summary.missing]>) {
if (group.length === 0) continue;
const head = document.createElement("div");
@@ -2620,7 +2620,7 @@
{
"alternative_amount": null,
"amount": "0.16",
"amount_unit": "",
"amount_unit": "개소",
"group_ratio_pct": null,
"pum_form": "requirement",
"pum_table_id": "F0326",
@@ -2635,7 +2635,7 @@
{
"alternative_amount": null,
"amount": "0.14",
"amount_unit": "",
"amount_unit": "개소",
"group_ratio_pct": null,
"pum_form": "requirement",
"pum_table_id": "F0326",
@@ -2650,7 +2650,7 @@
{
"alternative_amount": null,
"amount": "0.21",
"amount_unit": "",
"amount_unit": "개소",
"group_ratio_pct": null,
"pum_form": "requirement",
"pum_table_id": "F0327",
@@ -2665,7 +2665,7 @@
{
"alternative_amount": null,
"amount": "0.19",
"amount_unit": "",
"amount_unit": "개소",
"group_ratio_pct": null,
"pum_form": "requirement",
"pum_table_id": "F0327",
@@ -6287,14 +6287,13 @@
},
"source_master_file": {
"file": "work_item_master_2026-01-01.json",
"sha256": "08b0c7c26c4aa569ace3b13490b8cbd00606254abb1439894eac750d387bfb03"
"sha256": "3752af1e0328a2faf4947268e449e0bc602a0738cc6a29a78ed71d343cf2e583"
},
"stats": {
"rows": 418,
"skipped_forms": {
"coefficient": 19,
"example_form": 8,
"reference": 56,
"reference": 64,
"undetermined": 75
},
"unmatched": 497
+4
View File
@@ -725,6 +725,10 @@ export const ui_locales_b2 = {
"검산용 줄 — 수량만 보이고 금액을 매기지 않습니다",
"Check rows — quantity only, never priced",
],
B09_Estimation_Boq_NotOurs: [
"여기서 세지 않는 줄 (다른 표에 있거나 이 노선에 없음)",
"Counted elsewhere or not present on this route",
],
B09_Estimation_Boq_NeedsInput: [
"입력하면 풀리는 것 (설계 화면에서 값을 고르면 금액이 섭니다)",
"Waiting on input — pick the value on the design screen and the amount appears",