import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { recordSales, saveSalesBook, } from '../../resources/js/lib/iva-operations.ts'; import { recordAcquisitions, evaluateAcquisition, saveAcquisitionBook, acquisitionBook, acquisitionCurrent, acquisitionReportRows, readAcquisitionStore, } from '../../resources/js/lib/iva-acquisitions.ts'; import { saveImportExemptionBook } from '../../resources/js/lib/iva-import-exemptions.ts'; import { newAcquisitionAllocation, adoptAllocationReduced, } from '../../resources/js/lib/iva-acquisition-allocation.ts'; import { newReducedBase, reducedBaseConditions, ownReducedConditions, recordReducedBases, saveReducedBaseBook, reducedBaseBook, } from '../../resources/js/lib/iva-reduced-bases.ts'; const frozen = JSON.parse( fs.readFileSync( new URL('./fixtures/iva-l2d-preserved.json', import.meta.url), 'utf8', ), ); export function allocationFixture() { const draft = { ...structuredClone(frozen), context_opportunity: 'opportunity:370', project_title: 'SYNTHETIC QA — L2-D afectação e proporções', }; const store = JSON.parse(frozen.modelo_a_snapshot); draft.modelo_a_snapshot = saveSalesBook( draft, recordSales( draft, structuredClone(store.salesOperations['opportunity:369']), ), ); draft.modelo_a_snapshot = saveImportExemptionBook( draft, structuredClone(store.importExemptions['opportunity:369']), ); const base = store.books['opportunity:369']; const d = (method, patch = {}) => ({ ...newAcquisitionAllocation('2026-12'), method, numerator: '1', denominator: '3', unit: 'm2 utilizados', scopeRef: 'SYNTHETIC QA entidade/actividades/ano2026', source: 'SYNTHETIC QA contabilidade/critério', communicationRef: 'SYNTHETIC QA comunicação prévia22(2)', noExcludedPayments: 'yes', basis: 'prior_year', facts: { scopeConfirmed: 'yes', rightBasis: 'yes', actualScope: 'yes', communication: 'yes', conditionsMet: 'yes', annualScope: 'yes', netExclusions: 'yes', }, ...patch, }); const row = (id, method = 'actual', patch = {}, dpatch = {}) => ({ ...structuredClone(base.rows[3]), id, description: 'SYNTHETIC QA ' + id, documentRef: 'SYNTHETIC QA ' + id, deductionLink: undefined, allocation: 'mixed', d: d(method, dpatch), ...patch, }); const imported = { ...structuredClone(base.rows[0]), id: 'imported', deductionLink: undefined, allocation: 'mixed', d: d('pro_rata', { numerator: '2', denominator: '3' }), }; const book = { currency: 'MZN', rightVersion: 'acquisition-operation-right/1', taxpayerRegistered: 'yes', rows: [ row('actual'), row('pro-rata', 'pro_rata'), row('diesel', 'actual', { bc: { ...base.rows[1].bc } }), imported, ], periods: structuredClone(base.periods), }; return { draft, book, row, d }; } void test('actual allocation uses exact fraction and prior communication,without inventing approval or bypassing C', () => { const { draft, row } = allocationFixture(); const r = row('actual'); let value = evaluateAcquisition(r, 'MZN', 'yes', draft); assert.deepEqual(value.deductibleExact, { numerator: '16', denominator: '3', }); assert.deepEqual(value.nonDeductibleExact, { numerator: '32', denominator: '3', }); assert.equal(value.eligibility.status, 'eligible'); for (const patch of [ { numerator: '' }, { denominator: '0' }, { denominator: '0.1' }, { unit: '' }, { communicationRef: '' }, { scopeRef: '' }, { source: '' }, { facts: { ...r.d.facts, communication: '' } }, { facts: { ...r.d.facts, conditionsMet: '' } }, { facts: { ...r.d.facts, rightBasis: '' } }, ]) assert.equal( evaluateAcquisition( { ...r, d: { ...r.d, ...patch } }, 'MZN', 'yes', draft, ).deductible, null, JSON.stringify(patch), ); for (const patch of [ { held: '' }, { documentRef: '' }, { legalDocument: '' }, { documentDate: '2026-11-10' }, ]) assert.equal( evaluateAcquisition({ ...r, ...patch }, 'MZN', 'yes', draft) .deductible, null, ); assert.equal( evaluateAcquisition( { ...r, bc: { ...r.bc, expense: 'travel' } }, 'MZN', 'yes', draft, ).deductible, '0.00', ); assert.equal( evaluateAcquisition( { ...r, bc: { ...r.bc, reducedSupply: 'yes' } }, 'MZN', 'yes', draft, ).deductible, '0.00', ); }); void test('pro rata uses annual prior year or declared initial estimate;ceil hundredth is preserved separately from money', () => { const { draft, row } = allocationFixture(); const r = row('pro', 'pro_rata'); const calc = (patch) => evaluateAcquisition( { ...r, d: { ...r.d, ...patch } }, 'MZN', 'yes', draft, ); const v = calc({}); assert.deepEqual(v.allocationCalculation.rawRatio, { numerator: '1', denominator: '3', }); assert.deepEqual(v.allocationCalculation.ratio, { numerator: '17', denominator: '50', }); assert.equal(v.deductible, '5.44'); assert.match(v.reason, /34%/); assert.equal(calc({ numerator: '0' }).deductible, '0.00'); assert.equal(calc({ numerator: '3' }).deductible, '16.00'); assert.equal(calc({ numerator: '1', denominator: '2' }).deductible, '8.00'); for (const patch of [ { referenceYear: '2026' }, { actualRequired: 'yes' }, { basis: '' }, { facts: { ...r.d.facts, annualScope: '' } }, { facts: { ...r.d.facts, netExclusions: '' } }, ]) assert.equal(calc(patch).deductible, null, JSON.stringify(patch)); const initial = { basis: 'initial_changed', referenceYear: '2026', declarationRef: 'SYNTHETIC QA início/alteração', facts: { ...r.d.facts, initialChanged: 'yes' }, }; assert.equal(calc(initial).deductible, '5.44'); assert.equal(calc({ ...initial, declarationRef: '' }).deductible, null); }); void test('F composes C diesel only once with D and import11,keeps exact fractions and unknown dependencies', () => { const { draft, book } = allocationFixture(); const result = recordAcquisitions(draft, book).result; assert.deepEqual(result.rows[2].allocationCalculation.before, { numerator: '8', denominator: '1', }); assert.deepEqual(result.rows[2].deductibleExact, { numerator: '8', denominator: '3', }); assert.deepEqual( ['09', '11', '14', '15', '16', '17', '18'].map( (k) => result.periods[0].fields[k], ), ['13.44', '10.72', '1000.00', '24.16', '160.00', '135.84', '0.00'], ); const incomplete = structuredClone(book); incomplete.rows[0].d.denominator = '0'; assert.equal( recordAcquisitions(draft, incomplete).result.periods[0].fields['15'], null, ); const coverage = structuredClone(book); coverage.periods[0].importsComplete = false; assert.equal( recordAcquisitions(draft, coverage).result.periods[0].fields['17'], null, ); const duplicate = structuredClone(book); duplicate.rows.push({ ...book.rows[0], id: 'duplicate' }); assert.throws(() => recordAcquisitions(draft, duplicate), /repetido/); const saved = recordAcquisitions(draft, book); draft.modelo_a_snapshot = saveAcquisitionBook(draft, saved); addReduced(draft); assert.equal(acquisitionCurrent(draft, saved), false); const outputGap = recordAcquisitions(draft, saved).result; assert.equal(outputGap.periods[0].fields['15'], '24.16'); assert.equal(outputGap.periods[0].fields['16'], null); }); function addReduced(draft) { const rows = [ 'regulated_energy', 'aeronautical_fees', 'public_works', 'public_water', ].map((t) => ({ ...newReducedBase(t, 'MZN'), treatment: t, description: 'SYNTHETIC QA ' + t, period: '2026-12', operationDate: '2026-12-10', documentDate: '2026-12-10', documentRef: 'SYNTHETIC QA ' + t, priceRef: 'SYNTHETIC QA preço/taxa', priceFrom: '2026-01-01', priceScope: 'SYNTHETIC QA âmbito', consideration: '100', projectRef: 'SYNTHETIC QA contrato público', workCategory: 'roads', compositionRef: 'SYNTHETIC QA composição semIVA', evidence: 'SYNTHETIC QA condições', conditions: Object.fromEntries( [...reducedBaseConditions, ...ownReducedConditions(t)].map( ([key]) => [key, 'yes'], ), ), })); draft.modelo_a_snapshot = saveReducedBaseBook( draft, recordReducedBases(draft, { rows }), ); } void test('18(6) reuses all four demonstrated reduced bases;no double base reduction or invented output tax', () => { const { draft, row } = allocationFixture(); addReduced(draft); const expected = { regulated_energy: '9.92', aeronautical_fees: '13.60', public_works: '6.40', public_water: '12.00', }; for (const [id, value] of Object.entries(expected)) { const r = row('purchase-' + id, 'reduced', { allocation: 'taxable_only', }); r.d = adoptAllocationReduced(draft, r.d, id); r.d.facts.scopeConfirmed = 'yes'; const result = evaluateAcquisition(r, 'MZN', 'yes', draft); assert.equal(result.deductible, value, id); assert.equal(r.net, '100'); assert.equal(r.vat, '16'); const book = recordAcquisitions(draft, { currency: 'MZN', taxpayerRegistered: 'yes', rows: [r], periods: [ { period: '2026-12', complete: true, importsComplete: true, absent: ['12', '13'], }, ], }); assert.equal(book.result.periods[0].fields['15'], value); for (const f of ['14', '16', '17', '18']) assert.equal(book.result.periods[0].fields[f], null, f); const saved = { ...draft, modelo_a_snapshot: saveAcquisitionBook(draft, book), }; assert.ok(acquisitionCurrent(saved, book)); const removed = { ...saved, modelo_a_snapshot: saveReducedBaseBook(saved, { rows: reducedBaseBook(saved).rows, }), }; assert.equal(acquisitionCurrent(removed, book), false); assert.equal( evaluateAcquisition( { ...r, allocation: 'mixed' }, 'MZN', 'yes', draft, ).deductible, null, ); const changed = reducedBaseBook(draft); changed.rows.find((x) => x.id === id).description += ' alteração'; const other = { ...draft, modelo_a_snapshot: saveReducedBaseBook( draft, recordReducedBases(draft, changed), ), }; assert.equal( evaluateAcquisition(r, 'MZN', 'yes', other).deductible, null, ); } }); void test('save recovery/report preserves every prior ABC/L1 book and frozen D histories;no automatic recalculation', () => { let { draft, book } = allocationFixture(); const prior = JSON.parse(frozen.modelo_a_snapshot); book = recordAcquisitions(draft, book); draft.modelo_a_snapshot = saveAcquisitionBook(draft, book); const first = structuredClone(book.result); book = recordAcquisitions(draft, book); draft.modelo_a_snapshot = saveAcquisitionBook(draft, book); const recovered = JSON.parse(JSON.stringify(draft)); assert.ok(acquisitionCurrent(recovered, acquisitionBook(recovered))); assert.deepEqual(book.history, [first]); const current = JSON.parse(draft.modelo_a_snapshot); for (const k of Object.keys(prior).filter((k) => k !== 'version')) for (const [id, v] of Object.entries(prior[k])) assert.deepEqual(current[k][id], v, k + id); for (const scope of ['opportunity:368', 'opportunity:369']) assert.ok( acquisitionCurrent( { ...recovered, context_opportunity: scope }, prior.books[scope], ), ); const report = JSON.stringify(acquisitionReportRows(recovered)); for (const token of [ 'AfectaçãoD', '16/3', '1/3', '34%', '24.16', '135.84', '22(2)', ]) assert.ok(report.includes(token), token); book.rows[0].d.numerator = '2'; draft.modelo_a_snapshot = saveAcquisitionBook(draft, book); assert.equal(acquisitionCurrent(draft, book), false); assert.deepEqual(book.history, [first]); assert.match( JSON.stringify(acquisitionReportRows(draft)), /Histórico desactualizado/, ); const broken = JSON.parse(recovered.modelo_a_snapshot); broken.books['opportunity:370'].rows[0].d.facts.scopeConfirmed = 'maybe'; assert.throws( () => readAcquisitionStore(JSON.stringify(broken)), /AfectaçãoD/, ); if (process.env.IVA_L2D_CALCULATED) { const special = { ...recovered, context_opportunity: 'opportunity:371', }; special.modelo_a_snapshot = saveSalesBook( special, recordSales( special, structuredClone(current.salesOperations['opportunity:370']), ), ); addReduced(special); const reduced = allocationFixture().row( 'reduced-public-works', 'reduced', { allocation: 'taxable_only' }, ); reduced.d = adoptAllocationReduced(special, reduced.d, 'public_works'); reduced.d.facts.scopeConfirmed = 'yes'; const reducedBook = recordAcquisitions(special, { currency: 'MZN', taxpayerRegistered: 'yes', rows: [reduced], periods: [ { period: '2026-12', complete: true, importsComplete: true, absent: ['12', '13'], }, ], }); special.modelo_a_snapshot = saveAcquisitionBook(special, reducedBook); fs.writeFileSync( process.env.IVA_L2D_CALCULATED, JSON.stringify({ ...special, context_opportunity: 'opportunity:370', }), ); } });