diff --git a/tools/est-test/PLAN.md b/tools/est-test/PLAN.md index 5a8fb0216..a3f724170 100644 --- a/tools/est-test/PLAN.md +++ b/tools/est-test/PLAN.md @@ -489,6 +489,7 @@ ative-standard.js에 표준시장단가 원천(SilJukDat)과 내역 행(EstMainD - 남음: 구성비·요율 전환(CalcBase), 약어 표시(SName), 제비율 기준 문서 보기(원본 한글 파일). - [x] 수량산출서 검색·전체보기(원본 TFRMMULLANG btnSerch·btnAllDisplay — 빈칸·|·괄호 무시 포함 검색) — 고르기 줄을 `native-quantity-sheets.js` 로 옮겨 700줄 제한 유지. - 검증완료: `test_est_quantity_sheets.py` 검색 시험 포함 수량 시험 22개 통과. ORCA 브라우저에서 「집수」 검색 → 항목에 집수정이 있는 「배수」만·선택 이동, 전체보기 → 3개 복귀, 샘플 복구. + - [x] 다른 공사 불러오기 창(원본 barbtnSelfLoad → TfrmOtherLoad, 찾기 popSerch) — 저장된 다른 작업을 골라 같은 표를 띄우고 찾기(품명·규격, A&B 둘 다)·고른 줄을 하위 자료와 함께 가져오기(내역서는 고른 줄 아래에 줄, 나머지는 자료·호표 합침, 같은 코드는 이 공사 것). 검증완료: 바인딩 통과, ORCA 브라우저에서 산불진화임도 작업의 일위대가 3개 → 「취수장」 1개 → 가져오기 호표 8→9·하위 41건, 샘플 복구. - [x] 사용위치 검색 창(원본 TfrmUsesDataSerch btnSerch·btnAllDisplay) — 현재 표 항목을 품명·규격(빈칸·|·괄호 무시)으로 거르고 골라 사용위치 보기. 검증완료: 바인딩 통과, ORCA 브라우저에서 노임 9개 → 「보 통」 1개 → 보통인부 사용위치 11곳. - [x] 인쇄양식 불러오기·저장하기(원본 mnuPrintFormatLoad·Save 0x10ed318·0x10ed000 — spec_pc §3) — .pfot(인쇄정보표 MIDAS 이진) 읽기·쓰기 `print-format.cjs`(설명 BLOB·빈 칸 표지까지 보존, 원본 파일 그대로 다시 쓰면 바이트 같음). 불러오면 공사 인쇄표를 그 값으로, 저장은 지금 인쇄표를 원본 설치 main.pfot 필드 설명자 위에(`EST_PFOT_TEMPLATE`). .gfot(cxGrid 열 배치)는 웹 격자와 호환되지 않아 하지 않음. - 검증완료: `test_est_print_format.py`(설치 .pfot 두 개 바이트 같음·고친 값 반영) 및 바인딩 시험 통과, 서버 경로로 읽고 다시 쓴 파일 cmp 같음. ORCA 브라우저에서 샘플 인쇄양식 저장(32,755 바이트). diff --git a/tools/est-test/index.html b/tools/est-test/index.html index 05c27ada2..aed780765 100644 --- a/tools/est-test/index.html +++ b/tools/est-test/index.html @@ -20,6 +20,7 @@ + @@ -317,6 +318,7 @@ > { typeof EstPriceTools !== "undefined" && EstPriceTools, typeof EstMiscTools !== "undefined" && EstMiscTools, typeof EstExcelToEst !== "undefined" && EstExcelToEst, + typeof EstOtherLoad !== "undefined" && EstOtherLoad, ].filter(Boolean); function handle(name, state, node) { for (const module of modules()) if (module.handle(name, state, node)) return true; diff --git a/tools/est-test/native-other-load.js b/tools/est-test/native-other-load.js new file mode 100644 index 000000000..c1267e76f --- /dev/null +++ b/tools/est-test/native-other-load.js @@ -0,0 +1,113 @@ +// 원본 「다른 공사 불러오기」 창(barbtnSelfLoad → f135b8 → TfrmOtherLoad — spec_pb2 §5.2·§11): 저장된 다른 작업의 같은 표를 띄워 +// 찾기(Ctrl+F: 품명·규격 빈칸·|·괄호 무시, 「A&B」 는 둘 다)·고른 줄을 하위 자료와 함께 이 공사로 가져오기(EstTransfer, 같은 코드는 이 공사 것). +// 내역서는 고른 줄 아래에 줄을 넣고, 자재·노임·표준·견적·일위·단산·기계는 자료(호표)를 합친다. +const EstOtherLoad = (() => { + const KIND = { + StuffcDat: 5, + LaborcDat: 6, + SilJukDat: 21, + EstiMateDat: 101, + HeadMainDat: 103, + CostMainDat: 104, + MachMainDat: 105, + }; + const norm = (s) => String(s ?? "").replace(/[\s|()]/g, ""); + const match = (row, word) => { + const k = norm(row.Name || EstText.clean(row.LineData || "")) + norm(row.Size); + return norm(word) + .split("&") + .filter(Boolean) + .every((p) => k.includes(p)); + }; + + async function open(state) { + if (!state.project.tables[state.view]) throw Error("자료 화면에서 쓰세요."); + const o = (state.otherLoad ||= { id: "", word: "", picked: new Set() }); + o.projects = await EstApp.api("/api/projects"); + draw(state); + } + function rowsOf(o, view) { + const rows = o.source?.tables?.[view] || []; + return rows + .map((r, i) => [r, i]) + .filter(([r]) => { + if (["HeadMainDat", "CostMainDat", "MachMainDat"].includes(view) && !(Number(r.Index) > 0)) + return false; + return (r.Name || r.Code || r.LineData) && (!o.word || match(r, o.word)); + }); + } + function draw(state) { + const o = state.otherLoad, + { esc, number } = EstApp, + list = rowsOf(o, state.view).slice(0, 400); + EstApp.showDialog( + "다른 공사 불러오기", + `
| ${esc(r.Code ?? "")} | ${esc(r.Name || EstText.clean(r.LineData || ""))} | ${esc(r.Size ?? "")} | ${esc(r.Unite ?? "")} | ${number(r.TC)} |