100 lines
3.8 KiB
JavaScript
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);
|
|
});
|