126 lines
4.1 KiB
JavaScript
126 lines
4.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import fs from 'node:fs';
|
|
import {
|
|
operationTreatments,
|
|
newSalesOperation,
|
|
evaluateSalesOperation,
|
|
recordSales,
|
|
saveSalesBook,
|
|
salesBook,
|
|
salesCurrent,
|
|
} from '../../resources/js/lib/iva-operations.ts';
|
|
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
|
const ids = [
|
|
'financial_stamp',
|
|
'insurance_stamp',
|
|
'public_waste',
|
|
'public_funeral',
|
|
];
|
|
function fixture() {
|
|
const draft = {
|
|
purpose: 'simulate_only',
|
|
currency: 'MZN',
|
|
context_opportunity: 'opportunity:310',
|
|
project_title: 'SYNTHETIC QA — G1 serviços isentos',
|
|
province_id: 'cf5e81f1-ffbc-535d-b1b6-b44b445c4421',
|
|
selection_labels: { province_id: 'Manica' },
|
|
};
|
|
let book = {
|
|
currency: 'MZN',
|
|
rows: ids.map((id, i) => ({
|
|
...newSalesOperation(`g1-${i}`, '2026-01', 'MZN'),
|
|
description: `SYNTHETIC QA ${id}`,
|
|
establishment: 'SYNTHETIC QA estabelecimento',
|
|
amount: '100',
|
|
basis: 'net',
|
|
treatment: id,
|
|
confirmed: [0, 1],
|
|
evidence:
|
|
'SYNTHETIC QA — condições documentadas pressupostas, sem certificação',
|
|
})),
|
|
periods: [{ period: '2026-01', complete: true }],
|
|
};
|
|
book = recordSales(draft, book);
|
|
draft.modelo_a_snapshot = saveSalesBook(draft, book);
|
|
return { draft, book };
|
|
}
|
|
void test('G1 four documented operations use the same conditions and persistence, with independent applicability', () => {
|
|
const { draft, book } = fixture();
|
|
for (const row of book.rows) {
|
|
const r = evaluateSalesOperation(row, 'MZN');
|
|
assert.equal(r.vat, '0.00');
|
|
assert.equal(r.field, '07');
|
|
assert.match(r.article, /9\(/);
|
|
assert.match(r.source, /Lei22/);
|
|
assert.equal(
|
|
evaluateSalesOperation({ ...row, confirmed: [0] }, 'MZN').vat,
|
|
null,
|
|
);
|
|
assert.equal(
|
|
evaluateSalesOperation({ ...row, evidence: '' }, 'MZN').vat,
|
|
null,
|
|
);
|
|
}
|
|
assert.equal(book.result.periods[0].fields['07'], '400.00');
|
|
const recovered = JSON.parse(JSON.stringify(draft));
|
|
assert.equal(salesCurrent(recovered, salesBook(recovered)), true);
|
|
assert.match(
|
|
JSON.stringify(
|
|
createProjectDossierReport(recovered, {
|
|
selectedSections: new Set(['finance']),
|
|
}),
|
|
),
|
|
/400\.00/,
|
|
);
|
|
assert.equal(
|
|
salesCurrent({ ...recovered, currency: 'USD' }, salesBook(recovered)),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
salesCurrent(
|
|
{ ...recovered, context_opportunity: 'opportunity:309' },
|
|
salesBook(recovered),
|
|
),
|
|
false,
|
|
);
|
|
const rule = operationTreatments.find((t) => t.id === 'financial_stamp');
|
|
const source = rule.source;
|
|
try {
|
|
rule.source += ' — changed source';
|
|
assert.equal(salesCurrent(recovered, salesBook(recovered)), false);
|
|
} finally {
|
|
rule.source = source;
|
|
}
|
|
});
|
|
void test('adding independent catalogue rules does not invalidate or recalculate accepted rational snapshots', () => {
|
|
const draft = JSON.parse(
|
|
fs.readFileSync(
|
|
new URL('./fixtures/iva-rational.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
const original = draft.modelo_a_snapshot;
|
|
assert.equal(salesCurrent(draft, salesBook(draft)), true);
|
|
assert.equal(draft.modelo_a_snapshot, original);
|
|
assert.equal(
|
|
operationTreatments.filter((t) => ids.includes(t.id)).length,
|
|
4,
|
|
);
|
|
operationTreatments.push({
|
|
...operationTreatments[0],
|
|
id: 'synthetic_future_independent',
|
|
});
|
|
try {
|
|
assert.equal(salesCurrent(draft, salesBook(draft)), true);
|
|
assert.equal(draft.modelo_a_snapshot, original);
|
|
} finally {
|
|
operationTreatments.pop();
|
|
}
|
|
});
|
|
if (process.env.IVA_G1_OUT)
|
|
fs.writeFileSync(
|
|
process.env.IVA_G1_OUT,
|
|
JSON.stringify(fixture().draft, null, 2),
|
|
);
|