feat(iva): prepare P095 regulated fuel base excluding TC in QA
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class IvaFuelBaseDraftTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_fuel_bases_recover_privately_preserving_all_delivered_books(): void
|
||||
{
|
||||
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
||||
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
|
||||
$this->assertSame(55441, (int) $target->port);
|
||||
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
||||
$this->actingAs(User::factory()->create(['email_verified_at' => now()]));
|
||||
$draft = json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-g7d-bases.json')), true, flags: JSON_THROW_ON_ERROR);
|
||||
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => [], 'economic_snapshot' => $draft], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
||||
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
|
||||
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
|
||||
$this->assertSame('opportunity:342', $recovered['context_opportunity']);
|
||||
$this->assertSame('Manica', $recovered['selection_labels']['province_id']);
|
||||
$store = json_decode($recovered['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
|
||||
$book = $store['regulatedFuelBases']['opportunity:342'];
|
||||
$this->assertCount(2, $book['rows']);
|
||||
$this->assertSame(['fuel_tax_included','fuel_tax_excluded'], array_column($book['rows'], 'treatment'));
|
||||
$this->assertSame(['1400.15','1500.25'], array_column($book['result']['rows'], 'baseAmount'));
|
||||
$this->assertSame(['determined','determined'], array_column($book['result']['rows'], 'status'));
|
||||
$this->assertSame([null,null], array_column($book['result']['rows'], 'vat'));
|
||||
$this->assertSame([null,null], array_column($book['result']['rows'], 'rate'));
|
||||
$this->assertSame('1500.25', $book['rows'][0]['consideration']);
|
||||
$this->assertSame('100.10', $book['rows'][0]['fuelTax']);
|
||||
$this->assertStringContainsString('TC desta operação', $book['rows'][0]['fuelTaxRef']);
|
||||
$this->assertStringContainsString('preço A', $book['rows'][0]['priceRef']);
|
||||
$this->assertStringContainsString('Manica', $book['rows'][0]['priceScope']);
|
||||
$this->assertSame('2026-12-12', $book['rows'][0]['operationDate']);
|
||||
$this->assertSame('2026-12-01', $book['rows'][0]['priceFrom']);
|
||||
$this->assertSame('2026-12-31', $book['rows'][0]['priceTo']);
|
||||
$this->assertStringContainsString('15(2)(i)', $book['result']['source']);
|
||||
$this->assertSame($book['rows'], $book['result']['inputs']);
|
||||
$this->assertCount(2, $book['history']);
|
||||
$this->assertNull($book['history'][0]['rows'][0]['baseAmount']);
|
||||
$frozen = json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-g7d-preserved-inputs.json')), true, flags: JSON_THROW_ON_ERROR);
|
||||
$prior = json_decode($frozen['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
|
||||
$this->assertSame($prior, array_diff_key($store, ['regulatedFuelBases' => true]));
|
||||
$this->assertSame('1250.30', $store['publicAuthorityBases']['opportunity:339']['result']['rows'][1]['baseAmount']);
|
||||
$this->assertNull($store['publicAuthorityBases']['opportunity:339']['result']['rows'][1]['vat']);
|
||||
$this->assertSame('400.00', $store['importExemptions']['opportunity:338']['result']['rows'][1]['importVat']);
|
||||
$this->assertNull($store['books']['opportunity:329']['result']['periods'][0]['fields']['11']);
|
||||
file_put_contents(base_path('outputs/iva-l1-g7d-fuel-base-20261024/recovered.json'), json_encode($recovered, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,39 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import {newFuelBase,switchFuelTaxTreatment,fuelBaseTreatments,fuelBaseConditions,evaluateFuelBase,recordFuelBases,saveFuelBaseBook,fuelBaseBook,fuelBaseCurrent,fuelBaseReportRows} from '../../resources/js/lib/iva-fuel-base.ts';
|
||||
import {actSaleCurrent} from '../../resources/js/lib/iva-act-sale-base.ts';
|
||||
import {commissionBaseCurrent} from '../../resources/js/lib/iva-commission-base.ts';
|
||||
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
|
||||
const frozen=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-g7d-preserved-inputs.json',import.meta.url),'utf8'));
|
||||
const row=(treatment=fuelBaseTreatments[0].id)=>({...newFuelBase('g7d-'+treatment,'MZN'),treatment,description:'SYNTHETIC QA revenda de combustível A',period:'2026-12',operationDate:'2026-12-12',priceRef:'SYNTHETIC QA referência preço A / Autoridade Pública',priceScope:'SYNTHETIC QA combustível A, revenda A, Manica, dezembro2026, pressupostos',priceFrom:'2026-12-01',priceTo:'2026-12-31',documentRef:'SYNTHETIC QA G7D '+treatment,documentDate:'2026-12-12',consideration:'1500.25',fuelTax:'100.10',fuelTaxRef:'SYNTHETIC QA TC desta operação sem estimar taxa',compositionRef:'SYNTHETIC QA composição15(1)/(5)/(6),líquida de IVA',evidence:'SYNTHETIC QA pressupostos expressos,não documento real',conditions:Object.fromEntries(fuelBaseConditions.map(([key])=>[key,'yes']))});
|
||||
const draft=()=>({...structuredClone(frozen),context_opportunity:'opportunity:342',project_title:'SYNTHETIC QA — G7D / Bases de combustíveis'});
|
||||
|
||||
test('P095 own resale/price/scope/composition conditions; missing references and wrong date never become zero',()=>{
|
||||
for(const rule of fuelBaseTreatments){const input=row(rule.id),ok=evaluateFuelBase(input,'MZN');assert.equal(ok.status,'determined');assert.equal(ok.baseAmount,rule.id==='fuel_tax_included'?'1400.15':'1500.25');assert.equal(ok.vat,null);assert.equal(ok.rate,null);
|
||||
for(const[key]of fuelBaseConditions)for(const value of ['','unknown','no']){const r=evaluateFuelBase({...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 [{description:''},{priceRef:''},{priceScope:''},{documentRef:''},{documentDate:'2026-02-30'},{compositionRef:''},{evidence:''},{period:'2025-12'},{currency:'USD'},{treatment:'unknown'},{operationDate:'2026-11-12'},{operationDate:'2026-02-30'},{priceFrom:''},{priceTo:'invalid'},{priceFrom:'2026-12-20'},{priceTo:'2026-12-11'},{priceFrom:'2026-12-31',priceTo:'2026-12-01'}])assert.equal(evaluateFuelBase({...input,...patch},'MZN').baseAmount,null);
|
||||
assert.equal(evaluateFuelBase({...input,priceTo:''},'MZN').status,'determined');
|
||||
for(const operationDate of ['2026-12-01','2026-12-31'])assert.equal(evaluateFuelBase({...input,operationDate},'MZN').status,'determined');
|
||||
}
|
||||
});
|
||||
|
||||
test('TC subtracted exactly once only when included; zero,precision,excess and treatment changes preserve inputs',()=>{
|
||||
const input=row();for(const[patch,expected]of [[{consideration:'0',fuelTax:'0'},'0.00'],[{consideration:'1.000002',fuelTax:'0.000001'},'1.000001'],[{consideration:'999999999999999.999999',fuelTax:'0.000001'},'999999999999999.999998'],[{treatment:'fuel_tax_excluded',fuelTax:'invalid',fuelTaxRef:''},'1500.25']])assert.equal(evaluateFuelBase({...input,...patch},'MZN').baseAmount,expected);
|
||||
for(const patch of [{consideration:''},{fuelTax:''},{fuelTaxRef:''},{consideration:'-1'},{fuelTax:'NaN'},{fuelTax:'0.0000001'},{fuelTax:'1500.26'}])assert.equal(evaluateFuelBase({...input,...patch},'MZN').baseAmount,null);
|
||||
const switched=switchFuelTaxTreatment(input,'fuel_tax_excluded');assert.equal(switched.conditions.fuelTaxTreatment,'');for(const field of ['consideration','fuelTax','fuelTaxRef','priceRef','priceScope','priceFrom','priceTo','documentRef'])assert.equal(switched[field],input[field]);assert.equal(evaluateFuelBase(switched,'MZN').baseAmount,null);assert.equal(evaluateFuelBase({...switched,conditions:{...switched.conditions,fuelTaxTreatment:'yes'}},'MZN').baseAmount,'1500.25');
|
||||
});
|
||||
|
||||
test('save/recovery/history/report preserve all81 delivered books including P094/P091 and currentkeys',()=>{
|
||||
const d=draft(),prior=JSON.parse(d.modelo_a_snapshot);assert.deepEqual(fuelBaseBook(d),{rows:[]});assert.deepEqual(fuelBaseReportRows(d),[]);
|
||||
let book=recordFuelBases(d,{rows:fuelBaseTreatments.map(rule=>({...row(rule.id),conditions:{}}))});book=recordFuelBases(d,{...book,rows:fuelBaseTreatments.map(rule=>({...row(rule.id),conditions:{...row(rule.id).conditions,publicFixedPrice:'no'}}))});book=recordFuelBases(d,{...book,rows:fuelBaseTreatments.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(fuelBaseCurrent(d,book));
|
||||
for(const field of ['treatment','consideration','fuelTax','fuelTaxRef','priceRef','priceScope','priceFrom','priceTo','operationDate'])assert.ok(!fuelBaseCurrent(d,{...book,rows:book.rows.map(r=>({...r,[field]:'changed'}))}));for(const patch of [{context_opportunity:'opportunity:343'},{currency:'USD'},{selection_labels:{province_id:'Maputo'}}])assert.ok(!fuelBaseCurrent({...d,...patch},book));
|
||||
d.modelo_a_snapshot=saveFuelBaseBook(d,book);assert.deepEqual(fuelBaseBook(JSON.parse(JSON.stringify(d))),book);const next=JSON.parse(d.modelo_a_snapshot);const{regulatedFuelBases,...untouched}=next;assert.deepEqual(untouched,prior);for(const[scope,previous]of Object.entries(prior.actSaleBases))assert.ok(actSaleCurrent({...d,context_opportunity:scope},previous));for(const[scope,previous]of Object.entries(prior.commissionBases))assert.ok(commissionBaseCurrent({...d,context_opportunity:scope},previous));
|
||||
assert.equal(next.actSaleBases['opportunity:341'].result.rows[1].baseAmount,'2200.50');assert.equal(next.commissionBases['opportunity:340'].result.rows[0].baseAmount,'900.15');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 G7D'}));for(const token of ['Base P095','1400.15','1500.25','IVA: Indeterminado','opportunity:342','Manica','2026-12-12','preço A','15(2)(i)','100.10','2026-12-01','2026-12-31','campo11'])assert.ok(report.includes(token),token);assert.deepEqual(fuelBaseReportRows({...d,context_opportunity:'opportunity:343'}),[]);
|
||||
if(process.env.IVA_G7D_CALCULATED)fs.writeFileSync(process.env.IVA_G7D_CALCULATED,JSON.stringify(d));
|
||||
});
|
||||
|
||||
test('corrupt fuel rows/store cannot overwrite originals; duplicate operation identifiers cannot be recorded',()=>{
|
||||
const d=draft(),original=d.modelo_a_snapshot;for(const patch of [{fuelTax:4},{conditions:[]},{priceRef:null}])assert.throws(()=>saveFuelBaseBook(d,{rows:[{...row(),...patch}]}),/originais preservados/);assert.equal(d.modelo_a_snapshot,original);assert.throws(()=>recordFuelBases(d,{rows:[row(),row()]}),/distintos/);assert.throws(()=>recordFuelBases(d,{rows:[]}),/distintos/);assert.throws(()=>fuelBaseBook({...d,modelo_a_snapshot:JSON.stringify({...JSON.parse(original),regulatedFuelBases:[]})}),/originais preservados/);
|
||||
});
|
||||
Reference in New Issue
Block a user