# Project plan — qoutes (Silicon Overdrive Quotes)

Evidence date: 2026-10-05.

Source repository: `git@bitbucket.org:overdrive/qoutes.git`.

Inspected revision: `master` at `0eb2f86480c90e824a279296b4dbfa15e7eb7ac1` (2019-11-19, rachelmogano, "First Commit"). The scan-host path `~/projects/sonar_scan/repos/qoutes` was not on this machine. The tree was read from that git revision. Database passwords in `system.php` are not reproduced here.

The directory name is spelled **qoutes**. The live host configured in code is `quotes.overdrive.co.za`. This plan describes what the repository contains. It does not decide what the product should become.

## Product

There is no README and no product requirements document in the source repository.

The application is an internal PHP quoting and sales-operations system for Silicon Overdrive. Evidence:

| Signal | Where | Provenance |
|---|---|---|
| Host `quotes.overdrive.co.za`, live database `quoteslive` | `system.php` | **Implemented** |
| Email subject fragment "Pricing: Silicon" | `includes/quote.cls.php` `EmailQuoteTo` | **Implemented** |
| Field label "Silicon Notes" on the quote form | `quote.php` | **Implemented** |
| Brand and title loaded from `sysSettings` | `system.php` | **Implemented** behaviour; the stored brand string is **Unknown** (it lives in the database) |
| Spreadsheet "Sales Workflow" describing quote arrival, status, email, and supplier order | `Sales Workflow.xlsx` | **Documented** in that workbook |

A second product area, CSP, has its own client pipeline (`cspClient`) and can create a quote and push it toward invoicing. What the letters CSP stand for is **Unknown / Requires Confirmation**.

A third area, Service 360, stores grouped service items and can generate a client PDF report (`client.service.360.php`).

## Branch reality

| Line | Tip | Date | What it is |
|---|---|---|---|
| `master` | `0eb2f86` | 2019-11-19 | Only commit on the inspected clone: "First Commit" |

Inline comments in the PHP files are dated from 2012 through 2019 (authors named in comments include Fanie, Jacques, Christiaan, Gael, Rachel, Maanie, PJ, PS). Those dates are comments, not git history. Git history does not show later commits, a `develop` branch, or a removed feature after this snapshot.

Dated copies sit beside live files (`*.20190910.php`, `includes/quote.cls.20190918.php`, `*.bak`). Controllers include the unsuffixed files. Those dated copies are **Implemented** as files in the tree. Whether they are still deployed anywhere is **Unknown**.

## Objectives visible in the code

These are recovered from behaviour, not from a written charter.

1. Let staff create, price, revise, PDF, and email client quotes.
2. Move a quote through a status list from new, through sent and invoicing, to paid, ordered, stock arrived, and delivered.
3. Keep clients, products, suppliers, categories, sales people, and quote templates.
4. Email operations when status changes, and email clients a follow-up when a sent quote is old.
5. Pull invoice and paid state from a QuickBooks web-services database.
6. Run CSP as a separate client pipeline that can generate a quote.
7. Produce ETA, quote-status, and profit reports.
8. Restrict pages by security group.

## Scope

### In this repository

- Nemo page framework: login, menu, list, detail, toolbar, filters, paging, messages.
- Quote, quote template, and quote bundle maintenance.
- Client maintenance, including import from an eIT client list.
- Product, category, supplier, and CSV product import.
- Sales person, user, security group, settings, email log, and email templates.
- Reports: ETA, quote status, profit.
- CSP dashboard, CSP client, CSP FAQ, CSP import.
- Service 360 catalogue and per-client Service 360 report.
- Cron scripts for QuickBooks status mail, ETA mail, stale-quote mail, and client follow-up mail.
- PDF generation (mPDF) and spreadsheet generation (PHPExcel).
- Highcharts dashboard on `index.php`.

### Not in this repository

- The MySQL schema as a migration or dump. Table shapes are implied by queries and by foreign-key notes in `relationships.rtf` and class-file comments.
- Menu rows (`sysMenuLevel1`, `sysMenuLevel2`) and setting values (`sysSettings`). The menu is built from the database.
- Crontab entries. Script names suggest a schedule; the schedule itself is not in git.
- The QuickBooks connector application. This repo calls `WebSeviceURL` (spelled that way in code) and reads `invoice_table`.
- The eIT application. This repo can search and import eIT clients through a second database connection.
- Automated tests, Composer or npm manifests, Docker, and a CI pipeline.
- A current production operations runbook.

## System architecture

Browser posts a single HTML form to the current PHP script. `system.php` picks a database profile from `$_SERVER[SERVER_NAME]`, opens MySQLi, loads `sysSettings` into `$SystemSettings`, and starts the session. `Nemo` refuses the page when `$_SESSION[USER]` is missing and redirects to the session-expired URL from settings. Page rights come from `sysSecurity` for the user's security group.

