fix(stmate-test): resolve 5 UI/calculation issues found during browser control verification
This commit is contained in:
@@ -188,8 +188,39 @@
|
||||
renderWorkspace();
|
||||
});
|
||||
onClick("modal-apply-expnd", () => {
|
||||
const code = ($("expnd-code") || {}).value;
|
||||
const ilwi =
|
||||
(ctx.state.ilwiItems || []).find((x) => x.code === code) || ctx.state.ilwiItems[0];
|
||||
if (ilwi && ilwi.lines && ilwi.lines.length) {
|
||||
ilwi.lines.forEach((ln, idx) => {
|
||||
const r = ctx.state.resources.find((x) => x.id === ln.refId || x.code === ln.refId);
|
||||
const recno = (Date.now() % 90000) + idx + 1;
|
||||
ctx.state.boqItems.push({
|
||||
id: "BOQ_" + recno,
|
||||
code: r ? r.code : ln.refId,
|
||||
name: `[전개] ${r ? r.name : ln.refId}`,
|
||||
refId: ln.refId,
|
||||
rowType: "normal",
|
||||
qty: ln.qty || 1,
|
||||
changedQty: ln.qty || 1,
|
||||
_recno: recno,
|
||||
});
|
||||
if (ctx.dbfData && ctx.dbfData.boq_rows) {
|
||||
ctx.dbfData.boq_rows.splice(5 + idx, 0, {
|
||||
_recno: recno,
|
||||
ITNUM: "",
|
||||
BDCODE1: r ? r.code : ln.refId,
|
||||
NAME1: `[전개] ${r ? r.name : ln.refId}`,
|
||||
SIZE1: r ? r.spec : "",
|
||||
UNIT1: r ? r.unit : "식",
|
||||
QTY1: String(ln.qty || 1),
|
||||
ENDCODE: "0.0000",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
closeModal();
|
||||
alert("선택 공종의 일위대가/산근 구성행이 전개되었습니다.");
|
||||
renderWorkspace();
|
||||
});
|
||||
bindEach(".btn-apply-qty-expr", "onclick", (btn) => {
|
||||
const id = btn.getAttribute("data-id");
|
||||
@@ -455,6 +486,13 @@
|
||||
const code = $("ilwi-btn-apply-f9").getAttribute("data-code");
|
||||
const txt = ($("smt-formula-textarea") || {}).value || "";
|
||||
ctx.uiState.editedSmtMap[code] = txt;
|
||||
if (ctx.dbfData && ctx.dbfData.costn_memos) {
|
||||
const prev = ctx.dbfData.costn_memos[code] || { code, blockNo: 1 };
|
||||
ctx.dbfData.costn_memos[code] = Object.assign({}, prev, {
|
||||
text: txt,
|
||||
byteLen: txt.length,
|
||||
});
|
||||
}
|
||||
const evalRes = ViewDanIlwi.evaluateSmtFormulaText(txt, ctx);
|
||||
if (evalRes.sumT > 0)
|
||||
ViewPrjBoq.syncCostnUnitPrice(ctx, code, evalRes.sumM, evalRes.sumL, evalRes.sumS);
|
||||
|
||||
@@ -327,7 +327,10 @@ const StmateCalc = (() => {
|
||||
});
|
||||
const directT = directM + directL + directS,
|
||||
govCombinedRaw = govRawTotal + govFeeTotal;
|
||||
const totals = { directM, directL, directS, directT, govRawTotal, govFeeTotal, govCombinedRaw };
|
||||
const totals = Object.assign(
|
||||
{ directM, directL, directS, directT },
|
||||
{ govRawTotal, govMatTotal: govRawTotal, govFeeTotal, govCombinedRaw },
|
||||
);
|
||||
return Object.assign({ rows, directTotal: directT, totals }, totals);
|
||||
}
|
||||
|
||||
@@ -348,7 +351,7 @@ const StmateCalc = (() => {
|
||||
const truncAmt = truncInd(rawCalcAmt);
|
||||
const base = Object.assign(
|
||||
{ key: code, code, label, formula: baseDesc },
|
||||
{ baseDesc, baseAmt, rate: ratePct, ratePct },
|
||||
{ baseDesc, baseAmt, base: baseAmt, rate: ratePct, ratePct },
|
||||
);
|
||||
if (!origKanjubRes) return Object.assign(base, { amount: truncAmt, modeUsed: "원설계" });
|
||||
const origRow = origKanjubRes.itemMap[code],
|
||||
@@ -507,6 +510,7 @@ const StmateCalc = (() => {
|
||||
["label", label],
|
||||
["formula", formula],
|
||||
["baseAmt", baseAmt],
|
||||
["base", baseAmt],
|
||||
["rate", rate],
|
||||
["amount", amount],
|
||||
]);
|
||||
@@ -658,8 +662,19 @@ const StmateCalc = (() => {
|
||||
kanjubOrig = calcKanjub(data, boqOrig, null);
|
||||
const boqRev = calcBoq(data, resources.map, machines.map, sanCal.map, ilwi.map, true),
|
||||
kanjubRev = calcKanjub(data, boqRev, kanjubOrig);
|
||||
const revMap = Object.fromEntries((boqRev.rows || []).map((r) => [r.id, r]));
|
||||
(boqOrig.rows || []).forEach((r) => {
|
||||
const rv = revMap[r.id];
|
||||
r.changedTAmt = rv ? rv.tAmt : r.tAmt;
|
||||
r.diffTAmt = r.changedTAmt - r.tAmt;
|
||||
});
|
||||
const base = { resources, machines, sanCal, ilwi, boqOrig, kanjubOrig };
|
||||
Object.assign(base, { boqRev, kanjubRev, resList: resources.list });
|
||||
Object.assign(base, {
|
||||
boqRev,
|
||||
kanjubRev,
|
||||
resList: resources.list,
|
||||
revComputed: { revBoq: boqRev, revKj: kanjubRev },
|
||||
});
|
||||
return Object.assign(base, { boqComputed: boqOrig, kanjubComputed: kanjubOrig });
|
||||
}
|
||||
|
||||
|
||||
@@ -82,13 +82,14 @@
|
||||
const vExpr = m[2].trim();
|
||||
const val = evalMathWithVars(vExpr);
|
||||
if (val > 0 || vExpr === "0") {
|
||||
vars[vName] = Math.round(val * 10000) / 10000;
|
||||
vars[vName] = Math.round(val * 100) / 100;
|
||||
assignedHere.push(`${vName} = ${vars[vName]}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 자원 참조 (&X00026L& / Q = , &M00080& * 0.00438'㎥' = )
|
||||
// 2) 자원 참조 (&X00026L& / Q = , &M00080& * 0.00438'㎥' = ) 또는 주석형 단가 요약
|
||||
const refMatch = ln.match(/&([A-Z]\d{4,5})([LMS])?&(.*)/);
|
||||
const commentCostMatch = !refMatch && ln.match(/(재료비|노무비|경\s*비)\s*[:=]\s*([\d,]+)/);
|
||||
let refInfo = null;
|
||||
if (refMatch) {
|
||||
const refCode = refMatch[1];
|
||||
@@ -116,6 +117,20 @@
|
||||
baseUnitPrice,
|
||||
calcAmt: roundedAmt,
|
||||
};
|
||||
} else if (commentCostMatch) {
|
||||
const cKind = commentCostMatch[1].replace(/\s+/g, "");
|
||||
const cVal = num(commentCostMatch[2], 0);
|
||||
const cTag = cKind === "노무비" ? "L" : cKind === "경비" ? "S" : "M";
|
||||
if (cTag === "L") sumL += cVal;
|
||||
else if (cTag === "S") sumS += cVal;
|
||||
else sumM += cVal;
|
||||
refInfo = {
|
||||
refCode: cKind,
|
||||
compTag: cTag,
|
||||
refName: "단가 직접지정",
|
||||
baseUnitPrice: cVal,
|
||||
calcAmt: cVal,
|
||||
};
|
||||
}
|
||||
|
||||
linesOut.push({
|
||||
@@ -357,8 +372,10 @@
|
||||
ctx.uiState.selectedIlwiCode &&
|
||||
bdxRows.some((r) => String(r.CODE).trim() === ctx.uiState.selectedIlwiCode)
|
||||
? ctx.uiState.selectedIlwiCode
|
||||
: bdxRows[0]
|
||||
? String(bdxRows[0].CODE).trim()
|
||||
: bdxRows.find((r) => Boolean(memos[String(r.CODE || "").trim()])) || bdxRows[0]
|
||||
? String(
|
||||
(bdxRows.find((r) => Boolean(memos[String(r.CODE || "").trim()])) || bdxRows[0]).CODE,
|
||||
).trim()
|
||||
: "";
|
||||
|
||||
const selRow = bdxRows.find((r) => String(r.CODE).trim() === selCode) || {};
|
||||
|
||||
@@ -518,14 +518,16 @@
|
||||
`;
|
||||
}
|
||||
if (toolKind === "wExpnd") {
|
||||
const bdxList = (ctx.state.ilwiItems || []).slice(0, 30);
|
||||
return `
|
||||
<div style="display:flex;flex-direction:column;gap:10px;">
|
||||
<p style="margin:0;"><strong>[wExpnd / wM_Expnd] 일위대가·단가산출 내역서 풀어넣기</strong> — 호표 구성행을 내역서 하위 행으로 전개합니다.</p>
|
||||
<div class="kanjub-16grid" style="grid-template-columns:repeat(2,1fr);">
|
||||
<p style="margin:0;"><strong>[wExpnd / wM_Expnd] 일위대가·단가산출 내역서 풀어넣기</strong> — 선택한 호표의 재료·노무·경비 구성행을 내역서에 직접 전개합니다.</p>
|
||||
<div class="kanjub-16grid" style="grid-template-columns:repeat(3,1fr);">
|
||||
<div class="kanjub-field"><label>전개할 호표 선택</label><select id="expnd-code">${bdxList.map((x) => `<option value="${x.code}">${x.code} ${x.rawName || x.name}</option>`).join("")}</select></div>
|
||||
<div class="kanjub-field"><label>집계 구분선(RGrpToT)</label><select id="expnd-tot"><option value="E1">소계(=)</option><option value="E2">계(==)</option><option value="E3">합계(===)</option></select></div>
|
||||
<div class="kanjub-field"><label>단가 끝전 처리</label><select id="expnd-round"><option value="trunc">절삭하여 소수 0위 적용</option><option value="round">반올림하여 소수 0위 적용</option></select></div>
|
||||
</div>
|
||||
<div style="text-align:right;"><button class="win-btn primary" id="modal-apply-expnd">일위대가 풀어넣기 확인</button></div>
|
||||
<div style="text-align:right;"><button class="win-btn primary" id="modal-apply-expnd">일위대가 풀어넣기 실행</button></div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user