# Phase E Retro — Year-End Ceremony Validation

**Sprint:** S21 (Tax & Zakat)
**Date:** 2026-05-08
**Assessment scope:** Does the full year-end ceremony sequence (period close → surplus → tax/zakat draft → distribution) hold together as a coherent story for a koperasi demo?

---

## What Was Built (Sprint S21)

| Task     | Description                                                                           | Status  |
|----------|---------------------------------------------------------------------------------------|---------|
| S21-004  | tax_settings + tax_drafts schema, models, enums, factories — foundation for all Tax domain work | ✅ Done |
| S21-001  | CukaiWorksheet — pure computation class; net_surplus → §65A exemption → chargeable income | ✅ Done |
| S21-002  | AllowancesCatalog — 10 deductions, 7 add-backs per ITA 1967 §34/§39; BM + EN labels  | ✅ Done |
| S21-006  | ZakatCalc — on_surplus and on_working_capital methods; default 250 bps; negative-base clamp | ✅ Done |
| S21-005  | DraftPdf — cukai worksheet PDF (A4, DomPDF)                                           | ✅ Done |
| S21-008  | ZakatDraftPdf — zakat worksheet PDF with Shariah advisory notice; method-specific layout | ✅ Done |
| S21-011  | Permissions registry — 4 permission constants; tenant_admin (all), auditor (view + download) | ✅ Done |
| S21-010  | DisclaimerBanner — mandatory DRAFT/DRAF banner for all Tax screens; BM + EN; LHDN non-auto-filing | ✅ Done |
| S21-003  | CukaiUiController + CukaiUi.tsx page                                                  | ✅ Done |
| S21-007  | ZakatUiController + ZakatUi.tsx page                                                  | ✅ Done |
| S21-012  | This retro                                                                            | ✅ Done |

---

## Year-End Ceremony Sequence Validation

The year-end ceremony for a koperasi is the sequence:

1. Period Close (accounts locked for the fiscal year)
2. Penyata Kewangan PDF generated and signed off
3. Surplus computed (Module M — Surplus domain)
4. Tax draft computed (Module T — this sprint)
5. Zakat draft computed (Module T — this sprint)
6. AGM presentation (tax + zakat amounts visible to auditor)
7. Surplus distribution (post-AGM)

### Sequence Readiness Assessment

**✅ STEP 1 — Period Close**
Implemented in S15/S16. FiscalPeriod state machine: Open → Closed. Hard lock prevents mutations after close.

**✅ STEP 2 — Penyata Kewangan PDF**
Implemented in S18. Full GP23-compliant PDF with sign-offs. Sign-off roles: Setiausaha, Bendahari, Auditor.

**⚠ STEP 3 — Surplus Computation**
Module M is NOT yet implemented (post-Sprint 21 scope). CukaiWorksheet and ZakatCalc both accept `net_surplus_cents` as a parameter, so the computation layer is decoupled and ready. When Surplus module lands, it will call `CukaiWorksheet::compute()` and `ZakatCalc::compute()` with the finalised surplus figure.

**✅ STEP 4 — Tax Draft Computation**
`CukaiWorksheet::compute()` — full §65A logic, SME tiered rates. TaxDraft model persists versioned computation snapshots. `DraftPdf::render()` produces A4 cukai worksheet PDF.

**✅ STEP 5 — Zakat Draft Computation**
`ZakatCalc::compute()` — on_surplus and on_working_capital. `ZakatDraftPdf::render()` produces A4 zakat worksheet PDF with Shariah advisory notice.

**✅ STEP 6 — AGM-Facing Output**
CukaiUi and ZakatUi pages render the draft figures. DisclaimerBanner on both pages — DRAFT/DRAF notice. Auditor role scoped to view + download only.

**🔲 STEP 7 — Surplus Distribution**
Module M is future scope. The tax/zakat payable figures from `TaxDraft.computation_json` will be input to the distribution algorithm (retained earnings = surplus − tax − zakat − distributions).

---

## Assumptions Logged (for founder review)

**A01:** AC copy-paste mismatch — S21-001, S21-002, S21-003 prompts all reference TAX-TA-01 (settings form) ACs but task titles describe computation classes/pages. Implemented to task titles per S06-L4.

**A02:** §65A threshold confirmed as RM100,000 exemption for koperasi with paid-up capital < RM750k within 5-year establishment window. Rates: 17% on first RM600k, 24% above (SME); flat 24% (non-SME). Source: ITA 1967 §65A + LHDN koperasi guidance 2023 edition. Founder should verify against latest LHDN circular if rates change.

**A03:** `auditor` user role is new — not in original RolesSeeder. `Permissions::seed()` creates it via `firstOrCreate` (idempotent). No existing data is affected. Founder should add `auditor` to `RolesSeeder::run()` in a maintenance sprint.

**A04:** TaxDraft `computation_json` stores the result of `CukaiWorksheet::compute()` directly. The exact computation parameters (net_surplus, deductions, non-deductibles) are not stored — only the result waterfall. If re-computation is needed, the input must be re-supplied. A future task may want to store the input alongside the result.

**A05:** Zakat payable and cukai payable are stored separately in two TaxDraft records (one with `draft_type='cukai'`, one with `'zakat'`). The surplus distribution module will need to query both to arrive at the distributable surplus.

---

## Demo Readiness: Tender S005/2026

For the 21 May 2026 demo, the Tax domain can show:

- ✅ Cukai worksheet computation with §65A exemption
- ✅ Zakat computation (on_surplus method — the common koperasi method)
- ✅ PDF outputs for both (suitable for accountant/auditor review)
- ✅ Disclaimer banners on both screens (regulatory compliance)
- ✅ Auditor read-only access (TA + Auditor permission model)

**Not yet demo-ready (acceptable gaps for tender):**

- ⚠ Manual input form for tax adjustments (UX only — computations work)
- ⚠ Surplus domain — year-end ceremony is partial without it
- ⚠ RolesSeeder does not yet include `auditor` role
