39 lines
7.5 KiB
JavaScript
39 lines
7.5 KiB
JavaScript
import test from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import fs from 'node:fs';
|
||
import {newCommissionBase,switchCommissionDirection,commissionBaseTreatments,commissionBaseConditions,evaluateCommissionBase,recordCommissionBases,saveCommissionBaseBook,commissionBaseBook,commissionBaseCurrent,commissionBaseReportRows} from '../../resources/js/lib/iva-commission-base.ts';
|
||
import {publicBaseCurrent} from '../../resources/js/lib/iva-public-authority-base.ts';
|
||
import {importExemptionCurrent} from '../../resources/js/lib/iva-import-exemptions.ts';
|
||
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
|
||
const frozen=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-g7b-preserved-inputs.json',import.meta.url),'utf8'));
|
||
const row=(treatment=commissionBaseTreatments[0].id)=>({...newCommissionBase('g7b-'+treatment,'MZN'),treatment,description:'SYNTHETIC QA bens transferidos em comissão',period:'2026-12',principal:'SYNTHETIC QA comitente',agent:'SYNTHETIC QA comissário',agreementRef:'SYNTHETIC QA contrato A,comissão desta operação',agreedPrice:'1000.25',priceRef:'SYNTHETIC QA preço acordado pelo comissário antes do ajuste',commissionAmount:'100.10',commissionRef:'SYNTHETIC QA comissão contratada em valor,semIVA',compositionRef:'SYNTHETIC QA composição15(5)/(6),valores líquidos e sem ajuste anterior',documentRef:'SYNTHETIC QA G7B '+treatment,documentDate:'2026-11-14',evidence:'SYNTHETIC QA pressupostos expressos,bens/contrato/sentido/próprias condições,não documento real',conditions:Object.fromEntries(commissionBaseConditions.map(([key])=>[key,'yes']))});
|
||
const draft=()=>({...structuredClone(frozen),context_opportunity:'opportunity:340',project_title:'SYNTHETIC QA — G7B / Bases de comissão'});
|
||
|
||
test('P091 own goods/contract/direction/composition conditions and references;unknown/no never become tax or base zero',()=>{
|
||
for(const rule of commissionBaseTreatments){const input=row(rule.id),ok=evaluateCommissionBase(input,'MZN');assert.equal(ok.status,'determined');assert.equal(ok.baseAmount,rule.id==='commission_sale_transfer'?'900.15':'1100.35');assert.equal(ok.vat,null);assert.equal(ok.rate,null);
|
||
for(const [key]of commissionBaseConditions)for(const value of ['','unknown','no']){const r=evaluateCommissionBase({...input,conditions:{...input.conditions,[key]:value}},'MZN');assert.equal(r.status,value==='no'?'not_applicable':'indeterminate');assert.equal(r.baseAmount,null);assert.equal(r.vat,null);}
|
||
for(const patch of [{principal:''},{agent:''},{agreementRef:''},{priceRef:''},{commissionRef:''},{compositionRef:''},{documentRef:''},{documentDate:'2026-02-30'},{period:'2025-12'},{currency:'USD'}])assert.equal(evaluateCommissionBase({...input,...patch},'MZN').baseAmount,null);
|
||
}
|
||
});
|
||
|
||
test('sale subtracts and purchase adds exact commission once;explicitzero differs fromunknown and negative difference is not floored',()=>{
|
||
const input=row();for(const[patch,expected]of [[{agreedPrice:'0',commissionAmount:'0'},'0.00'],[{agreedPrice:'1.000002',commissionAmount:'0.000001'},'1.000001'],[{treatment:'commission_purchase_transfer',agreedPrice:'999999999999999.999999',commissionAmount:'999999999999999.999999'},'1999999999999999.999998']])assert.equal(evaluateCommissionBase({...input,...patch},'MZN').baseAmount,expected);
|
||
for(const patch of [{commissionAmount:''},{agreedPrice:''},{agreedPrice:'-1'},{commissionAmount:'NaN'},{commissionAmount:'0.0000001'}])assert.equal(evaluateCommissionBase({...input,...patch},'MZN').baseAmount,null);
|
||
const negative=evaluateCommissionBase({...input,agreedPrice:'50',commissionAmount:'100'},'MZN');assert.equal(negative.baseAmount,null);assert.match(negative.reason,/−50.00/);assert.equal(negative.vat,null);assert.equal(evaluateCommissionBase({...input,treatment:'commission_purchase_transfer',agreedPrice:'50',commissionAmount:'100'},'MZN').baseAmount,'150.00');
|
||
const switched=switchCommissionDirection(input,'commission_purchase_transfer');assert.equal(switched.conditions.directionConfirmed,'');assert.equal(switched.agreedPrice,input.agreedPrice);assert.equal(switched.priceRef,input.priceRef);assert.equal(switched.commissionAmount,input.commissionAmount);assert.equal(switched.principal,input.principal);assert.equal(evaluateCommissionBase(switched,'MZN').baseAmount,null);assert.equal(evaluateCommissionBase({...switched,conditions:{...switched.conditions,directionConfirmed:'yes'}},'MZN').baseAmount,'1100.35');
|
||
});
|
||
|
||
test('P091 save/recovery/history/report preserve all79 delivered books including P090/P060/P084P085 and old currentkeys',()=>{
|
||
const d=draft(),prior=JSON.parse(d.modelo_a_snapshot);assert.deepEqual(commissionBaseBook(d),{rows:[]});assert.deepEqual(commissionBaseReportRows(d),[]);
|
||
let book=recordCommissionBases(d,{rows:commissionBaseTreatments.map(rule=>({...row(rule.id),conditions:{}}))});book=recordCommissionBases(d,{...book,rows:commissionBaseTreatments.map(rule=>({...row(rule.id),conditions:{...row(rule.id).conditions,commissionContract:'no'}}))});book=recordCommissionBases(d,{...book,rows:commissionBaseTreatments.map(rule=>row(rule.id))});assert.equal(book.history.length,2);assert.ok(book.history.every(h=>h.rows.every(r=>r.baseAmount===null&&r.vat===null)));assert.ok(commissionBaseCurrent(d,book));
|
||
for(const field of ['treatment','agreedPrice','commissionAmount','priceRef','commissionRef','agreementRef','principal'])assert.ok(!commissionBaseCurrent(d,{...book,rows:book.rows.map(r=>({...r,[field]:'changed'}))}));for(const patch of [{context_opportunity:'opportunity:341'},{currency:'USD'},{selection_labels:{province_id:'Maputo'}}])assert.ok(!commissionBaseCurrent({...d,...patch},book));
|
||
d.modelo_a_snapshot=saveCommissionBaseBook(d,book);assert.deepEqual(commissionBaseBook(JSON.parse(JSON.stringify(d))),book);const next=JSON.parse(d.modelo_a_snapshot);const{commissionBases,...untouched}=next;assert.deepEqual(untouched,prior);for(const[scope,previous]of Object.entries(prior.importExemptions))assert.ok(importExemptionCurrent({...d,context_opportunity:scope},previous));for(const[scope,previous]of Object.entries(prior.publicAuthorityBases))assert.ok(publicBaseCurrent({...d,context_opportunity:scope},previous));
|
||
assert.equal(next.publicAuthorityBases['opportunity:339'].result.rows[0].vat,null);assert.equal(next.importExemptions['opportunity:338'].result.rows[1].importVat,'400.00');assert.equal(next.books['opportunity:329'].result.periods[0].fields['11'],null);
|
||
const report=JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance']),version:'QA G7B'}));for(const token of ['Base P091','900.15','1100.35','IVA: Indeterminado','opportunity:340','Manica','2026-12','contrato A','15(2)(e)','100.10','campo11'])assert.ok(report.includes(token),token);assert.deepEqual(commissionBaseReportRows({...d,context_opportunity:'opportunity:341'}),[]);
|
||
if(process.env.IVA_G7B_CALCULATED)fs.writeFileSync(process.env.IVA_G7B_CALCULATED,JSON.stringify(d));
|
||
});
|
||
|
||
test('corrupt commission rows/store cannot overwrite originals;duplicate operation identifiers cannot be calculated',()=>{
|
||
const d=draft(),original=d.modelo_a_snapshot;for(const patch of [{commissionAmount:4},{conditions:[]},{priceRef:null}])assert.throws(()=>saveCommissionBaseBook(d,{rows:[{...row(),...patch}]}),/originais preservados/);assert.equal(d.modelo_a_snapshot,original);assert.throws(()=>recordCommissionBases(d,{rows:[row(),row()]}),/distintos/);assert.throws(()=>recordCommissionBases(d,{rows:[]}),/distintos/);assert.throws(()=>commissionBaseBook({...d,modelo_a_snapshot:JSON.stringify({...JSON.parse(original),commissionBases:[]})}),/originais preservados/);
|
||
});
|