Files
Investidor-V2/tests/frontend/iva-international-assets.test.mjs
T

27 lines
4.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { internationalAssetTreatments } from '../../resources/js/lib/iva-international-assets.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-g4a-inputs.json',import.meta.url),'utf8'));
const row=(rule,i)=>({...newSalesOperation(`g4b-${i}`,'2026-12','MZN'),description:`SYNTHETIC QA — ${rule.label}`,establishment:'SYNTHETIC QA estabelecimento',amount:'100',basis:i%2?'included':'net',treatment:rule.id,confirmed:rule.conditions.map((_,n)=>n),evidence:'SYNTHETIC QA:embarcação/avião,operador,utilização e ligação da operação expressamente pressupostos;sem certificação de matrícula ou documentos'});
function fixture(){const draft={...structuredClone(frozen),context_opportunity:'opportunity:324',project_title:'SYNTHETIC QA — G4B / Embarcações e aviões'};const book=recordSales(draft,{currency:'MZN',rows:internationalAssetTreatments.map(row),periods:[{period:'2026-12',complete:true}]});draft.modelo_a_snapshot=saveSalesBook(draft,book);return{draft,book};}
test('three branches/four treatments require eligible asset and actual operation; all missing conditions block zero-VAT classification',()=>{
assert.equal(internationalAssetTreatments.length,4);
assert.deepEqual(internationalAssetTreatments.map(r=>r.article),['CIVA arts.13(1)(f),19(1)(b)(i)','CIVA arts.13(1)(g),19(1)(b)(i)','CIVA arts.13(1)(i),19(1)(b)(i)','CIVA arts.13(1)(i),19(1)(b)(i)']);
for(const [i,rule]of internationalAssetTreatments.entries()){const input=row(rule,i);assert.equal(evaluateSalesOperation(input,'MZN').vat,'0.00');assert.equal(evaluateSalesOperation(input,'MZN').field,'05');for(const missing of input.confirmed){const r=evaluateSalesOperation({...input,confirmed:input.confirmed.filter(n=>n!==missing)},'MZN');assert.equal(r.vat,null);assert.equal(r.status,'indeterminate');}
for(const patch of [{evidence:''},{amount:''},{basis:''},{sourceCurrency:'USD'},{period:'2027-01'},{establishment:''}])assert.equal(evaluateSalesOperation({...input,...patch},'MZN').vat,null);
}
assert.match(internationalAssetTreatments[0].conditions[1],/alto mar/);assert.match(internationalAssetTreatments[0].conditions[1],/pesca costeira/);assert.match(internationalAssetTreatments[1].conditions[1],/principalmente/);assert.match(internationalAssetTreatments[1].conditions[2],/aluguer autónomo/);assert.match(internationalAssetTreatments[2].conditions[3],/distinto/);
});
test('unknown direct link leaves totals indeterminate and preserves the last result without recalculation of previous books',()=>{
const {draft,book}=fixture();assert.equal(book.result.periods[0].fields['05'],'400.00');const changed=recordSales(draft,{...book,rows:book.rows.map((r,i)=>i===2?{...r,confirmed:r.confirmed.filter(n=>n!==2)}:r)});assert.equal(changed.result.periods[0].fields['05'],null);assert.deepEqual(changed.history.at(-1),book.result);assert.equal(evaluateSalesOperation({...book.rows[0],amount:'0'},'MZN').net,'0.00');
});
test('stored context and report preserve sources/values and all15 delivered books remain 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,15);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 G4B'}));for(const token of ['opportunity:324','Manica','2026-12','400.00','13(1)(f)','13(1)(g)','13(1)(i)'])assert.ok(report.includes(token),token);
if(process.env.IVA_G4B_CALCULATED)fs.writeFileSync(process.env.IVA_G4B_CALCULATED,JSON.stringify(draft));
});