# 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 < 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 > 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`.