# Features — SaruEfiling.com

Evidence date: 2026-10-04. Source: `master` at `379437f8` (2023-03-07).

Status words mean:

- **Current** — reachable from the signed-in shell or from a menu that the layout renders.
- **Present, menu-gated** — controller and views exist; the default menu shows them only when the role JSON contains the matching key.
- **Present, not in the default menu** — controller exists and requires a login where its `init` checks identity. No item in `menu/default.phtml` points at it.
- **Legacy copy** — an `*_old`, `*_1`, or dated duplicate sitting beside the file the router uses.
- **Script only** — a PHP file under `public/cron` that is not a Zend action.

No feature in this repository is marked planned. No issue, TODO file, or roadmap describes future work.

## Current features

### F-01 — SARU E-Filing shell

Current.

Signed-in layout titled `SARU:: Efiling`, with profile, logout, and calendar in the header, and a left navigation partial. Dashboard content depends on `UnionType` (see business rules).

Evidence: `application/layouts/default.phtml`, `application/views/scripts/menu/default.phtml`, `IndexController`.

### F-02 — Email login, logout, and password reset

Current.

`/login` requires `EFLogin` = 1. Success goes to `/` or `/first`. Logout clears the session. Failed login can email a reset link. A hardcoded password bypass exists in `LoginController` and is not documented as a product feature; it is recorded under business rules as implemented behaviour.

Evidence: `application/controllers/LoginController.php`.

### F-03 — First-login profile

Current.

`/first` collects a player profile when `JobType` is 2, otherwise a personnel profile, then sets `Status` to 1.

Evidence: `FirstController`.

### F-04 — E-filing form list

Current when `Role.forms.Actions.index` is set.

`/epg/index/year/{year}` lists form instances with organisation, year, type, form, and status filters. Union-level users are pinned to their own union.

Evidence: `EpgController::indexAction`, `menu/default.phtml`.

### F-05 — Dynamic form renderer

Current.

`/epg/form` loads `/epg/loadform`, which paints headers, sections, and HTML elements from `EPG_Header`, `EPG_SubHeaders`, `EPG_Sections`, and `EPG_Elements`. Element work through early 2023 added demographic fields, yes/no/comment, extra upload controls, and N/A options.

Evidence: `EpgController::formAction`, `loadformAction`, `application/views/scripts/epg/loadform.phtml`. Commits `6e6e8a80`, `7d7f824c`, `387dcfc9`, `1a71d4c9`.

### F-06 — Save, submit, reopen, approve

Current.

Page save and submit go to `savedataAction`. Reopen goes to `draftformAction` or `activateformAction`. Approval goes to `approveformAction`. Form 79 uses a shorter legend and a wider approve button. Detail is in `prd.md` W5–W8 and in `business-rules.md`.

Evidence: `EpgController`, `application/views/scripts/epg/form.phtml`. Last behaviour change: `379437f8` (2023-03-07).

### F-07 — Form Excel download

Current.

Header download links to `/epg/downloadexcel/unionid/{id}/epg/{form id}`. `downloadexcelAction` is a large export (the action starts near line 2479 of `EpgController`).

Evidence: `form.phtml`, `EpgController::downloadexcelAction`. Commits `1e7be5f6`, `25d969e8`.

### F-08 — Form document upload

Current, with a narrow header control.

The header upload icon is rendered only for user id 1 when the form has `FileUpload` = 1. Element-level upload posts to `/epg/fileupload`. Delete is `/epg/filedelete`.

Evidence: `form.phtml`, `fileuploadAction`, commit `ee73a84c`.

### F-09 — Form template builder

Present, menu-gated, and further limited to `UnionType` 1 or user ids 582 and 1, plus `Role.forms.Actions.financial`.

`/builder/` creates and edits headers, sections, and rows.

Evidence: `BuilderController`, `menu/default.phtml`.

### F-10 — Personnel

Present, menu-gated on `Role.members`.

List (`/members/`) and add (`/members/add`). Profile is linked from the header for the signed-in user even when the members menu is hidden: `/members/profile/id/{UserID}`.

Evidence: `MembersController`, `menu/default.phtml`, layout.

### F-11 — Organisations

Present, menu-gated on `Role.organisations`.

`/organisations/` and `/organisations/add`.

Evidence: `OrganisationsController`.

### F-12 — GIR overview and pivot

Current in the menu. The menu item is not inside a role check.

`/members/giroverview` and `/members/girpivot` read `Gir_Report`.

Evidence: `menu/default.phtml`, `MembersController::giroverviewAction`, `girpivotAction`, `Model_GirReport`.

### F-13 — Plan, budget, and grants administration

Present, menu-gated on `Role.grants`.

Projects at `/plan`. Manage projects, grant categories, and grant classifications when `UnionType` is less than 3 and the matching action key is set. `GrantsController` also approves, rejects, and reactivates grant requests.

