10 KiB
10 KiB
SPEC — Ciclo EOD → Closing Till → Remittance Pack → HO (definitiva)
Status: DEFINITIVA — aprovada por Roger em 2026-10-07 (blocos 1 e 2)
Rules version: CYCLE_RULES_VERSION = 2026-10-07-r1
Substitui: SPEC-CLOSING-TILL-FREEZE-ARCHIVE.md (2026-10-01-r1), RULE-CLOSING-TILL-AFTER-CUT-LOCKED.md, releases/011.2026.md (2026-10-06-r1) e .cursor/rules/eow-cycle-start-rules.mdc naquilo que contradizem esta spec.
Implementação: ⏳ ainda não implementada — PRD corre 2026-10-01-r1. Implementar em TEST, validar com Roger, depois PRD.
1. Visão geral
Dia a dia Dia de fecho EOW – Closing Till EOW Remittance Pack HO
Save statement ─▶ Save EOD for Closing Till ─▶ Cycle Start → Apply → Draft ─▶ Freeze TEMPORÁRIO ─▶ Pack → Official Draft ─▶ Approve ROI → Send to HO
(editável) (linha de corte) (nada trava) (trava valores, reversível) (CONGELADO DEFINITIVO)
O congelamento definitivo acontece só no Send to HO.
2. Regras
R1 — Save statement (dia a dia, EOD Transactions)
- Ao fim do dia o operador clica Save statement → cria um ficheiro EOD (cards Saved EOD file e Recent saved EOD files).
- Pode salvar várias vezes no mesmo dia (correcções, lançamentos esquecidos).
- O ficheiro fica editável (não imutável) enquanto o ciclo a que pertence não foi enviado ao HO.
R1a — Auto-save às 23:55 (se o operador esquecer)
- Um job diário às 23:55 (hora local, Europe/Dublin) verifica o dia:
- se há movimentos e nenhum statement salvo, ou o último save está desactualizado (R3a) → faz o Save statement automaticamente (salvo por
system (auto 23:55)); - envia aviso para admin@myvexx.com com a lista do que foi salvo automaticamente (dia, nº do ficheiro, total, nº de movimentos).
- se há movimentos e nenhum statement salvo, ou o último save está desactualizado (R3a) → faz o Save statement automaticamente (salvo por
- Assim cada dia começa com os ficheiros do dia anterior salvos.
- O auto-save não faz Save EOD for Closing Till (o corte é sempre um acto do operador).
- Implementação: timer systemd
rently-prod-eod-autosave.timer(padrão dos jobs existentes),OnCalendar=*-*-* 23:55 Europe/Dublin.
R2 — Save EOD for Closing Till (dia de fecho: quinta ou outro dia escolhido)
- Faz o mesmo que o Save statement e marca a hora do clique, colocando a linha de corte após o último lançamento:
- before-cut (00:00 → corte) = este ciclo;
- after-cut (corte → 23:59) = próximo ciclo.
- Um Save statement no dia de fecho depois do corte gera/actualiza o after-cut (próximo ciclo).
- Segundo clique no mesmo dia: avisar "Já existe uma linha de corte neste dia (HH:MM). Deseja criar uma nova?"
- Se o EOW ainda não foi enviado: o novo corte substitui o ficheiro final da semana no Cycle Start e o processo recomeça (drafts anteriores ficam desactualizados).
- Se existir freeze temporário activo: pedir primeiro para o libertar (R5).
- Se o EOW já foi enviado: bloquear.
R3 — Week EOD files (Cycle Start) — EOW Closing Till
Lista todos os ficheiros do ciclo aberto:
- o after-cut do último fecho (semana anterior);
- o ficheiro de cada dia entre os fechos — só o save mais recente de cada dia;
- o before-cut do dia de fecho actual (até à hora do clique).
- Ficheiros do ciclo aberto nunca aparecem como used · immutable.
- O dia de fecho dividido não mostra o ficheiro de dia inteiro (só before/after).
- Ficheiros de ciclos já enviados não aparecem.
- Nada vem pré-seleccionado; used · applied só depois de marcar + Apply start & preview.
R3a — Ficheiro desactualizado
- Se houver lançamento ou correcção num dia depois do último save desse dia, o ficheiro aparece no Cycle Start com o selo "desactualizado — salve de novo" (com o nº de movimentos novos).
- O auto-save das 23:55 (R1a) re-salva automaticamente estes casos.
R4 — Apply start & preview / Generate draft
- Apply start & preview une os ficheiros marcados num ficheiro único (preview). Pode repetir-se.
- Generate draft gera um draft a partir de uma selecção de cada vez.
- Pode haver vários drafts; os drafts não trancam ficheiros (os mesmos ficheiros podem estar em vários drafts). Só um será usado; os outros ficam para leitura e podem ser apagados.
R4a — Limpeza de drafts não usados (card "Drafts" já existente no Closing Till)
- O card Drafts (n) passa a mostrar em cada draft o estado: Em uso (é o pacote em freeze temporário ou enviado) ou Não usado.
- Drafts Não usados têm Delete individual e um botão "Apagar todos os não usados" (com confirmação), para evitar lixo na base.
- Drafts Em uso não podem ser apagados.
- Depois do Send to HO, o card sugere apagar os drafts não usados daquele ciclo.
R5 — Freeze temporário (Closing Till) — OBRIGATÓRIO antes do Remittance Pack
- O operador escolhe um draft e faz Freeze → estado Temporarily frozen.
- Trava os ficheiros e valores desse pacote, para que o envelope e o pack batam com o que vai ser enviado (edições nesses dias ficam bloqueadas com mensagem).
- O operador pode libertar (Unfreeze) enquanto não houver envio — volta a draft e terá de refazer as etapas seguintes.
- O Unfreeze não apaga a linha de corte (o corte pertence ao Save EOD for Closing Till, R2).
- Selo na UI: "Temporarily frozen" (nunca "FROZEN — immutable" antes do envio).
R6 — EOW Remittance Pack
- Pack Summary mostra o montante do pacote em freeze temporário.
- Operador preenche os dados do envelope e gera previews da revisão (quantos quiser; os não usados podem ser apagados e não ficam congelados).
- Create Official Draft → fica disponível em 3. Approve selected ROI.
- Aviso obrigatório: se não houver pacote em freeze temporário, mostrar no topo do Remittance Pack:
"Ainda não existe um Closing Till em Freeze temporário. Volte a EOW – Closing Till, escolha o draft e clique em Freeze antes de montar o pack." — e desactivar Create Official Draft até existir.
R7 — Approve selected ROI → Send to HO (congelamento DEFINITIVO)
- Neste momento os ficheiros do pacote (incluindo o before-cut) passam a Frozen · Sent: imutáveis, indisponíveis para novos ciclos.
- O after-cut não fica congelado — pertence ao próximo ciclo (R3.1).
- Depois do envio só o admin pode reverter, como excepção:
- motivo obrigatório, registado em auditoria;
- fica um registo visível no ROI Archive e o pacote é marcado "Re-aberto", para o HO saber que haverá reenvio;
- os ficheiros voltam ao estado Temporarily frozen (não a editáveis) até novo envio ou unfreeze.
- Só existe um pacote em freeze temporário por ciclo; para trocar de draft é preciso libertar o freeze primeiro.
R8 — Lançamentos atrasados em dias enviados
- Por regra nada entra nos ficheiros imutáveis/enviados. Um lançamento num dia já enviado é bloqueado.
- Futuro (fora desta entrega): módulo / conta de Correcção Contabilística para registar esses casos no ciclo seguinte, com rasto.
3. Estados
| Estado | Onde | Ficheiros travados? | Quem reverte |
|---|---|---|---|
| Ficheiro EOD salvo | EOD Transactions | Não | — |
| Draft (vários) | Closing Till | Não | apagar draft |
| Temporarily frozen (1 por ciclo) | Closing Till | Sim (valores do pacote) | operador (Unfreeze) |
| Official draft / previews | Remittance Pack | Sim (herda o freeze) | operador (apagar / unfreeze) |
| Frozen · Sent | após Send to HO | Sim, definitivo | só admin (excepção auditada) |
4. Diferenças face ao sistema actual (2026-10-01-r1 em PRD)
| Ponto | Hoje | Esta spec |
|---|---|---|
| Ficheiros no Cycle Start | só for_eow=1 |
todos os Save statement (mais recente por dia) + before/after-cut |
| Draft tranca ficheiros | sim (eod_ids_held_by_draft_or_freeze) |
não |
| Freeze | "FROZEN — immutable" | Temporarily frozen, reversível pelo operador |
| Unfreeze | só admin; apaga a linha de corte | operador; mantém o corte |
| Imutável definitivo | no Freeze | no Send to HO |
| After-cut do fecho anterior | preso no freeze (ex.: EOD-20261001-37722C €129) | aberto para o próximo ciclo |
| Corte | carimbado pelo Freeze | carimbado pelo Save EOD for Closing Till |
| 2.º clique no dia de fecho | sem tratamento | aviso + substituir enquanto não enviado |
| Remittance Pack sem freeze | sem aviso | aviso + Create Official Draft desactivado |
| Dia sem statement salvo | dinheiro fica fora do Cycle Start | auto-save 23:55 + email admin@myvexx.com |
| Statement desactualizado | sem aviso | selo "desactualizado — salve de novo" |
| Drafts não usados | Delete um a um | estado Em uso / Não usado + "Apagar todos os não usados" |
| Reversão após envio | impossível | só admin, motivo + ROI Archive "Re-aberto" |
5. Notas de implementação (TEST primeiro)
eow_report.list_eod_choices: listar todos os EOD do ciclo aberto (último save por dia), excluir só os de ciclos enviados.eod_ids_held_by_draft_or_freeze→ passa a "held by sent" (e "temporarily frozen" só para bloquear edição, não a listagem).freeze_eow_draft: não acrescentar o after-cut à lista do pacote; não carimbar corte (R2 já o fez).unfreeze_eow_report: permitir operador quando não enviado; não limparclosing_till_cut; admin com motivo depois do envio.eod_report: Save EOD for Closing Till gera before/after + aviso de 2.º clique.- Remittance Pack (frontend + API): aviso R6 e bloqueio de Create Official Draft.
- Auto-save (R1a): job
app/jobs/eod_autosave.py+send_email(já existe emmodules/users/service.py) + timer systemd 23:55 Europe/Dublin (VM em UTC). - Card Drafts (R4a): estado Em uso / Não usado + apagar em massa (API protege drafts em uso).
- Reversão admin (R7): motivo, evento de auditoria, marca "Re-aberto" no ROI Archive.
- Testes de regressão: reescrever
tests/test_eow_cycle_start_rules.pypara esta versão. - Ao implementar: actualizar
.cursor/rules/eow-cycle-start-rules.mdcpara apontar para esta spec.