docs: RentCharge 006.2026 — SPEC-ACCOUNT-RECEIVABLES.md

This commit is contained in:
roger 2026-09-19 11:22:06 +00:00
parent cbbad7c64d
commit acd9fb618c

View file

@ -0,0 +1,259 @@
# SPEC — Account Receivables / Credit Book / Period dashboard
**Data:** 2026-09-08 → 2026-09-09 (noite)
**Status:** implementado na VM500 (`rentcharge-backend` + `rentcharge-frontend`)
**Produto:** RentCharge / RenteCharge Weekly & Arrears
**Operador:** Roger
**Relacionados:** `SPEC-VM500-RENTCHARGE.md` (infra) · `PROJECT-RENTCHARGE.md` (produto) · Rules UI `/rules` secção **12. Credit Book (R-CB01…R-CB05)** · **`SPEC-AR-QR-BINARY-EYE.md`** (cartões QR 1–50 + Binary Eye — draft) · **`SPEC-TRANSACTION-IDS.md`** (prefixos ME/KC/EL/DN/LY · CR/CT · hash ROI)
---
## 1. Escopo desta noite
Módulo **Account Receivables** (ancillary, ≠ rent SA / arrears):
- Meals (Lunch / Dinner / Cup of tea)
- Access key
- Electricity top-up
Canais:
| Canal (código) | Label IE | Cor |
|----------------|----------|-----|
| `cash` | Cash sale | Verde |
| `credit` | Credit sale (ex-fiado) | Vermelho |
| `credit_payment` | Credit settlement | Azul |
Glossário contabilístico (Irlanda):
| Conceito | Termo canónico |
|----------|----------------|
| Fiado | **Credit sale** |
| Pagamento do fiado | **Credit settlement** |
| Crédito a haver (pagou a mais) | **Over-settlement** |
| Ainda a limpar | **To clear** |
| Status | Clear · Outstanding · Over-settlement |
---
## 2. Credit Book — saldo assinado (R-CB01…R-CB05)
### Fórmula
```
signed_balance = Σ credit sales − Σ credit settlements
```
| signed_balance | UI | Cor |
|----------------|----|-----|
| `> 0` | **To clear** / status **Outstanding** | Vermelho |
| `< 0` | **Over-settlement** | Azul |
| `≈ 0` | **Clear** | Neutro |
Helpers: `backend/app/services/ledger.py` → `credit_book_balance`, `credit_book_position`.
### R-CB02 — Settlement pode criar over-settlement
Exemplo: deve €25, paga €50 settlement → limpa €25; sobra **€25 over-settlement** (signed −€25).
Cash do settlement entra no remittance ROI Finance; o surplus fica no Credit Book (não é crédito de rent).
**Implementação:** deixou de bloquear `credit_payment > to_clear`.
### R-CB03 — Novos tickets consomem over-settlement primeiro
Novo **Credit sale** (meals / key / electricity) com over-settlement existente: o lançamento move o saldo em direção a zero; só o excedente vira **Outstanding**.
### R-CB04 — Credit consumption statuses
Clear · Outstanding · Over-settlement (filtro + cores no report).
### R-CB05 — Modal Post sale
Mostra **To clear** (vermelho) + **Over-settlement** (azul) do residente seleccionado + stamp + hints R-CB02/03.
Documentado também em `/rules` secção 12.
---
## 3. APIs ledger
Base: `/api/ledger/…` · auth: utilizador logado; create/edit/delete: `require_payment_editor` (`can_edit_payments` / superuser).
| Método | Path | Notas |
|--------|------|-------|
| GET | `/api/ledger/accounts` | Catálogo MEALS_* / ACCESS_KEY / ELEC_TOPUP |
| GET | `/api/ledger/entries` | Filtros date/resident/account/channel |
| POST | `/api/ledger/entries` | Create; stamp week/weekday/time |
| PUT | `/api/ledger/entries/{id}` | Edit + `confirm_password` |
| POST | `/api/ledger/entries/{id}/delete` | Delete + `confirm_password` |
| GET | `/api/ledger/credit-book` | Overview + `to_clear` / `credit_available` / `status` |
| GET | `/api/residents/{id}/credit-book` | Posição + entries |
| GET | `/api/ledger/reports/roi-finance` | Pack ROI Finance |
| GET | `/api/ledger/reports/credit-consumption` | Credit report |
| GET | `/api/ledger/reports/roi-finance` | Pack JSON ROI Finance |
| GET | `/api/ledger/reports/roi-finance/pack` | **A4 remittance pack HTML** (print) |
| GET | `/api/brand/sa-shield` | Escudo Salvation Army (PNG) |
| GET | `/api/ledger/reports/payables-remittance` | Remittance view |
Tabela: `service_ledger_entries`.
**Public Txn id:** ver **`SPEC-TRANSACTION-IDS.md`**. Cash sale manual → curto **`000000-AA`** padded (`000084-ME`, `000010-EL`, …). Credit sale → `CR-…`. Credit settlement → `CT-…`. Import mantém ids do ficheiro.
Edit/delete: mesma matriz de acesso que pagamentos de rent (`User.can_edit_payments`); password do utilizador obrigatória.
---
## 4. Stamp padrão (todo lançamento AR)
Em create/list/UI:
- Dia da semana (Mon…Sun)
- Semana ISO `Wxx/yyyy`
- Hora `HH:MM` (`created_at`)
Campo composto: `stamp` (ex.: `Tue · W37/2026 · 23:58`).
Modal mostra preview live antes do post.
---
## 5. UI — Account Receivables `/receivables`
- Layout estilo dashboard Residents (grelha + painel Credit Book)
- Nav colorida: Receivables · Payables · ROI Finance · Credit report
- Botões: **+ Cash sale** (verde) · **+ Credit sale** (vermelho) · **+ Credit settlement** (azul)
- Modal Post sale / credit / settlement com tabs coloridas
- Coluna Stamp; Actions Edit / Delete (senha)
- Painel lateral: saldos Credit Book (Outstanding vermelho / Over-settlement azul)
---
## 6. UI — ROI Finance report `/receivables/roi-finance`
### Cards (drill-down → modal de lançamentos)
| Card | Cor | Conteúdo |
|------|-----|----------|
| Rent cash | Verde | SAGE SA cash no range |
| Ancillary cash | Verde | Cash meals/keys/elec |
| Credit settlements | Azul | Cash que limpa Credit Book |
| Credit sales | Vermelho | Credit sales (≠ cash till) |
| Credit net | Cinza / ± cor | Sales − Settlements |
| Total cash to ROI Finance | Verde | Rent + ancillary cash + settlements |
**Regra remittance:** Total cash = rent + ancillary cash + settlements.
Credit sales **não** entram no cash to ROI Finance.
Credit net = movimento do livro (≠ dinheiro físico).
### By account (colunas)
Account · Cash · Credit sales · Settlements · **Remit to ROI Finance** · **Credit net** · Family · (footer Total)
- Remit to ROI Finance = Cash + Settlements
- Credit net = Credit sales − Settlements (+ vermelho / − azul)
### By resident
Room · Resident · Rent cash · Ancillary cash · Credit sales · Credit paid · Total cash
### A4 remittance pack (print)
UI fields on the same page + **Print ROI Finance pack (A4)**:
| Campo UI | No documento |
|----------|--------------|
| Bank logbook no. | Controlo depósito / livro banco |
| Brinks Priority Bag no. | Selo Priority Bag |
| Brinks Malote / collection bag no. | Malote / bag de coleta Brinks |
| Manager 1 / Manager 2 / Prepared by | Três blocos de assinatura |
Documento HTML A4 (~98% da folha):
- Letterhead **The Salvation Army** + escudo oficial (`sa-shield-white-bg.png`, embutido base64)
- Período do material (From → To)
- KPIs: Rent cash · Ancillary cash · Settlements · Credit sales · Credit net · Cash to ROI Finance
- Tabela **Accounts remittance schedule** (todas as contas + Remit to ROI Finance + Credit net)
- Tabela **Resident cash detail** (linhas com movimento)
- Nota contabilística (cash ≠ credit sales; R-CB02/03)
- Assinaturas: Manager 1 · Manager 2 · Prepared / presented by
- Rodapé SA vermelho com total cash + período + ref `ROI-FINANCE-YYYYMMDD-YYYYMMDD`
**API:** `GET /api/ledger/reports/head-office/pack` (HTML, auth cookie)
**Template:** `backend/app/templates/ho_remittance_pack.html`
**Brand:** `GET /api/brand/sa-shield` · `backend/app/static/brand/`
---
## 7. UI — Credit consumption report `/receivables/credit-report`
- Head período: Opening · Issued (vermelho) · Paid (azul) · Closing (cards clicáveis)
- Botão **Today** + Generate
- Grelha estilo Residents: # · Room · SAGE · Name · Staff · Opening · Issued · Paid · Closing · Status · View
- Filtros por coluna; Status inclui **Over-settlement**
- Closing &lt; 0 mostrado como over-settlement (azul)
- Lista todos os residentes activos (+ inactivos com movimento)
---
## 8. UI — Period dashboard (ficha residente)
### Cards principais (5)
1. **Should have paid by now** — weeks × weekly due
2. **Actually paid** — cash SA no período (verde)
3. **Arrears / Positive balance** — paid − due (vermelho se − / azul se +)
4. **% vs amount due** — variance % + liquidation %
5. **Still to pay to year-end (W52/53)**
Removido o bloco duplicado “Period position” (Should/Actually/Arrears/%).
### Other balances (4 cards)
1. **Prior years unpaid** — preview agreement cut-off dia anterior ao From; link Payment map
2. **Credit Book · to clear** — vermelho; link Credit consumption
3. **Credit Book · over-settlement** — azul; link Receivables
4. **Agreements** — balance activo(s); link `#agreements-panel`
---
## 9. Payables
`/payables` — remittance view (cash + settlements por conta) alinhado ao ROI Finance.
---
## 10. Ficheiros tocados (noite)
Backend:
- `backend/app/services/ledger.py` (`render_ho_remittance_pack`, Credit Book helpers)
- `backend/app/modules/ledger/router.py` (`/roi-finance/pack`)
- `backend/app/templates/ho_remittance_pack.html`
- `backend/app/main.py` (`/api/brand/sa-shield`)
- `backend/app/database.py` (`ServiceLedgerEntry` — já existente)
Frontend:
- `frontend/src/app/receivables/page.tsx`
- `frontend/src/app/receivables/roi-finance/page.tsx` (pack fields + Print A4)
- `frontend/src/app/receivables/credit-report/page.tsx`
- `frontend/src/app/payables/page.tsx`
- `frontend/src/app/residents/[id]/page.tsx`
- `frontend/src/app/rules/page.tsx` (secção 12)
- `frontend/src/lib/api.ts` (`openRoiFinancePack`)
Docs:
- Este ficheiro: `docs/SPEC-ACCOUNT-RECEIVABLES.md`
---
## 11. Checklist agente (AR)
1. Nunca misturar Credit Book com rent arrears / SAGE SA.
2. Total cash to ROI Finance = rent cash + ancillary cash + settlements (não inclui credit sales).
3. Over-settlement = settlement &gt; to clear; novos credit sales consomem primeiro.
4. Edit/delete ledger = senha + `can_edit_payments`.
5. Stamp Mon–Sun week + hora em todo post AR.
6. Cores: cash verde · credit sale vermelho · settlement azul · over-settlement azul.
7. Rebuild frontend sem `.env.local`; restart `rentcharge-backend` + `rentcharge-frontend`.