diff --git a/docs/raw/요구_1104/_분석_867_기계상세_여럿_안내판.md b/docs/raw/요구_1104/_분석_867_기계상세_여럿_안내판.md new file mode 100644 index 000000000..fca0970d0 --- /dev/null +++ b/docs/raw/요구_1104/_분석_867_기계상세_여럿_안내판.md @@ -0,0 +1,208 @@ +# 분석 867 — 기계 한 대 조종원 · 잡품 여럿 / 거창 안내판 −50,000 + +범위 = 읽기 전용(제품 코드 · 마스터 고치지 않음). 측정 스크립트 · 결과 = `tmp/brain_867/` (`hourly_all.py` · `hourly_base.json` · `t_gyechang.py` · `t_others.py` · `gyechang_apply.json` · `samples_fixed.json` · `fixed_line.py`). +표기 — 「사실」 = 코드 · 자료 · 실행으로 확인 · 「짐작」 = 읽고 추론(미실행). + +--- + +## 부분 A — 기계 한 대에 조종원 여럿 · 잡품 재료 여럿 + +### A1. 지금 기계 한 대 자료 꼴 (사실) + +파일 `resources/master_data/기계/EQ*.json` 655 대(+`_머리.json`) · 한 대 한 파일. + +| 층 | 칸 | +|---|---| +| 맨 위 | 키 · 원문번호 · 원문 · 구분 · 상세구분 · 이름 · 규격 · **단위{칸}** · **값{칸}** · **출처{칸}** · 비고(478) · 값원문(34) · 별칭(26) · 옛이름(10) | +| 값 칸(대수) | 손료계수 649 · 가격 620 · (내용시간 · 연간표준가동시간 · 상각비율 · 정비비율 · 연간관리비율 · 상각비계수 · 정비비계수 · 관리비계수 · 주연료 · 주연료종류 · **잡재료율** · **조종원** · **조종원직종** 각 619) · 선원 63 · 준설선기관사 30 · 준설선선장 23 · 고급선원 16 · 장비가격 20 · 전력 10 · 취득가액 3 · 주연료2 · 주연료2종류 각 2 · 시간당손료계수 1 | +| 단위 | 조종원 「인/일」 · 잡재료율 「주연료의 %」 · 선원류 「인」 · 조종원직종 「」(인력 원문번호 글) | + +내 기계 `내기계/<키>.json`(`M02_MyMachine.py` 3 · 36 줄) = 같은 줄 꼴 + `방식`(바로 · 품셈 · 직접) + `시간당{노무비 · 재료비 · 경비}`(직접). 저장 때 `clean`(`M02_MyMachine.py` 258~)이 **값 칸을 `NUMS`(가격 · 비율 · 계수 · 손료계수 · 주연료 · 잡재료율 · 조종원 · 전력) + `_kinds`(주연료종류 · 조종원직종)로만 거름** → 모르는 칸은 조용히 버림. + +**틀 검사**(`check_master.check_form` · M01 저장 관문 `Store_Save.py` 69 · `Store_Cache.py` 272) — 요소 줄은 `키 · 원문번호 · 이름 · 값 · 출처` 필수 + 「단위」 · 「출처」 묶음 칸이 「값」 묶음 칸과 같은 것만 요구. **값 칸 이름 · 값 꼴(수 · 글 · 목록)은 제한 없음.** 실험(655 대 틀 검사 · 한 대에 값 칸 「조종원줄」 = 목록 둘 + 단위 · 출처 추가 · 맨 위 칸 추가) → 오류 0 · `mf.Master` 로드 정상 (사실). + +**조종원이 사실상 여럿인 기계** (사실 · 655 대 조사) + +| 구분 | 대수 | 예 | +|---|---|---| +| 조종원 값 있음 | 301 (1 인 282 · 2 인 18 · 7 인 1) | 2 인 = 아스팔트 믹싱플랜트 EQ187~191(직종 1048) · 펌프 준설선 EQ541~553(1054) · 7 인 = 현장가열 표층재생기 EQ202(직종 칸 없음 · 주연료 「73.7+」 로 시간당 못 셈) | +| 조종원 값 있고 직종 칸 비움 | 42 (EQ40 · 153~156 · … ) | 직종은 식의 입력 「직종」(GC000275)으로 고름 — 기계 줄에 없음 | +| 조종원직종 값 | 1048(건설기계운전사) 184 · 1054(준설선운전사) 30 · 1049 24 · 1050 21 | | +| **선원류 칸 있는 기계** | **79** | 펌프 준설선 13 · 그래브 준설선 10 · 예선 9 · 양묘선 11 · 기중기선 5 · 토운선 6 · 이우선 2 · 대선 16 · 하천골재채취선 7 | +| 직종 종류 ≥ 2(조종원 + 선원류) | 35 | 펌프 준설선 EQ541 = 조종원 2(1054) + 준설선선장 1 + 준설선기관사 2 + 선원 3 | + +**원문 표기**(`resources/knowledge/original/원가계산/건설공사_표준품셈/본문/01_공통부문/제08장_건설기계/8-04_운전경비_산정.md`) — 8-4-1~8-4-8 = 표 한 칸 「조종원 (인/일)」 한 열 · 8-4-9 해상기계 = **직종마다 한 줄**(준설선선장 · 준설선기관사 · 준설선운전사 · 선원 · 고급선원 · 단위 「인」). 코드 쪽은 준설선운전사만 `조종원`+`조종원직종 1054` 로 옮겼고 나머지 직종은 이름 그대로 값 칸(`선원` …)에 보관 · 단위 · 출처 「건설품셈 공통 8-4-9」. + +**선원류 칸을 읽는 식 = 0** (사실 · `수식문서/…08장_건설기계.json` · `로직_…08장_건설기계.json` · M0x 파이썬 · TS 전수 검색 → 읽는 곳 없음). 그래서 해상기계 시간당 노무비가 선원류를 안 담음: + +| 기계 | 지금 시간당 노무비 / 계 | 선원류 몫(짐작 · 인력 1052 · 1053 · 1055 노임 × 조종원 환산 5/24 가정) | +|---|---|---| +| EQ541 펌프 준설선 224㎾ | 87,267 / 267,746 | +약 270,900 | +| EQ554 그래브 준설선 0.65㎥ | 43,633 / 105,244 | +약 137,800 | +| EQ564 예선 10ton | 0 / 80,335 | +약 130,300 | +| EQ589 토운선 60㎥ | 0 / 8,473 | +약 43,400 | +| EQ597 대선 50ton(고급선원 1) | 0 / 4,172 | 노임 짝 없음(아래) | + +인력 대응(사실 · `인력.json`): 준설선선장 1052 · 준설선기관사 1053 · 준설선운전사 1054 · 선원 1055. **고급선원 = 같은 이름 직종 없음**(`2. 임금적용요령.md` 56 행 「통합후소멸되는직종: … 보통선원, 고급선원」). +655 대 시간당 기준선(사실 · `hourly_base.json`) — 611 대 셈됨 · 44 대 까닭(일 단위 손료 28 · 가격/계수 없음 12 · 잡재료율 「13∼18」 범위 2 · 주연료 「중유」 유가 없음 1 · 「73.7+」 1). 식 쓰임: GC000273 256 · GC000269 129 · GC000268 97 · GC000272 50 · GC000275 39 · GC000276 19 · GC000267 9 · 전력 계열 10 · 기타 2. + +### A2. 지금 덮음 층(`기계덮음`) 꼴 (사실) + +자리 = 단가산출 문서 칸 `기계덮음` `{기계 입력 글: {값?: {칸: 값}, 조종원?: [{키, 인, 이름?}], 잡품?: [{줄? | 키?, 이름?, 수량?, 율}]}}` (`master_doc_cover.py` 4 · `common_util_formula_doc_cover.ts` 60~79). + +| 항목 | 덮음 층 꼴 | 기계 정본 줄 칸 | 같은가 | +|---|---|---|---| +| 값 칸 | `값{칸: 값}` (식이 읽는 칸 · `NOT_VALUE` = 조종원 · 조종원직종 · 잡재료율 제외) | 값 묶음 그대로 | 같은 칸 이름 | +| 조종원 | 줄 목록 `{키 'LB:1054' | 노임 키, 인, 이름?}` | 칸 둘 `조종원`(수) · `조종원직종`(코드 한 개) | **다름** — 줄 목록(직종마다 인원) 대 단일 칸 둘 | +| 잡품 | 줄 목록 `{줄(밑 재료 줄 이름) | 키(재료 열쇠), 이름, 수량, 율%}` | 칸 하나 `잡재료율`(주연료의 %) | **다름** — 재료 여럿 · 수량 · 율 대 율 하나 | + +기본값 · 지움: `defaults_of(doc, vals)`(137 행) = 원본 식 답에서 `조종원 = [{키 LB:직종 , 인: 조종원 칸 값}]` · `잡품 = [{줄: 밑 재료 줄 이름, 율: 잡재료율}]` 로 지음 · `prune(entry, base)`(184 행) = 원본과 같은 칸 · 줄(`_canon` 정규화 비교 · 이름 · 단위 글 무시)이면 지움. `clean`(304 행) = 줄 30 개까지 · 조종원 줄 `키 · 인` 필수 · 잡품 줄 `율` 필수 + `줄|키` 중 하나. + +**정본 줄에 그대로 쓸 수 있나** — 줄 목록 꼴 자체는 그대로 쓸 수 있음(이미 서버 `clean`이 여러 줄 허용 · 기계 보기 서버 `M02_MyMachine_Sheet.sheet()` 의 `덮음` 몸도 여러 줄을 받음 — 막은 곳 = 화면뿐). 다만 다음이 다름(사실): +1. 덮음 줄의 `줄`(밑 재료 줄 이름 참조)과 `수량` 비움 = 「식 밑줄 수량을 따라감」 은 **식(GC) 구조에 매인 말** — 정본 기계 줄은 식 모양과 무관해야 하므로 정본 목록은 `키`(재료 열쇠) + `수량` + `율` 만 쓰는 꼴이 안전. 기본(원본) 식의 「주연료 × 잡재료율」 은 `줄: 주연료` 로 표현되는데 정본에 목록이 없으면 이 기본으로 돌아감. +2. 덮음은 `기계 입력 글` 키별 · 정본은 기계 한 대 줄 안이라 키 없이 값만. +3. 조종원 줄 `키`는 노임 열쇠(`LB:1054` 꼴 또는 LB 키)이고 정본 `조종원직종` 은 인력 원문번호 글 — 변환 `jobCode`(`common_util_machine_sheet.ts` 141)가 이미 있음. + +### A3. 시간당 식의 읽는 법 · 셈 길 (사실) + +식 = `수식문서/수식_건설품셈_08장_건설기계.json` GC000268 외 10 개 기계경비식(`부품 갈래 = 기계경비식`) — 줄 4 개가 한 벌: ① 주연료(수량 = `EQ.주연료` · 단가 = 유가) ② **조종원**(`수량 = Q_기계조종원 × Q_시간환산` · `단가 = w_일반기계운전 = LB:{S_직종}` · `Q_기계조종원 = EQ.조종원`) ③ **잡재료비**(`단가 = 재료비 × r_기계잡재료 ÷ 100` · `r = EQ.잡재료율`) ④ 기계손료(`C_손료`). 식 정수 크기 = 칸 하나씩. +`M02_Machine_Hourly.pick`(92~) = ㉠ 목록(원문번호 ∈ 식 「기계」 고르기) › ㉡ 그 기계만의 식(`_own` · GF000145 · GF000337) › ㉢ 꼴(`M02_MyMachine.logic_key` 189~ — 연료 · 조종원 · 전력 유무 + 직종 유무로 GC 고름) · `_operated`(63) = 원문번호 기계 가운데 하나라도 조종원 > 0 이면 조종원 줄 든 식을 앞세움. + +**두 엔진**(사실) +- 로직 엔진(`mf.run` + `mcut.engine`) — `M02_Machine_Hourly.hourly` · `brief`(기계 창 목록 · M01 기계 시간당 · B09 · 내 기계 `M02_MyMachine.hourly`) 이 씀. **`기계덮음` 을 모름.** +- 문서 엔진(`master_doc_calc.calc` · TS `calcDoc`) — 단가산출 `수식` 문서가 있는 SK · 기계 보기 `M02_MyMachine_Sheet.sheet()` 이 씀. `_Run.sub`(master_doc_calc.py 301)가 부를 때 `cover_doc(doc, given, self.cover)` 로 덮음을 얹음. 655 대 시간당 같음 시험 = `test_840_2_machine_sheet.py::test_655대_박은_식_셈_같음` (문서 엔진). + +→ 정본 줄에 조종원 · 잡품 여러 줄이 있으면 **두 길 모두 읽어야** 화면(기계 보기 오른쪽 산출근거) · M01 목록 시간당 · 단가산출 사본 · B09 값이 갈라지지 않음. 지금은 문서 엔진만 덮음을 읽음. + +#### 후보 비교 + +| | ㉠ 정본 줄에 `조종원줄[] · 잡품줄[]` + 식 그대로 + 셈 때 덮음 함수로 얹음 | ㉡ 식(GC)이 여러 줄을 읽게 고침 | ㉢ 기계마다 식 문서 | +|---|---|---|---| +| 바꾸는 파일 | `master_doc_cover.py`(`cover_doc` 에 기본 덮음 병합 · `defaults_of`·`prune_doc` 기준 변경) · `master_doc_calc.py`(`sub` 에서 그 기계 줄의 목록을 읽어 덮음과 병합) · `master_doc_link.py`/`master_doc_record.py`(목록 값을 링크 · 연결 기록으로 실음) · TS 짝 `common_util_formula_doc_cover.ts` + TS 링크(`createDocCache`) · `M02_Machine_Hourly.hourly/brief` + `M02_MyMachine.hourly`(문서 엔진 길로 이동 또는 덮음 읽기) · `M02_MyMachine.clean/engine` · `M01_MasterData_Machine.fix`(단위 · 출처 채움) · 화면 3(ctl · sheet · common_util_machine_sheet) · 시험 | 문서 언어에 「줄 목록 반복」 이 없음 → 문서 언어(py · TS · 로직 엔진 3 벌) + 로직 JSON `로직_…08장_건설기계.json` 빌더(`build_로직_건설품셈_08장_건설기계.py`) + 수식문서 빌더 + 11 식 | 식 문서 약 98~655 장 신설(조종원 여럿 19 · 선원류 79 대는 필요) · `pick` ㉠ 목록 · `_own` 확장 · 빌더 | +| 655 대 금액 불변 | 목록 칸이 없는 대는 같은 객체를 돌려줌(`cover_doc` 덮음 없음 = `doc` 그대로) → **불변**(기준선 `hourly_base.json` 로 대조) · 선원류 옮김 대(79)만 의도된 변동 | 식 구조가 바뀌므로 4 줄 식 모두 시험 다시 · 금액은 이론상 불변 | 값은 같으나 문서 655 중복 | +| 단가산출 사본 | SK 사본은 EQ 줄을 통째 복사(`M02_Sangeun_Copy` · `Copy_Slim.cut` 은 `prices.to_json(whole.index["EQ"][k])` 로 줄 통째) → **목록 칸이 줄 안에 있으면 자동 동승** · 줄 지문(`skc._fp`) 이 바뀌어 `M02_Sk_AutoRenew._covers` 가 그 기계 덮음을 지움 + 알림(`_row_diff` 는 값 칸 비교 글 — 목록은 글로만 보임) | 식 사본 갱신 | 식 사본 갱신 | +| 덮음과 겹칠 때 차례 | 정본 목록 = 「기본 덮음」 · 단가산출 `기계덮음` = 위에 얹음. 병합 단위 = **부분별 통째 교체**(현재 `cover_doc` 도 `조종원` · `잡품` 을 부분별 교체) → 값은 칸별 · 조종원 · 잡품은 목록 통째 | — | — | +| 불러오기 내 기계 자동 생성 | `M02_San_MyMachine` 을 목록 꼴로 넓히면 됨(아래) | 같음 | 같음 | +| 위험 | `defaults_of`(원본 식 줄에서 기본을 지음)를 **정본 목록 기준으로** 바꿔야 함 — 안 바꾸면 단가산출 제어 구역이 「기본」 을 정본 목록이 아닌 식 단일 값으로 보여 「고침」 표지가 틀림 | 가장 큼 | 식 수 폭증 · 사용자가 편집하는 곳이 문서 | + +**판단**: 사용자 문장 「기계 상세에서도 조종원을 여럿 둘 수 있음」 = 자료 편집이 기계 상세에서 일어남 → ㉠ 이 맞음(짐작 · 분량도 가장 작음). ㉡ · ㉢ 는 권하지 않음. + +#### 걸린 곳 하나씩 (사실) + +- **양식 저장 API**: M01 = `Store_Make.save` → `M01_MasterData_Machine.fix`(칸 단위 · 출처 「자체」 채움 · 계수 재계산) → `check_form` — 목록 값 칸 통과(실험). 내 기계 = `/api/m02/layers/personal/my-machines` → `M02_MyMachine.clean` **화이트리스트로 목록 칸을 버림 → 고쳐야 함**(NUMS 밖 · `_kinds` 밖). +- **기호 짧은 이름 사전**(`common_util_machine_symbol_name.ts` 32 · 70 · 89 · 90 행): `Q_기계조종원 → 조종원` · `r_기계잡재료 → 잡품` · `조종원 → 조종원` · `잡재료율 → 잡품` 등 — 목록 칸을 표시하는 새 이름(예 `조종원줄` · `잡품줄`)만 더하면 됨 · 식 기호는 안 바뀜(덮음이 새 변수 `w_조종원N` · `P_잡품N` 를 문서에 더하는 방식 — `_add_var`). +- **불러오기 내 기계 자동 생성**(`M02_San_MyMachine.py`): 경쟁사 구성에서 **조종원은 첫 줄만**(`not cur.get("조종원")` 가 EST 원파일 87 행 · EST 엑셀 116 행 · STmate 152 행 모두) · **잡품 % 첫 값만**(`cur.get("잡재료율") is None`) · **연료 첫 줄만**(`_fuel`) · 연료 아닌 소모 재료 줄(단위 ℓ 아님)은 읽지 않음 → 둘째 운전사 · 조수 · 잡품 재료 줄은 **조용히 버림**(알림 없음). 목록 꼴이 생기면 여기서 목록으로 받고 못 이은 직종은 「확인 필요」 비고(`CHECK`). +- **기계 보기 서버 `POST /api/m02/machine-sheet`**(`M02_MyMachine_Look.py` 140): 몸 `{줄, 본, 덮음, 개인}` → `sheet()` 이 `mcv.clean({no: 덮음})` 로 여러 줄 허용(30 줄) — **서버는 이미 여러 줄 가능**(사실). +- **시간당 길**: `M02_Machine_Hourly.hourly`(로직 엔진 `store.calc`) — 정본 목록을 읽게 하려면 (a) `hourly` · `brief` · `M02_MyMachine.hourly` 를 문서 엔진 길로 옮기거나 (b) 로직 엔진에 목록을 읽히는 방법뿐 — **(a) 권함**(문서 엔진은 이미 덮음 · 거울 시험이 있음). 그러나 로직 엔진 대 문서 엔진 금액 일치 시험은 655 대 전체로는 확인하지 못함(`test_840_2` = 문서 엔진 안 전후 비교) — **못 함**(단가산출 SK 중 `수식` 없는 옛 SK 는 로직 엔진 길이라 정본 목록이 안 닿음 → 옛 SK 처리 정해야 함). + +### A4. 화면 쪽 (사실 · 줄 번호) + +「sheet 훅」 이 한 줄로 막는 자리(`A00_Common/line_stack_machine_ctl.ts`): +- 훅 선언 47~48 · `const table = !!h.sheet`(125) +- 조종원 추가 단추: `table && crew.length ? null : …`(290~293) — 한 줄 있으면 숨김 +- 잡품 재료 고르기 잠김 `ro || table`(241) · 수량 칸 숨김(244~249) · 율을 모든 잡품 줄에 같게 `misc.map(x => ({...x, 율: n}))`(256) · 잡품 추가 = 밑 줄이 있고 목록 비었을 때만 `parts.base`(300~303) +- 호출: `line_stack_machine_sheet.ts` 261~281(`sheet: true` 279) + +**왜 막았나(근본 까닭)** — 화면이 아니라 **줄 꼴**: 기계 줄 값 칸이 `조종원` · `조종원직종` · `잡재료율` 하나씩이라 `common_util/common_util_machine_sheet.ts` 의 +`coverFrom`(113~137 · 조종원 1 줄 `{키 LB:직종, 인}` 만 만들고 잡품은 `parts.base` 밑줄마다 같은 율) · `applyCover`(143~175 · `entry.조종원[0]` · `entry.잡품[0]?.율` 만 줄에 되돌림) · `ownedCols`(107 · 조종원 · 직종 · 잡재료율을 제어 구역 몫으로) 가 여러 줄을 **줄에 못 담음**. 그래서 훅이 UI 를 한 줄로 맞춘 것. + +**제어 구역을 기계 보기에서 여러 줄로 열려면** (㉠ 기준) +1. `line_stack_machine_ctl.ts` — `table` 분기 5 자리 삭제(조종원 단추 · 재료 고르기 · 수량 칸 · 율 개별 · 잡품 추가 제한). +2. `common_util_machine_sheet.ts` — `coverFrom`/`applyCover` 의 조종원 · 잡품 부분을 「줄 칸 목록 ↔ 덮음 목록」 복사로 교체(`CREW` · `MISC` 단일 칸 처리 제거 · `ownedCols` 에서 세 칸 빼고 목록 칸 추가). +3. `line_stack_machine_sheet.ts` — `BASE_KEYS` 에서 세 단일 칸 입력 뺌(거울 표시 또는 감춤) · `drawBase` 의 `Object.keys(cur.값)` 가 목록 값을 `numField` 로 그리지 않게 거름 · `rangeWarnings` 는 수만 보므로 그대로. +4. M01 상세 `commit()` · 내 기계 `bodyOfSheet`(M02_MyMachine_Form.ts 167) 는 `값` 묶음을 그대로 실어 보내므로 목록 칸이 있으면 그대로 저장 길로 감(M01) · 내 기계는 서버 `clean` 고침 필요. +5. 거울 시험 `test_840_2_machine_sheet.py`(655 대 줄 같음 · 박음 거울) · `test_836_1_machine_cover.py` 확장. + +### A5. 권하는 꼴 · 걸음 · 정할 것 + +**권하는 꼴(한 줄)** = ㉠ — 기계 정본 줄 `값`에 `조종원줄`(`[{키 'LB:1054', 인 2, 이름?}]`) · `잡품줄`(`[{키 재료열쇠, 이름?, 수량, 율}]`)을 두고(없으면 지금 그대로) 셈 때 덮음과 같은 `cover_doc` 로 얹으며, 단가산출 `기계덮음` 이 부분별 통째 교체로 그 위에 덮임. 시간당은 문서 엔진 한 길로 모음. + +**걸음 나누기(파일 경계)** +| 걸음 | 파일 | 확인 | +|---|---|---| +| 1 자료 · 셈 | `master_doc_cover.py`(+`defaults_of` 정본 기준) · `master_doc_calc.py`/`master_doc_link.py`/`master_doc_record.py` · TS 짝 `common_util_formula_doc_cover.ts` · TS 링크 | 거울 시험 · 655 대 시간당 `hourly_base.json` 불변 | +| 2 시간당 한 길 | `M02_Machine_Hourly.hourly/brief` · `M02_MyMachine.hourly` · (옛 SK 처리) | 로직 대 문서 엔진 655 대 같음 시험 신설 | +| 3 저장 | `M02_MyMachine.clean/engine` · `M01_MasterData_Machine.fix` · `check_master`(목록 칸 검사 규칙 한 줄 — 칸 이름 · 줄 꼴) | 저장 왕복 시험 | +| 4 화면 | `line_stack_machine_ctl.ts` · `common_util_machine_sheet.ts` · `line_stack_machine_sheet.ts` · M01 상세 · 내 기계 | ORCA 조작 · 거울 시험 | +| 5 불러오기 | `M02_San_MyMachine.py`(조종원 · 잡품 · 소모 재료 줄 여럿 받음 · 못 이은 직종 「확인 필요」) | `test_821_4` 확장 | +| 6 자료(사용자 판단 뒤) | 해상기계 79 대 선원류 → `조종원줄` 옮김 | 금액 변동 목록(의도) | + +**정해야 할 것(사용자 판단)** +1. 조종원 여러 줄이 있을 때 기존 `조종원` · `조종원직종` 칸 — ㉮ 남기고 목록이 있으면 목록 우선(옛 시험 · M01 목록 화면 그대로) ㉯ 목록으로 완전 이전(칸 삭제 — 문서 엔진 식 변수 `Q_기계조종원` 은 목록 합계로 바꿔야 함). +2. 선원류 칸(선원 · 준설선선장 · 준설선기관사 · 고급선원) → 조종원줄로 옮길지(옮기면 79 대 시간당이 오름 — 위 표 · 약 +4 만~27 만원/시간) · 안 옮기면 계속 시간당에 안 들어감. +3. 선원류 「인」의 시간 환산 — 조종원 「인/일」 과 같은 `1/8 × 16/12 × 25/20` 를 쓰는지(원문 단위 표기가 「인」 한 글자라 해석 필요). +4. **고급선원 직종 대응**(인력에 직종 없음 — 소멸 직종) — 어느 직종 노임으로 갈지. +5. 잡품 재료 여러 줄의 기본 수량 · 율 뜻 — 지금 잡재료율 = 「주연료의 %」 하나 · 재료 여럿이면 줄마다 「수량 × 율%」 인지 「주연료 대비 %」 인지(덮음 층 `수량 × 율 ÷ 100` 을 그대로 쓸지). +6. 옛 SK(수식 문서 없음 · 로직 엔진 길)가 정본 목록을 못 읽는 문제 — 그대로 둘지 · 모두 수식 문서로 올릴지. +7. 자료 고침(선원류 옮김 · 목록 채움)은 사용자 판단 후 별도 걸음 — 이 분석은 자료를 안 고침. + +--- + +## 부분 B — 거창 견본 「안내판」 줄 −50,000 + +### B1. 그 줄 (사실) + +엑셀 `01.산불거창(거창북상병곡)/01.내역서/00.25년_산불_거창(거창,북상,병곡,산8외)내역+수량.xlsx` +- 시트 「내역서」 **67 행** `급수 및 노폭 좁은 안내판` · 규격 `Φ600, 원형` · 수량 1 · 단위 개소 · 단가 296,295(노 140,043 · 재 153,329 · 경 2,923) · 금액 296,295(수량집계표 F66 연결) +- 시트 「일위대가」 **제13호표**(91~96 행) 구성: + +| 구성 줄 | 규격 | 수량 | 엑셀 단가(노 / 재 / 경) | 줄 금액 | +|---|---|---|---|---| +| 안내표지판 설치 | 단주식 | 1 개소 | 84,540 / 701 / 2,533 (단가산출총괄표 G47 연결) | 87,774 | +| 교통안전표지판 | 600,원형(고휘도) | 1 EA | 재 91,200 | 91,200 | +| **표지판지주** | Φ60.5×3000 | 1 EA | **재 50,000**(자재단가 AA32 연결) | **50,000** | +| 레미콘타설(인력운반타설) | 소형구조물 | 0.14 ㎥ | 117,270 / 2,345 / 0 | 16,746.1 | +| 합판거푸집 | 6회, 간단 | 1.26 ㎡ | 31,020 / 8,810 / 310 | 50,576.4 | +| 합(TRUNC) | | | 140,043 / 153,329 / 2,923 | **296,295** | + +### B2. 우리 쪽 이음 · 어느 줄에서 빠지나 (사실 · 실행) + +실행 — 시험 `test_707_7` 도우미(`world` fixture)로 거창 한 번 불러오기 → 결과 `어긋남` 1 건: +`{행 67 · 「급수 및 노폭 좁은 안내판」 · 엑셀 296,295 · 우리 246,295 · 까닭 「이음 단가 = 우리 셈」}` (`gyechang_apply.json`). + +이어짐 — 내역 줄 → 일위대가 제13호표(`SC-000013` · 참조 사본 `precombo@project@-@…-13`) = **가져온 문서의 「고정 줄」 5 개**(식 SK · 일위대가 아님 · `고정` 줄은 엑셀 단가를 줄에 그대로 둠). 그중 **「표지판지주」 고정 줄만 `이음.자재 = MT003240`**(우리 M01 자재 「표지판지주 Φ60.5×3000」 · 물가정보 50,000 · `재료_자재품목.json` 3260 행)으로 이어짐. + +줄마다 엑셀 대 우리(B09 대가 블록 · `gyechang_apply.json` `daega_blocks`): + +| 줄 | 엑셀 줄 금액 | 우리 줄 금액 | 차 | +|---|---|---|---| +| 안내표지판 설치 | 87,774 | 87,774 | 0 | +| 교통안전표지판 | 91,200 | 91,200 | 0 | +| **표지판지주** | **50,000** | **0**(`prices.material` 0 · `own.material` 50,000 인데 0 처리) | **−50,000** | +| 레미콘타설 | 16,746.1 | 같음 | 0 | +| 합판거푸집 | 50,576.4 | 같음 | 0 | +| 합 | 296,295 | 246,295 | **−50,000** | + +**빠지는 길**(코드 사실): +1. `B09_Estimation_Supply.supply_defaults`(41~50) — 대비표 기본 표시 = `marks.get(키, "별도")`. `material_marks`(28~38)는 **재료 줄(`kind == "material"`)의 `mark` 만** 모음 → 고정 줄이 이은 자재 MT003240 은 `marks` 에 없어 **기본 「별도」** 로 감(`payload.sheets.compare` 에 `supply: "별도"` 확인). +2. `B09_Estimation_Calc_Labor._fixed`(140~148) — 이은 자재가 관급 · 별도이면 고정 줄 재료 0 (「841-1 단가 책 값으로 다시 안 덮음」). +3. **대가 밖으로 간 몫이 자재대에 안 잡힘**: 대가 블록 줄이 `kind == "material"` 일 때만 `extra["aside"]` 를 달고(Calc_Labor 213~214) 집계가 `aside` 를 모아 `aside_qty` 로 4 자재대에 한 번 올림(`Summary.py` 157~158 · `Router.py` 202 · `Calc_Bill.py` 135) — **고정 줄은 `_fixed_lines`(Summary 166~174)로 빠져 `aside` 표시 없음** → `aside_qty = {}`(실행 확인) → 50,000 이 대가에서도 자재대에서도 사라짐. 한편 재료비수량금액집계표(`sum_material`)에는 MT003240 qty 1 · 50,000 이 남음 → **집계표와 내역이 어긋남**(사실). +4. M02 엔진 자신은 같은 문서에서 **296,295**를 냄(`M02_Labor_Fixed.line` 은 고정 줄의 이은 자재를 별도계상 판단 없이 기준에 더함 — 실행 `fixed_line.py`: 노 140,043 · 재 153,329.9 · 경 2,923.6 · 합 296,296.5 → 줄 TRUNC 뒤 296,295). 즉 「B09 = M02 값」 이라는 841-1 취지와 어긋나는 곳이 **B09 의 고정 줄 별도 처리** 하나. + +### B3. 841-1 전 · 같은 까닭의 다른 줄 (사실) + +- 841-1 전(옛 B09 단가 책) = 같았음: 시험 `WANT` 거창 gap 이 0(`git show 5d8d9a4fd` 에서 `…, 0, 0` → `…, 0, 50000`) · 옛 책이 자재 단가를 고정 줄에 그대로 덮었고 「별도」 기본 판정이 없었음. +- 견본 4 개 전수(거창 · 대흥 · 소광 · 영월 · `samples_fixed.json`): 고정 줄 이음 수 = 거창 노임 10 + **자재 1** · 대흥 0 · 소광 0(블록 0) · 영월 0. 고정 줄 재료가 0 으로 바뀐 줄 = **거창 표지판지주 1 건뿐** · 다른 견본 어긋남은 영월 「끝수」 28 건(별개). 같은 까닭의 다른 줄 = **0 건**(견본 안). 장수 · 기번3(.estx · .STC)은 일위대가 시트 없음 — 해당 없음. +- 일반화(짐작): 이음 자재를 가진 고정 줄이 늘어나면(경쟁사 파일이 자재 이음을 많이 받는 파일) 같은 누락이 그만큼 생김 — 현재 이음 자재는 불러오기 `이음.자재` 후보가 1 건이라 견본에선 1 건. + +### B4. 고칠 자리 후보 · 사용자 확정과의 충돌 + +| 후보 | 고치는 곳 | 효과 | 사용자 확정과 | +|---|---|---|---| +| **F1 (권함)** 고정 줄이 이은 자재의 기본 표시 = 직접계산(별도 아님) | `B09_Estimation_Supply.material_marks`(고정 줄 `link.material` 키를 `None` 으로 등록 · 약 4 줄 · `Calc_Labor`/`Summary` 의 TS 짝 포함 여부 점검) | 거창 −50,000 → 0 · M02 엔진과 일치 · 시험 `WANT` gap 50000 → 0 · 집계표와 내역 정합 | 부딪힘 없음 — 「별도계상 재료는 대가 안에 안 나오는 게 맞음」은 **자재표시가 있는 재료 줄**(M02 `자재` 목록 `MARK_DEFAULT 별도계상`) 얘기 · 고정 줄 이음 자재는 M02 에 표시 칸 자체가 없고 M02 엔진도 대가에 넣음. 판정은 줄 종류(고정 줄)라는 로직이지 값 기준 아님 → 「매칭 · 판정은 로직만 · 값은 참고」와도 합치 | +| F2 (보강) 고정 줄 자재가 사용자 표시로 별도 · 관급일 때 대가 밖 몫을 `aside` 로 실어 자재대에 올림 | `Calc_Labor._block`(213 행 `kind == "material"` 조건에 고정 줄 이음 자재 포함) · `Summary._fixed_lines`(`aside` 전달) | 사용자가 「별도」 로 직접 고른 고정 줄 자재가 사라지는 것(지금은 증발) 방지 | 「사급 표시면 대가 안」 과 합치 · 지금은 사용자 표시가 없으니 발현 0 건(잠복) | +| F3 엑셀 단가로 덮기(옛 방식) | 이음 단가 덮개 부활 | 거창 같음 | **충돌** — 841-1 「B09 가 값을 따로 셈하지 않음」 · 사용자 확정 「이음 단가 = 우리 셈」 과 반대 → 비권장 | +| F4 시험 상수만 맞춤 | `test_707_7` WANT | 흠을 시험이 덮음 | 비권장(원인 안 고침) | + +권고: **F1 + F2**(한 걸음 · 파일 2~3 · 시험 `test_707_7` gap 0 · `test_841_1`). +※ 사용자 「사급」 표시로 대가에 돌아오는 경로(`supply()` 가 사급이면 None)는 코드 읽기로 확인 · 별도 실행은 못 함(`/estimation/calc` 가 DB 풀 필요 — 비동기 길을 읽기 전용으로 못 돌림 → 「못 함」). + +--- + +## 못 함 · 못 찾음 + +- 로직 엔진 대 문서 엔진 655 대 금액 일치 시험: 못 찾음(문서 엔진 내 전후 비교만 있음). 정본 목록을 문서 엔진 한 길로 읽히려면 신설 필요. +- 고급선원 인력 직종: 못 찾음(소멸 직종). +- 선원류 시간 환산(5/24)과 노임 곱 금액: 짐작(식이 없음 · 사용자 판단 전). +- 사용자 「사급」 표시 후 거창 실제 재셈: 못 함(위 까닭). +- 산출물 정리: `tmp/brain_867/_pt` · `_pt2`(pytest 임시 폴더) 지우기는 권한이 막혀 못 지움 — 사용자 지움 필요.