140 lines
5.9 KiB
Markdown
140 lines
5.9 KiB
Markdown
# PROJECT — Rent and Charge (Weekly and Arrears)
|
||
|
||
Produto de cobrança semanal de aluguel e atrasos (arrears) para hostel/residência Granby Lifehouse (quartos, SAGE, staff).
|
||
|
||
**Atualizado:** 2026-09-19 · **Versão:** **006.2026**
|
||
**SPEC infra:** `SPEC-VM500-RENTCHARGE.md`
|
||
**SPEC AR / Credit Book:** `SPEC-ACCOUNT-RECEIVABLES.md`
|
||
**SPEC Txn / Ticket:** `SPEC-TRANSACTION-IDS.md`
|
||
**SPEC MAP WEEK:** `SPEC-PAYMENTS-MAP-WEEK-PRINT.md`
|
||
**Sessões:** `SPEC-SESSION-2026-09-18.md` · `SPEC-SESSION-2026-09-19.md`
|
||
**App:** https://rentcharge.itecnologys.com · Forgejo: https://git.itecnologys.com/myvexx/rently
|
||
|
||
## O que o sistema faz (escopo actual)
|
||
|
||
- Lista residentes / quartos (padrão SAGE: filtros por coluna, `#`, Room estreita, badges NP / Name dup / Room conflict)
|
||
- Valor semanal devido via **charge bands** (RENT_35/40/41/45/65, FB_85/91, BANK_ACCOUNT, FLEXIBLE_FB)
|
||
- **Pagamentos:** fonte única = exports SAGE *Customer Invoices Due* (não o Excel de arrears)
|
||
- Totais do mês / ano; statements HTML/PDF; debit letter; agreements
|
||
- UI: Residents, Reporting (mesmo layout), Settings, ficha do residente com grelha de pagamentos
|
||
- **Account Receivables:** cash / credit sale / settlement (meals, keys, electricity); Credit Book com **over-settlement**; ROI Finance + Credit consumption; Period dashboard (due vs paid vs % + other balances)
|
||
- Utilizadores: registo público com código de e-mail, recuperação de senha, sessões revogáveis e auditoria no menu Admin
|
||
- Infra: VM500 BIG + Traefik CT120 + Cloudflare Tunnel
|
||
|
||
## Stack
|
||
|
||
- Backend FastAPI + SQLite (`arrears.db`)
|
||
- Frontend Next.js 15
|
||
- Tudo do projeto: `/home/mini/rentcharge` (código, venv, sage-payments, config, archive)
|
||
- Host: BIG VM 500 — **não** big1
|
||
|
||
---
|
||
|
||
## Regras de negócio — ocupação de quarto
|
||
|
||
### RN-01 — Um quarto físico = um residente
|
||
|
||
1. O mesmo `room_no` físico **não pode aparecer duas vezes** na lista de ocupação.
|
||
2. Um quarto só pode ter **um** residente activo.
|
||
3. A dívida pertence à **pessoa** (SAGE ID), nunca ao quarto.
|
||
|
||
### RN-02 — Validação de ocupação pelo último pagamento (**cash SA**)
|
||
|
||
1. Prova operacional = **último pagamento cash** (SAGE Type **SA**, category `cash` > 0).
|
||
2. **RENTSUPP e refunds não contam** como pagamento de renda para esta regra.
|
||
3. Em conflito de quarto, prevalece quem tem o cash mais recente.
|
||
|
||
### RN-03 — Not Present (NP##) vs nome em duplicidade
|
||
|
||
- **A:** não pagou / saiu ou mudou → `NP01`, `NP02`, … + `last_room_no`.
|
||
- **B:** nome duplicado → badge para revisão humana; sem merge automático.
|
||
|
||
API: `POST /api/residents/reconcile-occupancy`.
|
||
|
||
---
|
||
|
||
## Regras de negócio — pagamentos SAGE (2026-09-05/06)
|
||
|
||
### RN-PAY-01 — Fonte única
|
||
|
||
- Exports SAGE **Customer Invoices Due** são a **única** fonte de pagamentos.
|
||
- O Excel de arrears (`JUN 2026` / `Total Arrears-2025`) **não grava** pagamentos (`excel_import._upsert_payment` = no-op).
|
||
- Endpoint: `POST /api/import/sage-payments` (`replace_all=true` apaga pagamentos anteriores).
|
||
- Código: `backend/app/services/sage_import.py`.
|
||
|
||
### RN-PAY-02 — Semana e data
|
||
|
||
- Semana = **segunda → domingo** (ISO).
|
||
- `period_start` / `period_end` = Mon–Sun da `payment_date`.
|
||
- Reports usam a **data de pagamento** da linha SAGE.
|
||
|
||
### RN-PAY-03 — Type SA = cash (pago)
|
||
|
||
| SAGE | Campo BD | Conta como pago? |
|
||
|------|----------|------------------|
|
||
| Type **SA** + Details CASH/CHQ/… | `category=cash`, `cash_paid=abs(Amount)` | **Sim** |
|
||
| Type **SA** + Details **RENTSUPP** | `category=rentsupp`, `rentsupp=abs` | **Não** (arquivo / relatório próprio) |
|
||
| Refund / Type SP / Details *REFUND* | `category=refund`, `refund_amount=abs` | **Não** (não subtrai do pago) |
|
||
|
||
Amount no ficheiro SAGE é **negativo** → armazenar valor absoluto.
|
||
|
||
### RN-PAY-04 — ID único
|
||
|
||
- Coluna SAGE **No** → `payments.txn_no` (único; índice `ux_payments_txn_no`).
|
||
- Também: `txn_ref`, `sage_type`, `details`, `payment_date`, `counts_as_paid`.
|
||
- Reimport não duplica pelo mesmo `txn_no`.
|
||
|
||
### RN-PAY-05 — Match residente
|
||
|
||
- Match obrigatório por **SAGE A/C** ↔ `residents.sage_id`.
|
||
- Ex.: **Mapule Uwaene** = A/C **481** · band **RENT_35**.
|
||
- **Patrick McNamara** = A/C **272** · B15 · band FB_85.
|
||
|
||
### RN-PAY-06 — Due vs pago (accounting)
|
||
|
||
- Due semanal = charge band (`get_cap`); excess cash **não credita** semanas futuras.
|
||
- `summarize_payments` agrega **cash por semana** antes do cap; RENTSUPP/refund ignorados no pago.
|
||
- Statement / lista de pagamentos: **default só cash**; filtro UI para rentsupp / refund / all.
|
||
|
||
### Ficheiros fonte (operador)
|
||
|
||
`E:\Reports Week\PAYMENTS-REPORTS-BY-WEEK\2026\`
|
||
|
||
Import consolidado (sem duplicar):
|
||
|
||
1. `Payments_week_01_to_52_from_2025.xlsx`
|
||
2. `Payments_week_2026-total_partial.xlsx` (até ~30/08/2026)
|
||
|
||
Cópia VM: `/home/mini/rentcharge/sage-payments/reimport/`.
|
||
|
||
---
|
||
|
||
## UI (padrão SAGE) — estado 2026-09-06
|
||
|
||
| Ecrã | Padrão |
|
||
|------|--------|
|
||
| Residents `/` | Command bar, views, filtros por coluna, pager, export |
|
||
| Reporting `/reports` | Mesmo layout que Residents |
|
||
| Ficha Payments | Grelha SAGE; colunas **ID · Ref · SAGE · Details · Status · Amount**; search + filtros; Type default **Cash (SA)** |
|
||
|
||
---
|
||
|
||
## Utilizadores e autenticação
|
||
|
||
A especificação completa está em `AUTH-USERS-SPEC.md`.
|
||
|
||
- `/login` oferece **Register new user**.
|
||
- O novo utilizador valida o cadastro com um código de seis dígitos enviado por e-mail e entra imediatamente após a validação.
|
||
- Recuperação de senha só usa e-mail verificado e token longo, de uso único.
|
||
- Sessões são mantidas no servidor, expiram por inatividade/tempo absoluto e podem ser revogadas.
|
||
- O menu **Admin** reúne contas, sessões (IP, SO, browser, duração e features) e eventos de segurança.
|
||
- O cookie do browser é `Secure`, `HttpOnly` e `SameSite=Strict`; o frontend não persiste credenciais em `localStorage`.
|
||
|
||
---
|
||
|
||
## Fora de escopo (por agora)
|
||
|
||
- Cloudflare Access na borda
|
||
- Merge automático de residentes só por nome
|
||
- Alterar `/etc/network/interfaces` do Proxmox
|
||
- Contar RENTSUPP como renda paga
|