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

29 lines
3.3 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import fs from 'node:fs';
import {operationTreatments,newSalesOperation,evaluateSalesOperation,recordSales,saveSalesBook,salesBook,salesCurrent} from '../../resources/js/lib/iva-operations.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const ids=['social_assistance_public','social_assistance_nonprofit','social_care_public','social_care_nonprofit','activity_facilities_public','activity_facilities_nonprofit'];
function seed(){return JSON.parse(fs.readFileSync(new URL('./fixtures/iva-health-goods.json',import.meta.url),'utf8'));}
function fixture(){const draft=seed();draft.context_opportunity='opportunity:311';draft.project_title='SYNTHETIC QA — G2B social';
let book={currency:'MZN',rows:ids.map((id,i)=>({...newSalesOperation(`g2b-${i}`,'2026-03','MZN'),description:`SYNTHETIC QA ${id}`,establishment:'SYNTHETIC QA equipamento Manica',amount:'100',basis:i%2?'included':'net',treatment:id,confirmed:operationTreatments.find(t=>t.id===id).conditions.map((_,n)=>n),evidence:'SYNTHETIC QA — natureza, entidade, reconhecimento e condições cumulativas pressupostos documentados; sem certificação'})),periods:[{period:'2026-03',complete:true}]};book=recordSales(draft,book);draft.modelo_a_snapshot=saveSalesBook(draft,book);return {draft,book};}
test('G2B three branches have six entity-specific treatments and cumulative nonprofit conditions',()=>{
const {book}=fixture();for(const row of book.rows){const rule=operationTreatments.find(t=>t.id===row.treatment),r=evaluateSalesOperation(row,'MZN');assert.equal(r.field,'07');assert.equal(r.net,'100.00');assert.equal(r.vat,'0.00');assert.equal(r.gross,'100.00');assert.match(r.article,/10\(/);
assert.equal(rule.conditions.length,row.treatment.endsWith('_nonprofit')?7:4);
for(const missing of row.confirmed)assert.equal(evaluateSalesOperation({...row,confirmed:row.confirmed.filter(n=>n!==missing)},'MZN').vat,null);
assert.equal(evaluateSalesOperation({...row,evidence:''},'MZN').vat,null);
}
assert.equal(book.result.periods[0].fields['07'],'600.00');
});
test('new social context round-trips and reports only its operations, preserving both accepted books without recalculation',()=>{
const {draft,book}=fixture(),original=seed();const old=JSON.parse(original.modelo_a_snapshot).salesOperations;
const recovered=JSON.parse(JSON.stringify(draft)),store=JSON.parse(recovered.modelo_a_snapshot).salesOperations;
for(const id of ['opportunity:309','opportunity:310']){assert.deepEqual(store[id],old[id]);assert.equal(salesCurrent({...recovered,context_opportunity:id},store[id]),true);}
assert.equal(salesCurrent(recovered,salesBook(recovered)),true);
const model=JSON.stringify(createProjectDossierReport(recovered,{selectedSections:new Set(['finance'])}));
for(const token of [...ids,'600.00','opportunity:311','Manica','2026-03','MZN'])assert.ok(model.includes(token),token);
for(const token of ['financial_stamp','patient_transport'])assert.equal(model.includes(token),false);
assert.equal(book.result.rows.length,6);assert.equal(draft.currency,original.currency);assert.deepEqual(draft.selection_labels,original.selection_labels);
});
if(process.env.IVA_G2B_OUT)fs.writeFileSync(process.env.IVA_G2B_OUT,JSON.stringify(fixture().draft,null,2));