44 lines
2.3 KiB
JavaScript
44 lines
2.3 KiB
JavaScript
// EST 보고서의 성분별 행 절사와 원 미만 합계 절사를 참고한 테스트 계산.
|
|
// shortcut: 실제 EST의 모든 자릿수·비율 옵션은 미구현, 원본 대조 시 확장.
|
|
const EstCalc = (() => {
|
|
const kinds = ['재료비', '노무비', '경비'];
|
|
const trunc = n => Math.trunc((Number(n) || 0) * 100) / 100;
|
|
function calculate(data) {
|
|
const prices = Object.fromEntries(data.sources.map(s => [s.id, s]));
|
|
const units = Object.fromEntries(data.units.map(u => {
|
|
const parts = Object.fromEntries(kinds.map(k => [k, 0]));
|
|
const lines = u.lines.map(line => {
|
|
const source = prices[line.sourceId];
|
|
const amount = source ? trunc(source.price * line.quantity) : 0;
|
|
if (source) parts[source.kind] += amount;
|
|
return { source, amount };
|
|
});
|
|
for (const k of kinds) parts[k] = Math.trunc(parts[k]);
|
|
return [u.id, { parts, lines, total: kinds.reduce((sum, k) => sum + parts[k], 0) }];
|
|
}));
|
|
const direct = Object.fromEntries(kinds.map(k => [k, 0]));
|
|
const rows = data.estimate.map(row => {
|
|
const unit = units[row.unitId];
|
|
const parts = Object.fromEntries(kinds.map(k => [k, unit ? Math.trunc(unit.parts[k] * row.quantity) : 0]));
|
|
for (const k of kinds) direct[k] += parts[k];
|
|
return { parts, total: kinds.reduce((sum, k) => sum + parts[k], 0) };
|
|
});
|
|
const directTotal = kinds.reduce((sum, k) => sum + direct[k], 0);
|
|
let running = directTotal;
|
|
const costs = data.costs.map(row => {
|
|
const base = row.base === '누계' ? running : row.base === '직접공사비' ? directTotal : direct[row.base] || 0;
|
|
const amount = Math.trunc(base * row.rate / 100);
|
|
running += amount;
|
|
return { base, amount, running };
|
|
});
|
|
return { units, rows, direct, directTotal, costs, total: running };
|
|
}
|
|
function progress(unitPrice, previous, current, approved, useApproved) {
|
|
const accepted = useApproved ? approved : current;
|
|
const cumulative = previous + accepted;
|
|
return { currentAmount: Math.trunc(unitPrice * current), approvedAmount: Math.trunc(unitPrice * approved), cumulative, cumulativeAmount: Math.trunc(unitPrice * cumulative) };
|
|
}
|
|
return { kinds, calculate, progress };
|
|
})();
|
|
if (typeof module !== 'undefined') module.exports = EstCalc;
|