# Business rules — eitaws (eIT)

Evidence date: 2026-10-15. Source: `git@bitbucket.org:overdrive/eitaws.git`, branch `master` at `9dc596e` unless a rule names another file.

Rules are taken from behaviour in the code or from notes in the repository. They are not a new policy. Each rule is marked **Documented**, **Implemented**, or **Inferred**.

`development` and the PHP 8.2 branches were not read. A rule may differ there.

## Access

**BR-001 — Three sign-in fields.** Login requires a username, a password, and an external PIN. The browser blocks submit when any of them is empty.

- Provenance: **Implemented** (`index.php` `validate_form`).

**BR-002 — Only active users sign in.** The login query requires `tblUser.blnActive = 1`.

- Provenance: **Implemented** (`get_login()` in `includes/db_sql.php`).

**BR-003 — Shared external PIN.** The posted PIN must equal `sysSettings.strValue` for `strSetting = 'ExternalLoginPin'`. It is one value for the system, not a code per user.

- Provenance: **Implemented** (`index.php`).
- The Composer package `wayne-oliver/otp` is installed and unused. It is not this PIN.

**BR-004 — Password check.** The browser sends an MD5 of the typed password. The server accepts the login when that value equals `md5` of `tblUser.strPassword`.

- Provenance: **Implemented**.
- **Inferred:** the column holds the original password, because the browser has already hashed once. **Requires Confirmation**.

**BR-005 — Cookie is the session.** After login, `myCookie` is the level digit plus the user id. `checkLogin()` allows `sheet.php` when the cookie is present and refreshes it for another 14370 seconds.

- Provenance: **Implemented** (`includes/system.php`).
- The cookie payload is not signed in the code that was read.

**BR-006 — Levels.** The user form offers User `5`, Data Admin `7`, and System Admin `9`.

- Provenance: **Implemented** (`entities/user/view_details.php`).
- A user who is not level 7 or 9 can open only their own user row. Others see "You are not allowed to perform this action!"
- Level 7 and 9 see transit rate, areas, billing codes, labour codes, job status, client status, and leave type.
- Level 9 sees the batch operations block.

**BR-007 — Flags are separate from level.** Stock, accounts, support contracts, ADSL, backup assessments, software licences, staff leave, responsibilities, accounts email, staff cost, and the lock-on-save switches are columns on `tblUser`. The menu shows Stock only when `blnEditStock` is 1, and Accts only when `blnAcctsEdit` is 1.

- Provenance: **Implemented** (`includes/menu.php`, `includes/settings_entry.php`, `includes/settings_entry_hr.php`).

**BR-008 — Failed login is silent.** A wrong PIN or password redisplays the form. The branch that was read does not set an error string.

- Provenance: **Implemented**.

**BR-009 — Logout lands on the login page.** The logout control sets the browser location to `index.php`. That page clears the cookie superglobal for the current request and destroys the PHP session. It does not expire `myCookie`.

- Provenance: **Implemented** navigation. **Inferred** that the browser cookie can survive. **Requires Confirmation**.

## Billing

**BR-010 — Billing status legend.** `system notes.txt` says billing status `1` is active and `0` is deleted.

- Provenance: **Documented** in that note.
- Month-end candidate insert uses `Status = '1'`. Provenance: **Implemented**.

**BR-011 — Work location drives transit.** Locations are `ON-SITE`, `OFF-SITE`, `ON-SITE and OFF-SITE`, and `ON-SITE (No Mileage)`. If the client is not flagged `blnTransitCharge`, the transit checkbox is cleared. If the client is flagged, on-site and mixed locations check it, and off-site or "no mileage" clear it.

- Provenance: **Implemented** (`entities/billing/view_details.php`).

**BR-012 — On-site mileage is counted at export.** For non-SLA lines, location `ON-SITE` or `ON-SITE and OFF-SITE` increments a transit-charge counter.

- Provenance: **Implemented** (`entities/billing/action_iif_export.php`).
- The counter's later effect on the invoice line was not fully traced.

**BR-013 — Month-end selection, as the button states it.** The confirm text says the run takes the selected month's billing that has an invoice number shorter than 2 characters, is not a fixed SLA, is not client "Silicon Overdrive", and is marked to bill at month end via the billing code.

- Provenance: **Documented** in the button's `confirm()` string (`entities/billing/view_list.php`).

**BR-014 — Month-end selection, as the queries do it.** The insert into `tmpBilling` keeps `Status = 1`, invoice `''` or `'0'`, and dates inside the selected month. Ignore-dates drops the date filter and limits the insert to 1000 rows. The export then keeps billable codes (`blnBill = 1`) or code `Labour NC`, excludes client name `Silicon Overdrive`, excludes billing-code type `Fixed SLA`, and requires invoice length under 2.

- Provenance: **Implemented**.
- **Inferred:** `blnBill` is what the confirm text calls "billed at the end of the month". The column comment was not found. `Labour NC` is an extra inclusion the confirm text does not mention.

**BR-015 — Silicon Overdrive is not invoiced by this export.** Client name `Silicon Overdrive` is excluded in the export SQL.

- Provenance: **Implemented**. The match is the string, not an id.

**BR-016 — SLA versus ad hoc.** Lines with `refSLAID = 0` are exported as non-SLA. Lines whose billing-code type is `SLA` are exported on the SLA path. The file comment says those hours are billed at the SLA rate until `dblHours` is used up, and the query selects `dblRollOverRate`.

