29 lines
3.7 KiB
JavaScript
29 lines
3.7 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=['public_security','official_military_supplies','sisa_subject_operation','exempt_activity_asset_sale','no_deduction_right_asset_sale','excluded_deduction_asset_sale'];
|
|
function seed(){return JSON.parse(fs.readFileSync(new URL('./fixtures/iva-services-nature.json',import.meta.url),'utf8'));}
|
|
function fixture(){const draft=seed();draft.context_opportunity='opportunity:316';draft.project_title='SYNTHETIC QA — G2G social';
|
|
let book={currency:'MZN',rows:ids.map((id,i)=>({...newSalesOperation(`g2g-${i}`,'2026-08','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-08',complete:true}]};book=recordSales(draft,book);draft.modelo_a_snapshot=saveSalesBook(draft,book);return {draft,book};}
|
|
test('G2G four branches with six conditional treatments require their own operation and eligibility 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,/9\((2|11|12)\)/);
|
|
assert.ok(rule.conditions.length>=3);
|
|
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(evaluateSalesOperation({...row,period:'2025-08'},'MZN').vat,null); assert.equal(evaluateSalesOperation(row,'USD').vat,null);
|
|
}
|
|
assert.equal(book.result.periods[0].fields['07'],'600.00');assert.equal(book.result.periods[0].fields['05'],'0.00');assert.ok(book.result.rows.every(r=>r.reason.includes('sem direito')));
|
|
});
|
|
test('new conditional context round-trips and reports only its operations, preserving seven 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','opportunity:311','opportunity:312','opportunity:313','opportunity:314','opportunity:315']){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:316','Manica','2026-08','MZN'])assert.ok(model.includes(token),token);
|
|
for(const token of ['financial_stamp','patient_transport','social_assistance_public','statutory_membership','author_rights','industrial_feed','special_tax_games'])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_G2G_OUT)fs.writeFileSync(process.env.IVA_G2G_OUT,JSON.stringify(fixture().draft,null,2));
|