Files
Investidor-V2/tests/frontend/iva-export-direct.test.mjs
T

34 lines
4.1 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { directExportTreatments } from '../../resources/js/lib/iva-export-operations.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-g3-inputs.json',import.meta.url),'utf8'));
function row(rule,index=0){return {...newSalesOperation(`g4a-${index}`,'2026-11','MZN'),description:`SYNTHETIC QA — ${rule.label}`,establishment:'SYNTHETIC QA estabelecimento',amount:'100',basis:index%2?'included':'net',treatment:rule.id,confirmed:rule.conditions.map((_,i)=>i),evidence:'SYNTHETIC QA — intervenientes,origem/destino e ligação descritos como pressupostos da projecção; não certificação documental'};}
function fixture(){const draft={...structuredClone(frozen),context_opportunity:'opportunity:323',project_title:'SYNTHETIC QA — G4A / Exportações directas'};const book=recordSales(draft,{currency:'MZN',rows:directExportTreatments.map(row),periods:[{period:'2026-11',complete:true}]});draft.modelo_a_snapshot=saveSalesBook(draft,book);return {draft,book};}
test('five autonomous article13 rules classify field05 only after their own facts and evidence are determined',()=>{
assert.equal(directExportTreatments.length,5);
for(const rule of directExportTreatments){const input=row(rule),result=evaluateSalesOperation(input,'MZN');assert.equal(result.field,'05');assert.equal(result.net,'100.00');assert.equal(result.vat,'0.00');assert.equal(result.gross,'100.00');assert.match(result.source,/13\(1\)/);
for(const missing of input.confirmed){const r=evaluateSalesOperation({...input,confirmed:input.confirmed.filter(i=>i!==missing)},'MZN');assert.equal(r.status,'indeterminate');assert.equal(r.vat,null);}
for(const patch of [{amount:''},{basis:''},{evidence:''},{description:''},{establishment:''},{sourceCurrency:'USD'},{period:'2025-11'}])assert.equal(evaluateSalesOperation({...input,...patch},'MZN').vat,null);
assert.equal(evaluateSalesOperation({...input,amount:'0'},'MZN').net,'0.00');
}
assert.match(directExportTreatments[0].conditions[1],/Caminhos de Ferro de Moçambique/);
assert.match(directExportTreatments[1].conditions[2],/nacionalidade/);
assert.match(directExportTreatments[2].conditions[3],/não estabelecido/);
assert.match(directExportTreatments[3].conditions[2],/Banco de Moçambique/);
assert.match(directExportTreatments[4].conditions[2],/afectação/);
});
test('missing evidence leaves period indeterminate and recalculation preserves the previous result',()=>{
const {draft,book}=fixture();const next=recordSales(draft,{...book,rows:book.rows.map((r,i)=>i===2?{...r,evidence:''}:r)});assert.equal(next.result.periods[0].fields['05'],null);assert.deepEqual(next.history.at(-1),book.result);
assert.equal(book.result.periods[0].fields['05'],'500.00');assert.equal(book.result.periods[0].fields['01'],'0.00');
});
test('snapshot/report retain context and sources while all14 delivered books stay byte-equivalent and current',()=>{
const {draft,book}=fixture();assert.equal(salesCurrent(draft,book),true);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,14);
for(const [context,original]of Object.entries(before)){assert.deepEqual(after[context],original);assert.equal(salesCurrent({...draft,context_opportunity:context},after[context]),true);}
const model=createProjectDossierReport(draft,{selectedSections:new Set(['finance']),version:'QA G4A'});for(const value of ['500.00','opportunity:323','Manica','2026-11','MZN','13(1)(o)','13(1)(p)','13(1)(q)','13(1)(r)','13(1)(t)'])assert.ok(JSON.stringify(model).includes(value),value);
if(process.env.IVA_G4A_CALCULATED)fs.writeFileSync(process.env.IVA_G4A_CALCULATED,JSON.stringify(draft));
});