import { inputText } from './input-text.ts'; import type { AcquisitionCalculation } from './iva-acquisitions.ts'; import { addFractions, decimalFraction, fraction, subtractFractions, positiveFraction, fractionLabel, fractionPresentation, type FiscalFraction, } from './fiscal-rational.ts'; export const closureVersion = 'iva-closure-ab/1'; export const closureSource = 'L3-A/B: CIVA21(2/5),Lei13/2016 PDF15/p1426(273),23(1),PDF16/p1426(274);RCIVA12/15,Decreto7/2008 PDF3/p101;ModeloA/VAT Return9c0b99a8,p1–2,quadros8/10/11. Crédito anterior/comunicado19/20;22=max(17−19−20,0);25=max(18+19+20−17,0);24=22+23;reporte integral26=25 quando expressamente escolhido. Sem substituição21,reembolso27 ou restituição13(2). Cabeçalho remete18/19 mas caixas são19/20;divergência conservada,distinta deP00105/06.'; type Choice = '' | 'yes' | 'no'; export type ClosureSource = { revision: number; calculatedAt: string; fingerprint: string; opportunity: string; currency: string; period: string; location: string; projected: boolean; debit: FiscalFraction | null; credit: FiscalFraction | null; }; export type ClosureCredit = { id: string; kind: 'opening' | 'communication' | 'previous'; period: string; reference: string; date: string; amount: string; previousId: string; carryKey: string; }; export type ClosurePayment = { id: string; reference: string; date: string; amount: string; }; export type ClosureInput = { id: string; period: string; entityRef: string; origin: 'projected' | 'effective'; source: ClosureSource | null; firstDeclaration: Choice; filing: '' | 'timely' | 'late'; submissionDate: string; filingRef: string; creditsComplete: Choice; credits: ClosureCredit[]; interest: '' | 'none' | 'documented'; interestAmount: string; interestRef: string; destination: '' | 'report' | 'refund'; refundAmount?: string; payments: ClosurePayment[]; }; export type ClosureResult = { id: string; period: string; entityRef: string; origin: ClosureInput['origin']; status: 'determined' | 'indeterminate'; reason: string; inputKey: string; financialKey: string; carryKey: string; fields: Record; paid: FiscalFraction | null; outstanding: FiscalFraction | null; overpayment: FiscalFraction | null; source: string; }; export type ClosureBook = { version: 1; rows: ClosureInput[]; result?: { calculatedAt: string; key: string; inputs: ClosureInput[]; rows: ClosureResult[]; }; history?: Array>; }; const scope = (d: Record) => inputText(d.context_opportunity || 'general'); const zero = () => fraction(0n); export function closureFingerprint(v: unknown): string { const raw = JSON.stringify(v); let h = 14695981039346656037n; for (let i = 0; i < raw.length; i++) h = BigInt.asUintN( 64, (h ^ BigInt(raw.charCodeAt(i))) * 1099511628211n, ); return `${raw.length}:${h.toString(16)}`; } function store(d: Record): Record { const s = JSON.parse( inputText(d.modelo_a_snapshot || '{"version":1,"books":{}}'), ); if (s.version !== 1 || !s.books) throw Error('Livros fiscais não recuperáveis;originais preservados.'); return s; } function maps(d: Record): Record { const v = store(d).ivaClosures; if (v === undefined) return {}; if (!v || typeof v !== 'object' || Array.isArray(v)) throw Error('Mapa de fechos não recuperável;originais preservados.'); return v as Record; } function validate(b: ClosureBook): void { if ( !b || b.version !== 1 || !Array.isArray(b.rows) || (b.history !== undefined && !Array.isArray(b.history)) || (b.result !== undefined && (!Array.isArray(b.result.rows) || !Array.isArray(b.result.inputs) || typeof b.result.key !== 'string')) ) throw Error('FechoL3 não recuperável;originais preservados.'); if ( b.result?.rows.some( (r) => !r || typeof r.id !== 'string' || !r.fields || typeof r.fields !== 'object' || !['determined', 'indeterminate'].includes(r.status) || Object.values(r.fields).some( (v) => v !== null && (!v || !/^\d{1,80}$/.test(v.numerator) || !/^\d{1,80}$/.test(v.denominator) || BigInt(v.denominator) === 0n), ), ) ) throw Error('ResultadoL3 não recuperável;originais preservados.'); for (const r of b.rows) { if ( !r || ![ 'id', 'period', 'entityRef', 'submissionDate', 'filingRef', 'interestAmount', 'interestRef', ].every((k) => typeof r[k as keyof ClosureInput] === 'string') || !['projected', 'effective'].includes(r.origin) || !['', 'yes', 'no'].includes(r.firstDeclaration) || !['', 'yes', 'no'].includes(r.creditsComplete) || !['', 'timely', 'late'].includes(r.filing) || !['', 'none', 'documented'].includes(r.interest) || !['', 'report', 'refund'].includes(r.destination) || (r.refundAmount !== undefined && typeof r.refundAmount !== 'string') || !Array.isArray(r.credits) || !Array.isArray(r.payments) || r.credits.some( (c) => !c || !['opening', 'communication', 'previous'].includes( c.kind, ) || ![ 'id', 'period', 'reference', 'date', 'amount', 'previousId', 'carryKey', ].every( (k) => typeof c[k as keyof ClosureCredit] === 'string', ), ) || r.payments.some( (p) => !p || !['id', 'reference', 'date', 'amount'].every( (k) => typeof p[k as keyof ClosurePayment] === 'string', ), ) || (r.source !== null && (!r.source || !Number.isInteger(r.source.revision) || ![ 'calculatedAt', 'fingerprint', 'opportunity', 'currency', 'period', 'location', ].every( (k) => typeof r.source![k as keyof ClosureSource] === 'string', ))) ) throw Error( 'EntradasL3 não recuperáveis;originais preservados,sem substituir por zero.', ); } } export function closureBook(d: Record): ClosureBook { const b = maps(d)[scope(d)] ?? { version: 1, rows: [] }; validate(b); return b; } export function saveClosureBook( d: Record, b: ClosureBook, ): string { validate(b); const s = store(d); return JSON.stringify({ ...s, ivaClosures: { ...maps(d), [scope(d)]: b } }); } export function closureSources(d: Record): ClosureSource[] { const b = ( store(d).books as Record< string, { result?: AcquisitionCalculation; history?: AcquisitionCalculation[]; } > )[scope(d)]; return b ? [...(b.history ?? []), ...(b.result ? [b.result] : [])] .flatMap((calc) => calc.periods.map((p) => ({ revision: calc.revision, calculatedAt: calc.calculatedAt, fingerprint: closureFingerprint(calc), opportunity: calc.opportunity, currency: calc.currency, period: p.period, location: calc.location, projected: calc.inputs.length === 0 || calc.inputs.some((r) => r.origin === 'projected'), debit: p.exactFields?.['17'] ?? (p.fields['17'] === null ? null : decimalFraction(p.fields['17'])), credit: p.exactFields?.['18'] ?? (p.fields['18'] === null ? null : decimalFraction(p.fields['18'])), })), ) .filter( (r, i, a) => a.findIndex( (s) => s.fingerprint === r.fingerprint && s.period === r.period, ) === i, ) : []; } export function newClosure( id: string, source: ClosureSource | null, entityRef = '', ): ClosureInput { return { id, period: source?.period ?? '', entityRef, origin: 'projected', source: source ? structuredClone(source) : null, firstDeclaration: '', filing: '', submissionDate: '', filingRef: '', creditsComplete: '', credits: [], interest: '', interestAmount: '', interestRef: '', destination: '', payments: [], }; } export function newClosureCredit( id: string, kind: ClosureCredit['kind'], ): ClosureCredit { return { id, kind, period: '', reference: '', date: '', amount: '', previousId: '', carryKey: '', }; } const priorPeriod = (p: string) => { const d = new Date(p + '-01T00:00:00Z'); d.setUTCMonth(d.getUTCMonth() - 1); return d.toISOString().slice(0, 7); }; const validDate = (d: string) => /^20\d{2}-(0[1-9]|1[0-2])-\d{2}$/.test(d) && !Number.isNaN(Date.parse(d)) && new Date(d).toISOString().slice(0, 10) === d; const normalize = (s: string) => s.trim().toLocaleLowerCase(); function creditIdentity(r: ClosureInput, c: ClosureCredit) { return closureFingerprint([ normalize(r.entityRef), r.origin, c.kind === 'previous' ? 'carry' : 'document', c.kind === 'previous' ? c.previousId : normalize(c.reference), c.period, ]); } function paymentIdentity(r: ClosureInput, p: ClosurePayment) { return closureFingerprint([ normalize(r.entityRef), r.origin, normalize(p.reference), ]); } function inputKey(r: ClosureInput) { return closureFingerprint(r); } function financialKey(r: ClosureInput) { const { payments: _, ...rest } = r; return closureFingerprint(rest); } function otherUses(d: Record, b: ClosureBook): ClosureInput[] { return [ ...b.rows, ...Object.entries(maps(d)) .filter(([id]) => id !== scope(d)) .flatMap(([, book]) => { validate(book); return book.rows.filter((r) => r.origin === 'effective'); }), ]; } function duplicateCredits( d: Record, b: ClosureBook, ): Set { const uses = new Map(); for (const r of otherUses(d, b)) for (const c of r.credits) { const k = creditIdentity(r, c); uses.set(k, (uses.get(k) ?? 0) + 1); } return new Set([...uses].filter(([, n]) => n > 1).map(([k]) => k)); } function substitutionPayments(d: Record): string[] { const m = store(d).ivaSubstitutions as | Record< string, { result?: { inputs: Array<{ id: string; prior: { entityRef: string; origin: string } | null; payments: ClosurePayment[]; }>; rows: Array<{ id: string; status: string; paid: FiscalFraction | null; }>; }; history?: Array<{ inputs: Array<{ id: string; prior: { entityRef: string; origin: string } | null; payments: ClosurePayment[]; }>; rows: Array<{ id: string; status: string; paid: FiscalFraction | null; }>; }>; } > | undefined; return Object.entries(m ?? {}).flatMap(([id, b]) => [...(b.history ?? []), ...(b.result ? [b.result] : [])].flatMap((c) => c.inputs .filter( (r) => r.prior && (id === scope(d) || r.prior.origin === 'effective') && c.rows.some( (v) => v.id === r.id && v.status === 'determined' && v.paid, ), ) .flatMap((r) => r.payments.map((p) => closureFingerprint([ normalize(r.prior!.entityRef), r.prior!.origin, normalize(p.reference), ]), ), ), ), ); } function bookKey(d: Record, b: ClosureBook) { const sources = closureSources(d); const values: unknown[] = [ b.rows, b.rows.map((r) => sources.some((s) => JSON.stringify(s) === JSON.stringify(r.source)), ), otherUses(d, b).map((r) => [ normalize(r.entityRef), r.origin, r.period, r.credits.map((c) => creditIdentity(r, c)), r.payments.map((p) => paymentIdentity(r, p)), ]), ]; const reserved = substitutionPayments(d), conflicts = b.rows .flatMap((r) => r.payments.map((p) => paymentIdentity(r, p))) .filter((k) => reserved.includes(k)); if (conflicts.length) values.push(conflicts); return closureFingerprint(values); } export function closureCurrent( d: Record, b: ClosureBook, ): boolean { return ( !!b.result && b.result.key === bookKey(d, b) && b.result.rows.length === b.rows.length && b.rows.every( (r) => b.result!.rows.filter( (x) => x.id === r.id && x.inputKey === inputKey(r), ).length === 1, ) ); } export function adoptPreviousCredit( c: ClosureCredit, previous: ClosureResult, ): ClosureCredit { if (previous.status !== 'determined' || !previous.fields['26']) throw Error('Fecho anterior indeterminado;sem crédito presumido.'); return { ...c, kind: 'previous', period: previous.period, reference: `Fecho ${previous.id}`, previousId: previous.id, carryKey: previous.carryKey, amount: fractionPresentation(previous.fields['26']).decimal, date: '', }; } function refundLockConflict( d: Record, row: ClosureInput, fields: Record, ): boolean { const books = store(d).ivaRefunds as | Record< string, { rows: Array<{ source: { closureId: string; entityRef: string; origin: string; period: string; credit: FiscalFraction; carry: FiscalFraction; requested: FiscalFraction; } | null; stage: string; decision: string; receipts: unknown[]; }>; result?: { inputs: Array<{ source: { closureId: string; entityRef: string; origin: string; period: string; credit: FiscalFraction; carry: FiscalFraction; requested: FiscalFraction; } | null; stage: string; decision: string; receipts: unknown[]; }>; }; history?: Array<{ inputs: Array<{ source: { closureId: string; entityRef: string; origin: string; period: string; credit: FiscalFraction; carry: FiscalFraction; requested: FiscalFraction; } | null; stage: string; decision: string; receipts: unknown[]; }>; }>; } > | undefined; return Object.entries(books ?? {}).some(([context, book]) => [ ...book.rows, ...[ ...(book.history ?? []), ...(book.result ? [book.result] : []), ].flatMap((c) => c.inputs), ].some( (r) => r.source && (context === scope(d) || r.source.origin === 'effective') && r.source.closureId === row.id && normalize(r.source.entityRef) === normalize(row.entityRef) && r.source.origin === row.origin && r.source.period === row.period && (r.stage === 'submitted' || r.decision !== 'pending' || r.receipts.length > 0) && [ ['25', r.source.credit], ['26', r.source.carry], ['27', r.source.requested], ].some( ([f, v]) => JSON.stringify(fields[f as string]) !== JSON.stringify(v), ), ), ); } function effectiveCarryAlreadyUsed( d: Record, row: ClosureInput, fields: Record, ): boolean { if (row.origin !== 'effective' || row.destination !== 'refund') return false; const books = maps(d), own = books[scope(d)]; if (!own) return false; const prior = [...(own.history ?? []), ...(own.result ? [own.result] : [])] .flatMap((c) => c.rows) .filter( (r) => r.id === row.id && r.origin === 'effective' && r.fields['26'] && fields['26'] && BigInt( subtractFractions(r.fields['26'], fields['26']).numerator, ) > 0n, ); return prior.some((p) => Object.values(books).some((b) => [...(b.history ?? []), ...(b.result ? [b.result] : [])].some((c) => c.inputs.some( (input) => input.origin === 'effective' && normalize(input.entityRef) === normalize(row.entityRef) && input.period > row.period && input.credits.some( (credit) => credit.kind === 'previous' && credit.previousId === p.id && credit.carryKey === p.carryKey, ) && c.rows.some( (r) => r.id === input.id && r.status === 'determined', ), ), ), ), ); } export function recordClosure( d: Record, b: ClosureBook, now = new Date().toISOString(), ): ClosureBook { validate(b); if (new Set(b.rows.map((r) => r.id)).size !== b.rows.length) throw Error('Identidade de fecho repetida.'); const contexts = b.rows.map((r) => JSON.stringify([normalize(r.entityRef), r.origin, r.period]), ); if (new Set(contexts).size !== contexts.length) throw Error( 'Mesmo âmbito/período repetido neste cenário;sem duplicar o fecho.', ); const duplicate = duplicateCredits(d, b), puses = new Map(); for (const r of otherUses(d, b)) for (const p of r.payments) { const k = paymentIdentity(r, p); puses.set(k, (puses.get(k) ?? 0) + 1); } const results: ClosureResult[] = []; for (const row of [...b.rows].sort((a, z) => a.period.localeCompare(z.period), )) { const fields: Record = Object.fromEntries( [ '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', ].map((f) => [f, null]), ); const r: ClosureResult = { id: row.id, period: row.period, entityRef: row.entityRef, origin: row.origin, status: 'indeterminate', reason: '', inputKey: inputKey(row), financialKey: financialKey(row), carryKey: '', fields, paid: null, outstanding: null, overpayment: null, source: closureSource, }; const stop = (reason: string) => { r.reason = reason; results.push(r); }; if ( !/^2026-(0[1-9]|1[0-2])$/.test(row.period) || !row.entityRef.trim() || d.currency !== 'MZN' ) { stop( 'Identifique âmbito fiscal e período2026/MZN;sem consolidar oportunidades automaticamente.', ); continue; } if ( row.origin === 'effective' && otherUses(d, b).some( (other) => other !== row && other.origin === 'effective' && normalize(other.entityRef) === normalize(row.entityRef) && other.period === row.period, ) ) { stop( 'Mesmo âmbito fiscal/período efectivo reservado noutra oportunidade recuperada;reconcilie a declaração única,sem duplicar ou consolidar dossiers silenciosamente.', ); continue; } const source = closureSources(d).find( (s) => JSON.stringify(s) === JSON.stringify(row.source), ); if ( !source || source.period !== row.period || source.opportunity !== scope(d) || source.currency !== 'MZN' || !source.debit || !source.credit ) { stop( 'ResultadoL2 congelado correspondente ausente ou17/18 indeterminados;sem recalcular nem presumir impostozero.', ); continue; } fields['17'] = source.debit; fields['18'] = source.credit; if ( BigInt(source.debit.numerator) < 0n || BigInt(source.credit.numerator) < 0n || (BigInt(source.debit.numerator) > 0n && BigInt(source.credit.numerator) > 0n) ) { stop('Sinais17/18 incompatíveis;resolver origemL2.'); continue; } if (row.origin === 'effective' && source.projected) { stop( 'OrigemL2 contém pressupostos projectados;não os apresentar como declaração efectiva.', ); continue; } if (row.firstDeclaration !== 'yes') { stop( 'Este percursoA/B exige primeira declaração;substituição21 permaneceL3-C.', ); continue; } if ( !validDate(row.submissionDate) || row.submissionDate.slice(0, 7) < row.period || !row.filingRef.trim() || row.filing !== 'timely' ) { stop( row.filing === 'late' ? 'Declaração fora do prazo:RCIVA15 e exemplar não permitem uso19/20 neste percurso;conservar conta de crédito e tratar procedimento próprio,sem o apagar.' : 'Indique data e fundamento da entrega em prazo,efectivos ou pressupostos;sem calendário/prazo presumido.', ); continue; } if (row.creditsComplete !== 'yes') { stop( 'Reconcilie todos os créditos aplicáveis;lista vazia só significa ausência quando expressamente confirmada.', ); continue; } const credits19: FiscalFraction[] = [], credits20: FiscalFraction[] = []; let invalid = ''; for (const c of row.credits) { if ( !c.reference.trim() || !/^20\d{2}-(0[1-9]|1[0-2])$/.test(c.period) || c.period > row.period || (c.kind !== 'communication' && c.period === row.period) || duplicate.has(creditIdentity(row, c)) ) { invalid = 'Crédito sem origem/período aplicável ou já utilizado/reservado noutra linha/âmbito recuperado;sem utilização duplicada.'; break; } if (c.kind === 'previous') { const p = results.find((p) => p.id === c.previousId); if ( !p || p.status !== 'determined' || p.period !== priorPeriod(row.period) || p.entityRef.trim().toLowerCase() !== row.entityRef.trim().toLowerCase() || p.origin !== row.origin || p.period !== c.period || p.carryKey !== c.carryKey || !p.fields['26'] ) { invalid = 'Fecho anterior alterado,indeterminado,fora do mês imediatamente anterior ou de outro âmbito;não adoptar novo crédito silenciosamente.'; break; } credits19.push(p.fields['26']); } else { let v: FiscalFraction; try { v = decimalFraction(c.amount); } catch { invalid = 'Montante de crédito em falta/inválido;não substituir porzero.'; break; } if ( c.kind === 'opening' && c.period !== priorPeriod(row.period) ) { invalid = 'Saldo de abertura exige referência ao saldo disponível do mês imediatamente anterior;origem mais antiga deve ser reconciliada nesse saldo.'; break; } if ( c.kind === 'opening' && b.rows.some( (p) => p.id !== row.id && p.entityRef.trim().toLowerCase() === row.entityRef.trim().toLowerCase() && p.origin === row.origin && p.period === priorPeriod(row.period), ) ) { invalid = 'Há fecho do período anterior neste livro;reutilize26 expressamente em vez de introduzir outra abertura.'; break; } if ( c.kind === 'communication' && (!validDate(c.date) || c.date > row.submissionDate) ) { invalid = 'Crédito20 exige comunicação recebida,referência e data não posterior à entrega declarada;pedido não é comunicação.'; break; } (c.kind === 'opening' ? credits19 : credits20).push(v); } } if (invalid) { stop(invalid); continue; } fields['19'] = addFractions(credits19); fields['20'] = addFractions(credits20); const balance = subtractFractions( addFractions([source.credit, fields['19'], fields['20']]), source.debit, ); fields['22'] = positiveFraction( fraction(-BigInt(balance.numerator), BigInt(balance.denominator)), ); fields['25'] = positiveFraction(balance); if (row.interest === 'none' && row.interestRef.trim()) fields['23'] = zero(); else if (row.interest === 'documented' && row.interestRef.trim()) { try { fields['23'] = decimalFraction(row.interestAmount); } catch { /* Preserve unknown. */ } } fields['24'] = fields['23'] ? addFractions([fields['22'], fields['23']]) : null; if (row.destination === 'report') { fields['26'] = fields['25']; fields['27'] = zero(); } else if (row.destination === 'refund') { let amount: FiscalFraction; try { amount = decimalFraction(row.refundAmount ?? ''); } catch { stop( 'Identifique a parcela destinada ao pedido;sem montante presumido.', ); continue; } if ( BigInt(amount.numerator) === 0n || BigInt(subtractFractions(fields['25'], amount).numerator) < 0n ) { stop( 'Parcela do pedido deve ser positiva e não exceder o crédito25;sem dupla utilização.', ); continue; } fields['27'] = amount; fields['26'] = subtractFractions(fields['25'], amount); r.source += ' D:afectação expressa26+27=25,sem concessão/recebimento;CIVA21 eModeloA11.'; } else { stop( 'Escolha reporte integral ou parcela para preparação de reembolsoD;sem destino presumido.', ); continue; } if (refundLockConflict(d, row, fields)) { stop( 'Crédito ligado a pedido apresentado/decisão/recebimento;conserve a afectação e reconcilie o procedimento,sem o voltar a reportar ou alterar silenciosamente.', ); continue; } if (effectiveCarryAlreadyUsed(d, row, fields)) { stop( 'Reporte efectivo já utilizado numa declaração posterior recuperada;prepare o pedido sobre o saldo disponível do período reconciliado,sem reafectar retroactivamente crédito consumido.', ); continue; } if (!fields['24']) { stop( 'Juros23 por identificar:indique montante documentado/pressuposto ou inexistência expressa com motivo;sem taxa presumida.', ); continue; } r.status = 'determined'; r.carryKey = closureFingerprint([ r.id, r.financialKey, fields['26'], scope(d), ]); const payments: FiscalFraction[] = []; for (const p of row.payments) { if ( !p.reference.trim() || !validDate(p.date) || (puses.get(paymentIdentity(row, p)) ?? 0) > 1 || substitutionPayments(d).includes(paymentIdentity(row, p)) ) { invalid = 'Pagamento sem referência/data ou repetido noutro período/declaração;conserve o documento e reconcilie a imputação.'; break; } try { payments.push(decimalFraction(p.amount)); } catch { invalid = 'Montante de pagamento por identificar;sem baixa presumida.'; break; } } if (invalid) { stop(invalid); continue; } r.paid = addFractions(payments); r.outstanding = positiveFraction( subtractFractions(fields['24'], r.paid), ); r.overpayment = positiveFraction( subtractFractions(r.paid, fields['24']), ); r.status = 'determined'; r.carryKey = closureFingerprint([ r.id, r.financialKey, fields['26'], scope(d), ]); r.reason = 'Saldo calculado, pagamentos registados e crédito transportado distintos. Pagamento não altera22/25/26;excedente pago não cria crédito20 sem comunicação.21 não aplicável à primeira declaração;' + (row.destination === 'refund' ? '26/27 separados pela afectação;27 é parcela destinada a pedidoD,sem concessão nem recebimento. ' : '27zero pela opção expressa de reporte integral. ') + (row.origin === 'projected' ? 'Pressupostos de simulação,sem declaração ou pagamento efectuados pelo portal.' : 'Dados efectivos declarados;registo não certifica cobrança nem submissãoAT.'); results.push(r); } const result = { calculatedAt: now, key: bookKey(d, b), inputs: structuredClone(b.rows), rows: results, }; return { ...b, ...(b.result ? { history: [...(b.history ?? []), structuredClone(b.result)] } : {}), result, }; } export function closureReportRows( d: Record, ): Array<[string, string, string, string]> { try { const b = closureBook(d); if (!b.rows.length) return []; const hasRefund = b.result?.rows.some( (r) => r.fields['27'] && BigInt(r.fields['27'].numerator) > 0n, ); const description = hasRefund ? closureSource.replace( 'Sem substituição21,reembolso27 ou restituição13(2).', 'ExtensãoD:26+27=25;27é parcela destinada a pedido,não decisão/recebimento. Substituição21 e restituição13(2) mantêm percursos próprios.', ) : closureSource; const out: Array<[string, string, string, string]> = [ [ 'IVA mensal', 'L3-A/B — fecho por período', closureCurrent(d, b) ? 'Resultado correspondente às entradas' : 'Histórico preservado;rever entradas/origens antes de utilizar', description, ], ]; for (const r of b.result?.rows ?? []) { const input = b.result?.inputs.find((x) => x.id === r.id), source = input?.source; const context = `${r.entityRef};${scope(d)};MZN;${r.origin === 'projected' ? 'Pressuposto de simulação' : 'Dados efectivos declarados'};versão guardada${b.result!.calculatedAt}`; out.push([ 'IVA mensal', `Fecho A/B — ${r.period}`, Object.entries(r.fields) .map( ([f, v]) => `${f}:${v ? fractionPresentation(v).decimal : f === '21' && input?.firstDeclaration === 'yes' ? 'Não aplicável (primeira declaração)' : 'Indeterminado'}`, ) .join('; '), `${context};${r.reason}`, ]); const credits = (input?.credits ?? []) .map( (c) => `${c.kind === 'communication' ? 'Comunicação20' : c.kind === 'previous' ? 'Transporte19' : 'Abertura19'}: ${c.reference};origem${c.period};montante apresentado${c.amount}MZN${c.date ? ';recebida' + c.date : ''}`, ) .join(' | ') || 'Sem créditos registados'; const payments = (input?.payments ?? []) .map((p) => `${p.reference};${p.date};${p.amount}MZN`) .join(' | ') || 'Sem pagamentos registados'; out.push([ 'IVA mensal', `Pagamentos e reporte — ${r.period}`, `Calculado24:${r.fields['24'] ? fractionLabel(r.fields['24']) : 'Indeterminado'};pagamentos registados:${r.paid ? fractionLabel(r.paid) : 'Indeterminado'};por liquidar:${r.outstanding ? fractionLabel(r.outstanding) : 'Indeterminado'};excedente pago:${r.overpayment ? fractionLabel(r.overpayment) : 'Indeterminado'};transportado26:${r.fields['26'] ? fractionLabel(r.fields['26']) : 'Indeterminado'}`, `${context};OrigemL2:revisão${source?.revision ?? 'por identificar'},${source?.period ?? ''},${source?.location ?? ''},${source?.calculatedAt ?? ''};${credits};${payments};entrega${input?.submissionDate ?? ''},${input?.filingRef ?? ''};juros:${input?.interestRef ?? ''}`, ]); } return out; } catch { return [ [ 'IVA mensal', 'L3-A/B', 'Fecho guardado não recuperável', 'Originais preservados;sem crédito ou pagamento presumidos.', ], ]; } }