feat(est-test): 원가계산서 내용 삭제와 기본양식 저장
- 원본 popupContentDel: 고른 줄의 연결·금액·요율·산출근거·자리 비움 - 원본 popupSaveAsMain: 원가 양식 「기본양식」 저장, 새 내역서에 적용 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -487,6 +487,8 @@ 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] 원가계산서 내용 삭제·기본양식으로 저장(원본 TFRMWONGABASE popupContentDel A7 · popupSaveAsMain) — 원가계산서(W) 「선택 줄 내용 삭제」: 연결·금액·비율·요율·산출근거·자리 비움(이름·기호 유지, 재계산 없음). 양식 목록 「기본양식으로 저장」: 이름 「기본양식」 — 새 내역서를 만들 때 원가계산서로 씀.
|
||||
- 검증완료: 양식·원가·바인딩 시험 8개 통과. ORCA 브라우저에서 간접노무비 줄 내용 삭제(이름 유지·식·요율·금액 비움), 기본양식 저장 → 새 내역서 원가 31줄, 양식 지우고 샘플 복구.
|
||||
- [x] 갑지·표지 양식(원본 TFRMGABGI·TFRMCOVER popupSaveFormat·popupLoadFormat·popupFormatTableS·popupSaveToDefault·popupInit·popupPrint) — 편집 창 위 단추: 양식목록(불러오기·지우기), 양식저장하기(이름), 기본양식으로 저장(처음 여는 갑지·표지에 채움), 초기화(문서 지우고 다시 열기), 인쇄(서식 8·9 미리보기로). 양식은 서버 보관함 종류 document 에 { docKind, fields }, 공사명은 넣지 않음.
|
||||
- 검증완료: 문서·바인딩 시험 4개 통과. ORCA 브라우저에서 갑지 공사위치 「X위치」 양식 저장·기본양식 저장 → 초기화 뒤 다시 열면 「X위치」 채움, 양식목록에서 불러오기, 인쇄 → 미리보기 서식 8 에 갑지, 양식·인쇄 설정 지워 복구.
|
||||
- [x] 공사설명서·시방서 서식 편집(원본 TFRMESTEDITOR mnuFormatPar·mnuTableCreate·mnuFormatTable·popupBookMark·mnuFormatTableS·mnuSaveToDefault) — 서식 있는 편집 칸: 문단모양(정렬·들여쓰기·왼쪽 여백·줄간격), 표만들기(줄·칸), 표모양(테두리·칸 여백·너비), 책갈피(넣기·찾아가기), 양식목록(서버 양식 보관함 종류 document — 불러오기·지우기·현재 문서 저장), 기본양식으로 저장(빈 문서를 열면 채움). 본문은 `docs[kind].html`(허용 태그·속성만)과 글자 `text` 를 함께 두고 인쇄는 html 우선. 갑지에서 붙여넣기는 커서 자리에. 원본 WPT 서식 가져오기·ESTX 저장은 여전히 하지 않음.
|
||||
|
||||
@@ -211,7 +211,8 @@
|
||||
><button data-action="jungsang-init">당초금액 초기화</button>
|
||||
<button data-action="wonga-gita">기타경비 계산</button
|
||||
><button data-action="wonga-anjun">산업안전보건관리비 비교</button
|
||||
><button data-action="wonga-sname">산출근거 약어로 표시</button>
|
||||
><button data-action="wonga-sname">산출근거 약어로 표시</button
|
||||
><button data-action="wonga-content-del">선택 줄 내용 삭제</button>
|
||||
</div>
|
||||
</details>
|
||||
<details>
|
||||
|
||||
@@ -140,6 +140,7 @@ const EstActions = (() => {
|
||||
if (confirm("저장하지 않은 입력을 비우고 새 내역서를 만드시겠습니까?")) {
|
||||
EstApp.setProject(EstNative.empty());
|
||||
if (typeof EstDefaults !== "undefined") await EstDefaults.applyNew();
|
||||
if (typeof EstFormsLibrary !== "undefined") await EstFormsLibrary.applyDefault();
|
||||
}
|
||||
} else if (name === "sample") {
|
||||
if (confirm("현재 작업을 REA 샘플로 바꾸시겠습니까?"))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// 원본 원가계산서 양식(TFRMWONGABASE popupSaveAs·popupFormats·popupLoadFrom)과 양식목록(TFRMFORMATFILELIST)
|
||||
// — 현재 원가 표를 이름 붙여 서버 보관함(data/forms.json)에 등록하고, 목록에서 열기·삭제, 파일로 내려받기·불러오기.
|
||||
// 기본양식으로 저장(popupSaveAsMain): 이름 「기본양식」 — 새 내역서를 만들 때 원가계산서로 쓴다.
|
||||
const EstFormsLibrary = (() => {
|
||||
const DEFAULT = "기본양식";
|
||||
// 원가 표 양식으로 남길 필드 — 금액(Cost)은 계산 결과라 남기지 않는다.
|
||||
function strip(rows) {
|
||||
return rows.map((row) => {
|
||||
@@ -23,7 +25,7 @@ const EstFormsLibrary = (() => {
|
||||
forms = await list();
|
||||
EstApp.showDialog(
|
||||
"원가계산서 양식 목록",
|
||||
`<p>현재 원가계산서의 항목·수식·요율을 양식으로 등록하고, 다른 공사에서 열어 씁니다. 금액은 열 때 다시 계산합니다.</p><button data-action="wonga-form-register">현재 원가계산서 등록</button> <button data-action="wonga-form-export">파일로 내려받기</button> <button data-action="wonga-form-import">파일에서 불러오기</button><table class="sheet" style="margin-top:8px"><thead><tr><th>양식 이름</th><th>행</th><th>등록</th><th>작업</th></tr></thead><tbody>${forms.map((f) => `<tr><td>${esc(f.name)}</td><td>${f.data.length}</td><td>${esc(f.saved.slice(0, 10))}</td><td><button data-action="wonga-form-open" data-name="${esc(f.name)}">열기</button><button data-action="wonga-form-delete" data-name="${esc(f.name)}">삭제</button></td></tr>`).join("") || '<tr><td colspan="4">등록된 양식이 없습니다.</td></tr>'}</tbody></table>`,
|
||||
`<p>현재 원가계산서의 항목·수식·요율을 양식으로 등록하고, 다른 공사에서 열어 씁니다. 금액은 열 때 다시 계산합니다.</p><button data-action="wonga-form-register">현재 원가계산서 등록</button> <button data-action="wonga-form-default">기본양식으로 저장</button> <button data-action="wonga-form-export">파일로 내려받기</button> <button data-action="wonga-form-import">파일에서 불러오기</button><table class="sheet" style="margin-top:8px"><thead><tr><th>양식 이름</th><th>행</th><th>등록</th><th>작업</th></tr></thead><tbody>${forms.map((f) => `<tr><td>${esc(f.name)}</td><td>${f.data.length}</td><td>${esc(f.saved.slice(0, 10))}</td><td><button data-action="wonga-form-open" data-name="${esc(f.name)}">열기</button><button data-action="wonga-form-delete" data-name="${esc(f.name)}">삭제</button></td></tr>`).join("") || '<tr><td colspan="4">등록된 양식이 없습니다.</td></tr>'}</tbody></table>`,
|
||||
);
|
||||
state.formsLibrary = forms;
|
||||
}
|
||||
@@ -52,6 +54,18 @@ const EstFormsLibrary = (() => {
|
||||
body: JSON.stringify({ kind: "wonga", name: title, data }),
|
||||
});
|
||||
await show(state);
|
||||
} else if (name === "wonga-form-default") {
|
||||
if (!confirm("현재 원가계산서를 새 내역서의 기본양식으로 저장하시겠습니까?")) return;
|
||||
await EstApp.api("/api/forms", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
kind: "wonga",
|
||||
name: DEFAULT,
|
||||
data: strip(validRows(state.project.tables.Wonga)),
|
||||
}),
|
||||
});
|
||||
await show(state);
|
||||
} else if (name === "wonga-form-open") {
|
||||
const form = state.formsLibrary?.find((f) => f.name === node.dataset.name);
|
||||
if (!form) throw Error("양식을 찾을 수 없습니다. 목록을 다시 여세요.");
|
||||
@@ -92,6 +106,7 @@ const EstFormsLibrary = (() => {
|
||||
const names = new Set([
|
||||
"wonga-forms",
|
||||
"wonga-form-register",
|
||||
"wonga-form-default",
|
||||
"wonga-form-open",
|
||||
"wonga-form-delete",
|
||||
"wonga-form-export",
|
||||
@@ -107,5 +122,13 @@ const EstFormsLibrary = (() => {
|
||||
return true;
|
||||
}
|
||||
|
||||
return { strip, validRows, handle };
|
||||
// 새 내역서에 기본양식 원가계산서
|
||||
async function applyDefault() {
|
||||
const form = (await list()).find((f) => f.name === DEFAULT);
|
||||
if (form)
|
||||
EstApp.change((project) => (project.tables.Wonga = structuredClone(validRows(form.data))));
|
||||
return Boolean(form);
|
||||
}
|
||||
|
||||
return { strip, validRows, applyDefault, handle };
|
||||
})();
|
||||
|
||||
@@ -282,6 +282,26 @@ const EstWongaTools = (() => {
|
||||
}
|
||||
|
||||
function handle(name, state) {
|
||||
if (name === "wonga-content-del") {
|
||||
// 내용 삭제(popupContentDel A7): 연결·금액·비율·요율·산출근거·자리 비움, 이름·기호·계산방식 유지, 재계산 없음
|
||||
const rows = state.project.tables.Wonga || [],
|
||||
picked = [...state.selection].filter((i) => rows[i]);
|
||||
if (state.view !== "Wonga" || !picked.length)
|
||||
throw Error("원가계산서에서 지울 줄을 고르세요.");
|
||||
EstApp.change((project) => {
|
||||
for (const i of picked)
|
||||
Object.assign(project.tables.Wonga[i], {
|
||||
LinkIndex: 0,
|
||||
Cost: 0,
|
||||
Biul: "",
|
||||
Youl: "",
|
||||
VSusic: "",
|
||||
Diget: 0,
|
||||
Checked: false,
|
||||
});
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
if (name === "wonga-sname") {
|
||||
EstApp.change(
|
||||
(project) => (project.options.WongaSNameShow = !project.options.WongaSNameShow),
|
||||
|
||||
Reference in New Issue
Block a user