Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 — 서브 갈래마다 한 줄(산림 627)·총칙 기본 감춤·이름표 읽기 받음 · 「연결됨」·줄 구실 칸을 갈래 줄에 얹음(공종 열쇠 @key 로 판정) · 연결 시험은 표가 붙은 줄만 잼(묶는 마디 CW-01329 는 목록 밖)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""Z01 공종 축 — 산림·건설 두 kind 를 기초단가와 **같은 계약**으로(2026-09-17 브레인 · PLAN_공종축 8-4).
|
||||
|
||||
줄 = **품셈 표가 붙은 마디**(`axis_policy.json` `flat_list_filter: pum_tables > 0` — 잎으로 거르면 부모에 붙은 표가 안 뜸) ·
|
||||
갈래(`variant_keys`)는 칸으로(편 수 = `stats.units`).
|
||||
갈래(`variant_keys`)마다 한 줄로 폄 — 줄 수 = 편 수(`stats.units`) · 공종 수 = `stats.work_items`.
|
||||
이름 = 뿌리부터 전체 경로(「토공 › 토사깍기 › 기계」 · 건설은 부문부터) — 잎 이름만으론 겹침.
|
||||
계산 규칙 = 표 수준 `rules`(부모 마디 choose_one · sum_steps) + 줄 칸 `rule`·`step_weight`
|
||||
— 빠지면 발파암(절취 0.1 + 깍기 0.9 + 집토 1) 금액이 틀어짐.
|
||||
@@ -77,6 +77,9 @@ def base_rows(kind: str) -> list[dict[str, Any]]:
|
||||
return []
|
||||
d, name = found
|
||||
items, by, children = _tree(d)
|
||||
# 계산 규칙 이름 — 이름표 `value_overrides["work_item_master::<방식>"]`(「아래를 단계로 다 더함」) · 없으면 영문
|
||||
named = tables.load_labels().get("value_overrides") or {}
|
||||
linked, roles = linked_keys(), _role_names()
|
||||
rows = []
|
||||
for item in items:
|
||||
if not item.get("tables"):
|
||||
@@ -86,24 +89,32 @@ def base_rows(kind: str) -> list[dict[str, Any]]:
|
||||
(s["weight"] for s in parent.get("steps") or [] if s["code"] == item["work_item_code"]),
|
||||
None,
|
||||
)
|
||||
rows.append(
|
||||
{
|
||||
"@id": _key(item),
|
||||
"@source": name,
|
||||
"work_item_code": item["work_item_code"], # 목차 코드 — 열쇠 아님, 칸으로만
|
||||
"number": item["number"],
|
||||
"name": _path(item, by),
|
||||
"variant_keys": item.get("variant_keys") or [],
|
||||
"pum_tables": [t["pum_table_id"] for t in item["tables"]],
|
||||
"rule": parent.get("parent_mode"),
|
||||
"step_weight": weight,
|
||||
# 「임도가 쓰는 것」 — 연결고리 표가 확정으로 이은 줄(판정은 그 표 · 감추지 않고 표시만)
|
||||
"link": LINKED if _key(item) in linked_keys() else "",
|
||||
# 줄 구실(총칙·공종) — 이름은 axis_policy.json · 감추지 않고 표시(거르기 상자로 고름)
|
||||
"axis_role": _role_names().get(str(item.get("axis_role") or ""), ""),
|
||||
"effective_date": d.get("pum_edition") or d.get("effective_date"),
|
||||
}
|
||||
)
|
||||
key = _key(item)
|
||||
# 갈래마다 한 줄 — 일위대가가 갈래마다 달라 집는 단위가 갈래임(교목굴취 나무높이 9 · 2026-09-17 브레인 ③).
|
||||
# 열쇠 = 공종 열쇠#갈래 키(B08·B09 `코드#갈래` 꼴) · 갈래 키 글자는 마스터 것 그대로(조립 두 벌 금지).
|
||||
for variant in item.get("variant_keys") or [None]:
|
||||
rows.append(
|
||||
{
|
||||
"@id": f"{key}#{variant}" if variant else key,
|
||||
"@key": key, # 공종 열쇠 — 거르기·줄 수는 공종 단위로
|
||||
"@source": name,
|
||||
"work_item_code": item["work_item_code"], # 목차 코드 — 열쇠 아님, 칸으로만
|
||||
"number": item["number"],
|
||||
"name": _path(item, by),
|
||||
"variant": variant,
|
||||
"pum_tables": [t["pum_table_id"] for t in item["tables"]],
|
||||
"rule": (named.get(f"work_item_master::{parent.get('parent_mode')}") or {}).get(
|
||||
"name_ko"
|
||||
)
|
||||
or parent.get("parent_mode"),
|
||||
"step_weight": weight,
|
||||
# 「임도가 쓰는 것」 — 연결고리 표가 확정으로 이은 공종(판정은 그 표 · 감추지 않고 표시만)
|
||||
"link": LINKED if key in linked else "",
|
||||
# 줄 구실(총칙·공종) — 이름은 axis_policy.json · 표시 칸(거르기 상자로 고름)
|
||||
"axis_role": roles.get(str(item.get("axis_role") or ""), ""),
|
||||
"effective_date": d.get("pum_edition") or d.get("effective_date"),
|
||||
}
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
@@ -171,9 +182,12 @@ def notice(kind: str) -> list[str]:
|
||||
|
||||
|
||||
#: 거르기 — **자료에 있는 가름만**(건설 부문 · 줄 구실 · 연결고리 표). 어느 줄을 거를지는 서버 한 곳 ·
|
||||
#: 화면은 고른 값만 보냄 · 기본은 늘 「전부」(감추지 않음 — 사용자 「어디에 쓸지 모르니 건설 전체」 · 브레인).
|
||||
#: 화면은 고른 값만 보냄 · 연결은 기본 「전부」(감추지 않음 — 「어디에 쓸지 모르니 건설 전체」 · 브레인) ·
|
||||
#: 줄 구실만 기본 「공종」(총칙 기본 감춤 · 서브 2ee6a7ed · 브레인).
|
||||
FILTER_KEYS = ("link", "division", "axis_role")
|
||||
ALL = ""
|
||||
#: 값을 안 보냈을 때 거는 값 — 총칙 줄은 기본 감춤 · 「전부」를 고르면 보임(2026-09-17 브레인)
|
||||
DEFAULTS = {"axis_role": "work_item"}
|
||||
|
||||
|
||||
def _facets(kind: str) -> dict[str, dict[str, str]]:
|
||||
@@ -200,7 +214,7 @@ def _role_names() -> dict[str, str]:
|
||||
|
||||
|
||||
def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""거르기 상자 — 줄이 둘 이상으로 갈리는 가름만 · 기본은 「전부」(안 거름)."""
|
||||
"""거르기 상자 — 줄이 둘 이상으로 갈리는 가름만 · 기본은 `DEFAULTS`(그 값이 표에 있을 때) 아니면 「전부」."""
|
||||
facets = _facets(kind)
|
||||
labels = {
|
||||
"link": ("연결", {LINKED: "연결된 것만"}),
|
||||
@@ -211,19 +225,20 @@ def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
for key in FILTER_KEYS:
|
||||
counts: dict[str, int] = {}
|
||||
for row in rows:
|
||||
value = facets.get(row["@id"], {}).get(key, ALL)
|
||||
value = facets.get(row["@key"], {}).get(key, ALL)
|
||||
counts[value] = counts.get(value, 0) + 1
|
||||
values = [v for v in counts if v != ALL]
|
||||
if len(counts) < 2: # 다 같은 값이면 거를 것이 없음(연결은 「연결됨」 · 빈칸 둘로 갈림)
|
||||
continue
|
||||
label, names = labels[key]
|
||||
default = DEFAULTS.get(key, ALL)
|
||||
out.append(
|
||||
{
|
||||
"key": key,
|
||||
"label": label,
|
||||
"options": [{"value": ALL, "label": "전부", "rows": len(rows)}]
|
||||
+ [{"value": v, "label": names.get(v, v), "rows": counts[v]} for v in values],
|
||||
"default": ALL,
|
||||
"default": default if default in values else ALL,
|
||||
}
|
||||
)
|
||||
return out
|
||||
@@ -233,9 +248,12 @@ def apply_filters(
|
||||
kind: str, rows: list[dict[str, Any]], picked: dict[str, str]
|
||||
) -> list[dict[str, Any]]:
|
||||
facets = _facets(kind)
|
||||
for key, value in picked.items():
|
||||
if key in FILTER_KEYS and value != ALL:
|
||||
rows = [r for r in rows if facets.get(r["@id"], {}).get(key) == value]
|
||||
# 안 보낸 가름은 상자 기본값으로 — 상자에 보이는 값과 걸린 값이 같게(찾기 결과가 아니라 표 전체로 정함)
|
||||
defaults = {f["key"]: f["default"] for f in filters(kind, base_rows(kind))}
|
||||
for key in FILTER_KEYS:
|
||||
value = picked.get(key, defaults.get(key, ALL))
|
||||
if value != ALL:
|
||||
rows = [r for r in rows if facets.get(r["@key"], {}).get(key) == value]
|
||||
return rows
|
||||
|
||||
|
||||
@@ -246,7 +264,7 @@ def extra(kind: str) -> dict[str, Any]:
|
||||
"filters": filters(kind, rows),
|
||||
"rules": rules(kind),
|
||||
"stats": {
|
||||
"work_items": len(rows),
|
||||
"units": sum(max(1, len(r["variant_keys"])) for r in rows),
|
||||
"work_items": len({r["@key"] for r in rows}),
|
||||
"units": len(rows),
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user