From 4f138794aba41499ffca161ee788746785d9eaa1 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 8 Sep 2026 06:08:31 +0900 Subject: [PATCH] =?UTF-8?q?feat(B08):=20=EC=BD=98=ED=81=AC=EB=A6=AC?= =?UTF-8?q?=ED=8A=B8=20=ED=83=80=EC=84=A4=20=EC=A4=84=20=EC=9D=B8=EA=B3=84?= =?UTF-8?q?=20+=20=EB=B9=88=20=EB=8B=A8=EA=B0=80=EC=82=B0=EC=B6=9C?= =?UTF-8?q?=EC=84=9C=20=EC=84=9C=EC=8B=9D=20=EA=B1=B0=EB=A5=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ㉙ B09 2차 교차검토와 함께 나온 것. 콘크리트 타설 — placing_code() 가 시험에서만 불리던 자리를 실제로 이음 - build_handoff 가 구조물 종류별로 콘크리트 체적을 모아 타설 공종 줄을 냄 - 겹치지 않는 것을 확인함: 품셈 12-1-1 표가 직종·품만 주고 재료를 안 줌 (서브 일위대가 B-FP-12-01-01#철근구조물 = 재료 0원 · 노무 65,826.48원) 품은 이 줄, 재료는 자재 쪽으로 갈려 있음 - ⚠ 채움콘크리트는 뺌 — 돌쌓기 뒤채움이라 그 공종 품에 이미 들어 있을 수 있음 (13-6 [주]① 이 큰돌쌓기는 품에 포함이라 못 박음, 13-4 는 확인 전) - 방식을 안 정했으면 기본값으로 서되 placing_notes 로 알림 - 화면 문구를 「아직 반영 안 됨」에서 「방식에 따라 단가가 달라짐」으로 바꿈 빈 단가산출서 서식 — 품셈이 실어 둔 채워 넣으라고 둔 양식 8건 - 머리글 「단가산출서」가 정본 표지, 머리 두 줄 모양은 보조 - 값이 아예 없는 표라 공종으로 세우면 「값이 있는데 안 서는 자리」로 오해됨 - 실측: 견적 쪽 못 맞춘 자원 882 → 497, 밑수 미확보 160 → 137 - 자원 줄 418 · 단가 제목 330 은 그대로 — 정상 값은 안 지워짐 시험 - 서식 규칙 짝 시험 넷 (정상 표를 지우지 않는 것 · 다시 만든 마스터 대조 포함) - 타설 줄 시험 넷 (방식 셋이 갈리는 것 · 콘크리트가 없으면 줄도 없는 것) - 옛 시험 하나 정정 — 구조물 한 줄 규칙에 타설 줄이 걸리던 것 시험: 674 passed · 24 skipped (B05 코리도 1건 기존 깨짐, 무관) · tsc 오류 0. Co-Authored-By: Claude Opus 5 (1M context) --- .../B08_Quantity_Build_WorkItemMaster.py | 26 ++++ B08_Quantity/B08_Quantity_Engine_Handoff.py | 89 +++++++++++ B08_Quantity/B08_Quantity_Router_Material.py | 3 + B08_Quantity/B08_Quantity_UI_Page.ts | 6 +- .../data_work_item_master/_manifest.json | 10 +- .../basis_missing_2026-01-01.json | 138 ------------------ .../work_item_master_2026-01-01.json | 36 ++--- ui_template/ui_template_locale_b2.ts | 4 +- 8 files changed, 146 insertions(+), 166 deletions(-) diff --git a/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py b/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py index 017fa63f..e705ffcc 100644 --- a/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py +++ b/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py @@ -81,6 +81,19 @@ COEFFICIENT_ROW_KEYS = {"K", "f", "E", "Cm", "㎝(sec)", "q", "qo", "Q", "V", "L REFERENCE_MARKS = ("할증률", "할인", "공제율", "적재량", "지위") # 값 대신 「어디를 따르라」고만 적은 표. 품이 아니므로 공종으로 세우지 않는다. REFERENCE_CELL_MARKS = ("별도계상", "구역화물", "적용한다", "따른다", "준용") +# 품셈이 실어 둔 **빈 단가산출서 서식** — 값이 없는 예시 양식이다(2026-09-08 ㉙, 서브가 찾음). +# 첫 줄이 「위치 및 임·소반」·「위치 및 면적」이고 다음 줄이 「구분 | 작업량 | 단위품 | +# 소요품 | 단가」인 모양. 채워 넣으라고 둔 칸이라 **자원도 값도 없다.** +# ⚠ 이것을 공종으로 세우면 「값이 있는데 안 서는 자리」로 오해된다 — 애초에 값이 없다. +# 서브가 그 표들 탓에 못 맞춘 자원이 882 → 497 로 부풀어 있었다. +# ⚠ **두 조건을 다 만족할 때만** 본다 — 「구분」·「단가」는 정상 표에도 흔한 낱말이라 +# 하나만 보면 정상 표를 지운다(오늘 그 병을 열한 번 겪었다). +#: 표지는 **머리글에 그대로 적혀 있다** — 「ha당 참나무시들음병방제 **단가산출서(예시)**」. +#: 낱말 하나로 충분히 좁다(정상 표 머리글에 「단가산출서」가 올 일이 없다). +BLANK_FORM_MARK = "단가산출서" +#: 머리글이 비어 있는 판을 대비한 보조 표지 — **두 조건을 다 만족할 때만** 본다. +BLANK_FORM_HEAD_MARKS = ("위치및임소반", "위치및면적") +BLANK_FORM_BODY_MARKS = ("단위품", "소요품") # 직종이 값의 주인인 표 = 소요량형. `보통인부(인)`·`콘크리트공(인)` 처럼 `(인)` 이 붙는다. # ⚠ 원문에 `인 부` 처럼 낱말 사이 공백이 있어, 비교 전에 공백을 모두 지운다(`squeeze`). OCCUPATION_RE = re.compile( @@ -200,6 +213,19 @@ def detect_form(table: dict[str, Any], chapter: str | None) -> tuple[str, str]: if mark in squeezed: return "reference", f"'{mark}' — 값이 아니라 참조 지시" + # 빈 단가산출서 서식 — 머리글 표지가 정본, 머리 두 줄은 보조. + if BLANK_FORM_MARK in hay.replace(" ", ""): + return "reference", f"'{BLANK_FORM_MARK}' — 채워 넣으라고 둔 빈 서식" + head2 = "".join( + norm(str(c)) for row in (table.get("rows") or table.get("raw_row") or [])[:2] for c in row + ) + for mark in ("․", "·", "ㆍ", " "): + head2 = head2.replace(mark, "") + if any(m in head2 for m in BLANK_FORM_HEAD_MARKS) and any( + m in head2 for m in BLANK_FORM_BODY_MARKS + ): + return "reference", "품셈이 실어 둔 빈 단가산출서 서식 — 채워 넣으라고 둔 칸" + # ⚠ 생산량형을 **직종보다 먼저** 본다. 「작업능력(㎥/hr)」 표의 비고란에 흔히 # 「보통인부 1인/일」이 붙어 있어, 직종을 먼저 보면 생산량형이 소요량형으로 뒤집힌다. # 그 뒤집힘이 곧 PLAN 8-6 이 경고한 「값이 조용히 반대로 들어가는」 사고다. diff --git a/B08_Quantity/B08_Quantity_Engine_Handoff.py b/B08_Quantity/B08_Quantity_Engine_Handoff.py index 35bdea2f..bb73d436 100644 --- a/B08_Quantity/B08_Quantity_Engine_Handoff.py +++ b/B08_Quantity/B08_Quantity_Engine_Handoff.py @@ -687,6 +687,87 @@ def _structure_rows( return rows, unmatched +#: 타설 대상으로 보는 성분 이름 — **정확히 같은 이름**으로만 본다. +#: ⚠ **「채움콘크리트」는 뺀다** — 돌쌓기 뒤채움이라 그 공종의 품에 이미 들어 있을 수 있다. +#: 품셈 13-6 [주]① 은 큰돌쌓기의 채움콘크리트를 **품에 포함**이라고 못 박았고, 13-4 는 +#: 그 [주]가 없어 **확인 전까지 세우지 않는다.** 넓게 잡으면 그것이 곧 이중계상이다. +#: (넣으려면 돌쌓기 일위대가에 타설 품이 있는지부터 확인할 것 — B09 ㉢ 과 같은 자리.) +PLACING_TARGET_NAMES = frozenset({"콘크리트", "버림콘크리트", "레미콘"}) + + +def _placing_rows( + unit_quantity_table: dict[str, Any], + mapping: WorkItemMapping, + method: str | None, +) -> tuple[list[dict[str, Any]], list[str]]: + """콘크리트 **타설 공종** 줄 — 구조물 종류별로 체적을 모아 한 줄씩 낸다. + + ⚠ **이중계상이 아니다** (2026-09-08 두 창 확인). 품셈 12-1-1 표는 **직종·품만** 주고 + 재료를 안 준다(원문도 「콘크리트공(인) | 보통인부(인)」 두 열뿐). 서브 일위대가 + `B-FP-12-01-01#철근구조물` 도 **재료 0원 · 노무 65,826.48원**이다. + ⇒ **품은 이 줄, 재료는 자재 쪽**으로 갈려 있어 겹치지 않는다. + + ⚠ 방식은 **설계 판단**이고 종류(무근/철근)는 **철근이 있나 없나로 자동 판정**한다 — + 사람이 고르는 값이 아니다(`work_item_mapping` 의 `kind_rule`). + """ + code, used_default = placing_code(mapping, method) + if code is None: + return [], [] + buckets: dict[str, float] = {} + for structure in unit_quantity_table.get("structures") or []: + volume = sum( + float(component.get("amount") or 0.0) + for component in structure.get("components") or [] + if str(component.get("name") or "").strip() in PLACING_TARGET_NAMES + and component.get("unit") == "㎥" + ) + if volume <= 0: + continue + buckets[structure_kind(structure)] = buckets.get(structure_kind(structure), 0.0) + volume + rows = [ + { + "work_item_code": code, + "name": "콘크리트 타설", + "spec": kind, + "unit": "㎥", + "quantity": volume, + "quantity_gross": None, + "application_ratio_pct": None, + "application_ratio_breakdown": None, + "quantity_breakdown": None, + "ground_class": None, + "haul_distance_m": None, + "haul_equipment": None, + "station_from": None, + "station_to": None, + "excavation_method": None, + "spec_detail": kind, + "composite_parts": None, + "structure_kind": kind, + "blocked_kind": None, + "blocked_reason": "", + "variant_axis": "structure_kind", + "variant_value": kind, + "spec_class": kind, + "spec_class_basis": ( + "철근이 있으면 철근구조물, 없으면 무근구조물 — 원단위로 자동 판정" + ), + "composite_not_ready": None, + "in_bill": True, + "in_bill_reason": "", + "origin": ORIGIN_STRUCTURE, + } + for kind, volume in sorted(buckets.items()) + ] + notes: list[str] = [] + if rows and used_default: + notes.append( + "콘크리트 타설 방식을 아직 안 정해 기본값(레디믹스트)으로 섰습니다 — " + "산출 조건에서 정하면 이 공종의 단가가 달라집니다" + ) + return rows, notes + + def _material_rows(material_table: dict[str, Any]) -> list[dict[str, Any]]: """자재 줄 — **공종코드를 붙이지 않는다.** 자재 축은 B09 카탈로그가 잇는다(8-7).""" rows: list[dict[str, Any]] = [] @@ -718,6 +799,7 @@ def build_handoff( ground_class_set: str | None = None, ground_classes: list[str] | None = None, ground_methods: dict[str, str | None] | None = None, + concrete_placing_method: str | None = None, ) -> dict[str, Any]: """B09 가 그대로 받는 모양. 없는 표는 건너뛰되 **빈 표와 구별해 적는다**.""" table = mapping or load_mapping() @@ -738,6 +820,12 @@ def build_handoff( work_items.extend(rows) unmatched.extend(misses) + # 콘크리트 타설 — 품은 이 줄, 재료는 자재 쪽. 겹치지 않는다(위 `_placing_rows` 주석). + placing_rows, placing_notes = _placing_rows( + unit_quantity_table or {}, table, concrete_placing_method + ) + work_items.extend(placing_rows) + materials = _material_rows(material_table or {}) result: dict[str, Any] = { "work_items": work_items, @@ -780,6 +868,7 @@ def build_handoff( result["ratio_math_warnings"] = verify_ratio_math(result) result["material_code_warnings"] = verify_no_code_on_materials(result) result["bill_flag_warnings"] = verify_bill_flags(result) + result["placing_notes"] = placing_notes return result diff --git a/B08_Quantity/B08_Quantity_Router_Material.py b/B08_Quantity/B08_Quantity_Router_Material.py index 5498ec10..e76451e8 100644 --- a/B08_Quantity/B08_Quantity_Router_Material.py +++ b/B08_Quantity/B08_Quantity_Router_Material.py @@ -29,6 +29,7 @@ from B08_Quantity.B08_Quantity_Engine_Handoff import build_handoff, summarize from B08_Quantity.B08_Quantity_Engine_MaterialSummary import build_table as build_material_table from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table as build_unit_table from common_util.common_util_project_settings import ( + concrete_placing_method, quantity_settings, rock_classes, rock_method, @@ -161,6 +162,8 @@ async def get_handoff(project_id: UUID) -> JSONResponse: ground_class_set=settings.get("rock_class_set"), ground_classes=rock_classes(settings), ground_methods={name: rock_method(settings, name) for name in rock_classes(settings)}, + # 타설 방식 — 안 정했으면 기본값으로 서되 그 사실을 `placing_notes` 가 알린다. + concrete_placing_method=concrete_placing_method(settings)[0], ) handoff["summary"] = summarize(handoff) handoff["skipped_structures"] = skipped diff --git a/B08_Quantity/B08_Quantity_UI_Page.ts b/B08_Quantity/B08_Quantity_UI_Page.ts index 2ede41d7..eeecf98e 100644 --- a/B08_Quantity/B08_Quantity_UI_Page.ts +++ b/B08_Quantity/B08_Quantity_UI_Page.ts @@ -352,9 +352,9 @@ function buildQuantitySidePanel( placing.is_default ? `${label} (${L("B08_Quantity_Placing_Default_Tag")})` : label, ), ); - // ⚠ 고른 값이 **아직 금액에 안 닿는다**는 사실을 숨기지 않는다(2026-09-08 ㉘). - // 인계가 타설 공종 줄을 아직 안 세운다 — B09 일위대가가 타설 품을 이미 갖고 있는지 - // 확인되기 전까지는 세우면 같은 콘크리트를 두 번 센다(이중계상 ㉢ 과 같은 자리). + // 2026-09-08 ㉙: 인계가 **타설 공종 줄을 실제로 세운다.** 겹치지 않는 것이 확인됐다 — + // 품셈 12-1-1 표는 직종·품만 주고 재료를 안 줘서, 품은 이 줄 · 재료는 자재 쪽이다. + // ⚠ 돌쌓기 뒤채움(채움콘크리트)은 뺐다 — 그 공종 품에 이미 들어 있을 수 있다. const pending = document.createElement("p"); pending.className = "b08-quantity__note"; pending.textContent = L("B08_Quantity_Placing_NotApplied"); diff --git a/resources/data_work_item_master/_manifest.json b/resources/data_work_item_master/_manifest.json index dd120b46..1fa924fb 100644 --- a/resources/data_work_item_master/_manifest.json +++ b/resources/data_work_item_master/_manifest.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", "dataset_id": "data_work_item_master_manifest", - "generated_at": "2026-09-08T04:57:04+09:00", + "generated_at": "2026-09-08T06:00:25+09:00", "built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py", "source": { "dataset_id": "pum_forest", @@ -12,8 +12,8 @@ "files": [ { "file": "work_item_master_2026-01-01.json", - "sha256": "1c49012f9f50d721676ad8def15c87c96b77aad83123286dd6981b7d9cefcd81", - "size_bytes": 856450 + "sha256": "4d89c1eec7929c39d5adb36547b03f4675205b10f6b629eeb2f246a1d9230dfd", + "size_bytes": 856818 }, { "file": "form_undetermined_2026-01-01.json", @@ -22,8 +22,8 @@ }, { "file": "basis_missing_2026-01-01.json", - "sha256": "b69091149adb942ce507d902b7e6ac400777674301b9200b1f1c60cfbd709839", - "size_bytes": 22832 + "sha256": "9d7b9ee8df65be1c944a2e0af9efe0742bd9a356b367fc4de8eec47b3ece2147", + "size_bytes": 18627 } ] } \ No newline at end of file diff --git a/resources/data_work_item_master/basis_missing_2026-01-01.json b/resources/data_work_item_master/basis_missing_2026-01-01.json index 17c015fe..41773cee 100644 --- a/resources/data_work_item_master/basis_missing_2026-01-01.json +++ b/resources/data_work_item_master/basis_missing_2026-01-01.json @@ -825,144 +825,6 @@ "section": "13-16-2. 통기성매트", "pum_form": "requirement", "line": 7788 - }, - { - "pum_table_id": "F0454", - "section": "8-2-3 굴착기(2025)」를 참조하여 적용계수를 달리 적용하도록 한다.", - "pum_form": "requirement", - "line": 7983 - }, - { - "pum_table_id": "F0455", - "section": "2-1. 풀베기, (1) 둘레베기(조림목 본수 2,700본/ha, 조림1년차)", - "pum_form": "requirement", - "line": 8031 - }, - { - "pum_table_id": "F0456", - "section": "2-2. 풀베기, (2) 모두베기(조림목 본수 2,700본/ha, 조림2년차)", - "pum_form": "requirement", - "line": 8061 - }, - { - "pum_table_id": "F0457", - "section": "2-3. 풀베기, (3) 줄베기(조림목 본수 2,700본/ha, 조림2년차)", - "pum_form": "requirement", - "line": 8092 - }, - { - "pum_table_id": "F0458", - "section": "2-4. 풀베기, (4) 맹아제거+둘레베기(제거대상 맹아 1,000본/ha. 조림목 본수 2,700본/ha, 조림1년차)", - "pum_form": "requirement", - "line": 8124 - }, - { - "pum_table_id": "F0459", - "section": "2-5. 덩굴제거, (1) 지상부 덩굴걷기(큰나무 피해지. 덩굴 피복도 20~40%미만)", - "pum_form": "requirement", - "line": 8156 - }, - { - "pum_table_id": "F0460", - "section": "2-6. 덩굴제거, (2) 지상부 약제살포(큰나무 피해지. 덩굴 피복도 60~80%미만)", - "pum_form": "requirement", - "line": 8189 - }, - { - "pum_table_id": "F0461", - "section": "2-7. 덩굴제거, (3) 뿌리굴취(풀베기단계 조림지 1㎝미만 500본, 1~4㎝ 400본, 4㎝초과 100본)", - "pum_form": "requirement", - "line": 8225 - }, - { - "pum_table_id": "F0462", - "section": "2-8. 덩굴제거, (4) 뿌리굴취(풀베기단계 조림지 1㎝미만 500본, 1~4㎝ 400본,", - "pum_form": "requirement", - "line": 8265 - }, - { - "pum_table_id": "F0463", - "section": "2-9. 어린나무가꾸기, (1) 치수림단계 (20m 간격 소작업로 설치, 제거대상 피복도 ‘소’, 가지치기 미실행)", - "pum_form": "requirement", - "line": 8303 - }, - { - "pum_table_id": "F0464", - "section": "2-10. 어린나무가꾸기, (2) 유령림단계 (제거대상 피복도 ‘밀’, 가지치기 잣나무 0~2m. 500본/ha)", - "pum_form": "requirement", - "line": 8344 - }, - { - "pum_table_id": "F0465", - "section": "2-11. 솎아베기, (1) 산물을 임내에 버리는 경우", - "pum_form": "requirement", - "line": 8385 - }, - { - "pum_table_id": "F0466", - "section": "2-12. 솎아베기, (2) 산물을 전간재로 생산하는 경우", - "pum_form": "requirement", - "line": 8434 - }, - { - "pum_table_id": "F0467", - "section": "2-13. 위험목 베기", - "pum_form": "requirement", - "line": 8496 - }, - { - "pum_table_id": "F0468", - "section": "2-14. 산물수집, (1) 인력집재(단목 집재 + 집적)", - "pum_form": "requirement", - "line": 8542 - }, - { - "pum_table_id": "F0469", - "section": "2-15. 산물수집, (2) 지면끌기집재(공정별 독립작업)", - "pum_form": "requirement", - "line": 8585 - }, - { - "pum_table_id": "F0470", - "section": "2-16. 산물수집, (3) 지면끌기집재 (동시작업)", - "pum_form": "requirement", - "line": 8655 - }, - { - "pum_table_id": "F0471", - "section": "2-17. 산물임내정리", - "pum_form": "requirement", - "line": 8720 - }, - { - "pum_table_id": "F0472", - "section": "3-1. 임업용 동력기계톱, 우드그래플, 소형트럭", - "pum_form": "requirement", - "line": 8753 - }, - { - "pum_table_id": "F0473", - "section": "3-2. 임업용 동력기계톱, 스마트집재기, 우드그래플, 초소형포워더", - "pum_form": "requirement", - "line": 8828 - }, - { - "pum_table_id": "F0474", - "section": "3-3. 하베스터, 타워야더, 우드그래플, 소형포워더", - "pum_form": "requirement", - "line": 8912 - }, - { - "pum_table_id": "F0475", - "section": "4-1. 소나무재선충병방제", - "pum_form": "requirement", - "line": 8989 - }, - { - "pum_table_id": "F0476", - "section": "4-2. 참나무시들음병방제", - "pum_form": "requirement", - "line": 9106 } ] } \ No newline at end of file diff --git a/resources/data_work_item_master/work_item_master_2026-01-01.json b/resources/data_work_item_master/work_item_master_2026-01-01.json index 741b4fad..e718e55b 100644 --- a/resources/data_work_item_master/work_item_master_2026-01-01.json +++ b/resources/data_work_item_master/work_item_master_2026-01-01.json @@ -2,7 +2,7 @@ "schema_version": "1.0", "dataset_id": "work_item_master_forest", "effective_date": "2026-01-01", - "generated_at": "2026-09-08T04:57:04+09:00", + "generated_at": "2026-09-08T06:00:25+09:00", "dataset_version": { "dataset_id": "pum_forest", "effective_date": "2026-01-01", @@ -22,7 +22,7 @@ "tables_orphan": 19, "form_undetermined": 77, "basis_found": 183, - "basis_missing": 160, + "basis_missing": 137, "basis_grouped": 36 }, "orphan_tables": [ @@ -4157,8 +4157,8 @@ "pum_table_id": "F0455", "section": "2-1. 풀베기, (1) 둘레베기(조림목 본수 2,700본/ha, 조림1년차)", "source_line": 8031, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -5704,8 +5704,8 @@ "pum_table_id": "F0456", "section": "2-2. 풀베기, (2) 모두베기(조림목 본수 2,700본/ha, 조림2년차)", "source_line": 8061, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -6796,8 +6796,8 @@ "pum_table_id": "F0472", "section": "3-1. 임업용 동력기계톱, 우드그래플, 소형트럭", "source_line": 8753, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -7776,8 +7776,8 @@ "pum_table_id": "F0473", "section": "3-2. 임업용 동력기계톱, 스마트집재기, 우드그래플, 초소형포워더", "source_line": 8828, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -8874,8 +8874,8 @@ "pum_table_id": "F0474", "section": "3-3. 하베스터, 타워야더, 우드그래플, 소형포워더", "source_line": 8912, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -10245,8 +10245,8 @@ "pum_table_id": "F0475", "section": "4-1. 소나무재선충병방제", "source_line": 8989, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -11867,8 +11867,8 @@ "pum_table_id": "F0476", "section": "4-2. 참나무시들음병방제", "source_line": 9106, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, @@ -24844,8 +24844,8 @@ "pum_table_id": "F0454", "section": "8-2-3 굴착기(2025)」를 참조하여 적용계수를 달리 적용하도록 한다.", "source_line": 7983, - "pum_form": "requirement", - "form_basis": "'수량'", + "pum_form": "reference", + "form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식", "basis_quantity": null, "basis_unit": null, "basis_source": null, diff --git a/ui_template/ui_template_locale_b2.ts b/ui_template/ui_template_locale_b2.ts index b25bbbb4..d7136e4b 100644 --- a/ui_template/ui_template_locale_b2.ts +++ b/ui_template/ui_template_locale_b2.ts @@ -629,8 +629,8 @@ export const ui_locales_b2 = { B08_Quantity_Method_Ripping: ["긁어내기(암절취)", "Ripping"], B08_Quantity_Method_Blasting: ["터뜨리기(발파암)", "Blasting"], B08_Quantity_Placing_NotApplied: [ - "⚠ 이 선택은 아직 금액에 반영되지 않습니다 — 견적의 일위대가가 타설 품을 이미 갖고 있는지 확인 중입니다.", - "Not yet applied to cost — checking whether the unit-price already covers placing labour.", + "타설 방식에 따라 이 공종의 단가가 달라집니다 — 콘크리트 물량이 「콘크리트 타설」 공종으로 견적에 넘어갑니다.", + "The placing method changes this work item's unit price — concrete volume is handed over as a placing work item.", ], B08_Quantity_Side_Topsoil: ["표토제거", "Topsoil Removal"], B08_Quantity_Side_Topsoil_Label: ["표토 두께(m)", "Topsoil thickness (m)"],