From ada55c2b68277528f3f3ece54f00cfa3380ab971 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 22 Sep 2026 14:14:24 +0900 Subject: [PATCH] =?UTF-8?q?feat(M01):=20PLAN=207-4b=20=EB=92=A4=20?= =?UTF-8?q?=EC=A0=88=EB=B0=98=20=E2=91=A3=E2=91=A4=20=E2=80=94=20=EC=9E=AC?= =?UTF-8?q?=EB=A3=8C=5F=ED=92=88=EC=85=88=EC=9E=AC=EB=A3=8C.json=20?= =?UTF-8?q?=EC=9D=84=20old/=20=EB=A1=9C=20=EC=98=AE=EA=B9=80(MP=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=EC=B0=B8=EC=A1=B0=20=EB=8B=A4=20=EA=B1=B7?= =?UTF-8?q?=EC=9D=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 되돌렸던 옮기기를 마무리. 앞서 놓친 자리 — 호표 「요소」 칸만 훑어서 덧줄·수량 식 안에 그대로 박힌 MP 참조 16곳(집수정 뚜껑·철망태·쉬즈관·IV전선·백열등· 바퀴숫돌 넷·버너·노즐·테르밋용재·몰드·골무·퓨즈·용접봉)을 못 봤음 — 자재품목에 새 줄 일곱(값 미확보) · 기존 줄 셋(백열등·망태석·용접봉, 가장 맞는 것으로 이음)에 연결하고 식 안의 MP 키 문자열을 그 자재품목 키로 바로 바꿔치기(품셈재료 간접 없이). 재료_품셈재료.json 을 resources/master_data/old/ 로 옮김(지우지 않음) — check_master.load() 가 `*.json` 만 훑어 자동으로 빠짐(코드 안 고쳐도 검사·엔진 다 끊김) · build_품셈재료_고르기.py·build_로직_재료_고르기.py 는 다시 안 돌림(한 번 쓰고 마침). 시험 — 옛길(품셈재료 간접)이 죽지 않았는지 자체 마스터로 확인하는 시험 셋을 고쳐 남김(실화면 대신 합성 데이터) · 이제 못 보는 화면 기능(품셈재료 목록· 연결 안 된 줄 거르기) 시험 둘은 뺌(기능 자체가 오늘 사라짐) · 자재품목 분류 기대표에 새로 이은 것들 더함(스페이셔와 같은 이유로 이름 다른 셋 더 뺌). _틀.md — 재료_품셈재료 절을 「old/ 로 옮김·자료로만 둠」으로 고치고, 7장에 지역·계약종별 고르기 조건 칸을 추가. typecheck 통과 · 관련 시험 107 통과 · 로직 1354개 전수 대조 — 금액 달라짐 0 · 새로 멈춤 0 · 새로 통과 2(GC000374·GF000235, 덧줄 식이 못 풀던 것이 오늘 이어져 정상적으로 풀림). PLAN.md 는 이 워크트리에 7장이 없어(gitignore·기기별 파일) 체크 못 함 — 반복된 자리(문서에 이미 적음). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT --- resources/master_data/_키대장.json | 11 ++- resources/master_data/_틀.md | 17 ++-- .../master_data/{ => old}/재료_품셈재료.json | 20 ++--- resources/master_data/ref/_묶음_자재품목.md | 18 ++-- .../로직_건설품셈_04장_궤도공사.json | 4 +- .../로직_건설품셈_05장_강구조공사.json | 2 +- ...로직_건설품셈_06장_관부설_및_접합공사.json | 2 +- .../로직_건설품셈_06장_철근콘크리트공사.json | 4 +- .../로직_산림품셈_12장_철근콘크리트.json | 2 +- .../로직_산림품셈_13장_구조물.json | 2 +- resources/master_data/재료_자재품목.json | 9 +- resources/tester/test_m01_api.py | 11 +-- resources/tester/test_masterdata_check.py | 82 +++++++++++++++---- resources/tester/test_자재품목_분류.py | 23 +++++- 14 files changed, 142 insertions(+), 65 deletions(-) rename resources/master_data/{ => old}/재료_품셈재료.json (98%) diff --git a/resources/master_data/_키대장.json b/resources/master_data/_키대장.json index 7651882d..02ef4a5f 100644 --- a/resources/master_data/_키대장.json +++ b/resources/master_data/_키대장.json @@ -1,5 +1,5 @@ { - "다음": {"LB": 409, "EQ": 655, "RT": 20, "MN": 7000, "MT": 30712, "MO": 74, "MP": 364, "FX": 6, "CF": 159, "QF": 477, "GF": 252, "CC": 341, "GC": 1104, "QC": 2060, "GX": 1, "UA": 2}, + "다음": {"LB": 409, "EQ": 655, "RT": 20, "MN": 7000, "MT": 30719, "MO": 74, "MP": 364, "FX": 6, "CF": 159, "QF": 477, "GF": 252, "CC": 341, "GC": 1104, "QC": 2060, "GX": 1, "UA": 2}, "폐기": {"MT000001": "자재품목 휘발유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000002": "자재품목 경유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000003": "자재품목 선박용경유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000004": "자재품목 중유 — 값이 비고 글뿐 · 유가 테이블로 감", "MT000005": "자재품목 등유 — 값이 비고 글뿐 · 유가 테이블로 감", "LB000399": "이름 「〃」 — 직종이 아니라 되풀이 기호 · 소요량 13-6-9 에서 윗줄 직종으로 바로잡음", "MN": "재료_나라장터자재 — old 로 옮김 · 로직은 자재품목·품셈재료로 갈아 끼움", "LB000372": "미확보 고급기능사 — 측량노임 항공사진고급기능사 옛이름으로 옮김", "LB000393": "미확보 리베팅공 — 건설노임 철골공 옛이름으로 옮김(2010 통합표 연번10)", "LB000405": "미확보 Belt Conveyor 설치공 — 품셈 13-10-1 주② 배분으로 다섯 직종에 나눔", "MT000006": "자재품목 전력 — 재료_유가전력 전력 줄로 감", "MT000007": "자재품목 전력 — 재료_유가전력 전력 줄로 감", "LB000368": "미확보 기술사 — 기술사(건설) 옛이름으로 옮김", "LB000369": "미확보 특급기술자 — 특급기술자(건설) 옛이름으로 옮김", "LB000370": "미확보 고급기술자 — 고급기술자(건설) 옛이름으로 옮김", "LB000361": "미확보 중급기술자 — 중급기술자(건설) 옛이름으로 옮김", "LB000364": "미확보 초급기술자 — 초급기술자(건설) 옛이름으로 옮김", "LB000365": "미확보 고급숙련기술자 — 고급숙련기술자(건설) 옛이름으로 옮김", "LB000366": "미확보 중급숙련기술자 — 중급숙련기술자(건설) 옛이름으로 옮김", "LB000367": "미확보 초급숙련기술자 — 초급숙련기술자(건설) 옛이름으로 옮김", "LB000389": "미확보 기계기사 — 초급기술자(기계·설비) 옛이름으로 옮김", "LB000388": "미확보 기계산업기사 — 초급숙련기술자(기계·설비) 옛이름으로 옮김", "MO000055": {"원문번호": "주택용저압:기본_200이하", "파일": "재료_유가전력.json"}, "MO000056": {"원문번호": "주택용저압:기본_201~400", "파일": "재료_유가전력.json"}, "MO000057": {"원문번호": "주택용저압:기본_400초과", "파일": "재료_유가전력.json"}, "MO000059": {"원문번호": "주택용저압:전력량_다음200", "파일": "재료_유가전력.json"}, "MO000060": {"원문번호": "주택용저압:전력량_400초과", "파일": "재료_유가전력.json"}, "MO000061": {"원문번호": "주택용저압:월간최저요금", "파일": "재료_유가전력.json"}, "MO000062": {"원문번호": "일반용갑I저압:기본", "파일": "재료_유가전력.json"}, "MO000063": {"원문번호": "일반용갑I저압:전력량_여름철", "파일": "재료_유가전력.json"}, "MO000064": {"원문번호": "일반용갑I저압:전력량_봄가을철", "파일": "재료_유가전력.json"}, "MO000065": {"원문번호": "일반용갑I저압:전력량_겨울철", "파일": "재료_유가전력.json"}, "MO000066": {"원문번호": "산업용갑I저압:기본", "파일": "재료_유가전력.json"}, "MO000067": {"원문번호": "산업용갑I저압:전력량_여름철", "파일": "재료_유가전력.json"}, "MO000068": {"원문번호": "산업용갑I저압:전력량_봄가을철", "파일": "재료_유가전력.json"}, "MO000069": {"원문번호": "산업용갑I저압:전력량_겨울철", "파일": "재료_유가전력.json"}, "MO000070": {"원문번호": "임시전력갑:기본요금적용", "파일": "재료_유가전력.json"}, "MO000071": {"원문번호": "임시전력갑:전력량요금적용", "파일": "재료_유가전력.json"}, "MO000072": {"원문번호": "임시전력갑:월간최저요금", "파일": "재료_유가전력.json"}}, "키": { "CC000001": {"원문번호": "공통 1-3-1 콘크리트 및 포장용 재료", "파일": "계수_건설품셈_01장_적용기준.json"}, @@ -36584,6 +36584,13 @@ "MT030708": {"원문번호": "품셈재료 MP000005 전국", "파일": "재료_자재품목.json"}, "MT030709": {"원문번호": "품셈재료 MP000005 지역별", "파일": "재료_자재품목.json"}, "MT030710": {"원문번호": "품셈재료 MP000209", "파일": "재료_자재품목.json"}, - "MT030711": {"원문번호": "품셈재료 MP000214", "파일": "재료_자재품목.json"} + "MT030711": {"원문번호": "품셈재료 MP000214", "파일": "재료_자재품목.json"}, + "MT030712": {"원문번호": "품셈재료 MP000040", "파일": "재료_자재품목.json"}, + "MT030713": {"원문번호": "품셈재료 MP000094", "파일": "재료_자재품목.json"}, + "MT030714": {"원문번호": "품셈재료 MP000202", "파일": "재료_자재품목.json"}, + "MT030715": {"원문번호": "품셈재료 MP000205", "파일": "재료_자재품목.json"}, + "MT030716": {"원문번호": "품셈재료 MP000206", "파일": "재료_자재품목.json"}, + "MT030717": {"원문번호": "품셈재료 MP000207", "파일": "재료_자재품목.json"}, + "MT030718": {"원문번호": "품셈재료 MP000208", "파일": "재료_자재품목.json"} } } diff --git a/resources/master_data/_틀.md b/resources/master_data/_틀.md index 07b916dd..c91af730 100644 --- a/resources/master_data/_틀.md +++ b/resources/master_data/_틀.md @@ -17,7 +17,7 @@ | -------------------- | --------------------------------------------------------------------------------------- | | 인력 | `인력.json` 하나 — 줄마다 `구분` | | 기계 | `기계.json` 하나 — 줄마다 `원문` | -| 재료 | `재료_<원문>.json` — 자재품목 · 유가전력 · 품셈재료 | +| 재료 | `재료_<원문>.json` — 자재품목 · 유가전력 | | 환율 · 요율 | `환율_한국은행환율.json` · `요율_조달청제비율.json` | | 소요량 · 계수 · 로직 | `<그룹>_<원문>_장_<장 제목>.json` — 예 `소요량_건설품셈_10장_창호_및_유리공사.json` | @@ -37,7 +37,7 @@ | LB | 인력 | QF · QC | 소요량 산림 · 건설 | | MT | 재료 자재품목 | CF · CC | 계수 산림 · 건설 | | MO | 재료 유가 | RT | 요율 | -| MP | 재료 품셈재료 | GF · GC · GX | 로직 산림 · 건설 · 자체 | +| MP | 재료 품셈재료(old/ — PLAN 7-4b) | GF · GC · GX | 로직 산림 · 건설 · 자체 | | EQ | 기계 | | | - 빌더는 옛 모양(`열쇠` · 원문별 파일)으로 쓰고 끝에 `scripts/master_keys.py` 의 `adopt` 를 부름 — 키·원문번호·한 테이블·장 파일 이름으로 받음. 옛 이름으로 읽기는 `old_view`. @@ -119,10 +119,8 @@ - 유류·전력은 뗌 — 유가·전기요금은 `재료_유가전력`(유류는 값이 비고 글뿐 · 중유는 받지 않음). - `재료_유가전력` · `환율_한국은행환율` 도 열 한 벌 — 키 · 원문번호 · 구분 · 상세구분 · 이름 · 규격 · 단위 · 값 · 출처 · 비고. 유가전력 `구분` = 유류 · 전력 · `상세구분` = 유류(지역 이름) · 전력(계약종별) · `규격` = 기준일(유류 수집일 · 전력 시행일). 환율은 `규격` = 기준일 · 구분·상세구분 비움. - 로직 호표가 자재품목 키(`MT…`)를 바로 가리키면 그 줄의 값 열 가운데 낮은 값 — **시험 계산용**. -- `재료_품셈재료` = 품셈이 부르는 재료 목록 — `{ 키, 원문번호, 이름, 규격, 단위, 요구절: [출처 모양], 연결, 고르기 }` · 값 칸 없음. -- `고르기` = 그 재료가 자재품목 어느 묶음인지 — 재료 고르기 조건 `{ 구분, 상세구분[, 규격] }`(7장) · 못 가리면 `null` 에 비고 「고르기 없음(까닭)」. 채우기 = `scripts/build_품셈재료_고르기.py`(자재품목을 가른 바로 그 품명 글자 규칙 · 묶음 목록 `ref/_묶음_자재품목.md`) · 손으로 바로잡은 줄은 그 스크립트 `OVERRIDE` 에. `연결` 이 이미 있는 줄은 비움 — 옛 방식 그대로 씀. -- 로직 재료 줄 일괄 변환 = `scripts/build_로직_재료_고르기.py` — 호표 요소 `MP…` 를 그 줄의 `고르기` 조건으로 바꿈 · 고르기가 빈 줄과 `{이름}` 이 낀 원문번호 줄은 그대로 둠. -- `연결` = 자재품목·유가전력 키 하나 · 후보 조건 `{ 이름, 규격, 지역: "입력" }`(지역이 갈리는 레미콘·골재·아스콘) · `{ 이름, 계약종별: "입력" }`(전력 — 로직 입력 `전력 계약종별`) · `null`(아직 못 이음). +- `재료_품셈재료`(PLAN 7-4b 뒤 절반 — `old/` 로 옮김 · 살아 있는 마스터엔 안 읽힘 · 자료로만 둠) = 품셈이 부르는 재료 목록이던 것 — `{ 키, 원문번호, 이름, 규격, 단위, 요구절: [출처 모양], 연결, 고르기 }` · 값 칸 없음. 로직 호표·덧줄의 `MP…` 직접 참조는 다 걷어 자재품목 고르기 조건(7장)이나 대표 키로 바꿈 — 아래 두 줄은 그 옮기던 때의 자취. +- `연결` = 자재품목·유가전력 키 하나 · 후보 조건 `{ 이름, 규격, 지역: "입력" }`(지역이 갈리는 레미콘·골재·아스콘) · `{ 이름, 계약종별: "입력" }`(전력 — 로직 입력 `전력 계약종별`) · `null`(못 이음). 이 지역·계약종별 조건 묶음은 이제 7장의 고르기 조건(`PICK_KEYS` 의 `지역`·`계약종별`)에 그대로 들어가 호표에 바로 박힘 — 품셈재료 간접 없이 `master_material._region`·`_tariff` 가 품. - 단가 = 연결된 줄의 값 열 다섯 가운데 낮은 값 · 호표 결과 줄에 `출처`(`<키>.<열>`) — **시험 계산용**. 후보 조건 = 품명 뿌리가 `이름` 으로 끝남 · 이름에 로직 입력 `자재지역` 글자 · 단위 같음 · 규격이 둘 이상 갈리면 멈춤 「후보 여럿」 · 그 지역 줄이 없으면 가까운 시군을 고르지 않고 멈춤 「지역 값 없음」. ## 6. 표형 요소 (소요량 · 계수) @@ -220,7 +218,8 @@ } ``` -- 조건 칸 = `구분`(반드시) · `상세구분` · `이름` · `규격` · `대표` · 그 밖의 칸은 두지 않음. `종류` 는 「재료」만. +- 조건 칸 = `구분`(반드시 — `지역`·`계약종별` 조건은 예외) · `상세구분` · `이름` · `규격` · `대표` · `지역`("입력" 만) · `계약종별`("입력" 만) · 그 밖의 칸은 두지 않음. `종류` 는 「재료」만. +- `지역`·`계약종별` 조건(PLAN 7-4b 뒤 절반) = 구분·상세구분 없이 `이름` 하나로 자재품목(지역)·유가전력(계약종별)을 넓게 찾음 — 옛 품셈재료 `연결` 묶음과 같은 모양·같은 매칭(`master_material._region`·`_tariff`) · 로직 입력 `자재지역`·`전력 계약종별` 이 계산 때 좁힘 · 값은 `null`(지역·전력 마스터에 안 굳힘). - 구분·상세구분 = 자재품목 줄의 같은 이름 칸과 똑같이 적음(묶음 목록은 `ref/_묶음_자재품목.md`). - 규격 조건 = 원문이 규격을 밝힌 것만 좁힘 — 낱말이 **모두** 든 줄이 후보(「D300」 · 「D300 B종」) · 대소문자·빈칸·`φ` 는 안 가림. 원문이 규격을 안 밝히면 칸을 두지 않음. - 이름 조건 = 구분·상세구분·규격이 같아도 품명이 갈리는 자재품목을 가를 때만 둠(예: 파형강관 커플링밴드 vs 접속티 — 둘 다 관경만 규격에 있어 규격 조건으로는 안 갈림). 규격과 같은 방식(낱말이 **모두** 이름에 든 줄) — 대소문자·빈칸은 안 가림. @@ -229,7 +228,7 @@ - 조건 값에 `{입력}` 을 넣을 수 있음 — `"규격": "{관경}"` 은 계산 때 입력값으로 채워짐(검사에서는 그 칸을 뺌). - 대표가 없으면 시험 계산은 **조건 안 값 있는 첫 줄** · 로직 입력 `자재지역` 이 있으면 이름에 그 지역이 든 줄부터(레미콘·골재처럼 지역이 갈리는 품목). - 실제 줄 고르기는 프로젝트 몫 — 후보 목록은 `GET /api/m01/materials`(화면·테스트 컨테이너가 같이 씀). -- 옛 방식(품셈재료 키 `MP…` · 자재품목 키 `MT…`)도 그대로 돎 — 품셈재료 `고르기` 칸이 빈 줄(연결이 이미 있는 줄 · 짝 못 찾은 줄)과 `{이름}` 이 낀 원문번호 줄은 계속 옛 방식. +- 옛 방식(자재품목 키를 호표에 바로 적은 `MT…`)도 그대로 돎 — 그 줄은 그 자재품목 줄 값을 바로 씀. 품셈재료 간접(`MP…`)은 PLAN 7-4b 뒤 절반에서 다 걷음(위 4장) — 남았던 22줄(색소·에폭시·버너·퓨즈 등)도 자재품목 새 줄이나 대표 키로 이음. - 근거가 덜 선 줄은 `비고` 칸에 적음 — 「환산 근거 미확인」. - 입력 칸 = `이름`(반드시) · `설명` · `단위` · `고르기`·`범위`(둘 중 하나까지) · `출처`(원문 절) · `비고` · `시험입력`은 줄 머리에 따로. @@ -249,7 +248,7 @@ - 로직 부르기 — `로직(GC000871, 기계='0201-0070')` · 돈 로직의 결과는 비목 묶음 `.노무비` `.재료비` `.경비` `.계` · 돈 아닌 로직은 수 하나. - 입력 · 중간 · 비목 합은 이름 그대로. - 덧줄에서만 `줄.'호표 줄 이름'` = 그 호표 줄의 금액 — 비목 합에서 한 줄만 빼는 식에 씀(`GF000185` 콘크리트다짐). -- 후보 조건 품셈재료를 쓰는 로직(부르는 로직 포함)은 입력 `자재지역` 을 두고 하위 로직에 `자재지역=자재지역` 으로 넘김 — `지역` 은 유가 고르기. +- 지역 고르기 조건(7장 `지역: "입력"`)을 쓰는 로직(부르는 로직 포함)은 입력 `자재지역` 을 두고 하위 로직에 `자재지역=자재지역` 으로 넘김 — `지역` 은 유가 고르기. - 쓸 수 있는 것 — `+ - * /` · 괄호 · 비교 `< <= > >= == !=` · `그리고` `또는` · `찾기` · `로직` · `만약(조건, 참, 거짓)` · `올림` `버림` `반올림`(자리) · `최소` `최대`. 그 밖은 쓰지 않음. - 로직이 돌고 도는 참조를 만들지 않음. - 사람이 읽는 자리(M01 화면 · 검사 알림)는 키 옆에 이름. diff --git a/resources/master_data/재료_품셈재료.json b/resources/master_data/old/재료_품셈재료.json similarity index 98% rename from resources/master_data/재료_품셈재료.json rename to resources/master_data/old/재료_품셈재료.json index eb746f25..59922301 100644 --- a/resources/master_data/재료_품셈재료.json +++ b/resources/master_data/old/재료_품셈재료.json @@ -48,7 +48,7 @@ { "키": "MP000037", "원문번호": "커플링밴드 ∅1200㎜", "이름": "커플링밴드(파형강관)", "규격": "∅1200㎜", "단위": "EA", "요구절": ["산림품셈 12-11-3 주①"], "연결": null, "고르기": {"구분": "관·이음관", "상세구분": "파형강관", "이름": "파형강관 커플링밴드(관급)", "규격": "Φ1200mm", "대표": "MT015313"}, "비고": "일감35 — 규격(관경)만으론 접속티와 안 갈려 이름 조건을 더함" }, { "키": "MP000038", "원문번호": "지수활제", "이름": "지수활제", "규격": "", "단위": "g", "요구절": ["산림품셈 12-11-1"], "연결": "MT030601", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030601)로 이음 · 값 미확보" }, { "키": "MP000039", "원문번호": "모르타르 1:2", "이름": "접합몰탈", "규격": "1:2", "단위": "㎥", "요구절": ["산림품셈 12-11-2-1", "건설품셈 건축 2-1-4", "건설품셈 건축 3-2-2"], "연결": null, "고르기": {"구분": "시멘트·골재", "상세구분": "모르타르", "규격": "1:2"}, "비고": "자재품목에 같은 품명 없음" }, - { "키": "MP000040", "원문번호": "스틸그레이팅", "이름": "집수정 뚜껑", "규격": "스틸그레이팅", "단위": "개", "요구절": ["산림품셈 12-15"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, + { "키": "MP000040", "원문번호": "스틸그레이팅", "이름": "집수정 뚜껑", "규격": "스틸그레이팅", "단위": "개", "요구절": ["산림품셈 12-15"], "연결": "MT030712", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030712)로 이음 · 값 미확보" }, { "키": "MP000041", "원문번호": "원형거푸집 벽체", "이름": "원형거푸집(PE 10회)", "규격": "벽체", "단위": "조", "요구절": ["산림품셈 12-16"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000042", "원문번호": "원형거푸집 스라브 및 기초", "이름": "원형거푸집(PE 10회)", "규격": "스라브 및 기초", "단위": "조", "요구절": ["산림품셈 12-16"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000043", "원문번호": "철물", "이름": "철물(강관비계)", "규격": "", "단위": "개", "요구절": ["산림품셈 12-19"], "연결": null, "고르기": {"구분": "거푸집·가설재", "상세구분": "동바리·비계"}, "비고": "이음·조임·받침 철물 갈림" }, @@ -74,7 +74,7 @@ { "키": "MP000063", "원문번호": "목재", "이름": "목재(규준틀)", "규격": "", "단위": "㎥", "요구절": ["산림품셈 11-2", "산림품셈 11-3", "건설품셈 공통 2-5-4", "건설품셈 공통 2-11-1 재료량"], "연결": null, "고르기": {"구분": "목재", "상세구분": "각재·판재", "대표": "MT000409"}, "비고": "규준틀 목재 줄 없음 — 합성목재뿐" }, { "키": "MP000064", "원문번호": "줄눈 모르타르", "이름": "줄눈메꿈 모르타르", "규격": "", "단위": "㎥", "요구절": ["산림품셈 13-4-4 주④", "산림품셈 13-5-1 주③"], "연결": null, "고르기": {"구분": "시멘트·골재", "상세구분": "모르타르"}, "비고": "자재품목에 같은 품명 없음" }, { "키": "MP000065", "원문번호": "틈메우기돌", "이름": "틈메우기돌", "규격": "", "단위": "㎥", "요구절": ["산림품셈 13-5-1 주④"], "연결": "MT030608", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030608)로 이음 · 값 미확보" }, - { "키": "MP000066", "원문번호": "철망태", "이름": "철망태(사각형 돌망태)", "규격": "", "단위": "㎥", "요구절": ["산림품셈 13-11-4"], "연결": null, "고르기": {"구분": "매트·토목섬유", "상세구분": "돌망태·사방"}, "비고": "개비온 값은 「조」 — ㎥ 환산 안 함" }, + { "키": "MP000066", "원문번호": "철망태", "이름": "철망태(사각형 돌망태)", "규격": "", "단위": "㎥", "요구절": ["산림품셈 13-11-4"], "연결": "MT004110", "고르기": null, "비고": "PLAN 7-4b: 개비온 값은 「조」 — ㎥ 환산 안 함 · 후보 5줄(사석류) 가운데 돌망태에 넣는 망태석 300mm(MT004110)로 이음(정확한 짝 아님)" }, { "키": "MP000067", "원문번호": "돌망태 채움재", "이름": "채움재(돌망태)", "규격": "", "단위": "㎥", "요구절": ["산림품셈 13-11-4"], "연결": null, "고르기": {"구분": "매트·토목섬유", "상세구분": "돌망태·사방"}, "비고": "돌망태 채움돌 값 줄 없음" }, { "키": "MP000068", "원문번호": "농약(Fluroxypyr-meptyl+Triclypyr-TEA 미탁제)", "이름": "농약", "규격": "Fluroxypyr-meptyl+Triclypyr-TEA 미탁제", "단위": "병", "요구절": ["산림품셈 2-1-5-1", "산림품셈 6-4-2"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000069", "원문번호": "우드칩", "이름": "우드칩(목재칩)", "규격": "", "단위": "㎥", "요구절": ["산림품셈 6-8"], "연결": null, "고르기": null, "비고": "우드칩 값은 「포」 — ㎥ 환산 안 함 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, @@ -102,7 +102,7 @@ { "키": "MP000091", "원문번호": "합성수지 원형맨홀거푸집 ø1200", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1200", "단위": "조", "요구절": ["건설품셈 공통 6-3-5 주④"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000092", "원문번호": "합성수지 원형맨홀거푸집 ø1500", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1500", "단위": "조", "요구절": ["건설품셈 공통 6-3-5 주④"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000093", "원문번호": "합성수지 원형맨홀거푸집 ø1800", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1800", "단위": "조", "요구절": ["건설품셈 공통 6-3-5 주④"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000094", "원문번호": "쉬즈관", "이름": "쉬즈관", "규격": "", "단위": "m", "요구절": ["건설품셈 공통 6-4-1 주④", "건설품셈 공통 6-4-2 주④"], "연결": null, "고르기": null, "비고": "자재품목에 같은 품명 없음 · 고르기 없음(자재품목 묶음에 짝이 없음 — 관리자가 화면에서 이음)" }, + { "키": "MP000094", "원문번호": "쉬즈관", "이름": "쉬즈관", "규격": "", "단위": "m", "요구절": ["건설품셈 공통 6-4-1 주④", "건설품셈 공통 6-4-2 주④"], "연결": "MT030713", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030713)로 이음 · 값 미확보" }, { "키": "MP000095", "원문번호": "조립식 가설건축물 BASECHANNEL", "이름": "BASECHANNEL", "규격": "두께 2.0㎜ 이상", "단위": "m", "요구절": ["건설품셈 공통 2-2-3 주자재"], "연결": "MT030612", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030612)로 이음 · 값 미확보" }, { "키": "MP000096", "원문번호": "조립식 가설건축물 TOPCHANNEL", "이름": "TOPCHANNEL", "규격": "두께 2.0㎜ 이상", "단위": "m", "요구절": ["건설품셈 공통 2-2-3 주자재"], "연결": "MT030613", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030613)로 이음 · 값 미확보" }, { "키": "MP000097", "원문번호": "조립식 가설건축물 외부PANEL(벽)", "이름": "외부PANEL(벽)", "규격": "1,200×2,400㎜", "단위": "매", "요구절": ["건설품셈 공통 2-2-3 주자재"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, @@ -210,20 +210,20 @@ { "키": "MP000199", "원문번호": "블라인드리벳", "이름": "블라인드리벳", "규격": "", "단위": "개", "요구절": ["건설품셈 기계설비 2-2-6"], "연결": null, "고르기": {"구분": "볼트·앵커·철물", "상세구분": "볼트·너트"} }, { "키": "MP000200", "원문번호": "철물 D22 철근", "이름": "철물", "규격": "D22 철근", "단위": "㎏", "요구절": ["건설품셈 기계설비 2-2-6"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000201", "원문번호": "실리콘(㎏)", "이름": "실리콘", "규격": "", "단위": "㎏", "요구절": ["건설품셈 기계설비 2-2-6"], "연결": "MT030626", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030626)로 이음 · 값 미확보" }, - { "키": "MP000202", "원문번호": "IV전선 2.0㎜", "이름": "IV전선", "규격": "2.0㎜", "단위": "m", "요구절": ["건설품셈 토목 6-7-5 강관압입추진공 조명시설"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000203", "원문번호": "백열등 100W", "이름": "백열등", "규격": "100W", "단위": "EA", "요구절": ["건설품셈 토목 6-7-5 강관압입추진공 조명시설"], "연결": null, "고르기": {"구분": "전기·통신", "상세구분": "부속·기타", "규격": "100W"}, "비고": "자재품목 후보 1줄 — 지역·규격 선택 필요 (MT008751)" }, + { "키": "MP000202", "원문번호": "IV전선 2.0㎜", "이름": "IV전선", "규격": "2.0㎜", "단위": "m", "요구절": ["건설품셈 토목 6-7-5 강관압입추진공 조명시설"], "연결": "MT030714", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목은 ㎟ 단면(지름 아님)이라 짝 없어 새 줄(MT030714)로 이음 · 값 미확보" }, + { "키": "MP000203", "원문번호": "백열등 100W", "이름": "백열등", "규격": "100W", "단위": "EA", "요구절": ["건설품셈 토목 6-7-5 강관압입추진공 조명시설"], "연결": "MT008751", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 후보 1줄뿐이라 그대로 이음(MT008751)" }, { "키": "MP000204", "원문번호": "일체식 방수시트", "이름": "일체식 방수시트", "규격": "부직포 부착 터널 방수시트", "단위": "㎡", "요구절": ["건설품셈 토목 3-4-1 터널 방수 재료량"], "연결": null, "고르기": {"구분": "도료·방수·접착", "상세구분": "방수·실링"} }, - { "키": "MP000205", "원문번호": "바퀴숫돌 단면용", "이름": "바퀴숫돌", "규격": "단면용 A36m B11호 A150×8×22 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000206", "원문번호": "바퀴숫돌 측면용", "이름": "바퀴숫돌", "규격": "측면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000207", "원문번호": "바퀴숫돌 평면용", "이름": "바퀴숫돌", "규격": "평면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000208", "원문번호": "바퀴숫돌 최종용", "이름": "바퀴숫돌", "규격": "최종용 A24 QWV 5호 A205×22×22", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, + { "키": "MP000205", "원문번호": "바퀴숫돌 단면용", "이름": "바퀴숫돌", "규격": "단면용 A36m B11호 A150×8×22 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030715", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030715)로 이음 · 값 미확보" }, + { "키": "MP000206", "원문번호": "바퀴숫돌 측면용", "이름": "바퀴숫돌", "규격": "측면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030716", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030716)로 이음 · 값 미확보" }, + { "키": "MP000207", "원문번호": "바퀴숫돌 평면용", "이름": "바퀴숫돌", "규격": "평면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030717", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030717)로 이음 · 값 미확보" }, + { "키": "MP000208", "원문번호": "바퀴숫돌 최종용", "이름": "바퀴숫돌", "규격": "최종용 A24 QWV 5호 A205×22×22", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030718", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목 새 줄(MT030718)로 이음 · 값 미확보" }, { "키": "MP000209", "원문번호": "압접가열용 버너", "이름": "버너", "규격": "압접가열용", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030710", "고르기": null, "비고": "PLAN 7-4b: 후보 1줄(개장로용 가스버너, 915만원)은 산업용 화덕이라 다른 물건 — 새 줄(MT030710)로 이음 · 값 미확보" }, { "키": "MP000210", "원문번호": "압접버너용 노즐", "이름": "노즐", "규격": "압접버너용", "단위": "개", "요구절": ["건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)"], "연결": "MT030627", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030627)로 이음 · 값 미확보" }, { "키": "MP000211", "원문번호": "테르밋용재", "이름": "테르밋용재", "규격": "점화용", "단위": "포", "요구절": ["건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)"], "연결": "MT030628", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030628)로 이음 · 값 미확보" }, { "키": "MP000212", "원문번호": "테르밋 몰드", "이름": "몰드", "규격": "테르밋 용접용", "단위": "개", "요구절": ["건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)"], "연결": "MT030629", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030629)로 이음 · 값 미확보" }, { "키": "MP000213", "원문번호": "테르밋 골무", "이름": "골무", "규격": "테르밋 용접용", "단위": "개", "요구절": ["건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)"], "연결": "MT030630", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030630)로 이음 · 값 미확보" }, { "키": "MP000214", "원문번호": "테르밋 퓨즈", "이름": "퓨즈", "규격": "테르밋 용접용", "단위": "개", "요구절": ["건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)"], "연결": "MT030711", "고르기": null, "비고": "PLAN 7-4b: 후보 다섯(전선퓨즈·통형퓨즈·고리퓨즈)이 모두 전기용이라 다른 물건 — 새 줄(MT030711)로 이음 · 값 미확보" }, - { "키": "MP000215", "원문번호": "강교 용접봉", "이름": "용접봉", "규격": "강교 제작용", "단위": "㎏", "요구절": ["건설품셈 토목 5-1-3 기타재료 소요량"], "연결": null, "고르기": {"구분": "잡재료", "상세구분": "용접·가스"}, "비고": "자재품목 후보 12줄 — 지역·규격 선택 필요 (MT003186, MT003187, MT003188 외)" }, + { "키": "MP000215", "원문번호": "강교 용접봉", "이름": "용접봉", "규격": "강교 제작용", "단위": "㎏", "요구절": ["건설품셈 토목 5-1-3 기타재료 소요량"], "연결": "MT003191", "고르기": null, "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 후보 12줄(용접봉 전기·산소·스테인레스 등) 가운데 일반용 전기 용접봉 KS E4311(MT003191)로 이음" }, { "키": "MP000216", "원문번호": "철구(Shot ball)", "이름": "철구(Shot ball)", "규격": "", "단위": "㎏", "요구절": ["건설품셈 토목 5-2-1 소재 표면처리", "건설품셈 기계설비 9-2-1"], "연결": "MT030631", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030631)로 이음 · 값 미확보" }, { "키": "MP000217", "원문번호": "무기질아연말샵프라이머", "이름": "무기질아연말 샵프라이머", "규격": "도막두께 20μm", "단위": "ℓ", "요구절": ["건설품셈 토목 5-2-1 소재 표면처리"], "연결": null, "고르기": null, "비고": "고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, { "키": "MP000218", "원문번호": "철편(Grit)", "이름": "철편(Grit)", "규격": "", "단위": "㎏", "요구절": ["건설품셈 토목 5-2-2 제품 표면처리"], "연결": "MT030632", "고르기": null, "비고": "PLAN 7-4b: 자재품목 새 줄(MT030632)로 이음 · 값 미확보" }, diff --git a/resources/master_data/ref/_묶음_자재품목.md b/resources/master_data/ref/_묶음_자재품목.md index a5702e1a..8ee2b2a4 100644 --- a/resources/master_data/ref/_묶음_자재품목.md +++ b/resources/master_data/ref/_묶음_자재품목.md @@ -2,7 +2,7 @@ `scripts/build_자재품목_분류.py` 가 만든 표 — 손으로 고치지 않음. -- 구분 24 · 상세구분 100 · 미분류 25 줄 (전체 30704 줄) +- 구분 24 · 상세구분 100 · 미분류 25 줄 (전체 30711 줄) ## 규칙 @@ -14,9 +14,9 @@ ## 구분별 상세구분 (줄 수) -### 관·이음관 (7151) +### 관·이음관 (7152) -PE관 2907 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 461 · 파형강관 417 · 유리섬유·FRP관 398 · 흄관 222 · 동관·스텐관 133 · 단열이중관 77 +PE관 2907 · 이음쇠·부속 1003 · 주철관 828 · 강관 706 · PVC관 461 · 파형강관 417 · 유리섬유·FRP관 398 · 흄관 222 · 동관·스텐관 133 · 단열이중관 77 ### 식생·종자 (6128) @@ -42,9 +42,9 @@ PE관 2907 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 46 볼트·너트 526 · 와이어로프·클램프 208 · 앵커 189 · 못 41 · 철근커플러 38 -### 전기·통신 (901) +### 전기·통신 (902) -케이블·전선 319 · 판넬·차단기 164 · 전선관·트레이 139 · 조명·전등 133 · 제어·계측기기 89 · 부속·기타 57 +케이블·전선 320 · 판넬·차단기 164 · 전선관·트레이 139 · 조명·전등 133 · 제어·계측기기 89 · 부속·기타 57 ### 밸브·수도자재 (761) @@ -62,9 +62,9 @@ PE관 2907 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 46 기계류 267 · 보일러·공조 173 · 놀이·운동·시설물 109 · 측정·시험기기 68 · 소방·가스 10 -### 맨홀·수로·그레이팅 (602) +### 맨홀·수로·그레이팅 (603) -수로관 283 · 그레이팅 169 · 맨홀 150 +수로관 283 · 그레이팅 169 · 맨홀 151 ### 시멘트·골재 (588) @@ -90,9 +90,9 @@ PE관 2907 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 46 각재·판재 168 · 목재덱 161 · 합판 78 · 판재 24 -### 잡재료 (313) +### 잡재료 (317) -소모품 231 · 용접·가스 36 · 고철·기타금속 31 · 화약 13 · 용수 2 +소모품 235 · 용접·가스 36 · 고철·기타금속 31 · 화약 13 · 용수 2 ### 단열·보온 (284) diff --git a/resources/master_data/로직_건설품셈_04장_궤도공사.json b/resources/master_data/로직_건설품셈_04장_궤도공사.json index 1965c9ba..0da4a948 100644 --- a/resources/master_data/로직_건설품셈_04장_궤도공사.json +++ b/resources/master_data/로직_건설품셈_04장_궤도공사.json @@ -858,7 +858,7 @@ "덧줄": [ { "이름": "기타 소모품·재료비", - "식": "((찾기(QC000648, 품명='아세틸렌', 레일규격=레일규격).수량) * MT003163 + (찾기(QC000648, 품명='산소', 레일규격=레일규격, 규격='KSM 1101, 99.5%').수량 * 1000) * MT003165 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='단면용 A36m B11호 A150×8×22 KSL 6501').수량) * MP000205 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='측면용 A24 QWV1호 A205×25×25 KSL 6501').수량) * MP000206 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='평면용 A24 QWV1호 A205×25×25 KSL 6501').수량) * MP000207 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='최종용 A24 QWV 5호 A205×22×22').수량) * MP000208 + (찾기(QC000648, 품명='버너', 레일규격=레일규격, 규격='압접가열용').수량) * MP000209 + (찾기(QC000648, 품명='노즐', 레일규격=레일규격, 규격='압접버너용').수량) * MP000210) * 기타재료 / 100", + "식": "((찾기(QC000648, 품명='아세틸렌', 레일규격=레일규격).수량) * MT003163 + (찾기(QC000648, 품명='산소', 레일규격=레일규격, 규격='KSM 1101, 99.5%').수량 * 1000) * MT003165 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='단면용 A36m B11호 A150×8×22 KSL 6501').수량) * MT030715 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='측면용 A24 QWV1호 A205×25×25 KSL 6501').수량) * MT030716 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='평면용 A24 QWV1호 A205×25×25 KSL 6501').수량) * MT030717 + (찾기(QC000648, 품명='바퀴숫돌', 레일규격=레일규격, 규격='최종용 A24 QWV 5호 A205×22×22').수량) * MT030718 + (찾기(QC000648, 품명='버너', 레일규격=레일규격, 규격='압접가열용').수량) * MT030710 + (찾기(QC000648, 품명='노즐', 레일규격=레일규격, 규격='압접버너용').수량) * MT030627) * 기타재료 / 100", "비목": "재료비", "출처": "건설품셈 토목 4-5-1 참고자료 주①" } @@ -970,7 +970,7 @@ "덧줄": [ { "이름": "기타 소모품·재료비", - "식": "((찾기(QC000650, 품명='테르밋용재', 레일규격=레일규격, 규격='점화용').수량) * MP000211 + (찾기(QC000650, 품명='몰드', 레일규격=레일규격).수량) * MP000212 + (찾기(QC000650, 품명='골무', 레일규격=레일규격).수량) * MP000213 + (찾기(QC000650, 품명='퓨즈', 레일규격=레일규격).수량) * MP000214 + (찾기(QC000650, 품명='산소', 레일규격=레일규격).수량 * 1000) * MT003165 + (찾기(QC000650, 품명='프로판가스', 레일규격=레일규격).수량) * MT003176) * 기타재료 / 100", + "식": "((찾기(QC000650, 품명='테르밋용재', 레일규격=레일규격, 규격='점화용').수량) * MT030628 + (찾기(QC000650, 품명='몰드', 레일규격=레일규격).수량) * MT030629 + (찾기(QC000650, 품명='골무', 레일규격=레일규격).수량) * MT030630 + (찾기(QC000650, 품명='퓨즈', 레일규격=레일규격).수량) * MT030711 + (찾기(QC000650, 품명='산소', 레일규격=레일규격).수량 * 1000) * MT003165 + (찾기(QC000650, 품명='프로판가스', 레일규격=레일규격).수량) * MT003176) * 기타재료 / 100", "비목": "재료비", "출처": "건설품셈 토목 4-5-2 참고자료 주①" } diff --git a/resources/master_data/로직_건설품셈_05장_강구조공사.json b/resources/master_data/로직_건설품셈_05장_강구조공사.json index 1f68193b..c363fa1a 100644 --- a/resources/master_data/로직_건설품셈_05장_강구조공사.json +++ b/resources/master_data/로직_건설품셈_05장_강구조공사.json @@ -137,7 +137,7 @@ "덧줄": [ { "이름": "잡품·기타", - "식": "(찾기(QC000664, 품명='용접봉').수량 * MP000215 + 찾기(QC000664, 품명='산소').수량 * 1000 * MT003165 + 찾기(QC000664, 품명='LPG가스').수량 * MT003176) * 잡품 / 100", + "식": "(찾기(QC000664, 품명='용접봉').수량 * MT003191 + 찾기(QC000664, 품명='산소').수량 * 1000 * MT003165 + 찾기(QC000664, 품명='LPG가스').수량 * MT003176) * 잡품 / 100", "비목": "재료비", "출처": "건설품셈 토목 5-1-3 주②" } diff --git a/resources/master_data/로직_건설품셈_06장_관부설_및_접합공사.json b/resources/master_data/로직_건설품셈_06장_관부설_및_접합공사.json index 7d4f1b3f..12a5d620 100644 --- a/resources/master_data/로직_건설품셈_06장_관부설_및_접합공사.json +++ b/resources/master_data/로직_건설품셈_06장_관부설_및_접합공사.json @@ -2078,7 +2078,7 @@ }, { "이름": "잡재료", - "식": "(찾기(QC000707).IV전선 * MP000202 + 찾기(QC000707).백열등 * MP000203) * 2 / 100", + "식": "(찾기(QC000707).IV전선 * MT030714 + 찾기(QC000707).백열등 * MT008751) * 2 / 100", "비목": "재료비", "출처": "건설품셈 토목 6-7-5 주⑤" } diff --git a/resources/master_data/로직_건설품셈_06장_철근콘크리트공사.json b/resources/master_data/로직_건설품셈_06장_철근콘크리트공사.json index 29c1a31e..0b40493b 100644 --- a/resources/master_data/로직_건설품셈_06장_철근콘크리트공사.json +++ b/resources/master_data/로직_건설품셈_06장_철근콘크리트공사.json @@ -2463,7 +2463,7 @@ }, { "이름": "잡재료 및 소모재료", - "식": "MP000094 * 5 / 100", + "식": "MT030713 * 5 / 100", "비목": "재료비", "출처": "건설품셈 공통 6-4-1 주④" } @@ -3021,7 +3021,7 @@ }, { "이름": "잡재료 및 소모재료", - "식": "MP000094 * 5 / 100", + "식": "MT030713 * 5 / 100", "비목": "재료비", "출처": "건설품셈 공통 6-4-2 주④" } diff --git a/resources/master_data/로직_산림품셈_12장_철근콘크리트.json b/resources/master_data/로직_산림품셈_12장_철근콘크리트.json index f1de287f..b974d03b 100644 --- a/resources/master_data/로직_산림품셈_12장_철근콘크리트.json +++ b/resources/master_data/로직_산림품셈_12장_철근콘크리트.json @@ -3396,7 +3396,7 @@ "덧줄": [ { "이름": "집수정 뚜껑 설치비", - "식": "뚜껑수 * MP000040 * 5 / 100", + "식": "뚜껑수 * MT030712 * 5 / 100", "비목": "노무비", "출처": "산림품셈 12-15" } diff --git a/resources/master_data/로직_산림품셈_13장_구조물.json b/resources/master_data/로직_산림품셈_13장_구조물.json index 8d6eb3d3..72767681 100644 --- a/resources/master_data/로직_산림품셈_13장_구조물.json +++ b/resources/master_data/로직_산림품셈_13장_구조물.json @@ -1710,7 +1710,7 @@ "덧줄": [ { "이름": "잡재료", - "식": "찾기(QF000460, 구분='자재', 명칭='철망태').수량 * MP000066 * 찾기(QF000460, 구분='자재', 명칭='잡재료').수량 / 100", + "식": "찾기(QF000460, 구분='자재', 명칭='철망태').수량 * MT004110 * 찾기(QF000460, 구분='자재', 명칭='잡재료').수량 / 100", "비목": "재료비", "출처": "산림품셈 13-11-4" } diff --git a/resources/master_data/재료_자재품목.json b/resources/master_data/재료_자재품목.json index fa512393..d5c306d0 100644 --- a/resources/master_data/재료_자재품목.json +++ b/resources/master_data/재료_자재품목.json @@ -30724,6 +30724,13 @@ { "키": "MT030708", "구분": "시멘트·골재", "상세구분": "골재", "이름": "자갈(건조상태·전국)", "규격": "", "단위": "kg", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000005 · 산림품셈 12-1-3 주⑤", "비고": "품셈재료에서 옮김 · 값 미확보 · 전국 대표 값 자리(지역 갈림은 아래 줄)", "면수": null }, { "키": "MT030709", "구분": "시멘트·골재", "상세구분": "골재", "이름": "자갈(건조상태·지역별)", "규격": "", "단위": "kg", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000005 · 산림품셈 12-1-3 주⑤", "비고": "품셈재료에서 옮김 · 값 미확보 · 지역마다 값이 다름 — 필요한 지역마다 관리자가 줄을 더 만들어야 함", "면수": null }, { "키": "MT030710", "구분": "기계·설비", "상세구분": "보일러·공조", "이름": "버너", "규격": "압접가열용", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000209 · 건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)", "비고": "PLAN 7-4b: 자재품목 후보 1줄(MT009352 개장로용 가스버너, 915만원)은 산업용 화덕이라 다른 물건 — 못 이어 새 줄 · 값 미확보", "면수": null }, - { "키": "MT030711", "구분": "전기·통신", "상세구분": "판넬·차단기", "이름": "퓨즈", "규격": "테르밋 용접용", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000214 · 건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)", "비고": "PLAN 7-4b: 자재품목 후보 다섯(전선퓨즈·통형퓨즈·고리퓨즈)이 모두 전기용이라 다른 물건 — 못 이어 새 줄 · 값 미확보", "면수": null } + { "키": "MT030711", "구분": "전기·통신", "상세구분": "판넬·차단기", "이름": "퓨즈", "규격": "테르밋 용접용", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000214 · 건설품셈 토목 4-5-2 테르밋 용접 소모재료(참고자료)", "비고": "PLAN 7-4b: 자재품목 후보 다섯(전선퓨즈·통형퓨즈·고리퓨즈)이 모두 전기용이라 다른 물건 — 못 이어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030712", "구분": "맨홀·수로·그레이팅", "상세구분": "맨홀", "이름": "집수정 뚜껑", "규격": "스틸그레이팅", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000040 · 산림품셈 12-15", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030713", "구분": "관·이음관", "상세구분": "강관", "이름": "쉬즈관", "규격": "", "단위": "m", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000094 · 건설품셈 공통 6-4-1 주④; 건설품셈 공통 6-4-2 주④", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030714", "구분": "전기·통신", "상세구분": "케이블·전선", "이름": "IV전선", "규격": "2.0㎜", "단위": "m", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000202 · 건설품셈 토목 6-7-5 강관압입추진공 조명시설", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목은 ㎟ 단면(지름 아님)이라 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030715", "구분": "잡재료", "상세구분": "소모품", "이름": "바퀴숫돌", "규격": "단면용 A36m B11호 A150×8×22 KSL 6501", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000205 · 건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030716", "구분": "잡재료", "상세구분": "소모품", "이름": "바퀴숫돌", "규격": "측면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000206 · 건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030717", "구분": "잡재료", "상세구분": "소모품", "이름": "바퀴숫돌", "규격": "평면용 A24 QWV1호 A205×25×25 KSL 6501", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000207 · 건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null }, + { "키": "MT030718", "구분": "잡재료", "상세구분": "소모품", "이름": "바퀴숫돌", "규격": "최종용 A24 QWV 5호 A205×22×22", "단위": "개", "물가자료": null, "유통물가": null, "물가정보": null, "거래가격": null, "관급": null, "출처": "품셈재료 MP000208 · 건설품셈 토목 4-5-1 가스압접 소모재료(참고자료)", "비고": "PLAN 7-4b: 덧줄 식에 박힌 재료 — 자재품목에 짝 없어 새 줄 · 값 미확보", "면수": null } ] } diff --git a/resources/tester/test_m01_api.py b/resources/tester/test_m01_api.py index 5463b069..1cc17860 100644 --- a/resources/tester/test_m01_api.py +++ b/resources/tester/test_m01_api.py @@ -369,12 +369,6 @@ def test_구분_목록(client: TestClient) -> None: assert steel["details"] -def test_못_이은_줄만_거름(client: TestClient) -> None: - every = _get(client, "/api/m01/rows", file="재료_품셈재료.json", size=500) - cut = _get(client, "/api/m01/rows", file="재료_품셈재료.json", size=500, unlinked=1) - assert 0 < cut["total"] < every["total"] and not any(r["연결"] for r in cut["rows"]) - - def test_재료_고르기_줄_단가는_대표_자재품목의_낮은_값(client: TestClient) -> None: """옛 「MP:시멘트」 줄이 고르기 조건+대표로 바뀜 — 값은 대표 자재품목 줄의 낮은 값.""" one = _get(client, "/api/m01/logic", key=key_of("GC000628")) @@ -406,9 +400,8 @@ def test_하위_거름과_참조_이름(client: TestClient) -> None: assert {r["상세구분"] for r in field["rows"]} == {"기능계 도화"} machine = _get(client, "/api/m01/rows", file="기계.json", size=500, sub="산림품셈") assert 0 < machine["total"] < 100 and {r["원문"] for r in machine["rows"]} == {"산림품셈"} - linked = _get(client, "/api/m01/rows", file="재료_품셈재료.json", size=500) - keyed = [r for r in linked["rows"] if isinstance(r["연결"], str)] - assert keyed and all(linked["refs"][r["연결"]] for r in keyed) + # 참조 이름(refs) 확인은 예전에 재료_품셈재료.json 「연결」로 했음 — PLAN 7-4b 뒤 절반이 + # 그 파일을 old/ 로 옮겨(살아 있는 마스터 밖) 이 자리에서는 더 못 봄 def test_자재품목_저장은_띄어쓰기를_안_바꿈(client: TestClient) -> None: diff --git a/resources/tester/test_masterdata_check.py b/resources/tester/test_masterdata_check.py index 654c9f4b..7574707b 100644 --- a/resources/tester/test_masterdata_check.py +++ b/resources/tester/test_masterdata_check.py @@ -1,5 +1,6 @@ """마스터 데이터 검사 도구 — 견본 셋 손 계산 · 견본 파일 검사 통과 (`resources/master_data/scripts/check_master.py`).""" +import json import sys from decimal import ROUND_HALF_UP, Decimal from pathlib import Path @@ -432,8 +433,6 @@ def test_토목_보링_심도_가산(): files["재료_자재품목.json"]["줄"].append( {"키": "MT999999", "원문번호": "가짜", "물가자료": Decimal(1000)} ) - for row in files["재료_품셈재료.json"]["줄"]: - row["연결"] = row["연결"] or "MT999999" # 못 이은 재료 — 시험용 가짜 연결 given = {"층": "점토층", "규격": "BX", "깊이": 35, "심도가산율": 5} got = mf.run(mf.Master(files), "GC000431", given) qty = {x["이름"]: x["수량"] for x in got["줄"]} @@ -695,20 +694,49 @@ def test_노임_갈래_파일_원문_대조(): def test_품셈재료_연결_낮은_값과_출처(whole): - """연결 하나 — 값 열 다섯 가운데 낮은 값 · 출처 = 「<키>.<열>」.""" + """연결 하나 — 값 열 다섯 가운데 낮은 값 · 출처 = 「<키>.<열>」. + 재료_품셈재료.json 은 PLAN 7-4b 뒤 절반이 old/ 로 옮겨 살아 있는 마스터엔 없음 — + element() 의 옛길(품셈재료 간접)이 여전히 도는지 자체 마스터로 확인.""" row = whole.get("MT004176") # 시멘트 low = min(row[s] for s in mm.SLOTS if row.get(s) is not None) - value, source = mf.element(whole, "MP:시멘트", {}) + files = cm.load(["재료_자재품목.json"]) | { + "재료_품셈재료.json": { + "그룹": "재료", + "원문": "품셈재료", + "줄": [{"키": "MP900001", "이름": "시멘트", "단위": "kg", "연결": "MT004176"}], + } + } + value, source = mf.element(mf.Master(files), "MP900001", {}) assert value == low and source.split(".")[0] == row["키"] def test_전력은_계약종별로_고름(whole): - """전력은 자재품목이 아니라 유가전력 줄 — 계약종별은 로직 입력 · 그 안에서 낮은 값.""" + """전력은 자재품목이 아니라 유가전력 줄 — 계약종별은 로직 입력 · 그 안에서 낮은 값. + 옛길(품셈재료 연결이 계약종별 조건 묶음)로도 여전히 도는지 자체 마스터로 확인.""" assert whole.index["MT"].get("MT000006") is None # 자재품목 전력 2줄 뺌 + files = cm.load(["재료_유가전력.json"]) | { + "재료_품셈재료.json": { + "그룹": "재료", + "원문": "품셈재료", + "줄": [ + { + "키": "MP900002", + "이름": "전력", + "단위": "㎾h", + "연결": {"이름": "전력량요금", "계약종별": "입력"}, + } + ], + } + } + linked = mf.Master(files) with pytest.raises(mf.FormulaError): # 계약종별 없이는 값이 안 섬 - mf.element(whole, "MP:전력", {}) - value, source = mf.element(whole, "MP:전력", {mf.TARIFF: "주택용 저압"}) + mf.element(linked, "MP900002", {}) + value, source = mf.element(linked, "MP900002", {mf.TARIFF: "주택용 저압"}) assert value == 120 and source == "MO000058.값" + # PLAN 7-4b 뒤 절반 — 호표에 조건 묶음을 바로 박아도 같은 길(품셈재료 간접 없이) + cond = {"이름": "전력량요금", "계약종별": "입력"} + value2, source2 = mf.element(whole, cond, {mf.TARIFF: "주택용 저압"}) + assert value2 == value and source2 == source def test_자재품목_열_한_벌(): @@ -735,15 +763,31 @@ def test_자재품목_열_한_벌(): def test_품셈재료_자재지역_후보(whole): - """지역 재료 — 입력 없음 · 그 지역 줄 없음 · 규격 여럿은 멈춤 · 하나면 낮은 값.""" + """지역 재료 — 입력 없음 · 그 지역 줄 없음 · 규격 여럿은 멈춤 · 하나면 낮은 값. + 옛길(품셈재료 연결이 지역 조건 묶음)로도 여전히 도는지 자체 마스터로 확인.""" + files = cm.load(["재료_자재품목.json"]) | { + "재료_품셈재료.json": { + "그룹": "재료", + "원문": "품셈재료", + "줄": [ + {"키": "MP900003", "이름": "모래", "단위": "㎥", "연결": {"이름": "모래", "규격": "", "지역": "입력"}}, + {"키": "MP900004", "이름": "레미콘", "단위": "㎥", "연결": {"이름": "레미콘", "규격": "", "지역": "입력"}}, + ], + } + } + linked = mf.Master(files) with pytest.raises(mf.FormulaError, match="입력 「자재지역」 없음"): - mf.element(whole, "MP:모래", {}) + mf.element(linked, "MP900003", {}) with pytest.raises(mf.FormulaError, match="지역 값 없음"): - mf.element(whole, "MP:모래", {"자재지역": "울진"}) + mf.element(linked, "MP900003", {"자재지역": "울진"}) with pytest.raises(mf.FormulaError, match="후보 여럿"): - mf.element(whole, "MP:레미콘", {"자재지역": "울진"}) - value, source = mf.element(whole, "MP:모래", {"자재지역": "수원"}) + mf.element(linked, "MP900004", {"자재지역": "울진"}) + value, source = mf.element(linked, "MP900003", {"자재지역": "수원"}) assert source.startswith("MT") and value > 0 + # PLAN 7-4b 뒤 절반 — 호표에 조건 묶음을 바로 박아도 같은 길(품셈재료 간접 없이) + cond = {"이름": "모래", "규격": "", "지역": "입력"} + value2, source2 = mf.element(whole, cond, {"자재지역": "수원"}, "㎥") + assert value2 == value and source2 == source # ── 재료 고르기 조건 (`_틀.md` 7장) ──────────────────────────────────── @@ -955,13 +999,21 @@ def test_고르기_조건_글자_열쇠(): assert mm.cond_text({"구분": "레미콘", "대표": "MT900002"}) == "레미콘||||MT900002||" -def test_품셈재료_고르기_칸이_실파일에_있음(): - """일괄 변환의 바탕 — 모든 품셈재료 줄에 고르기 칸 · 조건은 자재품목 묶음 안.""" - whole = cm.master() +def test_품셈재료_고르기_칸이_옛_파일에_있음(): + """일괄 변환의 바탕(옛 자료) — PLAN 7-4b 뒤 절반이 재료_품셈재료.json 을 old/ 로 옮겨 + 이제 살아 있는 마스터엔 안 읽힘 — 옮기기 전 앞뒤 확인이 남긴 옛 자료 자체를 대고 봄.""" + market = cm.load(["재료_자재품목.json"]) + old_pm = json.loads( + (cm.MASTER / "old" / "재료_품셈재료.json").read_text(encoding="utf-8"), + parse_float=Decimal, + parse_int=Decimal, + ) + whole = mf.Master({**market, "재료_품셈재료.json": old_pm}) rows = whole.index["MP"] assert rows and all("고르기" in row for row in rows.values()) assert any(isinstance(row["고르기"], dict) for row in rows.values()) assert cm.check_links(whole) == [] + assert cm.master().index.get("MP") is None # 살아 있는 마스터엔 이제 없음 def test_로직_일괄_시험계산(): diff --git a/resources/tester/test_자재품목_분류.py b/resources/tester/test_자재품목_분류.py index 3195c7c5..ec1bd467 100644 --- a/resources/tester/test_자재품목_분류.py +++ b/resources/tester/test_자재품목_분류.py @@ -14,7 +14,9 @@ sys.path.insert(0, str(MD / "scripts")) import build_자재품목_분류 as B # noqa: E402 ROWS = json.loads((MD / "재료_자재품목.json").read_text(encoding="utf-8"))["줄"] -PM = json.loads((MD / "재료_품셈재료.json").read_text(encoding="utf-8"))["줄"] +# PLAN 7-4b 뒤 절반 — 재료_품셈재료.json 은 old/ 로 옮김(살아 있는 마스터엔 안 읽힘) · 이 시험은 +# 옮기기 전 일괄 변환이 옳았는지 옛 자료를 대고 보는 것이라 old/ 에서 그대로 읽음 +PM = json.loads((MD / "old" / "재료_품셈재료.json").read_text(encoding="utf-8"))["줄"] # 품셈재료 이름(뿌리) → 자재품목에서 들어가야 할 구분 기대 = { @@ -73,6 +75,16 @@ PM = json.loads((MD / "재료_품셈재료.json").read_text(encoding="utf-8"))[" # PLAN 7-4b 뒤 절반 ④ — 버너·퓨즈는 후보가 물건 자체가 달라 못 이어 새 줄을 만듦 "버너": "기계·설비", "퓨즈": "전기·통신", + # PLAN 7-4b 뒤 절반 — 덧줄 식에 바로 박혀 있던 나머지 아홉 종(그동안 「요소」 칸만 + # 훑어 안 걸렸던 자리) · 새 줄 넷은 이름이 그대로 같아 여기 더함 + "집수정 뚜껑": "맨홀·수로·그레이팅", + "쉬즈관": "관·이음관", + "IV전선": "전기·통신", + "바퀴숫돌": "잡재료", + # 철망태(사각형 돌망태)·백열등은 이름이 다른 자재품목 줄(망태석·백열등100W)로 이어 + # 뿌리-이름 검사에서 스페이셔와 같은 이유로 뺌(아래 제외_뿌리충돌) + "철망태(사각형 돌망태)": "매트·토목섬유", + "백열등": "전기·통신", # PLAN 7-4b 뒤 절반 ① — 자재품목에 짝 없던 재료 106종을 새 줄로 만들어 이음(값 미확보) "3-Bond": "잡재료", "BASECHANNEL": "건축마감", @@ -212,7 +224,14 @@ def test_품셈재료_이름과_같은_품명_줄이_한_묶음(): # 실제로는 안 섞임(test_품셈재료_연결_줄이_제_묶음 이 그 연결을 확인) · 이 뿌리-우선 검사만 뺌. # 색소·에폭시·땜납은 PLAN 7-4b ② — 품셈 이름과 자재품목 이름이 달라(착색제·주입용 에폭시· # 봉땜납) 대표로 콕 집어 이음 · 뿌리 이름으로는 자재품목에 아예 없어 이 검사 대상 밖. - 제외_뿌리충돌 = {"스페이셔(몰탈 블록)", "색소", "에폭시", "땜납"} + 제외_뿌리충돌 = { + "스페이셔(몰탈 블록)", + "색소", + "에폭시", + "땜납", + "철망태(사각형 돌망태)", + "백열등", + } idx = collections.defaultdict(list) for x in ROWS: idx[_root(x["이름"])].append(x)