fix(est): match repeated escalation items

This commit is contained in:
2026-11-07 10:40:30 +09:00
parent c1a4b9a178
commit 7422a70ac4
3 changed files with 38 additions and 11 deletions
@@ -1,6 +1,25 @@
from test_est_rea_parity import run
def test_escalation_distinguishes_repeated_codes_without_row_ids():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.options.SourceRefresh=false;p.options.EscDesignTotal=1000;
p.tables.EstMainDat=[{Code:'A',Name:'first',GN:10,GU:80},
{Code:'A',Name:'second',GN:20,GU:50},{LinkIndex:54}];
const q=EstBusiness.baseline(EstNative.calculate(p));
Object.assign(q.tables.EstMainDat[0],{AGU:100,GU:120,EscActual:2});
Object.assign(q.tables.EstMainDat[1],{AGU:100,GU:120,EscActual:5});
return EstEscalation.calculate(q);
})()""",
)
assert [row["EscApplied"] for row in result["rows"][:2]] == [8, 15]
assert [row["EGU"] for row in result["rows"][:2]] == [16, 10]
assert [row["ContractGU"] for row in result["rows"][:2]] == [80, 50]
assert result["excludedTotal"] == 410
def test_progress_exclusions_preserve_new_rows_and_reject_ambiguous_keys():
result = run(
"math",
+17 -5
View File
@@ -16,11 +16,23 @@ const EstEscalation = (() => {
if (row[field + "_"] != null) old[field] = row[field + "_"];
return old;
});
const contracts = new Map(original.map((row, index) => [key(row, index), row]));
const identities = (items) => {
const counts = new Map();
return items.map((row, index) => {
const id = key(row, index),
occurrence = counts.get(id) || 0;
counts.set(id, occurrence + 1);
return JSON.stringify([id, occurrence]);
});
};
const originalKeys = identities(original),
rowKeys = identities(rows);
const contracts = new Map(original.map((row, index) => [originalKeys[index], row]));
const design = structuredClone(original),
excluded = structuredClone(original);
rows.forEach((row, index) => {
const old = contracts.get(key(row, index)) || row;
const old = contracts.get(rowKeys[index]) || row;
units.forEach((unit) => (row[`Contract${unit}`] = num(old[unit])));
const auto = row.EscAuto !== false;
const quantity = auto
? Math.max(num(row.EscPlanned), num(row.EscActual), num(row.EscProgress))
@@ -48,10 +60,10 @@ const EstEscalation = (() => {
});
if (![1, 3].includes(num(row.CalcIndex))) row.TC = sum(row);
});
const current = new Map(rows.map((row, index) => [key(row, index), row]));
const current = new Map(rows.map((row, index) => [rowKeys[index], row]));
design.forEach((row, index) => {
if (num(row.Level) > 0 || special(row)) return;
const now = current.get(key(row, index));
const now = current.get(originalKeys[index]);
if (!now) return;
units.forEach((unit) => {
if (now["A" + unit] != null) row[unit] = num(now["A" + unit]);
@@ -59,7 +71,7 @@ const EstEscalation = (() => {
});
excluded.forEach((row, index) => {
if (num(row.Level) > 0 || special(row)) return;
const now = current.get(key(row, index)),
const now = current.get(originalKeys[index]),
quantity = num(now?.EscExcluded),
oldQuantity = num(row.GN);
if ([1, 3].includes(num(row.CalcIndex))) {
+2 -6
View File
@@ -218,16 +218,12 @@ const EstExtra = (() => {
![54, 55, 58, 59].includes(Number(row.LinkIndex)),
)
.map(({ row, index }) => {
const old =
project.baseline?.tables.EstMainDat.find(
(r, i) => EstBusiness.rowKey(r, i) === EstBusiness.rowKey(row, index),
) || row,
result = output.rows[index];
const result = output.rows[index];
return [
esc(row.Code),
esc(row.Name),
EstViews.cell("EstMainDat", index, `A${comp}`, row[`A${comp}`]),
number(project.baseline ? old[comp] : (row[comp + "_"] ?? row[comp])),
number(result[`Contract${comp}`]),
EstViews.cell("EstMainDat", index, comp, row[comp]),
number(result[`D${comp}`]),
number(result[`E${comp}`]),