- Provenance: **Implemented** for the split. The hour-by-hour rollover arithmetic was not fully extracted.
- **Documented** in `doc new iif export pseudocode 20121207`: fixed SLA shows hours when they exceed the SLA amount; ad hoc export excludes fixed SLA codes; overflow uses the rollover billing-code rate.

**BR-017 — Invoice line identity.** The QuickBooks line name is the billing code. The description includes the work date, technician initials in the memo, ticket number, contact names, and location plus the fix text.

- Provenance: **Implemented** (`action_iif_export.php`).

**BR-018 — Invoice header date.** The export sets the header transaction date to the last calendar day of the previous month at the time the PHP runs.

- Provenance: **Implemented** (`date("t/m/Y", strtotime("last month"))`).
- This is not the year and month selected in the menu. **Requires Confirmation** that finance accepts that date.

**BR-019 — Internet division is relabelled in the export.** When `strDivision` is `INTERNET`, the local variable is set to `HARDWARE`. The value sent as the QuickBooks line name is still the billing code. A software division would have been labelled `software` on an older class field that is no longer assigned.

- Provenance: **Implemented** for the variable. **Inferred** that the relabel no longer changes the payload.

**BR-020 — Invoice numbers are written back in bulk.** A `QBAPI` JSON list with `Invoice` and `BillingID` sets `strInvoice` on those billing rows.

- Provenance: **Implemented** (`sheet.php`).
- The caller must already hold `myCookie`. There is no extra role check in that block.

**BR-021 — Sign book.** List rendering still refers to on-site rows, `blnSignBook`, and `strBookSigned`. The column header that sorts unsigned books is inside an HTML comment.

- Provenance: **Implemented** check at `view_list.php`. **Inferred** that the visible column was removed. **Requires Confirmation**.

## Clients

**BR-022 — Client lock.** `DB changes.txt` says `blnLocked` means the record should not be editable (added 2013-02-07). The screen shows Locked or Not Locked. Users without `blnClientLock` get readonly controls where `$lockControl` is applied.

- Provenance: **Documented** in `DB changes.txt`, **Implemented** on those controls.
- The client-name field in the section that was read is still editable. **Requires Confirmation** of the intended lock scope.

**BR-023 — Client commercial flags.** The report console offers these selectors: Accounts on Hold, Active Support, Hand Delivered, Must Get Auth, No Support Allowed, Order number required, Only Upfront Payments Allowed, PDF Invoice, Posted, Problematic Payments, Quote COD Rates Only, Sign book, Special Labour Rate, plus active and inactive.

- Provenance: **Implemented** as filter options. The effect of each flag on whether a technician may open a job was not traced past the report filter and the "No Support Allowed" label on the client form.

**BR-024 — One-way kilometres.** The client form labels transit distance "Transit Actual (1 way km)".

- Provenance: **Documented** on the form label. **Implemented** as field `dblKM`.

## To-do and leave

**BR-025 — To-do status legend.** `system notes.txt` says `1` active, `0` deleted, `2` completed.

- Provenance: **Documented**. Enforcement in every to-do query was not re-checked.

**BR-026 — To-do mail is opt-in per user.** Mail goes out on create and on update only when `blnEmailToDo` is 1. A manager is copied when `boolManager` is 1.

- Provenance: **Implemented** (`sendTodoEmail()`).

**BR-027 — One leave row per person per date.** Saving leave alerts "Error:Duplicate leave entry for the same user on that same date" when `check_duplicates()` returns rows.

- Provenance: **Implemented** (`sheet.php`).
- User id `999999999` does not take the update path. **Inferred** placeholder. Purpose **Unknown / Requires Confirmation**.

## Assets

**BR-028 — MLPA inactivity.** Mark Inactive is a separate action from Delete (comment 2019-12-17).

- Provenance: **Implemented** (`entities/mlpa/_controller.php` includes `action_mark_inactive.php`). The column it writes was not read.

**BR-029 — Warranty buckets.** The MLPA list can filter warranty end before today, within 3 months, within 6 months, or still in the future.

- Provenance: **Implemented** (`entities/mlpa/view_list.php`).

**BR-030 — Tracking notification flags.** `DB changes.txt` adds `blnClientNotificationSent`, `blnClientQuoteRequested`, and `blnClientQuoteRejected` on `tblTracking`.

- Provenance: **Documented** as schema notes. The send and quote actions were not traced.

## Requests and feedback

**BR-031 — Feedback is described as anonymous.** The login page says all info is submitted anonymously to HR.

- Provenance: **Documented** (`index.php`).
- The feedback save action was not read. Whether a user id is stored is **Unknown / Requires Confirmation**.

**BR-032 — Change requests have priority, hours, section, and status.** Saves write those fields to `tblX`.

- Provenance: **Implemented** (`change_requests.php`).
- Who may change priority is unclear: the user-form checkbox for request priority shares its input name with the responsibilities flag (see the PRD). **Requires Confirmation**.

## QuickBooks

**BR-033 — Two invoicing mechanisms are in the tree.** Month-end on `master` calls the Online auth URL. The Web Connector SOAP application is still in `quickbooks_webservices/`.

- Provenance: **Implemented** as code. Which one finance runs is **Unknown / Requires Confirmation**.

**BR-034 — Web Connector clock.** The connector config sets `Africa/Johannesburg`.

- Provenance: **Implemented** in `quickbooks_webservices/config.php`.

## Rules that must not be treated as confirmed policy

- Package prices, public terms, and the 2005 support-agreement Word file. The Word file was not extracted.
- Anything that exists only on `development` or a PHP 8.2 branch.
- The README sentence that AWS is the current host. No AWS template is in the `master` tree that was listed. The pipeline is FTP.
