import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { specialRegimeTreatments as rules, specialRegimeOptions, specialRegimesFor, specialRegimeIssue, } from '../../resources/js/lib/iva-special-regimes.ts'; import { newSalesOperation, evaluateSalesOperation, recordSales, saveSalesBook, salesBook, salesCurrent, } from '../../resources/js/lib/iva-operations.ts'; import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts'; const frozen = JSON.parse( fs.readFileSync( new URL('./fixtures/iva-g4e-inputs.json', import.meta.url), 'utf8', ), ); const regimes = [ 'economic_zone', 'customs_warehouse', 'free_zone', 'duty_free_shop', 'transit', 'temporary_import', ]; const row = (rule, i) => ({ ...newSalesOperation(`g5a-${i}`, '2026-12', 'MZN'), description: `SYNTHETIC QA — ${rule.label}`, establishment: 'SYNTHETIC QA estabelecimento', amount: '100', basis: i % 2 ? 'included' : 'net', treatment: rule.id, specialRegime: regimes[i], confirmed: rule.conditions.map((_, n) => n), evidence: 'SYNTHETIC QA — pressuposto expresso de projecção: bens e operação identificados; regime e controlo/documento, destino, permanência no período, ausência de utilização/consumo final e ligação directa do serviço/transporte identificados. Cada linha tem preço próprio, sem duplicar bens. Sem certificação real.', }); function fixture() { const draft = { ...structuredClone(frozen), context_opportunity: 'opportunity:328', project_title: 'SYNTHETIC QA — G5A / Regimes especiais', }; const book = recordSales(draft, { currency: 'MZN', rows: rules.map(row), periods: [{ period: '2026-12', complete: true }], }); draft.modelo_a_snapshot = saveSalesBook(draft, book); return { draft, book }; } void test('three branches/six goods-service treatments require own conditions,no final use and identified regime', () => { assert.equal(rules.length, 6); for (const [i, rule] of rules.entries()) { const input = row(rule, i), result = evaluateSalesOperation(input, 'MZN'); assert.equal(result.field, '05'); assert.equal(result.vat, '0.00'); assert.equal(result.net, '100.00'); assert.equal(result.gross, '100.00'); assert.match(result.article, /19\(1\)\(b\)\(iv\)/); for (const missing of input.confirmed) assert.equal( evaluateSalesOperation( { ...input, confirmed: input.confirmed.filter((n) => n !== missing), }, 'MZN', ).vat, null, ); for (const patch of [ { amount: '' }, { evidence: '' }, { sourceCurrency: 'USD' }, { period: '2027-01' }, { basis: '' }, { description: '' }, { establishment: '' }, ]) assert.equal( evaluateSalesOperation({ ...input, ...patch }, 'MZN').vat, null, ); assert.match( rule.conditions.join(' '), /não têm utilização nem consumo finais/, ); } }); void test('regimes from another paragraph or unknown are indeterminate;destination and service conditions remain distinct', () => { for (const [i, rule] of rules.entries()) { for (const [regime] of specialRegimeOptions) { const result = evaluateSalesOperation( { ...row(rule, i), specialRegime: regime }, 'MZN', ); const allowed = specialRegimesFor(rule.id).some( ([id]) => id === regime, ); assert.equal(result.vat, allowed ? '0.00' : null); if (!allowed) { assert.equal(result.net, null); assert.equal(result.field, null); } } for (const regime of [undefined, '', null, 'other']) assert.equal( evaluateSalesOperation( { ...row(rule, i), specialRegime: regime }, 'MZN', ).vat, null, ); } assert.match( rules[0].conditions.join(' '), /loja franca por si não comprova/, ); assert.equal( evaluateSalesOperation( { ...row(rules[0], 0), specialRegime: 'duty_free_shop', confirmed: [0, 1, 3], }, 'MZN', ).vat, null, ); assert.equal( specialRegimeIssue('regime_internal_goods', 'duty_free_shop'), null, ); assert.equal(specialRegimeIssue('general', undefined), null); assert.deepEqual(specialRegimesFor('general'), []); }); void test('change of regime or ending eligibility preserves price,context/history and blocks presumptive totals', () => { const { draft, book } = fixture(); assert.equal(book.result.periods[0].fields['05'], '600.00'); for (const patch of [ { specialRegime: 'transit', confirmed: [] }, { specialRegime: '', confirmed: [] }, { confirmed: [], evidence: 'Regime terminado; rever enquadramento' }, ]) { const changed = recordSales(draft, { ...book, rows: book.rows.map((r, i) => (i === 0 ? { ...r, ...patch } : r)), }); assert.equal(changed.rows[0].amount, '100'); assert.equal(changed.rows[0].sourceCurrency, 'MZN'); assert.equal(changed.rows[0].period, '2026-12'); assert.equal(changed.result.periods[0].fields['05'], null); assert.deepEqual(changed.history.at(-1), book.result); const edited = { ...draft, modelo_a_snapshot: saveSalesBook(draft, { ...book, rows: changed.rows, }), }; assert.equal(salesCurrent(edited, salesBook(edited)), false); } }); void test('snapshot/report retain regime,source and assumptions;all19 previous books are identical/current without recalculation', () => { const { draft, book } = fixture(); assert.ok(salesCurrent(draft, book)); assert.deepEqual( salesBook(JSON.parse(JSON.stringify(draft))), JSON.parse(JSON.stringify(book)), ); const before = JSON.parse(frozen.modelo_a_snapshot).salesOperations, after = JSON.parse(draft.modelo_a_snapshot).salesOperations; assert.equal(Object.keys(before).length, 19); for (const [context, original] of Object.entries(before)) { assert.deepEqual(after[context], original); assert.ok( salesCurrent( { ...draft, context_opportunity: context }, after[context], ), ); } const report = JSON.stringify( createProjectDossierReport(draft, { selectedSections: new Set(['finance']), version: 'QA G5A', }), ); for (const token of [ 'opportunity:328', 'Manica', '2026-12', '600.00', '14(1)(b)', '14(1)(c)', '14(1)(d)', '19(1)(b)(iv)', 'Regime especial', 'Importação temporária', 'Loja franca', 'pressuposto expresso', 'QA G5A', ]) assert.ok(report.includes(token), token); if (process.env.IVA_G5A_CALCULATED) fs.writeFileSync(process.env.IVA_G5A_CALCULATED, JSON.stringify(draft)); });