# Features — indawo_65

Evidence date: 2026-10-12. Revision: `INDAWO_84_2026` `08157c5` (2026-03-24, "f ixed cronjob syncs").

The UI name is Indawo Online. The repository name is `indawo_65`.

`CHANGELOG.md` records PHP 8.4 fixes through 2026-02-11 only. Features changed after that date are taken from Git history and the current tree.

## Current features (`INDAWO_84_2026`)

### Access and administration

| Feature | What it does | Evidence | Status |
|---|---|---|---|
| Login gate | `index.php` sends anonymous users to `login.php` and signed-in users to `home.php` | `index.php` | Implemented |
| Email, password, and shared PIN | Active, unlocked user in an active security group; password via `NemoPassword`; PIN from system settings | `login.php` | Implemented |
| Monthly PIN rotation | On the 1st, when `EnablePINPolicy` is `True`, cron 1 stores a new PIN and emails template "Login PIN" | `Cron.daily.1.Lookups.php` | Implemented |
| Password expiry and reset | Expired or missing `dtPasswordExpiry` fails login when the expiry setting is the string `true`. Reset page and new-user reset email exist | `login.php`, `_nemo.password.cls.php`, `resetPassword.php`, `includes/user.cls.php` | Implemented. The save INSERT column/value mismatch is **Requires Confirmation** |
| TOTP MFA | Setup and verify pages. Issuer "Indawo Online". QR via Endroid. Remember-device rows in `tblUserMFARememberedDevices`. Recovery codes in `MFATables.sql` | `two.factor.authentication.*.php`, `MFATables.sql`, `composer.json` | Implemented |
| Users | User maintenance, including MFA enabled column on the list | `user.php`, `includes/user.cls.php` | Implemented |
| Idle-user deactivation | Toolbar action for six months, and deactivate selected rows. Sets `blnActive = 0` and sends the deactivation templates | `user.php`, `includes/user.cls.php`, `includes/UserAccountDeactivation.sql` | Implemented. Recipients are hardcoded test addresses |
| User settings | Per-user settings screen | `user.settings.php` | Implemented |
| Security groups | Menu editor with view, new, save, delete, special | `security.group.php`, `includes/security.group.cls.php` | Implemented |
| Companies | Company records, including folder path stored on the session | `company.php`, `includes/company.cls.php`, `setOWC()` | Implemented |
| Sales people | Sales-person maintenance, active rows for the current company on the list | `sales.person.php`, `includes/sales.person.cls.php` | Implemented |
| Settings | System settings screen | `settings.php`, `includes/settings.cls.php` | Implemented |
| Usage log | Usage log screen and online usage report | `usage.log.php`, `onlineUsage.rpt.php` | Implemented |
| My tasks | Task list for the signed-in user | `my.tasks.php`, `includes/my.tasks.cls.php` | Implemented |
| Messages | Internal messages | `message.php`, `message.incl.php` | Implemented |
| Email | Email log, templates, online read, read receipt | `email.php`, `email.template.php`, `email.read.online.php`, `email.read.receipt.php` | Implemented |

### Commercial and job operations

