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

30 lines
6.8 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {newGoodsAllocation,switchAllocationTreatment,switchAllocationValuation,goodsAllocationConditions,allocationSpecificConditions,goodsAllocationTreatments,evaluateGoodsAllocation,recordGoodsAllocations,saveGoodsAllocationBook,goodsAllocationBook,goodsAllocationCurrent,goodsAllocationReportRows} from '../../resources/js/lib/iva-goods-allocation.ts';
const frozen=JSON.parse(fs.readFileSync('tests/frontend/fixtures/iva-goods-allocation-preserved.json','utf8'));const draft={...frozen,currency:'MZN',context_opportunity:'opportunity:353',project_title:'SYNTHETIC QA — Afectação de bens / Manica'};
function row(t){const cost=['free_goods_transfer','fixed_asset_20a'].includes(t);return{...newGoodsAllocation(t,'MZN'),treatment:t,description:'SYNTHETIC QA '+t,period:'2026-12',origin:'projected',operationDate:'2026-12-12',operationRef:'SYNTHETIC QA operação',documentRef:'SYNTHETIC QA documento/pressuposto',documentDate:'2026-12-12',goodsRef:'SYNTHETIC QA conjunto de bens/elementos',deductionRef:'SYNTHETIC QA dedução histórica parcial,bens/elementos identificados',destinationRef:'SYNTHETIC QA destino/finalidade/sector/activo eâmbito',exceptionRef:'SYNTHETIC QA factos fora da excepção de amostras/ofertas,não limiar inventado',asset20aRef:'SYNTHETIC QA bens20(1)a/activoimobilizado',valuationMode:cost?'cost':'acquisition',acquisitionPrice:'1000.25',acquisitionRef:'SYNTHETIC QA preço aquisição reportado ao momento',currentCost:'800.15',costRef:'SYNTHETIC QA custo reportado ao momento',valuationDate:'2026-12-12',valuationScope:'SYNTHETIC QA conjunto identificado/preço ao momento,semIVA',evidence:'SYNTHETIC QA pressupostos expressos',conditions:{...Object.fromEntries([...goodsAllocationConditions,...allocationSpecificConditions(t)].map(([key])=>[key,'yes'])),valuationConfirmed:'yes',acquisitionUnavailable:'yes'}};}
for(const rule of goodsAllocationTreatments)test('P124/P088 '+rule.id+' ownfacts,historicaldeduction and base',()=>{
const r=row(rule.id),result=evaluateGoodsAllocation(r,'MZN');assert.equal(result.status,'determined');assert.equal(result.classification,'assimilated_goods');assert.equal(result.baseAmount,r.valuationMode==='cost'?'800.15':'1000.25');assert.equal(result.vat,null);assert.equal(result.rate,null);
for(const [key] of [...goodsAllocationConditions,...allocationSpecificConditions(rule.id)]){const missing=structuredClone(r);delete missing.conditions[key];assert.equal(evaluateGoodsAllocation(missing,'MZN').classification,'indeterminate');missing.conditions[key]='no';assert.equal(evaluateGoodsAllocation(missing,'MZN').status,'not_applicable');assert.equal(evaluateGoodsAllocation(missing,'MZN').baseAmount,null);}
for(const field of ['description','operationRef','documentRef','goodsRef','deductionRef','destinationRef','evidence',...(rule.clause==='e'?['exceptionRef']:[]),...(rule.id==='fixed_asset_20a'?['asset20aRef']:[])])assert.equal(evaluateGoodsAllocation({...r,[field]:''},'MZN').classification,'indeterminate',field);
for(const patch of [{operationDate:'2026-11-12'},{documentDate:'2026-02-30'},{period:'2025-12'}])assert.equal(evaluateGoodsAllocation({...r,...patch},'MZN').status,'indeterminate');
});
test('P124classification independentof missingP088base;no newdeduction and no temporaryservice substitution',()=>{
const r=row('permanent_private_goods');for(const patch of [{valuationMode:''},{acquisitionPrice:''},{valuationDate:'2026-12-11'},{valuationScope:''},{currency:'USD'},{acquisitionRef:''}]){const result=evaluateGoodsAllocation({...r,...patch},'MZN');assert.equal(result.status,'indeterminate');assert.equal(result.classification,'assimilated_goods');assert.equal(result.baseAmount,null);}
assert.match(evaluateGoodsAllocation(r,'MZN').reason,/não nova dedução/);assert.match(evaluateGoodsAllocation(r,'MZN').reason,/P089/);
const noPrior=structuredClone(r);noPrior.conditions.priorDeduction='no';assert.equal(evaluateGoodsAllocation(noPrior,'MZN').classification,'not_applicable');assert.equal(evaluateGoodsAllocation(noPrior,'MZN').baseAmount,null);
});
test('P088costfallback explicit,currentmoment,hidden retention and exact amounts',()=>{
const r=row('free_goods_transfer');for(const flag of ['','no']){const result=evaluateGoodsAllocation({...r,conditions:{...r.conditions,acquisitionUnavailable:flag}},'MZN');assert.equal(result.classification,'assimilated_goods');assert.equal(result.baseAmount,null);}
assert.equal(evaluateGoodsAllocation({...r,acquisitionPrice:'999999'},'MZN').baseAmount,'800.15');assert.equal(evaluateGoodsAllocation({...r,currentCost:'0'},'MZN').baseAmount,'0.00');assert.equal(evaluateGoodsAllocation({...r,currentCost:'0.000001'},'MZN').baseAmount,'0.000001');for(const v of ['','-1','1e3','1,5'])assert.equal(evaluateGoodsAllocation({...r,currentCost:v},'MZN').baseAmount,null);
const acquisition=switchAllocationValuation(r,'acquisition');assert.equal(acquisition.currentCost,r.currentCost);assert.equal(acquisition.acquisitionPrice,r.acquisitionPrice);assert.equal(acquisition.conditions.valuationConfirmed,'');assert.equal(evaluateGoodsAllocation(acquisition,'MZN').baseAmount,null);acquisition.conditions.valuationConfirmed='yes';assert.equal(evaluateGoodsAllocation(acquisition,'MZN').baseAmount,'1000.25');
const changed=switchAllocationTreatment(r,'fixed_asset_20a');assert.equal(changed.exceptionRef,r.exceptionRef);assert.equal(changed.asset20aRef,r.asset20aRef);assert.equal(changed.conditions.fixedAsset,undefined);assert.equal(evaluateGoodsAllocation(changed,'MZN').classification,'indeterminate');
});
test('Sharedoperation under2requirements persists once;all previous books/history/report preserved',()=>{
const rows=goodsAllocationTreatments.map(t=>row(t.id));let book=recordGoodsAllocations(draft,{rows});book=recordGoodsAllocations(draft,book);assert.equal(book.history.length,1);assert.notEqual(book.result.inputs,book.rows);
const next={...draft,modelo_a_snapshot:saveGoodsAllocationBook(draft,book)};assert.deepEqual(goodsAllocationBook(next),book);assert.ok(goodsAllocationCurrent(next,book));assert.equal(goodsAllocationCurrent({...next,currency:'USD'},book),false);assert.equal(goodsAllocationCurrent({...next,context_opportunity:'other'},book),false);assert.equal(goodsAllocationReportRows(next).length,4);assert.ok(goodsAllocationReportRows(next).every(r=>r[1].includes('P124/baseP088')));
const store=JSON.parse(next.modelo_a_snapshot);delete store.regulatedGoodsAllocations;assert.deepEqual(store,JSON.parse(frozen.modelo_a_snapshot));assert.throws(()=>recordGoodsAllocations(next,{rows:[rows[0],rows[0]]}));assert.throws(()=>goodsAllocationBook({...next,modelo_a_snapshot:JSON.stringify({...JSON.parse(next.modelo_a_snapshot),regulatedGoodsAllocations:[]})}));
if(process.env.IVA_ALLOCATION_FIXTURE)fs.writeFileSync(process.env.IVA_ALLOCATION_FIXTURE,JSON.stringify(next,null,2)+'\n');
});