Files
SGF/scripts/sgf-assets-statements-http.mjs
T
2026-11-11 15:04:01 +02:00

9 lines
6.4 KiB
JavaScript

import fs from 'node:fs';import assert from 'node:assert/strict';import crypto from 'node:crypto';import {session} from './sgf-single-http.mjs';import {checkedStatements} from '../resources/js/internal-statements-view.js';
const root=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')).root+'/private/receipt-composition-cc50a276c10c',progress=root+'/assets-statements-http-progress-private.json',saved=fs.existsSync(progress)?JSON.parse(fs.readFileSync(progress)):{},save=()=>fs.writeFileSync(progress,JSON.stringify(saved)),checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);},base='/api/general-ledger/statements';
const prep=await session('sgf:accounting_prepare','accounting'),review=await session('sgf:accounting_review','accounting'),read=await session('sgf:read_only','accounting');const get=async(q={view:'history',page:1,per_page:25},s=read)=>{const r=await s.get(base+'?'+new URLSearchParams(q));assert.equal(r.status,200);return checkedStatements(await r.json(),q);};let state=await get();ok(prep.identity.context.internal_statements_enabled===true,'selected installation feature enabled');const names=s=>s.identity.context.grants.filter(g=>g.permission.startsWith('general_ledger.statements.')).map(g=>g.permission);ok(JSON.stringify(names(prep))===JSON.stringify(['general_ledger.statements.prepare'])&&JSON.stringify(names(review))===JSON.stringify(['general_ledger.statements.review'])&&names(read).length===0,'exact approved preparation review rights only');
const accounts=await get({view:'accounts',page:1,per_page:100},prep),categories={'QA-CAIXA':'asset','QA-CLIENTES':'asset','QA-STOCK':'asset','QA-FORNECEDOR':'liability','QA-VENDAS':'income','QA-CONSUMO-STOCK':'expense','QA-CUSTO-DIRECTO':'expense','QA-CUSTO-INDUSTRIAL':'expense','QA-DESPESA-CAIXA':'expense','QA-DIFERENCA-INVENTARIO':'expense','QA-COMPENSACAO-ENSAIO':'unclassified','QA-COMPENSACAO-INDUSTRIAL':'unclassified','QA-COMPENSACAO-STOCK':'unclassified','QA-CONTRAPARTIDA':'unclassified','QA-DEVOLUCAO-FORNECEDOR':'unclassified','QA-IMPOSTO-TESTE':'unclassified','QA-LIQUIDACAO':'unclassified','QA-LIQUIDACAO-CLIENTE':'unclassified','QA-REDUCAO-CLIENTE':'unclassified','QA-ACTIVO-CUSTO':'asset','QA-ACTIVO-DEP-ACUM':'asset','QA-ACTIVO-GASTO-DEP':'expense','QA-ACTIVO-ORIGEM-QA':'unclassified','QA-ACTIVO-GASTO-ABATE':'expense'};const entries=Object.entries(categories).map(([code,category])=>{const row=accounts.records.data.find(a=>a.code===code);assert(row,'Explicit approved QA account missing '+code);return{account_id:row.id,category};});ok(entries.length===24&&entries.filter(e=>e.category==='unclassified').length===10,'explicit24 approved choices ten pending');const input=(kind,action,version,data)=>({kind,action,version,data,reason:'Decisão individual QA de demonstrações internas parciais, sem classificação legal ou novos lançamentos.'});
async function perform(name,s,body){saved[name]??={key:crypto.randomUUID()};save();const step=saved[name];if(step.result)return step.result;const old=await s.get(base+'/receipts/'+step.key);if(old.status===200){step.result=(await old.json()).result;save();return step.result;}assert.equal(old.status,404);const cut=await s.command(base+'/preview',body,step.key);assert.equal(cut.status,200,JSON.stringify(cut.value));step.cut=cut.value;save();const out=await s.command(base+'/confirm',{preview:cut.value.preview},step.key);assert.equal(out.status,201,JSON.stringify(out.value));step.result=out.value;save();return out.value;}
const m1=await perform('mappingPrepare',prep,input('mapping','prepare',2,{entries,evidence:'Conserva19 correspondências anteriores e acrescenta as cinco contas artificiais de activos explicitamente aprovadas.'}));ok(m1.version===3,'new mapping prepared version3');const m2=await perform('mappingReview',review,input('mapping','review',3,{decision:'approved'}));ok(m2.version===4,'new mapping independently reviewed version4');const r1=await perform('resultPrepare',prep,input('result','prepare',2,{mapping_id:m2.id,from_on:'2026-01-01',to_on:'2026-11-11',per_page:25,evidence:'Resultado interno parcial anual até11Nov;29 lançamentos QA incluindo admissão1200/quota100 e dez contas por classificar.'}));const r2=await perform('resultReview',review,input('result','review',3,{decision:'approved'}));ok(r1.version===3&&r2.version===4,'new result independently prepared reviewed versions3/4');const query={view:'result',version_id:r2.id,page:1,per_page:25},report=await get(query),summary=report.snapshot.summary,c=summary.currencies.MZN;ok(summary.plan.accounts===24&&summary.accounts===23&&summary.basis.journals===29&&report.current_source_matches,'24 chart accounts23 accounts with movements29 journals current source');ok(c.groups.asset.presentation_minor==='325500'&&c.groups.liability.presentation_minor==='10000','classified assets3255 supplier100');ok(c.groups.expense.presentation_minor==='230000'&&c.known_result_subtotal_minor==='28621','year-to-date expense2300 known subtotal286.21');ok(c.unclassified_accounts===10&&c.complete_result_minor===null&&c.equity_minor===null&&!c.complete_balance_sheet,'ten unclassified complete result and equity unknown');const larger=await get({...query,per_page:100});ok(JSON.stringify(larger.records.data)===JSON.stringify(report.records.data),'same frozen23 movement rows pages25/100');
const old=JSON.parse(fs.readFileSync(root+'/statements-http-progress.json')).resultReview.result;let response=await read.get(base+'/exports/'+old.id);const oldBytes=Buffer.from(await response.arrayBuffer());ok(response.status===200&&oldBytes.equals(fs.readFileSync(root+'/statements-frozen-export-private.csv')),'old reviewed export byte identical');const historical=await get({...query,version_id:old.id});ok(historical.snapshot.summary.accounts===19&&historical.snapshot.summary.basis.journals===27&&historical.current_source_matches===false,'old19/27 snapshot explicit historical');response=await read.get(base+'/exports/'+r2.id);const bytes=Buffer.from(await response.arrayBuffer());ok(response.status===200&&crypto.createHash('sha256').update(bytes).digest('hex')===report.snapshot.csv_sha256,'new partial result export and SHA');fs.writeFileSync(root+'/assets-statements-frozen-private.csv',bytes);fs.writeFileSync(root+'/assets-statements-sample-private.json',JSON.stringify(report));const proof=root+'/assets-statements-http-20261111.json';fs.writeFileSync(proof,JSON.stringify({passed:true,checks,administrative_commands:4,old_snapshot_preserved:true,new_demo:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof}));