feat(est): print progress and price adjustments
This commit is contained in:
@@ -1,6 +1,31 @@
|
||||
from test_est_rea_parity import run
|
||||
|
||||
|
||||
def test_progress_and_escalation_print_use_selected_calculations():
|
||||
result = run(
|
||||
"math",
|
||||
"""(()=>{
|
||||
const p=EstNative.empty();p.options.SourceRefresh=false;p.options.EscDesignTotal=1000;
|
||||
p.tables.EstMainDat=[{PkID:1,Code:'R',Name:'work',GN:10,GU:100,AGU:100,EscActual:3},{LinkIndex:54}];
|
||||
p.progress=[{id:'one',name:'first',inputs:{'1':{Gum:2}}}];
|
||||
const q=EstProgress.lock(EstNative.calculate(p),'one');
|
||||
q.tables.EstMainDat[0].GU=200;
|
||||
q.progress.push({id:'two',name:'second',inputs:{'1':{Gum:3}}});
|
||||
return {locked:EstForms.data('progress-summary',q,{roundId:'one'}),
|
||||
draft:EstForms.data('progress-summary',q,{roundId:'two'}),
|
||||
escalation:EstForms.data('escalation-summary',p),
|
||||
empty:EstForms.data('progress-summary',EstNative.empty())};
|
||||
})()""",
|
||||
)
|
||||
assert result["locked"]["rows"][0]["GumTC"] == 200
|
||||
assert result["locked"]["rows"][0]["GU"] == 100
|
||||
assert result["draft"]["rows"][0]["GumTC"] == 600
|
||||
assert result["draft"]["rows"][0]["TotalTC"] == 800
|
||||
assert result["escalation"]["rows"][0]["EscExcluded"] == 3
|
||||
assert result["escalation"]["rows"][0]["EscApplied"] == 7
|
||||
assert result["empty"]["errors"]
|
||||
|
||||
|
||||
def test_resource_report_separates_each_work_item_without_changing_aggregate():
|
||||
result = run(
|
||||
"math",
|
||||
|
||||
@@ -1,6 +1,54 @@
|
||||
const EstForms = (() => {
|
||||
const common = ["Code", "Name", "Size", "Unite"];
|
||||
function data(id, project) {
|
||||
function data(id, project, state = {}) {
|
||||
if (id === "progress-summary") {
|
||||
const round =
|
||||
project.progress.find((item) => item.id === state.roundId) || project.progress.at(-1);
|
||||
if (!round) return { columns: ["Name"], rows: [], errors: ["기성 회차가 없습니다."] };
|
||||
const result =
|
||||
round.locked && round.result ? round.result : EstProgress.calculate(project, round.id);
|
||||
return {
|
||||
columns: [
|
||||
"Code",
|
||||
"Name",
|
||||
"Unite",
|
||||
"GN",
|
||||
"TC",
|
||||
"JunGN",
|
||||
"JunTC",
|
||||
"GumGN",
|
||||
"GumTC",
|
||||
"SaGN",
|
||||
"SaTC",
|
||||
"TotalGN",
|
||||
"TotalTC",
|
||||
],
|
||||
rows: result.rows,
|
||||
errors: result.errors,
|
||||
detail: `${round.name || "기성"} (${round.locked ? "확정" : "작성 중"})`,
|
||||
};
|
||||
}
|
||||
if (id === "escalation-summary") {
|
||||
const result = EstEscalation.calculate(project);
|
||||
return {
|
||||
columns: [
|
||||
"Code",
|
||||
"Name",
|
||||
"Unite",
|
||||
"GN",
|
||||
"EscExcluded",
|
||||
"EscApplied",
|
||||
"TC",
|
||||
"ENC",
|
||||
"EGC",
|
||||
"EJC",
|
||||
"ESC",
|
||||
],
|
||||
rows: result.rows,
|
||||
errors: result.errors,
|
||||
detail: `도급액 ${result.contractTotal} · 조정액 ${result.adjustment} · 조정률 ${result.rate}%`,
|
||||
};
|
||||
}
|
||||
if (id === 171) {
|
||||
const output = EstReview.calculate(project);
|
||||
const rows = output.baseline.tables.EstMainDat.map((row, index) => ({
|
||||
@@ -179,6 +227,20 @@ const EstForms = (() => {
|
||||
SheetName: "산출서",
|
||||
Error: "계산 오류",
|
||||
Reason: "심사 사유",
|
||||
JunGN: "전회 수량",
|
||||
JunTC: "전회 금액",
|
||||
GumGN: "금회 수량",
|
||||
GumTC: "금회 금액",
|
||||
SaGN: "사정 수량",
|
||||
SaTC: "사정 금액",
|
||||
TotalGN: "누계 수량",
|
||||
TotalTC: "누계 금액",
|
||||
EscExcluded: "제외 수량",
|
||||
EscApplied: "적용 수량",
|
||||
ENC: "노무비 증감",
|
||||
EGC: "재료비 증감",
|
||||
EJC: "경비 증감",
|
||||
ESC: "산출경비 증감",
|
||||
TargetCode: "연결 내역",
|
||||
TU: "단가",
|
||||
TC: "금액",
|
||||
|
||||
@@ -20,7 +20,7 @@ const EstReport = (() => {
|
||||
const { state, esc } = EstApp;
|
||||
const settings = setting(),
|
||||
form = catalog.find((row) => String(row.Index) === settings.form),
|
||||
output = form ? EstForms.data(form.Index, state.project) : null;
|
||||
output = form ? EstForms.data(form.Index, state.project, state) : null;
|
||||
const number = (value) =>
|
||||
new Intl.NumberFormat("ko-KR", { maximumFractionDigits: 12 }).format(Number(value) || 0);
|
||||
const root = document.createElement("div");
|
||||
@@ -76,15 +76,18 @@ const EstReport = (() => {
|
||||
.forEach((node) => node.removeAttribute("contenteditable"));
|
||||
const title = form?.Name2 || EstApp.titles[state.view] || state.view;
|
||||
const detail =
|
||||
state.view === "quantity"
|
||||
output?.detail ||
|
||||
(state.view === "quantity"
|
||||
? state.project.quantitySheets?.find((sheet) => sheet.Code === state.quantitySheet)?.Name
|
||||
: state.view === "progress"
|
||||
? state.project.progress.find((round) => round.id === state.roundId)?.name
|
||||
: state.group
|
||||
? EstNative.groups(state.project.tables[state.view] || []).get(state.group)?.rows[0]
|
||||
?.Name
|
||||
: "";
|
||||
const totals = state.project.calculation;
|
||||
: "");
|
||||
const totals = ["progress-summary", "escalation-summary"].includes(form?.Index)
|
||||
? null
|
||||
: state.project.calculation;
|
||||
const errors = [...(totals?.errors || []), ...(output?.errors || [])];
|
||||
const source = `<!doctype html><html lang="ko"><head><meta charset="UTF-8"><title>${esc(state.project.name)} · ${esc(title)}</title>
|
||||
<style>@page{size:${settings.paper} ${settings.orientation};margin:${settings.margin}mm}*{box-sizing:border-box}body{font:${settings.font}pt "Malgun Gothic",sans-serif;color:#111;margin:0}
|
||||
@@ -127,6 +130,10 @@ const EstReport = (() => {
|
||||
...row,
|
||||
...original.get(row.Index),
|
||||
}));
|
||||
catalog.push(
|
||||
{ Index: "progress-summary", Name: "기성 내역서", Name2: "기성 내역서" },
|
||||
{ Index: "escalation-summary", Name: "물가변동 내역서", Name2: "물가변동 내역서" },
|
||||
);
|
||||
const table = EstApp.state.project.tables[EstApp.state.view];
|
||||
const s = setting(),
|
||||
{ esc } = EstApp;
|
||||
|
||||
Reference in New Issue
Block a user