diff --git a/Z01_MasterData/Z01_MasterData_BasePrices.py b/Z01_MasterData/Z01_MasterData_BasePrices.py index 6de5c298..174c5315 100644 --- a/Z01_MasterData/Z01_MasterData_BasePrices.py +++ b/Z01_MasterData/Z01_MasterData_BasePrices.py @@ -403,6 +403,37 @@ def spec(kind: str, columns: list[str]) -> dict[str, Any]: } +#: 갈래 둘 — 기초단가(원가 = 얼마인가) · 품셈 기준(수량 = 얼마나 드나). 화면은 이것으로 상자를 세움. +BASE_PRICE_GROUP, PUMSEM_GROUP = "base_price", "pumsem_basis" + + +def kind_group(kind: str) -> str: + return PUMSEM_GROUP if kind in base_tables.SPEC else BASE_PRICE_GROUP + + +def kind_label(kind: str) -> str: + """kind 한글 이름 — 이름표 `merged_tables` 에서만(코드에 박지 않음 · 없으면 영문 그대로).""" + merged = tables.load_labels().get("merged_tables") or [] + named = next((t for t in merged if t.get("key") in (kind, f"{kind}s")), {}) + return named.get("name_ko") or kind + + +def kinds() -> list[dict[str, Any]]: + """화면이 상자를 세울 목록 — **서버가 냄**(화면이 제 코드에 들면 새 kind 가 조용히 안 뜸). + + 갈래 · kind · 한글 이름(이름표) · 줄 수. + """ + return [ + { + "group": kind_group(kind), + "kind": kind, + "label": kind_label(kind), + "rows": len(rows(kind)), + } + for kind in KINDS + ] + + def row_label(kind: str, row: dict[str, Any] | None) -> str: if row is None: return "" diff --git a/Z01_MasterData/Z01_MasterData_Router.py b/Z01_MasterData/Z01_MasterData_Router.py index c9296fe9..7179fef1 100644 --- a/Z01_MasterData/Z01_MasterData_Router.py +++ b/Z01_MasterData/Z01_MasterData_Router.py @@ -2,7 +2,8 @@ GET /api/master-data/tree 갈래 → 파일 → 표 GET /api/master-data/rows?file=&table=&page=&size=&q= 표 줄(쪽 나누기 · 검색) - GET /api/master-data/base-prices/{kind}?page=&size=&q=&sort=&desc= 기초단가 한 표(labor|machine|material|oil|rate) + GET /api/master-data/base-prices 표 목록(갈래·kind·이름·줄 수) + GET /api/master-data/base-prices/{kind}?page=&size=&q=&sort=&desc= 한 표(기초단가 다섯 · 품셈 기준 열) PUT /api/master-data/base-prices/{kind}/{row_id} {values:{열:값}} → 덮개에만 씀 · null = 되돌리기 GET /api/master-data/overrides 고친 것·원본 바뀐 것·주인 없는 것(서버 정렬) ⚠ 권한은 등록하는 쪽(`main.py` · 랩탑 서브)이 `dependencies=[verify_session, require_system_admin]` 로 붙임. @@ -48,6 +49,12 @@ def _kind(kind: str) -> str: return kind +@router.get("/base-prices") +def get_base_price_kinds() -> dict: + """어떤 표가 있나 — 갈래·kind·한글 이름·줄 수. 화면이 목록을 제 코드에 들지 않게 서버가 냄.""" + return {"kinds": base_prices.kinds()} + + @router.get("/base-prices/{kind}") def get_base_prices( kind: str, diff --git a/resources/tester/test_z01_base_tables.py b/resources/tester/test_z01_base_tables.py index 19fa7877..d65819fa 100644 --- a/resources/tester/test_z01_base_tables.py +++ b/resources/tester/test_z01_base_tables.py @@ -271,3 +271,34 @@ def test_같은_기울기가_두_자리인_까닭을_표가_말함(client: TestC assert any("축과 근거가 다름" in line for line in notice) slope = _get(client, "masonry_slope", size=1)["notice"] assert any("횡단 도면" in line for line in slope) # 표준경사 쪽 알림은 그대로 + + +def test_kind_목록을_서버가_줌_새_kind_도_저절로( + client: TestClient, monkeypatch: pytest.MonkeyPatch +) -> None: + """화면이 kind 목록을 제 코드에 들면 **새 kind 가 조용히 안 뜸**(기계 작업량이 그랬음 · 브레인). + + ⇒ 갈래·kind·한글 이름·줄 수를 서버가 냄. 화면은 상자만 세운다. + """ + listed = client.get("/api/master-data/base-prices") + assert listed.status_code == 200, listed.text + items = listed.json()["kinds"] + assert [i["kind"] for i in items] == list(base_prices.KINDS) + groups = {i["kind"]: i["group"] for i in items} + assert groups["labor"] == "base_price" and groups["machine_productivity"] == "pumsem_basis" + assert {i["group"] for i in items} == {"base_price", "pumsem_basis"} + labor = next(i for i in items if i["kind"] == "labor") + assert labor["label"] == "노임" and labor["rows"] == 261 # 이름은 이름표에서 + assert next(i for i in items if i["kind"] == "machine_productivity")["rows"] == 47 + + from Z01_MasterData import Z01_MasterData_BasePrices_Tables as base_tables + + fake = dict(base_tables.SPEC) + fake["coef_fake"] = dict(base_tables.SPEC["coef"]) + monkeypatch.setattr(base_tables, "SPEC", fake) + monkeypatch.setattr(base_prices, "KINDS", (*base_prices.KINDS, "coef_fake")) + grown = client.get("/api/master-data/base-prices").json()["kinds"] + assert [i["kind"] for i in grown][-1] == "coef_fake" # 더하면 목록이 저절로 늚 + assert ( + next(i for i in grown if i["kind"] == "coef_fake")["label"] == "coef_fake" + ) # 이름표 전엔 영문