Files
Investidor-V2/tests/frontend/iva-acquisition-continuity.test.mjs
T

42 lines
5.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { acquisitionTreatmentIssue,continueWithoutFormerExploration,formerExplorationSource } from '../../resources/js/lib/iva-acquisition-continuity.ts';
import { newAcquisition,evaluateAcquisition,recordAcquisitions,acquisitionBook,acquisitionCurrent,saveAcquisitionBook,acquisitionReportRows } from '../../resources/js/lib/iva-acquisitions.ts';
import { 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-g5a-inputs.json',import.meta.url),'utf8'));
const row=()=>({...newAcquisition('g5b-0','2026-12','MZN'),field:'10',net:'100',vat:'16',gross:'116',documentType:'invoice',documentRef:'SYNTHETIC QA G5B 001',documentDate:'2026-12-10',supplier:'SYNTHETIC QA fornecedor',supplierRegistered:'yes',legalDocument:'yes',held:'yes',domestic:'yes',allocation:'taxable_only',exclusion:'none',integrity:'yes',description:'SYNTHETIC QA — serviço de pesquisa; antiga referência14(2)(c)',acquisitionTreatment:'former_exploration_exemption'});
function fixture(){
const draft={...structuredClone(frozen),context_opportunity:'opportunity:329',project_title:'SYNTHETIC QA — G5B / Continuidade da aquisição'};
const prior=recordAcquisitions(draft,{currency:'MZN',taxpayerRegistered:'yes',rows:[row()],periods:[{period:'2026-12',complete:true,absent:[]}]});draft.modelo_a_snapshot=saveAcquisitionBook(draft,prior);return{draft,prior};
}
test('2017 rectification prevents former14(2)(c) exemption in2026,including explicit zero;unknown is not a normal treatment',()=>{
assert.match(formerExplorationSource,/BR89/);assert.match(acquisitionTreatmentIssue('former_exploration_exemption'),/eliminada/);
for(const vat of ['16','0','']){const input={...row(),vat,gross:vat==='0'?'100':'116'},result=evaluateAcquisition(input,'MZN','yes');assert.equal(result.deductible,null);assert.match(result.reason,/Não se aplica nesta cobertura2026/);assert.equal(input.net,'100');}
assert.equal(evaluateAcquisition({...row(),acquisitionTreatment:'unknown'},'MZN','yes').deductible,null);
assert.match(evaluateAcquisition({...row(),period:'2016-12'},'MZN','yes').reason,/fora do âmbito/);
});
test('explicit continuation keeps values,document,answers and source;normal deduction requires existing conditions',()=>{
const input=row(),next=continueWithoutFormerExploration(input);for(const key of Object.keys(input).filter(k=>k!=='acquisitionTreatment'))assert.deepEqual(next[key],input[key],key);
assert.equal(input.acquisitionTreatment,'former_exploration_exemption');assert.equal(next.acquisitionTreatment,'normal');assert.equal(next.acquisitionTreatmentOrigin.id,'former_exploration_exemption');
assert.equal(evaluateAcquisition(next,'MZN','yes').deductible,'16.00');
for(const patch of [{held:''},{allocation:'mixed'},{legalDocument:''},{sourceCurrency:'USD'},{vat:'',gross:''},{domestic:'no'},{documentDate:'2026-11-10'}])assert.equal(evaluateAcquisition({...next,...patch},'MZN','yes').deductible,null);
assert.throws(()=>continueWithoutFormerExploration({...input,acquisitionTreatment:'normal'}),/antiga referência/);
});
test('manual purchase month does not require sales;previous classification remains in history and incomplete totals remain unknown',()=>{
const{draft,prior}=fixture();assert.equal(draft.monthly_iva_settings,undefined);assert.equal(prior.result.rows[0].deductible,null);assert.equal(prior.result.periods[0].fields['10'],null);
const next=recordAcquisitions(draft,{...prior,rows:[continueWithoutFormerExploration(prior.rows[0])]});assert.deepEqual(next.history,[prior.result]);assert.equal(next.result.rows[0].deductible,'16.00');assert.equal(next.result.periods[0].fields['10'],'16.00');
for(const f of ['01','02','11','14','15','16','17','18'])assert.equal(next.result.periods[0].fields[f],null,f);
assert.throws(()=>recordAcquisitions(draft,{...next,periods:[]}),/meses aplicáveis/);assert.throws(()=>recordAcquisitions(draft,{...next,periods:[...next.periods,...next.periods]}),/meses aplicáveis/);
assert.throws(()=>recordAcquisitions(draft,{...next,rows:[{...next.rows[0],sourceMonth:1,sourceAmount:'100',sourceBasis:'net'}]}),/orçamentos do plano mudaram/);
});
test('save/recovery/report retain rectification,continuation and history;all20 prior sales books stay identical/current',()=>{
const{draft,prior}=fixture();const book=recordAcquisitions(draft,{...prior,rows:[continueWithoutFormerExploration(prior.rows[0])]});draft.modelo_a_snapshot=saveAcquisitionBook(draft,book);assert.ok(acquisitionCurrent(draft,book));assert.deepEqual(acquisitionBook(JSON.parse(JSON.stringify(draft))),JSON.parse(JSON.stringify(book)));
const before=JSON.parse(frozen.modelo_a_snapshot),after=JSON.parse(draft.modelo_a_snapshot);assert.equal(Object.keys(before.salesOperations).length,20);assert.deepEqual(after.salesOperations,before.salesOperations);assert.deepEqual(Object.keys(after.books),['opportunity:329']);
for(const[context,original]of Object.entries(before.salesOperations))assert.ok(salesCurrent({...draft,context_opportunity:context},original));
const report=JSON.stringify(createProjectDossierReport(draft,{selectedSections:new Set(['finance']),version:'QA G5B'}));for(const token of ['opportunity:329','Manica','2026-12','16.00','BR89','Continuidade14(2)(c)','eliminado','expressamente escolhida'])assert.ok(report.includes(token),token);
assert.match(JSON.stringify(acquisitionReportRows(draft)),/antiga isenção/);
if(process.env.IVA_G5B_CALCULATED)fs.writeFileSync(process.env.IVA_G5B_CALCULATED,JSON.stringify(draft));
});