Files
Investidor-V2/tests/frontend/irpc-pec-plan.test.mjs
T
2026-11-11 10:37:33 +02:00

100 lines
3.8 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
newPecPlan,
calculatePecPlan,
validatePecPlan,
} from '../../resources/js/lib/irpc-pec-plan.ts';
import { calculatePecObligation } from '../../resources/js/lib/irpc-pec-obligation.ts';
import { plan as obligation } from './helpers/irpc-pec-obligation-case.mjs';
import { combinedCase } from './helpers/irpc-investment-combination-case.mjs';
import {
recordAnnual,
annualCurrent,
annualBook,
saveAnnualBook,
annualHtml,
} from '../../resources/js/lib/irpc-annual-settlement.ts';
const f = (n) => ({ numerator: String(n), denominator: '1' }),
three = () => ({
...newPecPlan(),
mode: 'three',
reference: 'SYNTHETIC proposed allocation29(1)',
june: '10000',
august: '15000',
october: '15000',
}),
calc = (p, total = f(40000), na = false) =>
calculatePecPlan(p, total, na, '2026');
test('three explicit positive instalments reconcile exact total without inventing equal allocation', () => {
const m = calc(three());
assert.deepEqual(m.pending, []);
assert.deepEqual(
m.rows.map((r) => r.month),
['2026-06', '2026-08', '2026-10'],
);
assert.deepEqual(
m.rows.map((r) => r.amount),
[f(10000), f(15000), f(15000)],
);
assert.equal(m.legalDeadlineValidated, false);
assert.equal(m.paymentExecuted, false);
assert.equal(m.annualDeductionCreated, false);
});
test('single option records chosen month and entire obligation but does not certify deadline', () => {
const m = calc({ ...three(), mode: 'single', singleMonth: '2026-06' });
assert.deepEqual(m.pending, []);
assert.deepEqual(m.rows, [{ month: '2026-06', amount: f(40000) }]);
assert.equal(m.legalDeadlineValidated, false);
});
test('unknown,total changed,zero,not applicable,invalid month and mismatched cents never release a reconciled schedule', () => {
for (const p of [
{ ...three(), june: '' },
{ ...three(), june: '9999.99' },
{ ...three(), june: '10000.01' },
{ ...three(), june: '0' },
{ ...three(), reference: '' },
{ ...three(), mode: 'single', singleMonth: '2025-06' },
]) {
const m = calc(p);
assert.ok(m.pending.length);
assert.equal(m.allocationReconciled, false);
assert.deepEqual(m.rows, []);
}
for (const t of [null, f(0), f(50000)])
assert.ok(calc(three(), t).pending.length);
assert.ok(calc(three(), f(40000), true).pending.length);
assert.throws(() => validatePecPlan({ ...three(), june: null }));
});
test('schedule preserves explicit option in native book and invalidates annual snapshot on edits without new paid deductions', () => {
const { d, b } = combinedCase();
b.pecObligation = { ...obligation(), subjectNuit: b.subjectNuit };
let current = recordAnnual(d, b, '2026-11-11T11:00:00Z');
current.pecObligation.plan = three();
assert.equal(annualCurrent(d, current), false);
current = recordAnnual(d, current, '2026-11-11T11:01:00Z');
d.modelo_a_snapshot = saveAnnualBook(d, current);
const back = annualBook(d);
assert.equal(annualCurrent(d, back), true);
assert.deepEqual(back.result.model.arithmeticBalance, f(138));
assert.deepEqual(back.pecPayments, b.pecPayments);
assert.equal(back.history.length, 1);
assert.match(annualHtml(d), /PEC — projecção de tesouraria/);
back.pecObligation.previousTurnover = '20000000';
assert.ok(
calculatePecPlan(
back.pecObligation.plan,
calculatePecObligation(
back.pecObligation,
back.subjectNuit,
back.year,
back.assessment,
).total,
false,
'2026',
).pending.length,
);
assert.equal(annualCurrent(d, back), false);
});