| Feature | What it does | Evidence | Status |
|---|---|---|---|
| Clients | Client list and edit | `client.php`, `includes/client.cls.php` | Implemented |
| Contacts | Contact list and edit | `contact.php`, `includes/contact.cls.php` | Implemented |
| Contact log | Contact activity log | `contact.log.php`, `includes/contact.log.cls.php` | Implemented |
| Jobs (Foreman) | Job edit, company-scoped lookups | `job.php`, `includes/foreman.cls.php` | Implemented |
| Enquiries | Enquiry page | `enquiry.php` | Implemented. Whether it uses the Foreman class was not fully traced |
| Job types | Job type maintenance | `job.type.php`, `includes/job.type.cls.php` | Implemented |
| Job suggestions | Suggest field changes. Accept (status 1) writes `tblForeman` and calls `SyncRecord`. Decline (status 2) does not | `job.suggestion.php`, `includes/job.suggestion.cls.php` | Implemented |
| Pre-start agreement | Pre-start workflow. Inserts job suggestions at status 0 | `prestart.agreement.php`, `includes/prestart.agreement.cls.php` | Implemented |
| Budget adjustment | Budget adjustment workflow | `budget.adjustment.php`, `includes/budget.adjustment.cls.php` | Implemented |
| Orders | Purchase orders | `order.php`, `includes/order.cls.php` | Implemented |
| Order authorisation | Admin and production filters: Pending, Accept, Declined | `order.authorisation.php`, `includes/order.authorisation.cls.php` | Implemented |
| Raise invoice | Invoice request and PDF class | `raiseInvoice.php`, `includes/raiseInvoice.cls.php`, `includes/invoicePDF.cls.php` | Implemented |
| Assets | Asset contacts and movements | `asset.contact.php`, `asset.movement.php` | Implemented |
| Search | Search page, updated for PHP 8.4 in `4a1b30b` | `Search.php`, `includes/ForemanSearch.cls.php` | Implemented |
| Archived | Archived page | `archived.php` | Implemented. What it lists was not fully read |
| KPI | KPI screen | `kpi.php` | Implemented |

### Dashboards and reports

| Feature | What it does | Evidence | Status |
|---|---|---|---|
| Home | Landing page after login | `home.php` | Implemented |
| Sales-person dashboard | SP home and a large user dashboard class. Cash under/over is receipts minus total actual cost, with overheads as a percentage of material and labour | `dashboard.sp.php`, `includes/dashboard.home.sp.cls.php`, `includes/dashboard.sp.cls.php`, `includes/dashboard.users.cls.php` | Implemented |
| Contract-manager dashboard | CM dashboard | `dashboard.cm.php`, `includes/dashboard.home.manager.cls.php` | Implemented |
| Cash-flow PDF | Monday or the 23rd. Under/over is amount paid minus actual prime times 1.3 | `cron.CashFlow.php` | Implemented |
| Foreman reports | Budget vs actual, labour vs invoiced, prime ratios, overspent, material, subcontractor, prime cost | `reportForeman.php`, `includes/reports/foreman/` | Implemented |
| QS incentive | QS incentive and fiscal summary | `reportQSIncentive.php`, `includes/reports/qsincentive/` | Implemented |
| Asset reports | Asset list report | `reportAssetManagement.php`, `includes/reports/assetmanagement/` | Implemented |
| Other reports | Referred-by, online usage, contact-log follow-up, enquiry follow-up | `includes/reports/other/` | Implemented |
| Charts | Highcharts and canvg assets | `charts/`, `plugins/Highcharts/`, `plugins/canvg-master/` | Implemented library. Which pages bind it was not fully mapped |

### Sync and operations

| Feature | What it does | Evidence | Status |
|---|---|---|---|
| Nightly lookup pull | Client type, sales person, job type, supplier | `Cron.daily.1.Lookups.php` | Implemented |
| Nightly client pull | Client, contact | `Cron.daily.2.Clients.php` | Implemented |
| Nightly Foreman pull | Job headers, then financials, then costings and history | `Cron.daily.3.Foreman.php` through `Cron.daily.5.Foreman.php` | Implemented |
| Excel dumps | Normal, quote, and full dumps | `Cron.daily.6.DataDumps.php`, `cron.DataDumps.php` | Implemented |
| Manual full sync | On-demand chain | `cron.daily.manuel.php` | Implemented. Body was not fully read |
| Order-auth email | Emails rows where admin or production status is 0, template "Order Authorisation Request" | `cron.daily.orderauth.php` | Implemented |
| Monthly order cancel | Company 1 on the 15th for old `New` orders. Extra scripts for companies 1, 4, 6, and 9 | `cron.daily.ordercancel.php` and `.1.php`, `.4.php`, `.6.php`, `.9.php` | Implemented |
| Accept-time Foreman push | `SyncRecord` UPDATE after a suggestion is accepted | `includes/job.suggestion.cls.php` | Implemented |
| ODBC probe scripts | Connection scripts | `odbc_connect.php`, `odbc_connect_2.php` | Implemented. `setup_composer.md` points operators at `odbc_connect.php` |
| Environment template | Commented keys for app env, protocol, MySQL, and SQL Server | `env`, `setup_composer.md` | Implemented. Non-local hosts do not read those keys |
| Sonar pipeline | SonarQube scan step | `bitbucket-pipelines.yml` | Implemented for branch pattern `{master}` only |

