import { closureBook, closureCurrent } from './iva-closure.ts'; import { substitutionBook, substitutionCurrent } from './iva-substitution.ts'; import { refundBook, refundCurrent } from './iva-refund.ts'; import { beverageRestitutionBook, beverageRestitutionCurrent, } from './iva-beverage-restitution.ts'; import { fractionPresentation, fractionLabel, type FiscalFraction, } from './fiscal-rational.ts'; export const l3FormReference = { file: 'VAT Return.pdf', sha256: '9c0b99a810c7db53eb75d63c22ee22fb86a50ba57bd5509041ed80ee10f75741', page: 2, scope: 'Preparação dos campos identificados dos quadros8–11 do exemplar recebido;edição/aceitação electrónica não estabelecida.', }; export const l3FormalitiesDependencies = [ { branch: 'A/B', identified: 'Quadros8/10/11 e campos19/20/22–27 do exemplar recebido,PDF2;CIVA21(2/5)/23(1);RCIVA12/15.', missing: 'Identificação da edição electrónica aplicável e dados de autenticação/meio de pagamento não inferidos dos recibos.', trigger: 'Exemplar/instrução da edição electrónica ou dados do sujeito passivo;nenhuma assinatura ou submissão automática.', }, { branch: 'C', identified: 'Quadro9/campo21 e transcrição positiva para22 do exemplar recebido,PDF2.', missing: 'RCIVA15 refereModeloB;exemplar recebido assinala substituiçãoModeloA. Correspondência de edição/formulário regulamentar por resolver.', trigger: 'ModeloB/instrução que esclareça a correspondência com a edição recebida. Preservar cálculo e preparação de21–24.', }, { branch: 'D', identified: 'Quadro11:25=26+27;pedido27 não volta a19 sem comunicação. Remissãoart20 impressa conservada como divergência;regime2026 assenta em21.', missing: 'Exemplares e instruções regulamentares específicos de reembolso:Decretos78/2017,30/2022 e52/2025 identificados na análise anterior;sem correspondência de campos demonstrada.', trigger: 'Texto/modelo/instrução integral novo ou já fornecido;sem repetir a pesquisa anterior sem nova evidência. Preparação26/27 não equivale ao pedido regulamentar completo.', }, { branch: 'E', identified: 'CIVA13(1)c/d/h e13(2–3);pedido,decisão e recebimento separados no dossier.', missing: 'Modelo e procedimento específico de restituição de bebidas por identificar. Não usar27 como se fosse a restituição13(2).', trigger: 'Exemplar ou instrução específica de13(2);sem importar limiares,prazos ou modelos do reembolso geralD.', }, ] as const; export type L3FormPreparation = { id: string; branch: string; period: string; entity: string; current: boolean; reference: string; status: string; fields: Array<{ field: string; label: string; value: string; exact: string; }>; notes: string[]; }; const fmt = (v: FiscalFraction | null | undefined) => v ? fractionPresentation(v).decimal : 'Indeterminado'; const cell = ( field: string, label: string, v: FiscalFraction | null | undefined, ) => ({ field, label, value: fmt(v), exact: v ? fractionLabel(v) : 'Indeterminado', }); export function l3FormPreparations( d: Record, ): L3FormPreparation[] { const out: L3FormPreparation[] = [], ab = closureBook(d), c = substitutionBook(d), rd = refundBook(d), e = beverageRestitutionBook(d); for (const r of ab.result?.rows ?? []) { const input = ab.result!.inputs.find((i) => i.id === r.id); out.push({ id: `AB:${r.id}`, branch: 'A/B', period: r.period, entity: r.entityRef, current: closureCurrent(d, ab), reference: `${l3FormReference.file};SHA256${l3FormReference.sha256};PDF2/quadros8,10,11`, status: r.status, fields: [ ['19', 'Excesso do período anterior'], ['20', 'Créditos comunicados'], ['22', 'IVA a entregar'], ['23', 'Juros compensatórios'], ['24', 'Importância a pagar'], ['25', 'Crédito de imposto'], ['26', 'Reporte seguinte'], ['27', 'Pedido de reembolso'], ].map(([f, label]) => cell(f, label, r.fields[f])), notes: [ `Versão congelada${ab.result!.calculatedAt};${input?.origin ?? ''};fonteL2${input?.source?.revision ?? ''}.`, 'Cabeçalho refere18/19,mas caixas19/20;original não renumerado. Meio de pagamento,assinatura e uso dos serviços ficam por preencher.', '27 é afectação a pedido geral,não decisão nem recebimento;05/06 permanecem fora desta preparaçãoL3.', ], }); } for (const r of c.result?.rows ?? []) { const input = c.result!.inputs.find((i) => i.id === r.id); out.push({ id: `C:${r.id}`, branch: 'C', period: input?.prior?.period ?? '', entity: input?.prior?.entityRef ?? '', current: substitutionCurrent(d, c), reference: `${l3FormReference.file};PDF2/quadro9;${l3FormalitiesDependencies[1].missing}`, status: r.status, fields: [ ['21', 'Diferencial'], ['22', 'Diferencial devedor'], ['23', 'Juros adicionais'], ['24', 'Importância adicional a pagar'], ].map(([f, label]) => cell(f, label, r.fields[f])), notes: [ `Anterior${input?.priorReference ?? ''};${input?.priorDate ?? ''};substituição${input?.reference ?? ''};${input?.date ?? ''};${input?.stage ?? ''}.`, r.reason, 'Crédito credor aguarda comunicação20;pagamentos anteriores conservam-se e não voltam a ser inscritos como pagamento adicional.', ], }); } for (const r of rd.result?.rows ?? []) { const input = rd.result!.inputs.find((i) => i.id === r.id); out.push({ id: `D:${r.id}`, branch: 'D', period: input?.source?.period ?? '', entity: input?.source?.entityRef ?? '', current: refundCurrent(d, rd), reference: `${l3FormReference.file};PDF2/quadro11;${l3FormalitiesDependencies[2].missing}`, status: r.status, fields: [ cell('25', 'Crédito de imposto', input?.source?.credit), cell('26', 'Reporte separado', r.reported), cell('27', 'Pedido de reembolso', r.requested), ], notes: [ `Pedido${input?.requestReference ?? ''};${input?.requestDate ?? ''};${input?.stage ?? ''}.`, r.reason, `Acompanhamento separado:reconhecido${fmt(r.approved)};recebido${fmt(r.received)};por receber${fmt(r.awaitingReceipt)}MZN. Estes valores não substituem27.`, ], }); } for (const r of e.result?.rows ?? []) { const input = e.result!.inputs.find((i) => i.id === r.id); out.push({ id: `E:${r.id}`, branch: 'E', period: input?.source?.period ?? '', entity: input?.entityRef ?? '', current: beverageRestitutionCurrent(d, e), reference: 'Dossier de apoio13(2);modelo oficial específico ainda não identificado.', status: r.status, fields: [ cell('Dossier', 'IVA documental', input?.source?.vat), cell('Dossier', 'Parcela pedida', r.requested), { field: 'Dossier', label: 'Dedução desta parcela', value: r.requested ? '0.00' : 'Indeterminado', exact: r.requested ? '0/1' : 'Indeterminado', }, cell('Dossier', 'Reconhecido', r.approved), cell('Dossier', 'Recebido', r.received), cell('Dossier', 'Por receber', r.awaitingReceipt), ], notes: [ `Documento${input?.source?.documentRef ?? ''};linha${input?.source?.documentLine ?? ''};operação${input?.source?.operationId ?? ''};pedido${input?.requestReference ?? ''};${input?.requestDate ?? ''}.`, r.reason, 'Sem campo27 nem formulárioD presumidos;IVA do fornecimento mantém cálculo próprio.', ], }); } return out; } export const l3PreparationStatus = (status: string) => status === 'determined' ? 'Cálculo determinado' : status === 'indeterminate' ? 'Indeterminado' : status; const escape = (s: string) => s.replace( /[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', })[c]!, ); export function l3FormPreparationHtml(p: L3FormPreparation): string { return `Preparação L3 ${escape(p.branch)}

Preparação L3 ${escape(p.branch)} — ${escape(p.period)}

${escape(p.entity)};${escape(l3PreparationStatus(p.status))};${p.current ? 'Correspondente às entradas' : 'Histórico preservado;rever entradas/origem'}. Submissão externa;preparação para conferência,não declaração AT submetida.

${escape(p.reference)}

${p.fields.map((f) => ``).join('')}
CampoFinalidadeMZNValor exacto
${escape(f.field)}${escape(f.label)}${escape(f.value)}${escape(f.exact)}
${p.notes.map((n) => `

${escape(n)}

`).join('')}

Formalidades ainda por completar

${l3FormalitiesDependencies .filter( (dep) => dep.branch === p.branch || (p.branch === 'A/B' && dep.branch === 'D'), ) .map( (dep) => `

${escape(dep.missing)}Condição de retoma:${escape(dep.trigger)}

`, ) .join( '', )}

Fracções exactas conservadas;decimais são apresentação técnica,sem arredondamento fiscal final ou alteração de histórico.

`; } export function l3FormPreparationReportRows( d: Record, ): Array<[string, string, string, string]> { try { return l3FormPreparations(d).flatMap((p) => [ [ 'IVA mensal', `Preparação formal L3${p.branch} — ${p.period}`, `${p.current ? 'Entradas correspondentes' : 'Histórico;rever origem'};${l3PreparationStatus(p.status)};${p.fields.map((f) => `${f.field}/${f.label}:${f.value}MZN;exacto${f.exact}`).join(' | ')}`, `${p.reference};${p.notes.join(' | ')}`, ] as [string, string, string, string], ]); } catch (error) { return [ [ 'IVA mensal', 'Preparação formalL3', 'Dados não recuperáveis;originais preservados', String(error), ], ]; } }