16 lines
6.3 KiB
PHP
16 lines
6.3 KiB
PHP
<?php
|
|
use App\Modules\Services\{ServiceInvoicing,MultiLineInvoiceCalculation};use Illuminate\Support\Str;
|
|
require __DIR__.'/sgf-multiline-invoice-proof-bootstrap.php';$host->beginTransaction();$native->beginTransaction();try{
|
|
$actor=$select('commercial_prepare');$engine=app(ServiceInvoicing::class);$tag=strtoupper(substr((string)Str::uuid(),0,8));$series=$engine->propose($actor,['kind'=>'series','identifier'=>'TEST-MULTI-REG-'.$tag,'data'=>['code'=>'TEST-MULTI-REG-'.$tag,'first_number'=>1,'state'=>'open','valid_from'=>'2026-11-01','valid_until'=>'2026-11-30','evidence'=>'Série artificial de regressão do ciclo multilinha.']]);$actor=$select('commercial_review');$engine->decide($series['id'],$actor,['version'=>1,'decision'=>'approved','reason'=>'Revisão independente da série fictícia multilinha.']);
|
|
foreach([['added',['400','600']],['included',['464','696']],['included',['100']]]as[$mode,$prices]){
|
|
$x=$fixture($mode,$prices,$tag);$actor=$select('finance_prepare');$c=app(MultiLineInvoiceCalculation::class);$in=['draft_id'=>$x['draft']['id'],'rule_event_id'=>$ruleEvent,'draft_version'=>1,'preparation_version'=>$x['preparation']['version'],'reason'=>'Cálculo individual de linhas e modalidade pela regra QA revista.'];$cut=$c->preview($actor,$in,(string)Str::uuid());$calc=$c->confirm($actor,$cut['preview']);$ok(($prices===['100']?$calc['result']['base_document']==='86.21'&&$calc['result']['tax_document']==='13.79'&&$calc['result']['total']==='100.00':$calc['result']['base_document']==='1000.00'&&$calc['result']['tax_document']==='160.00'&&$calc['result']['total']==='1160.00'),'shared math exact '.$mode);$replay=$c->confirm($actor,$cut['preview']);$ok($replay['replayed']&&$replay['id']===$calc['id'],'calculation replay no duplicate '.$mode);
|
|
$actor=$select('commercial_prepare');$data=['calculation_policy'=>MultiLineInvoiceCalculation::POLICY,'common_calculation_id'=>$calc['id'],'common_rule_event_id'=>$ruleEvent,'draft_id'=>$x['draft']['id'],'draft_version'=>1,'preparation_version'=>$x['preparation']['version'],'valid_from'=>'2026-11-01','valid_until'=>'2026-11-30','period_start'=>'2026-11-01','period_end'=>'2026-11-30','issue_window_start'=>'2026-11-11','issue_window_end'=>'2026-11-11','event'=>'on_issue_within_deadline','readiness_basis'=>'Origem, linhas e modalidade explícitos; prontidão apenas artificial.','evidence'=>'Conferência temporal individual de emissão QA multilinha.'];$temporal=$engine->propose($actor,['kind'=>'temporal','identifier'=>'MULTI-REG-'.$tag.'-'.$mode.'-'.count($prices),'data'=>$data]);$actor=$select('commercial_review');$engine->decide($temporal['id'],$actor,['version'=>1,'decision'=>'approved','reason'=>'Revisão distinta das linhas, valores e prontidão artificial.']);$actor=$select('commercial_prepare');$review=$engine->review($x['draft']['id'],$series['id'],$temporal['id'],$actor);$ok($review['ready'],'review current and ready '.$mode);$key=(string)Str::uuid();$input=['series_id'=>$series['id'],'rule_id'=>$temporal['id'],'review_hash'=>$review['review_hash']];$invoice=$engine->issue($x['draft']['id'],$actor,$input,$key);$again=$engine->issue($x['draft']['id'],$actor,$input,$key);$ok($again['replayed']&&$again['id']===$invoice['id'],'invoice key recovers number without duplicate '.$mode);$shown=$engine->show($invoice['id'],$actor);$pdf=$engine->pdf($invoice['id'],$actor);$ok(hash('sha256',$pdf)===$shown['pdf_sha256']&&count(array_filter($shown['document_lines'],fn($l)=>$l[0]==='section'&&str_starts_with($l[1],'Linha ')))===count($prices),'frozen PDF includes both lines '.$mode);
|
|
|
|
$sr=app(App\Modules\Services\ServiceReceivables::class);$actor=$select('finance_prepare','finance');$ob=$sr->propose($actor,['kind'=>'obligation','invoice_id'=>$invoice['id'],'currency'=>'MZN','source'=>'SIM-MULTI-REG','external_id'=>'MULTI-OB-'.$invoice['id'],'revision'=>0],(string)Str::uuid());$actor=$select('finance_review','finance');$sr->decide($ob['id'],$actor,['version'=>1,'revision'=>0,'decision'=>'approved','reason'=>'Abertura distinta do recebível multilinha sem recebimento.'],(string)Str::uuid());$position=$sr->position($ob['id'],$actor);$expected=$calc['result']['total'];$ok($position['balance']===$expected,'qualified commercial invoice opens correct receivable in finance '.$mode.' '.count($prices));
|
|
$p=$call('accounting_prepare','prepare',fn($e)=>$e->command('effect-prepare',['effect_type'=>'sales.invoice','source_id'=>$invoice['id'],'journal_on'=>'2026-11-11','period_key'=>'QA-2026-INTEGRADO','rule_key'=>'sales.invoice','reason'=>'Origem multilinha actual do mesmo SGF, sem copiar dívida.'],(string)Str::uuid()));$call('accounting_review','validate',fn($e)=>$e->command('validate',['proposal_id'=>$p['proposal_id'],'revision'=>$p['revision'],'decision'=>'approved','reason'=>'Conferência distinta dos totais documentais, base e imposto.'],(string)Str::uuid()));$j=$call('accounting_prepare','post',fn($e)=>$e->command('post',['proposal_id'=>$p['proposal_id'],'revision'=>$p['revision'],'reason'=>'Aplicar uma única vez a origem documental multilinha revista.'],(string)Str::uuid()));$lines=$native->table('gl_lines')->where('journal_id',$j['journal_id'])->orderBy('line_no')->get();$ok($lines->count()===3&&$lines[1]->credit_minor===(int)str_replace('.','',$calc['result']['base_document'])&&$lines[2]->credit_minor===(int)str_replace('.','',$calc['result']['tax_document']),'same three-line writer uses documentary base and tax '.$mode.' '.count($prices));
|
|
$associations=$host->table('identity_audit')->where('action','module.record.associated')->where('details->area','billing_drafts')->where('details->record_id',$x['draft']['id'])->pluck('details')->map(fn($v)=>json_decode($v,true)['module_id'])->all();$ok($associations===['commercial'],'financial dependency read does not assign draft to other modules');
|
|
}
|
|
$native->statement('SET CONSTRAINTS ALL IMMEDIATE');$ok(true,'native constraints validate all three qualified invoice journals');
|
|
$host->statement('SET CONSTRAINTS ALL IMMEDIATE');$ok(true,'host invoice constraints accept new typed photographs');
|
|
}finally{$native->rollBack();$host->rollBack();}file_put_contents($work.'/multiline-invoice-financial.json',json_encode(['passed'=>true,'checks'=>$checks,'fixtures_rolled_back'=>true,'new_demo'=>false,'new_grants'=>0,'new_accounts'=>0,'regression_only'=>true],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'checks'=>count($checks),'proof'=>$work.'/multiline-invoice-financial.json']).PHP_EOL;
|