## Recently changed

Commits after the issue snapshot `3699fee` (2026-02-17) through `08157c5` (2026-03-24):

| When | Change | Status |
|---|---|---|
| 2026-02 (commits `3dd3ab6`, `a9e544e`, `f378137`, `1b22361`) | MFA library, login branch, setup and verify pages, recovery codes, remember device, delete expired tokens | Implemented |
| 2026-02 (`f297a3a`, `792e613`) | Deactivate users idle for six months, selective deactivate, notification emails | Implemented |
| 2026-02-20 tip `fa114e3` | Password expiry on login | Implemented |
| 2026-02 (`2d0d840`) | IP and user details on login logging | Implemented. The new columns were not re-read |
| 2026-02 to 2026-03 | PHP 8.4 fixes for orders, search, contact log, KPI, toolbars, Nemo warnings, number format, dashboard PDFs | Implemented. Only the February 3–11 slice is in `CHANGELOG.md` |
| 2026-03 (`de4291a`, `2bc9634`, `1bb8ae0`) | Pre-start, job.php, contact.php | Implemented. Ticket text is the commit subject only |
| 2026-03-24 (`08157c5`) | Cron sync fix | Implemented. The diff was not re-read line by line |

## Planned

| Item | Evidence | Status |
|---|---|---|
| Repeater incremental sync | `cron.daily.repeater.update.php` prints that it is a temporary file | The file is a stub. **Implemented** as a placeholder |
| Deactivation administrator address | Comment in `DeactivateUsersOlderThan6Months`: "admin email still up for discussion" | **Requires Confirmation** |
| Changelog catch-up | `CHANGELOG.md` ends 2026-02-11 | Not a product feature. The log is behind the branch |

No roadmap file was found. Behaviour that exists only in `indawo_84` (realtime queue, ODBC dashboard, money impact) is not a plan inside this repository.

## Deprecated, copied, or unused-looking files

These files are in the tree beside the current scripts. They were not proven unreachable.

| File | Note |
|---|---|
| `systemOld20260203.php`, `Zsystem.php` | Older system copies. Live include path used by `index.php` is `system.php` |
| `Zcron.daily.php` | Name suggests a retired cron |
| `cron.daily.repeater.update.php` | Prints a temporary-file message |
| `order.php_20221215`, `includes/order.cls.php_20221215`, `includes/order.cls.php_07_10_2025`, `includes/order.cls.php_20251119`, `includes/order.cls.php.bak.220919` | Dated order copies |
| `includes/foreman.cls.php_30_01_2023`, `includes/foreman.cls.php.bak` | Dated Foreman copies |
| `includes/dashboard.users.cls.php_2023_01_19`, `_2023_02_02`, `_2025_03_25.php`, `.bak` | Dated dashboard copies |
| `* - B VAT.php` and `* - B VAT Update.php` on cash-flow, order, Foreman, pre-start, raise-invoice, and dashboard classes | Parallel VAT variants. Which one production runs is **Unknown / Requires Confirmation** |
| `project.functions.inc.php_2023_01_19` | Dated copy |
| `cron.daily.manuel.php_new`, `Cron.daily.6.DataDumps.php_2023_01_19` | Dated or alternate cron copies |
| `zSandBox.php`, `RoelData.php`, `ConcatenateClientContactSP.php`, `email.test.php` | Utility or one-off scripts. Not linked from `index.php` |
| `a_test_attachment1.txt`, `a_test_attachment2.txt` | Test attachments at the repo root |
| `includes/reports/assetmanagement/asset.list.rpt - Copy.php` and `*.old` report files | Copies |

`plugins/Highcharts/exporting-server/java/` is a vendored Java export server with build output. The PHP application does not show a call into that tree in this pass.
