Merge remote-tracking branch 'origin/main_desktop_1' into sub_desktop_1
This commit is contained in:
@@ -81,6 +81,19 @@ COEFFICIENT_ROW_KEYS = {"K", "f", "E", "Cm", "㎝(sec)", "q", "qo", "Q", "V", "L
|
|||||||
REFERENCE_MARKS = ("할증률", "할인", "공제율", "적재량", "지위")
|
REFERENCE_MARKS = ("할증률", "할인", "공제율", "적재량", "지위")
|
||||||
# 값 대신 「어디를 따르라」고만 적은 표. 품이 아니므로 공종으로 세우지 않는다.
|
# 값 대신 「어디를 따르라」고만 적은 표. 품이 아니므로 공종으로 세우지 않는다.
|
||||||
REFERENCE_CELL_MARKS = ("별도계상", "구역화물", "적용한다", "따른다", "준용")
|
REFERENCE_CELL_MARKS = ("별도계상", "구역화물", "적용한다", "따른다", "준용")
|
||||||
|
# 품셈이 실어 둔 **빈 단가산출서 서식** — 값이 없는 예시 양식이다(2026-09-08 ㉙, 서브가 찾음).
|
||||||
|
# 첫 줄이 「위치 및 임·소반」·「위치 및 면적」이고 다음 줄이 「구분 | 작업량 | 단위품 |
|
||||||
|
# 소요품 | 단가」인 모양. 채워 넣으라고 둔 칸이라 **자원도 값도 없다.**
|
||||||
|
# ⚠ 이것을 공종으로 세우면 「값이 있는데 안 서는 자리」로 오해된다 — 애초에 값이 없다.
|
||||||
|
# 서브가 그 표들 탓에 못 맞춘 자원이 882 → 497 로 부풀어 있었다.
|
||||||
|
# ⚠ **두 조건을 다 만족할 때만** 본다 — 「구분」·「단가」는 정상 표에도 흔한 낱말이라
|
||||||
|
# 하나만 보면 정상 표를 지운다(오늘 그 병을 열한 번 겪었다).
|
||||||
|
#: 표지는 **머리글에 그대로 적혀 있다** — 「ha당 참나무시들음병방제 **단가산출서(예시)**」.
|
||||||
|
#: 낱말 하나로 충분히 좁다(정상 표 머리글에 「단가산출서」가 올 일이 없다).
|
||||||
|
BLANK_FORM_MARK = "단가산출서"
|
||||||
|
#: 머리글이 비어 있는 판을 대비한 보조 표지 — **두 조건을 다 만족할 때만** 본다.
|
||||||
|
BLANK_FORM_HEAD_MARKS = ("위치및임소반", "위치및면적")
|
||||||
|
BLANK_FORM_BODY_MARKS = ("단위품", "소요품")
|
||||||
# 직종이 값의 주인인 표 = 소요량형. `보통인부(인)`·`콘크리트공(인)` 처럼 `(인)` 이 붙는다.
|
# 직종이 값의 주인인 표 = 소요량형. `보통인부(인)`·`콘크리트공(인)` 처럼 `(인)` 이 붙는다.
|
||||||
# ⚠ 원문에 `인 부` 처럼 낱말 사이 공백이 있어, 비교 전에 공백을 모두 지운다(`squeeze`).
|
# ⚠ 원문에 `인 부` 처럼 낱말 사이 공백이 있어, 비교 전에 공백을 모두 지운다(`squeeze`).
|
||||||
OCCUPATION_RE = re.compile(
|
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:
|
if mark in squeezed:
|
||||||
return "reference", f"'{mark}' — 값이 아니라 참조 지시"
|
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)」 표의 비고란에 흔히
|
# ⚠ 생산량형을 **직종보다 먼저** 본다. 「작업능력(㎥/hr)」 표의 비고란에 흔히
|
||||||
# 「보통인부 1인/일」이 붙어 있어, 직종을 먼저 보면 생산량형이 소요량형으로 뒤집힌다.
|
# 「보통인부 1인/일」이 붙어 있어, 직종을 먼저 보면 생산량형이 소요량형으로 뒤집힌다.
|
||||||
# 그 뒤집힘이 곧 PLAN 8-6 이 경고한 「값이 조용히 반대로 들어가는」 사고다.
|
# 그 뒤집힘이 곧 PLAN 8-6 이 경고한 「값이 조용히 반대로 들어가는」 사고다.
|
||||||
|
|||||||
@@ -687,6 +687,87 @@ def _structure_rows(
|
|||||||
return rows, unmatched
|
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]]:
|
def _material_rows(material_table: dict[str, Any]) -> list[dict[str, Any]]:
|
||||||
"""자재 줄 — **공종코드를 붙이지 않는다.** 자재 축은 B09 카탈로그가 잇는다(8-7)."""
|
"""자재 줄 — **공종코드를 붙이지 않는다.** 자재 축은 B09 카탈로그가 잇는다(8-7)."""
|
||||||
rows: list[dict[str, Any]] = []
|
rows: list[dict[str, Any]] = []
|
||||||
@@ -718,6 +799,7 @@ def build_handoff(
|
|||||||
ground_class_set: str | None = None,
|
ground_class_set: str | None = None,
|
||||||
ground_classes: list[str] | None = None,
|
ground_classes: list[str] | None = None,
|
||||||
ground_methods: dict[str, str | None] | None = None,
|
ground_methods: dict[str, str | None] | None = None,
|
||||||
|
concrete_placing_method: str | None = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""B09 가 그대로 받는 모양. 없는 표는 건너뛰되 **빈 표와 구별해 적는다**."""
|
"""B09 가 그대로 받는 모양. 없는 표는 건너뛰되 **빈 표와 구별해 적는다**."""
|
||||||
table = mapping or load_mapping()
|
table = mapping or load_mapping()
|
||||||
@@ -738,6 +820,12 @@ def build_handoff(
|
|||||||
work_items.extend(rows)
|
work_items.extend(rows)
|
||||||
unmatched.extend(misses)
|
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 {})
|
materials = _material_rows(material_table or {})
|
||||||
result: dict[str, Any] = {
|
result: dict[str, Any] = {
|
||||||
"work_items": work_items,
|
"work_items": work_items,
|
||||||
@@ -780,6 +868,7 @@ def build_handoff(
|
|||||||
result["ratio_math_warnings"] = verify_ratio_math(result)
|
result["ratio_math_warnings"] = verify_ratio_math(result)
|
||||||
result["material_code_warnings"] = verify_no_code_on_materials(result)
|
result["material_code_warnings"] = verify_no_code_on_materials(result)
|
||||||
result["bill_flag_warnings"] = verify_bill_flags(result)
|
result["bill_flag_warnings"] = verify_bill_flags(result)
|
||||||
|
result["placing_notes"] = placing_notes
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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_MaterialSummary import build_table as build_material_table
|
||||||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table as build_unit_table
|
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table as build_unit_table
|
||||||
from common_util.common_util_project_settings import (
|
from common_util.common_util_project_settings import (
|
||||||
|
concrete_placing_method,
|
||||||
quantity_settings,
|
quantity_settings,
|
||||||
rock_classes,
|
rock_classes,
|
||||||
rock_method,
|
rock_method,
|
||||||
@@ -161,6 +162,8 @@ async def get_handoff(project_id: UUID) -> JSONResponse:
|
|||||||
ground_class_set=settings.get("rock_class_set"),
|
ground_class_set=settings.get("rock_class_set"),
|
||||||
ground_classes=rock_classes(settings),
|
ground_classes=rock_classes(settings),
|
||||||
ground_methods={name: rock_method(settings, name) for name in 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["summary"] = summarize(handoff)
|
||||||
handoff["skipped_structures"] = skipped
|
handoff["skipped_structures"] = skipped
|
||||||
|
|||||||
@@ -352,9 +352,9 @@ function buildQuantitySidePanel(
|
|||||||
placing.is_default ? `${label} (${L("B08_Quantity_Placing_Default_Tag")})` : label,
|
placing.is_default ? `${label} (${L("B08_Quantity_Placing_Default_Tag")})` : label,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// ⚠ 고른 값이 **아직 금액에 안 닿는다**는 사실을 숨기지 않는다(2026-09-08 ㉘).
|
// 2026-09-08 ㉙: 인계가 **타설 공종 줄을 실제로 세운다.** 겹치지 않는 것이 확인됐다 —
|
||||||
// 인계가 타설 공종 줄을 아직 안 세운다 — B09 일위대가가 타설 품을 이미 갖고 있는지
|
// 품셈 12-1-1 표는 직종·품만 주고 재료를 안 줘서, 품은 이 줄 · 재료는 자재 쪽이다.
|
||||||
// 확인되기 전까지는 세우면 같은 콘크리트를 두 번 센다(이중계상 ㉢ 과 같은 자리).
|
// ⚠ 돌쌓기 뒤채움(채움콘크리트)은 뺐다 — 그 공종 품에 이미 들어 있을 수 있다.
|
||||||
const pending = document.createElement("p");
|
const pending = document.createElement("p");
|
||||||
pending.className = "b08-quantity__note";
|
pending.className = "b08-quantity__note";
|
||||||
pending.textContent = L("B08_Quantity_Placing_NotApplied");
|
pending.textContent = L("B08_Quantity_Placing_NotApplied");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"schema_version": "1.0",
|
"schema_version": "1.0",
|
||||||
"dataset_id": "data_work_item_master_manifest",
|
"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",
|
"built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py",
|
||||||
"source": {
|
"source": {
|
||||||
"dataset_id": "pum_forest",
|
"dataset_id": "pum_forest",
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"file": "work_item_master_2026-01-01.json",
|
"file": "work_item_master_2026-01-01.json",
|
||||||
"sha256": "1c49012f9f50d721676ad8def15c87c96b77aad83123286dd6981b7d9cefcd81",
|
"sha256": "4d89c1eec7929c39d5adb36547b03f4675205b10f6b629eeb2f246a1d9230dfd",
|
||||||
"size_bytes": 856450
|
"size_bytes": 856818
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "form_undetermined_2026-01-01.json",
|
"file": "form_undetermined_2026-01-01.json",
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "basis_missing_2026-01-01.json",
|
"file": "basis_missing_2026-01-01.json",
|
||||||
"sha256": "b69091149adb942ce507d902b7e6ac400777674301b9200b1f1c60cfbd709839",
|
"sha256": "9d7b9ee8df65be1c944a2e0af9efe0742bd9a356b367fc4de8eec47b3ece2147",
|
||||||
"size_bytes": 22832
|
"size_bytes": 18627
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -825,144 +825,6 @@
|
|||||||
"section": "13-16-2. 통기성매트",
|
"section": "13-16-2. 통기성매트",
|
||||||
"pum_form": "requirement",
|
"pum_form": "requirement",
|
||||||
"line": 7788
|
"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
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"schema_version": "1.0",
|
"schema_version": "1.0",
|
||||||
"dataset_id": "work_item_master_forest",
|
"dataset_id": "work_item_master_forest",
|
||||||
"effective_date": "2026-01-01",
|
"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_version": {
|
||||||
"dataset_id": "pum_forest",
|
"dataset_id": "pum_forest",
|
||||||
"effective_date": "2026-01-01",
|
"effective_date": "2026-01-01",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"tables_orphan": 19,
|
"tables_orphan": 19,
|
||||||
"form_undetermined": 77,
|
"form_undetermined": 77,
|
||||||
"basis_found": 183,
|
"basis_found": 183,
|
||||||
"basis_missing": 160,
|
"basis_missing": 137,
|
||||||
"basis_grouped": 36
|
"basis_grouped": 36
|
||||||
},
|
},
|
||||||
"orphan_tables": [
|
"orphan_tables": [
|
||||||
@@ -4157,8 +4157,8 @@
|
|||||||
"pum_table_id": "F0455",
|
"pum_table_id": "F0455",
|
||||||
"section": "2-1. 풀베기, (1) 둘레베기(조림목 본수 2,700본/ha, 조림1년차)",
|
"section": "2-1. 풀베기, (1) 둘레베기(조림목 본수 2,700본/ha, 조림1년차)",
|
||||||
"source_line": 8031,
|
"source_line": 8031,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -5704,8 +5704,8 @@
|
|||||||
"pum_table_id": "F0456",
|
"pum_table_id": "F0456",
|
||||||
"section": "2-2. 풀베기, (2) 모두베기(조림목 본수 2,700본/ha, 조림2년차)",
|
"section": "2-2. 풀베기, (2) 모두베기(조림목 본수 2,700본/ha, 조림2년차)",
|
||||||
"source_line": 8061,
|
"source_line": 8061,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -6796,8 +6796,8 @@
|
|||||||
"pum_table_id": "F0472",
|
"pum_table_id": "F0472",
|
||||||
"section": "3-1. 임업용 동력기계톱, 우드그래플, 소형트럭",
|
"section": "3-1. 임업용 동력기계톱, 우드그래플, 소형트럭",
|
||||||
"source_line": 8753,
|
"source_line": 8753,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -7776,8 +7776,8 @@
|
|||||||
"pum_table_id": "F0473",
|
"pum_table_id": "F0473",
|
||||||
"section": "3-2. 임업용 동력기계톱, 스마트집재기, 우드그래플, 초소형포워더",
|
"section": "3-2. 임업용 동력기계톱, 스마트집재기, 우드그래플, 초소형포워더",
|
||||||
"source_line": 8828,
|
"source_line": 8828,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -8874,8 +8874,8 @@
|
|||||||
"pum_table_id": "F0474",
|
"pum_table_id": "F0474",
|
||||||
"section": "3-3. 하베스터, 타워야더, 우드그래플, 소형포워더",
|
"section": "3-3. 하베스터, 타워야더, 우드그래플, 소형포워더",
|
||||||
"source_line": 8912,
|
"source_line": 8912,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -10245,8 +10245,8 @@
|
|||||||
"pum_table_id": "F0475",
|
"pum_table_id": "F0475",
|
||||||
"section": "4-1. 소나무재선충병방제",
|
"section": "4-1. 소나무재선충병방제",
|
||||||
"source_line": 8989,
|
"source_line": 8989,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -11867,8 +11867,8 @@
|
|||||||
"pum_table_id": "F0476",
|
"pum_table_id": "F0476",
|
||||||
"section": "4-2. 참나무시들음병방제",
|
"section": "4-2. 참나무시들음병방제",
|
||||||
"source_line": 9106,
|
"source_line": 9106,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
@@ -24844,8 +24844,8 @@
|
|||||||
"pum_table_id": "F0454",
|
"pum_table_id": "F0454",
|
||||||
"section": "8-2-3 굴착기(2025)」를 참조하여 적용계수를 달리 적용하도록 한다.",
|
"section": "8-2-3 굴착기(2025)」를 참조하여 적용계수를 달리 적용하도록 한다.",
|
||||||
"source_line": 7983,
|
"source_line": 7983,
|
||||||
"pum_form": "requirement",
|
"pum_form": "reference",
|
||||||
"form_basis": "'수량'",
|
"form_basis": "'단가산출서' — 채워 넣으라고 둔 빈 서식",
|
||||||
"basis_quantity": null,
|
"basis_quantity": null,
|
||||||
"basis_unit": null,
|
"basis_unit": null,
|
||||||
"basis_source": null,
|
"basis_source": null,
|
||||||
|
|||||||
@@ -629,8 +629,8 @@ export const ui_locales_b2 = {
|
|||||||
B08_Quantity_Method_Ripping: ["긁어내기(암절취)", "Ripping"],
|
B08_Quantity_Method_Ripping: ["긁어내기(암절취)", "Ripping"],
|
||||||
B08_Quantity_Method_Blasting: ["터뜨리기(발파암)", "Blasting"],
|
B08_Quantity_Method_Blasting: ["터뜨리기(발파암)", "Blasting"],
|
||||||
B08_Quantity_Placing_NotApplied: [
|
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: ["표토제거", "Topsoil Removal"],
|
||||||
B08_Quantity_Side_Topsoil_Label: ["표토 두께(m)", "Topsoil thickness (m)"],
|
B08_Quantity_Side_Topsoil_Label: ["표토 두께(m)", "Topsoil thickness (m)"],
|
||||||
|
|||||||
Reference in New Issue
Block a user