19 lines
6.0 KiB
JavaScript
19 lines
6.0 KiB
JavaScript
import fs from 'node:fs';import assert from 'node:assert/strict';import {session} from './sgf-single-http.mjs';
|
|
const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'));assert.equal(run.id,'2576427d1939');const root=run.root+'/private/receipt-composition-cc50a276c10c',file=root+'/single-financial-http-progress.json';const progress=fs.existsSync(file)?JSON.parse(fs.readFileSync(file)):{operations:{},checks:[]};
|
|
const save=()=>fs.writeFileSync(file,JSON.stringify(progress,null,2));const clients={};for(const [role,module]of [['finance_prepare','finance'],['finance_review','finance'],['accounting_prepare','accounting'],['accounting_review','accounting']])clients[role]=await session('sgf:'+role,module);
|
|
const step=async(name,role,path,body)=>{let op=progress.operations[name];if(!op){op=progress.operations[name]={key:crypto.randomUUID(),path,role,body};save();}assert.deepEqual({path:op.path,role:op.role,body:op.body},{path,role,body},'Preserve exact planned operation '+name);if(op.result)return op.result;const r=await clients[role].command(path,body,op.key);assert.equal(r.status,200,name+': '+JSON.stringify(r.value));op.result=r.value;save();return r.value;};
|
|
const getFinance=async()=>{const r=await clients.finance_prepare.get('/api/finance/payables');assert.equal(r.status,200);return r.json();};
|
|
let finance=await getFinance();const original=finance.obligations.find(o=>o.document_number==='FACT-COMPRA-COMPLETA-20261104');assert(original&&original.principal_minor===10000);const revision=original.source_revision;
|
|
const payment=await step('payment20','finance_prepare','/api/finance/payables/payment-prepare',{obligation_id:original.id,source_revision:revision,amount:'20.00',currency:'MZN',paid_on:'2026-11-10',fact_reference:'SIM-INTEGRADO-8085-20',evidence_reference:'SIM-EVIDENCIA-8085-20',reason:'Facto exclusivamente sintético20MZN sobre a obrigação original100, autorizado em10/11/2026.'});
|
|
await step('payment20-review','finance_review','/api/finance/payables/payment-decide',{payment_id:payment.payment_id,decision:'confirmed',evidence_reference:'SIM-CONFERENCIA-8085-20',reason:'Conferência independente do facto artificial; sem transferência monetária.'});
|
|
const allocation=await step('allocation20','finance_prepare','/api/finance/payables/allocation-prepare',{payment_id:payment.payment_id,reference:'SIM-AFECTACAO-8085-20',allocations:[{obligation_id:original.id,source_revision:revision,amount:'20.00'}],reason:'Proposta individual de afectação20 à dívida original, sem outro principal.'});
|
|
const decision=await step('allocation20-review','finance_review','/api/finance/payables/allocation-decide',{proposal_id:allocation.proposal_id,decision:'confirmed',reason:'Conferência distinta de saldo, origem e afectação20MZN.'});
|
|
finance=await getFinance();const confirmed=finance.money.allocations.find(a=>a.decision_id===decision.decision_id);assert(confirmed);if(!progress.operations['reversal20-review']){assert.equal(finance.obligations.find(o=>o.id===original.id).balance_minor,8000);progress.checks.push('one original100MZN obligation becomes80 after confirmed20 allocation');save();}
|
|
const post=async(name,kind,id)=>{const supplier=kind==='supplier_payable.recognised';const p=await step(name+'-prepare','accounting_prepare','/api/general-ledger/'+(supplier?'prepare':'effect-prepare'),{...(supplier?{obligation_id:id}:{effect_type:kind,source_id:id}),journal_on:'2026-11-10',period_key:'QA-2026-INTEGRADO',rule_key:kind,reason:'Origem individual revalidada no diário comum da instalação8085: '+name+'.'});await step(name+'-review','accounting_review','/api/general-ledger/validate',{proposal_id:p.proposal_id,revision:p.revision,decision:'approved',reason:'Revisão contabilística distinta do impacto exacto: '+name+'.'});return step(name+'-post','accounting_prepare','/api/general-ledger/post',{proposal_id:p.proposal_id,revision:p.revision,reason:'Aplicação individual da fotografia revista, com nova validação da origem.'});};
|
|
await post('supplier100','supplier_payable.recognised',original.id);await post('supplier-allocation20','allocation.confirmed',confirmed.id);
|
|
const reversal=await step('reversal20','finance_prepare','/api/finance/payables/reversal-prepare',{allocation_id:confirmed.id,source_revision:revision,reason:'Reversão explicitamente autorizada da afectação artificial20, sem apagar o original.'});const reversed=await step('reversal20-review','finance_review','/api/finance/payables/reversal-confirm',{proposal_id:reversal.proposal_id,reason:'Conferência independente da reversão20 e recomposição do saldo100.'});
|
|
await post('supplier-reversal20','allocation.reversed',reversed.reversal_id);
|
|
const commercial=JSON.parse(fs.readFileSync(root+'/single-commercial.json')),receivable=JSON.parse(fs.readFileSync(root+'/single-receivables.json')),direct=JSON.parse(fs.readFileSync(root+'/single-direct-cost.json')),industry=JSON.parse(fs.readFileSync(root+'/single-industrial.json'));
|
|
for(const [name,kind,id]of [['sale1000','sales.invoice',commercial.invoice],['customer400','receivable.allocated',receivable.allocations[0]],['customer600','receivable.allocated',receivable.allocations[1]],['customer-reversal400','receivable.reversed',receivable.reversal_effect],['direct275','workshop.direct_cost.validated',direct.order],['industrial1800','industry.cost.validated',industry.lot]])await post(name,kind,id);
|
|
finance=await getFinance();assert.equal(finance.obligations.find(o=>o.id===original.id).balance_minor,10000);const report=await clients.accounting_prepare.get('/api/general-ledger');assert.equal(report.status,200);const ledger=await report.json();assert.equal(ledger.journals.length,9);assert.equal(ledger.totals.debit_minor,ledger.totals.credit_minor);progress.checks.push('original supplier balance100 restored; nine individually reviewed balanced journals in same book; stock page remains readable alongside cost journals');progress.passed=true;save();console.log(JSON.stringify({passed:true,journals:9,supplier_balance:'100.00',proof:file,browser_visual_review:false}));
|