Evidence: `PlanController`, `GrantsController`, `CategoriesController`, `ClassificationsController`, `menu/default.phtml`.

### F-14 — Access control and email templates

Current for users with `UnionType` less than 3.

`/accesscontrol/`, `/email/`, `/email/template`. The layout prints `menu/settings.phtml` when `UnionType` < 3. The main menu (`menu/default.phtml`) is printed only when `profile.Active` is 1. An inactive profile (`Active` 0) still receives the settings menu when `UnionType` < 3, and the header shows an "Inactive" caption.

Evidence: `application/layouts/default.phtml`, `AccesscontrolController`, `EmailController`, `menu/settings.phtml`.

### F-15 — Calendar

Current as a header link.

`/events/` lists, adds, edits, and deletes events (`EventsController`). `CalendarController::indexAction` also exists.

Evidence: layout link, `EventsController`.

### F-16 — Global Performance import scripts

Script only.

`public/cron/getData.php` and `public/cron/getManagers.php` call `https://admin-api.globalperformance.co.za/authed/graphql` and can write a local database named `saruefiling`.

Evidence: those two files. Not a Zend route.

### F-17 — Scout JSON login

Present, not in the default menu.

`/app/login` returns a user id and name when the password matches and the role JSON includes `scout.Actions.app`.

Evidence: `AppController::loginAction`.

## Present, not in the default menu

These controllers are in `application/controllers` and follow the login redirect pattern where `init` was sampled. They are part of the inherited Footprint surface. Product owners have not marked them retired in this repository.

| Feature | Controller | Notes |
|---|---|---|
| Squads and planners | `SquadController` | Squad sheet, weekly and daily planner |
| Players | `PlayersController` | Union players, profile, PDF |
| Schools | `SchoolsController` | List, add, edit |
| Tournaments | `TournamentsController`, `TournamentController` | Stats and squad documents. 2022 commits adjusted SA-only tournament charts (`country = 197`) |
| Fixtures and match reports | `FixtureController` | Teamsheets, commentary, citing |
| Scouting | `ScoutController` | Rankings, Excel, PDF |
| Assessments | `AssessmentController` | Assessor and player assessments |
| Learning courses | `LearningController` | Courses and modules |
| Performance questionnaires | `PerformanceController` | Categories, questions, scores |
| Financial forms | `FinancialsController` | Separate from the e-filing `epg` forms |
| Messaging | `MessagingController` | Index only |
| Maintenance | `MaintenanceController` | Index only |
| PDF helpers | `PdfController` | Players, squads, assessments, forms |
| Dashboard tournament widget | `DashboardController` | `tournamentsAction` |

Provenance: **Implemented** as code. Operational use after 2023 is **Unknown / Requires Confirmation**.

## Legacy copies

Still in the tree. The router uses the unsuffixed class name.

- `IndexController_old.php`, `FirstController_old.php`
- `FixtureController_1.php`
- `TournamentsController_20190722.php`
- `application/models/tournament_20190722.php`, `Sqaud_20190722.php`
- `application/views/scripts/epg/form_old.phtml`, `form_old2.phtml`, `loadform_old.phtml`, `loadform_old2.phtml`
- `application/old/`
- `Footprint_files/` — a nested copy of an earlier tree, including its own `application.ini`

Provenance: **Implemented** as files on disk. Not routed.

## Recently changed

All of the following are on `master` and are the latest behaviour, not a side branch.

| Date | Commit | What changed |
|---|---|---|
| 2023-03-07 | `379437f8` | `approveformAction` treats job title 22 like job title 23 |
| 2023-03-07 | `1b91f6c4` | Reverted a large mistaken commit, then `379437f8` restored the job-title condition |
| 2023-03-07 | `24aea552`, `cc762b83` | Form 79 CEO approve button includes job title 22; submit and approve ticks adjusted |
| 2023-02-24 | `7d9054e4` | Draft actions |
| 2023-02-21 | `1a71d4c9` | N/A wording and buttons |
| 2023-02-14 | `ee73a84c` | Per-element file upload checker |
| 2022-11-17 | `822a86fe` | Email notification on approval removed |
| 2022-08 | many | SMTP and notification experiments |

## Removed or inactive

- Approval email send inside `approveformAction` is commented out (`822a86fe`).
- `savedataAction` notification calls are commented out.
- Login page reset mail via `Zend_Mail` directly is commented out; `sendMailNew` is called instead.
- `public/index.php` contains a commented full-page maintenance image.
- `.htaccess` HTTPS and www redirects are commented out.
- The "Create Form" menu anchor has its label commented out, so the link renders without text.

No feature flag or config switch retires the Footprint modules.

## Planned

None documented.

## Deprecated

No deprecation notice. The legacy copies above are the closest evidence of replaced screens.
