Files
compras/docs/passagem-historico-pagamentos.md
nala 413c201d97
tests / ci (push) Canceled after 0s
commit5
2026-10-29 22:03:09 +02:00

50 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Passagem de histórico de pagamentos para obrigações
29/10/2026. Continuação autorizada pelo proprietário após a conferência do novo menu. Identificador técnico: `PAYABLE-HISTORY-IMPORT-v1`.
## Resultado e limites
Implementada uma passagem explícita em duas etapas: preparar a fotografia dos pagamentos existentes e validá-la por pessoa distinta. A factura conferida mantém o principal integral. A obrigação comum passa a fornecer o saldo, deduzindo uma única vez apenas os pagamentos anteriormente confirmados. Pendentes e rejeitados conservam montantes/estados e não são deduzidos.
Não é um novo pagamento, afectação arbitrária ou reconciliação bancária. Não executa transferências, confirma pendentes, cria stock, consome novamente orçamento ou produz lançamentos contabilísticos. O circuito normal continua a recusar incorporar pagamentos implicitamente; o percurso novo tem acções e activação próprias.
Exemplo de referência: principal 1 160,00 MZN, confirmado 300,00 e pendente 100,00 → saldo 860,00. Prova PostgreSQL integrada: principal 11 600,00, confirmado 3 000,00, pendente 1 000,00 e rejeitado 500,00 → saldo 8 600,00; pendente/rejeitado não reduzem o saldo. Vencimento e dias de atraso mantêm-se nulos.
## Responsabilidade e preservação
- Fonte única em `sgf-tempo/packages/payables`: `HistoricalPayments`, `HistorySchema` e extensão opcional de `Payables`; sem segundo motor de saldo no adaptador Compras.
- `principal()` conserva o principal documental; `balance()` consulta a posição do núcleo. `ExternalPaymentWorkflow::outstanding()` recebe o saldo comum já líquido, sem voltar a subtrair os mesmos pagamentos.
- A fotografia guarda IDs, empresa/documento/moeda, valor, estado, autor/data e referências das auditorias de registo/decisão. Não copia referências externas cifradas, comprovativos, contas bancárias ou instruções de pagamento.
- O adaptador confere que a auditoria corresponde ao pagamento, factura, valor, estado e interveniente. Confirmações/rejeições exigem decisão independente; a importação não reescreve decisões históricas em função dos perfis actuais desses antigos intervenientes.
- Identidade canónica por instância/empresa/documento, chave única por pagamento original e uma importação por obrigação/origem. Mudança de identidade não pode criar uma segunda obrigação para a mesma factura local.
- Mudança de pagamentos entre preparação e validação produz conflito e exige nova fotografia. Leitura posterior detecta origem/histórico divergente e deixa o saldo indisponível, conservando principal/originais. Desactivar a integração com obrigação incorporada não autoriza cair silenciosamente no saldo antigo.
- A gravação do principal, passagem, ligações, eventos e idempotência é transaccional. Falha intermédia não deixa incorporação parcial. A importação não altera as tabelas originais de factura, pagamentos, orçamento ou stock.
## Esquema, acesso e interface
Migração aditiva `2026_10_29_000022_create_payable_history_imports.php`, com duas tabelas append-only: `pa_history_imports` e `pa_imported_payments`. Reutiliza os direitos explícitos de preparação/validação existentes; a validação própria permanece recusada. Não cria contas nem concessões.
Activação separada `COMMON_PAYABLES_HISTORY_ENABLED=false` por omissão. Exige integração anterior activa, esquema completo e adaptador com fornecedor de histórico. O SGF mantém o percurso anterior sem pagamentos; esta entrega não configura automaticamente um fornecedor de pagamentos históricos no adaptador SGF.
Na página comum, quando activado e existindo pagamentos na factura, surge «Incorporar factura com pagamentos anteriores». A proposta apresenta confirmados/pendentes/rejeitados. A obrigação apresenta principal e saldo por liquidar separadamente. As fotografias antigas continuam consultáveis. Depois da passagem, novos pagamentos e confirmação de pendentes ficam para o incremento do circuito comum; não continuar a escrever pelo percurso antigo após transferir a responsabilidade.
## Estado de aplicação
Após orientação posterior «continue», **000022 aplicada em `compras_dev`, lote 23**, e `COMMON_PAYABLES_HISTORY_ENABLED=true` guardado no `.env` local. Novo backup privado de 367 910 bytes, SHA-256 `1f29bdaf0ea0379475c26e78f07cffe2ca31401ab216031b499c2562bafad7dc`, restaurado e comparado nas 72 tabelas antes da aplicação; base de restauro removida. Registos/restrições anteriores preservados na aplicação transaccional; duas tabelas novas vazias e dois triggers append-only conferidos.
Activação registada em `supplier_payables.history_local_activated`, sem criar conta ou alterar concessões. Projecções dos registos das 72 tabelas anteriores conferidas novamente, descontando apenas o registo da nova migração e a nova entrada de auditoria. Identidade da instalação e permissões anteriores preservadas. A configuração foi confirmada num processo novo: activação histórica verdadeira, uma conta, três direitos anteriores e zero facturas/pagamentos/obrigações. Nenhuma incorporação automática.
Evidências sanitizadas: `historico-migracao-000022.json` e `historico-activacao-local.json`. Backup/manifesto privados em `storage/app/private/backups/payable-history-000022-20261029-193307-f5d793/`.
As demonstrações persistentes e o servidor público não foram migrados/configurados nesta aplicação. Conferência só de leitura em 8005 confirmou activação histórica falsa e ausência das tabelas novas nesse ambiente. A demonstração não passa a ter histórico sintético por consequência da activação de `compras_dev`. Migração/activação anteriores 000021, menus e acessos do proprietário preservados. A interface nova foi conferida por resposta HTML nas provas PostgreSQL, sem uma nova prova visual no navegador.
## Provas
`PayableHistoryImportTest.php`: principal bruto/saldo, decisão independente, repetição da mesma chave e de chaves distintas, pagamentos pendentes/rejeitados, total liquidado, alteração entre proposta/validação, ausência de auditoria, falha/recuperação, imutabilidade, configuração desactivada, duplicações/omissões/incompatibilidades, mudança de identidade e exemplo 1 160−300=860.
`scripts/payable-history-proof.mjs`: cria bases/roles QA exclusivas, regista/conferencia os pagamentos sintéticos pelo circuito existente, injecta uma falha e valida simultaneamente em dois processos. Confere uma obrigação, uma importação, três ligações, saldo correcto, original de negócio intacto, protecções SQL e recusa de alteração histórica; elimina as bases/roles no final. Relatório sanitizado: `proofs/payable-history-pg.json`.
Regressão geral: **517 aprovados, 2 ignorados, 4 337 asserções** (519 testes). Após o reforço final da consulta de identidade, repetida a bateria específica: **11 aprovados, 64 asserções**. PHPStan dos adaptadores/controlador e Pint do âmbito aprovados. A prova antiga de obrigações sem pagamentos também passou em Compras e SGF, com concorrência/recuperação e efeitos de orçamento/stock/pagamentos preservados. As bases e roles de ambas as provas PostgreSQL foram removidas.
Leitura anterior à aplicação: 000022 não aplicada e importação histórica desactivada. A aplicação/activação posteriores estão registadas acima. Não há build novo neste incremento PHP/esquema; o frontend e os menus anteriores não foram alterados. As verificações técnicas e a activação local não constituem aceitação visual ou publicação, nem executam pagamentos.