```text
Browser
  -> login.php / *.php controllers
       -> Nemo (session, menu, security)
       -> entity class (includes/*.cls.php)
            -> MySQL (quoteslive / eit2)
            -> second MySQL (eitlivedb) for eIT client import
            -> QuickBooks web-services MySQL (invoice_table)
            -> PHP mail()
            -> PDF files under the documents directory
```

Local profile key `lamp` uses database `eit2` on localhost. Live profile key `quotes.overdrive.co.za` uses database `quoteslive` on `sql24.jnb1.host-h.net`. A second live connection uses database `eitlivedb`. QuickBooks uses `quickbook_webservice` on `sql27.jnb1.host-h.net` in the live profile, and `quickbooks_webservices` in the lamp profile. The hourly cron also hardcodes database names `eit2` and `quickbooks_webservices` in SQL, which does not match the live database name `quoteslive`.

## Major components

| Component | Role | Evidence |
|---|---|---|
| Nemo | Session, security, menu, list/detail UI | `_nemo.cls.php`, `_nemo.details.cls.php`, `_nemo.list.cls.php`, `_nemo.menu.cls.php` |
| Quote | Quote header, lines, PDF, email, status | `quote.php`, `includes/quote.cls.php` |
| Catalogue | Product, category, supplier, import | `product.php`, `category.php`, `supplier.php`, `product.import.php` |
| Parties | Client, sales person | `client.php`, `sales.person.php` |
| Templates and bundles | Reusable quote content | `quote.template.php`, `quote.bundle.php` |
| CSP | Separate client pipeline into quotes | `csp.*.php`, `includes/csp.*.cls.php` |
| Service 360 | Grouped service catalogue and client PDF | `service.360.php`, `client.service.360.php` |
| Reports | ETA, status, profit | `report.php`, `includes/rpt.*.php` |
| Mail | Templates, outbox, `mail()` | `_nemo.email.cls.php`, `email.php`, `email.template.php` |
| Cron | QB sync mail, ETA, stale status, follow-up | `cron.hourly.php`, `cron.daily.php`, `cron.daily12.php`, `cron.monthly27.php` |
| File integrity | NemoFIM compare (hourly path) | `_nemo.fim.cls.php`, called from `cron.hourly.php` |

## Milestones visible in comments

These are historical notes inside the 2019 snapshot, not a forward plan.

| When (comment) | What the comment says |
|---|---|
| 2013-06 | Revision control on quotes |
| 2013-12 | Dashboard charts; email quote to client or to the logged-in user |
| 2014-01 | Supplier order number from invoice number and client name; status date on save; PO required before "To be Invoiced" |
| 2016-11 | Quote line linked to supplier; price breakdown rewritten around groupings |
| 2017-01 | Client follow-up email |
| 2017-03 | Option to hide the PDF total |
| 2017-10 | Sectional PDF branding |
| 2018-11 | Currency, including a path that skips VAT when currency is `$` |
| 2019-09 | CSP export fix; PDF terms layout fix (Rachel) |

No milestone after 2019-11-19 is in git.

## Implementation plan

There is no implementation plan file. The repository is a single import of a running PHP application. Further product work is **Unknown / Requires Confirmation**.

## Known dependencies

- PHP with MySQLi, sessions, and `mail()`.
- MySQL databases named above.
- Vendored libraries: mPDF (`includes/mpdf`), PHPExcel (`includes/phpExcel` and `includes/phpExcel_20190910`), jQuery 1.7.1 and jQuery UI, Highcharts (including a Java export server under `plugins/Highcharts`).
- An external QuickBooks web-service endpoint configured as setting `WebSeviceURL`.
- An eIT database for client import.
- Hetzner-style hosting is mentioned in comments (`system.php` cron server-name fix, email class comment about Hetzner). Hosting contract details are **Unknown**.

## Current project status

**Implemented** as a 2019 snapshot of a production-shaped internal app. Whether `quotes.overdrive.co.za` still serves this tree is **Unknown / Requires Confirmation**.

Silicon Ark had no `qoutes/` documents before this onboarding.

## Human confirmation

- Confirm the product name (repository `qoutes`, host `quotes`, emails "Pricing: Silicon", databases `eit2` / `quoteslive`).
- Confirm whether this snapshot is still the live system.
- Confirm CSP's full name and whether it is still in use.
- Confirm the real crontab for the four cron scripts.
- Confirm security-group names. Comments disagree: `report.php` calls group 3 a sales person; `quote.php` comments call group 3 admin; `csp.dashboard.php` treats groups 1 and 2 as admin.
- Rotate credentials. `system.php` stores database passwords in git. They are intentionally omitted from this documentation.
- The hourly cron SQL uses `eit2` and `quickbooks_webservices` even when the live profile uses `quoteslive` and `quickbook_webservice`. Confirm which names production actually uses.
