feat(est-test): 기성 회차 도급내역 선택(당초/변경)

- 설계변경 내역서에서 회차 추가 때 당초/변경 고르기
- 당초면 행마다 당초 칸으로 Index·품명·규격·단위·수량·단가·금액(GC 포함)
- 회차 추가 처리를 native-progress-view.js 로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 19:06:09 +09:00
co-authored by Claude Opus 5.5
parent 812928a51f
commit 4706229100
4 changed files with 83 additions and 17 deletions
+25
View File
@@ -59,3 +59,28 @@ def test_view_headers_follow_options_and_zero_hiding():
"비고",
]
assert result["jun"] == ""
def test_origin_load_method_uses_original_fields():
result = run(
"math",
"""(()=>{
const rows=[{Index:2,Index_:1,Name:'b',Name_:'a',Size:'s',Size_:' ',GN:5,GN_:3,GU:10,GU_:8,GC:50,GC_:24},
{Name:'c',GN:1,GU:4}];
const o=EstProgress.originRows(rows);
const p=EstNative.empty();p.options.SourceRefresh=false;
p.tables.EstMainDat=[{Code:'A',Name:'a',GN:10,GN_:4,GU:100,GU_:100},{LinkIndex:54}];
const q=EstNative.calculate(p);
q.progress=[{id:'r1',name:'1회',inputs:{},locked:false,loadMethod:'origin'},
{id:'r2',name:'2회',inputs:{},locked:false}];
const a=EstProgress.calculate(q,'r1').rows[0].GN;
q.progress=[q.progress[1]];
const b=EstProgress.calculate(q,'r2').rows[0].GN;
return {o:o.map(r=>[r.Index,r.Name,r.Size,r.GN,r.GU,r.GC]),a,b};
})()""",
)
assert result == {
"o": [[1, "a", "s", 3, 8, 24], [None, "c", None, 1, 4, None]],
"a": 4,
"b": 10,
}
+2 -13
View File
@@ -428,19 +428,8 @@ const EstActions = (() => {
const totals = EstQuantity.totals(project, state.quantitySheet);
if (confirm("연결된 내역 수량을 산출 결과로 바꾸시겠습니까?"))
EstApp.change(() => EstQuantity.applyTotals(project, totals));
} else if (name === "add-round") {
const next = {
id: EstApp.uid(),
name: EstBusiness.newProgressName(project.progress),
inputs: {},
approved: false,
locked: false,
};
EstApp.change(() => {
project.progress.push(next);
state.roundId = next.id;
}, false);
} else if (name === "lock-round") {
} else if (name === "add-round") EstProgressView.addRound(state);
else if (name === "lock-round") {
if (
confirm("이 회차를 확정하고 저장하시겠습니까? 전회 누계로 보존되고 직접 편집이 잠깁니다.")
) {
+36 -1
View File
@@ -287,6 +287,41 @@ const EstProgressView = (() => {
}
if (typeof document !== "undefined" && document.addEventListener) install();
// 기성 회차 추가: 설계변경 내역서면 「도급내역을 선택하세요.」(당초/변경 — 닫기 없음, 고른 값으로 회차를 만듦)
function addRound(state) {
const project = state.project,
push = (loadMethod) => {
const next = {
id: EstApp.uid(),
name: EstBusiness.newProgressName(project.progress),
inputs: {},
approved: false,
locked: false,
...(loadMethod && { loadMethod }),
};
EstApp.change(() => {
project.progress.push(next);
state.roundId = next.id;
}, false);
};
if (project.options.Mode !== "설계변경") return push();
EstActions.form(
"도급내역을 선택하세요.",
[
{
name: "method",
label: "설계변경한 내역서입니다. 도급내역으로 불러올 데이타를 선택하세요.",
value: "origin",
choices: [
["origin", "당초 내역서"],
["change", "변경 내역서"],
],
},
],
(values) => push(values.method),
);
}
function handle(name, state) {
if (name === "accom-option") dialog(state);
else if (name === "accom-option-ok") close(true);
@@ -294,5 +329,5 @@ const EstProgressView = (() => {
else return false;
return true;
}
return { view, get, parts, move, handle, dialog };
return { view, get, parts, move, handle, dialog, addRound };
})();
+20 -3
View File
@@ -26,11 +26,28 @@ const EstProgress = (() => {
}
return output;
}
// 도급내역 선택(TfrmAccomLoadMethodEst 0xc8cd50 · 덮어쓰기 c8e5e8): 설계변경 내역서로 회차를 처음 만들 때 당초를 고르면
// 행마다 당초 칸(_)으로 — Index, 품명·규격·단위(당초가 비면 지금 값), 수량·단가·금액. 원본은 GC 를 빠뜨리지만 웹은 함께 옮김.
function originRows(rows) {
return rows.map((row) => {
const out = { ...row };
if (row.Index_ != null) out.Index = row.Index_;
for (const k of ["Name", "Size", "Unite"])
if (String(row[k + "_"] ?? "").trim()) out[k] = row[k + "_"];
for (const k of ["GN", "TU", "TC", ...units, ...components])
if (row[k + "_"] != null) out[k] = row[k + "_"];
return out;
});
}
const contractRows = (project, round) =>
round.loadMethod === "origin"
? originRows(project.tables.EstMainDat)
: project.tables.EstMainDat;
function calculate(project, roundId) {
const round = project.progress.find((item) => item.id === roundId);
if (!round) throw Error("기성 회차 없음");
const source = round.contract || {
rows: project.tables.EstMainDat,
rows: contractRows(project, round),
wonga: project.tables.Wonga,
options: project.options,
};
@@ -316,7 +333,7 @@ const EstProgress = (() => {
if (!round) throw Error("기성 회차 없음");
if (round.locked) throw Error("이미 확정한 회차입니다.");
round.contract = {
rows: structuredClone(project.tables.EstMainDat),
rows: structuredClone(contractRows(project, round)),
wonga: structuredClone(project.tables.Wonga),
options: { ...project.options },
};
@@ -346,5 +363,5 @@ const EstProgress = (() => {
}
return project;
}
return { calculate, lock, unlock, rebuild, ambiguousKeys };
return { calculate, lock, unlock, rebuild, ambiguousKeys, originRows };
})();