Files
Investidor-V2/tests/frontend/iva-goods-location.test.mjs
T

36 lines
7.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {newGoodsLocation,switchGoodsTreatment,goodsLocationTreatments,goodsLocationConditions,ownGoodsConditions,evaluateGoodsLocation,recordGoodsLocations,saveGoodsLocationBook,goodsLocationBook,goodsLocationCurrent,goodsLocationReportRows} from '../../resources/js/lib/iva-goods-location.ts';
import {serviceNormalCurrent} from '../../resources/js/lib/iva-service-normal.ts';
import {valueReviewCurrent} from '../../resources/js/lib/iva-value-review.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const frozen=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-g8a-preserved-inputs.json',import.meta.url),'utf8'));
const row=(treatment='goods_with_transport')=>({...newGoodsLocation('g8a-'+treatment),treatment,description:'SYNTHETIC QA bens A',period:'2026-12',operationDate:'2026-12-12',operationRef:'SYNTHETIC QA operação A',documentRef:'SYNTHETIC QA G8A '+treatment,documentDate:'2026-12-12',goodsPlace:'SYNTHETIC QA local físico dos bens no momento relevante',placeCountry:treatment==='goods_with_transport'?'MZ':'foreign',placeRef:'SYNTHETIC QA referência do local e momento A',transportRef:'SYNTHETIC QA transporte A',importRef:'SYNTHETIC QA importação nacional A',chainRef:'SYNTHETIC QA importador A/transmissão subsequente antes da importação',scope:'SYNTHETIC QA bens A/operação A/dezembro2026/condições A',evidence:'SYNTHETIC QA pressupostos expressos,não documento real',conditions:Object.fromEntries([...goodsLocationConditions,...ownGoodsConditions(treatment)].map(([key])=>[key,'yes']))});
const draft=()=>({...structuredClone(frozen),context_opportunity:'opportunity:348',project_title:'SYNTHETIC QA — G8A / Localização de bens'});
test('P105 each route owns facts/references;unknown/no never defaultoutside/exempt orIVA zero',()=>{
for(const t of goodsLocationTreatments){const input=row(t.id),ok=evaluateGoodsLocation(input);assert.equal(ok.territory,t.id==='goods_without_transport'?'outside':'national');assert.equal(ok.baseAmount,null);assert.equal(ok.vat,null);assert.equal(ok.rate,null);
for(const[key]of [...goodsLocationConditions,...ownGoodsConditions(t.id)])for(const value of ['','unknown','no']){const r=evaluateGoodsLocation({...input,conditions:{...input.conditions,[key]:value}});assert.equal(r.status,value==='no'?'not_applicable':'indeterminate');assert.equal(r.territory,null);assert.equal(r.vat,null);}
for(const patch of [{description:''},{operationRef:''},{documentRef:''},{documentDate:'2026-02-30'},{operationDate:'2026-11-12'},{operationDate:'2026-02-30'},{scope:''},{evidence:''},{period:'2025-12'},{treatment:''}])assert.equal(evaluateGoodsLocation({...input,...patch}).territory,null);
const required=t.id==='goods_before_import'?['transportRef','importRef','chainRef']:['goodsPlace','placeCountry','placeRef',...(t.id==='goods_with_transport'?['transportRef']:[])];for(const field of required)assert.equal(evaluateGoodsLocation({...input,[field]:''}).territory,null);
}
});
test('physical start/disposal determines6(1);preimport6(2)overridesphysicalforeign;no inference fromclient ormoney',()=>{
for(const treatment of ['goods_with_transport','goods_without_transport'])for(const placeCountry of ['MZ','foreign'])assert.equal(evaluateGoodsLocation({...row(treatment),placeCountry}).territory,placeCountry==='MZ'?'national':'outside');
const before=row('goods_before_import');assert.equal(evaluateGoodsLocation({...before,goodsPlace:'',placeCountry:'',placeRef:''}).territory,'national');assert.equal(evaluateGoodsLocation({...before,placeCountry:'foreign'}).territory,'national');assert.equal(evaluateGoodsLocation({...row(),placeCountry:'unknown'}).territory,null);
const switched=switchGoodsTreatment(row('goods_without_transport'),'goods_before_import');for(const field of ['goodsPlace','placeCountry','placeRef','transportRef','importRef','chainRef'])assert.equal(switched[field],row('goods_without_transport')[field]);assert.equal(switched.conditions.beforeImport,undefined);assert.equal(evaluateGoodsLocation(switched).territory,null);
const d=draft(),book=recordGoodsLocations(d,{rows:[row()]});assert.ok(goodsLocationCurrent({...d,currency:'USD',customer_address:'foreign',customer_nationality:'foreign'},book));
});
test('save/recovery/history/report preserve all87 delivered books/currentkeys and territorialclassification distinctfromtax',()=>{
const d=draft(),prior=JSON.parse(d.modelo_a_snapshot);assert.deepEqual(goodsLocationBook(d),{rows:[]});assert.deepEqual(goodsLocationReportRows(d),[]);
let book=recordGoodsLocations(d,{rows:goodsLocationTreatments.map(t=>({...row(t.id),conditions:{}}))});book=recordGoodsLocations(d,{...book,rows:goodsLocationTreatments.map(t=>({...row(t.id),conditions:{...row(t.id).conditions,goodsSupply:'no'}}))});book=recordGoodsLocations(d,{...book,rows:goodsLocationTreatments.map(t=>row(t.id))});assert.equal(book.history.length,2);assert.ok(book.history.every(h=>h.rows.every(r=>r.territory===null&&r.vat===null)));assert.ok(goodsLocationCurrent(d,book));
for(const field of ['treatment','placeCountry','goodsPlace','placeRef','importRef','chainRef','scope','operationDate'])assert.ok(!goodsLocationCurrent(d,{...book,rows:book.rows.map(r=>({...r,[field]:'changed'}))}));for(const patch of [{context_opportunity:'opportunity:349'},{selection_labels:{province_id:'Maputo'}}])assert.ok(!goodsLocationCurrent({...d,...patch},book));
d.modelo_a_snapshot=saveGoodsLocationBook(d,book);assert.deepEqual(goodsLocationBook(JSON.parse(JSON.stringify(d))),book);const next=JSON.parse(d.modelo_a_snapshot);const{goodsLocations,...untouched}=next;assert.deepEqual(untouched,prior);for(const[scope,previous]of Object.entries(prior.serviceNormals))assert.ok(serviceNormalCurrent({...d,context_opportunity:scope},previous));for(const[scope,previous]of Object.entries(prior.valueReviews))assert.ok(valueReviewCurrent({...d,context_opportunity:scope},previous));
assert.equal(next.serviceNormals['opportunity:347'].result.rows[2].baseAmount,'900.75');assert.equal(next.valueReviews['opportunity:346'].result.rows[1].baseAmount,'1400.75');assert.equal(next.considerationExclusions['opportunity:345'].result.rows[0].baseAmount,'799.70');assert.equal(next.books['opportunity:329'].result.periods[0].fields['11'],null);
const report=JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance']),version:'QA G8A'}));for(const token of ['Localização P105','Fora do território nacional','IVA: Indeterminado','opportunity:348','Manica','2026-12','6(1)','6(2)','importador A','não equivale a isenção','campo11'])assert.ok(report.includes(token),token);assert.deepEqual(goodsLocationReportRows({...d,context_opportunity:'opportunity:349'}),[]);
if(process.env.IVA_G8A_CALCULATED)fs.writeFileSync(process.env.IVA_G8A_CALCULATED,JSON.stringify(d));
});
test('corrupt goods rows/store cannot overwrite originals;duplicateoperationids cannotbe recorded',()=>{
const d=draft(),original=d.modelo_a_snapshot;for(const patch of [{placeCountry:4},{conditions:[]},{chainRef:null}])assert.throws(()=>saveGoodsLocationBook(d,{rows:[{...row(),...patch}]}),/originais preservados/);assert.equal(d.modelo_a_snapshot,original);assert.throws(()=>recordGoodsLocations(d,{rows:[row(),row()]}),/distintos/);assert.throws(()=>recordGoodsLocations(d,{rows:[]}),/distintos/);assert.throws(()=>goodsLocationBook({...d,modelo_a_snapshot:JSON.stringify({...JSON.parse(original),goodsLocations:[]})}),/originais preservados/);
});