Files
SGF/scripts/sgf-single-stock-http.mjs
2026-11-11 09:00:17 +02:00

17 lines
4.9 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')),root=run.root+'/private/receipt-composition-cc50a276c10c';const input=JSON.parse(fs.readFileSync(root+'/single-workshop-stock-input.json')),physical=JSON.parse(fs.readFileSync(root+'/single-stock-physical-input.json'));const file=root+'/single-stock-http-progress.json',progress=fs.existsSync(file)?JSON.parse(fs.readFileSync(file)):{operations:{}};const save=()=>fs.writeFileSync(file,JSON.stringify(progress,null,2));
const clients={tech:await session('sgf:workshop_record','workshop'),warehouse:await session('purchasing:validator','workshop'),prepare:await session('sgf:accounting_prepare','accounting'),review:await session('sgf:accounting_review','accounting')};
const step=async(name,role,path,body)=>{let op=progress.operations[name];if(!op){op=progress.operations[name]={key:crypto.randomUUID(),role,path,body};save();}assert.deepEqual({role:op.role,path:op.path,body:op.body},{role,path,body});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;};
let r=await clients.tech.get('/api/workshop-stock');assert.equal(r.status,200);let data=await r.json();const source=data.sources.find(e=>e.id===input.entries.consumed);assert(source);assert(source.warehouses.some(w=>w.id===physical.warehouse));assert(source.deliveries.some(m=>m.id===physical.issue_movement));
const allocation=await step('allocate-consumed-half','tech','/api/workshop-stock/prepare-allocation',{entry_id:source.id,version:1,warehouse_id:physical.warehouse,movement_id:physical.issue_movement,reason:'Associar meia unidade consumida à entrega de uma unidade já registada, sem novo abatimento.','evidence':'QA-ENTREGA-INTEGRADA-8085'});assert.equal(allocation.impact.physical_before,allocation.impact.physical_after);
const linked=await step('allocate-consumed-half-review','warehouse',`/api/workshop-stock/${allocation.id}/confirm`,{reason:'Conferência física independente da origem verificada e da mesma entrega.'});assert.equal(linked.movement_id,physical.issue_movement);
const returned=await step('return-unused-half','tech','/api/workshop-stock/prepare-return',{entry_id:input.entries.returned,version:1,warehouse_id:physical.warehouse,movement_id:physical.issue_movement,reason:'Devolver a meia unidade não consumida ao armazém de origem.','evidence':'QA-DEVOLUCAO-INTEGRADA-8085'});assert.equal(returned.impact.physical_after,'1500');
await step('return-unused-half-review','warehouse',`/api/workshop-stock/${returned.id}/confirm`,{reason:'Recepção física independente de0,5UN não usadas, conservando a saída original.',received_in_warehouse:true});
r=await clients.prepare.get('/api/general-ledger');assert.equal(r.status,200);data=await r.json();const stock=data.stock.find(s=>s.book.stock_item_id===physical.stock_item);assert(stock&&stock.physical_balance_milli===1500);
const rate=await step('rate50','prepare','/api/general-ledger/stock/rate-prepare',{book_id:stock.book.id,version:0,unit_minor:5000,reason:'Taxa artificial50MZN por unidade, explicitamente preparada para este livro físico.'});
await step('rate50-review','review','/api/general-ledger/stock/rate-review',{rate_id:rate.rate_id,version:1,decision:'approved',reason:'Conferência independente da taxa e da unidade exacta do artigo QA.'});
for(const movement of stock.rows.map(row=>row.movement)){const kind={receipt_in:'stock.receipt',issue:'stock.issue',workshop_return_in:'stock.return'}[movement.movement_type];assert(kind);const name=kind+'-'+movement.id;
const proposal=await step(name+'-prepare','prepare','/api/general-ledger/effect-prepare',{effect_type:kind,source_id:movement.id,journal_on:'2026-11-10',period_key:'QA-2026-INTEGRADO',rule_key:kind,reason:'Origem física individual com documentação e revisão próprias: '+kind+'.'});
await step(name+'-review','review','/api/general-ledger/validate',{proposal_id:proposal.proposal_id,revision:proposal.revision,decision:'approved',reason:'Revisão distinta da origem física e da taxa50 aprovada.'});await step(name+'-post','prepare','/api/general-ledger/post',{proposal_id:proposal.proposal_id,revision:proposal.revision,reason:'Aplicação única da valorização revista, sem novo movimento físico.'});}
r=await clients.prepare.get('/api/general-ledger');assert.equal(r.status,200);data=await r.json();assert.equal(data.journals.length,16);assert.equal(data.totals.debit_minor,data.totals.credit_minor);assert.equal(data.stock.find(s=>s.book.stock_item_id===physical.stock_item).physical_balance_milli,1500);progress.passed=true;progress.journals=16;progress.final_physical_milli=1500;save();console.log(JSON.stringify({passed:true,journals:16,stock_milli:1500,proof:file,browser_visual_review:false}));