# Project plan — personal_laundry_20240415

Evidence date: 2026-10-06.

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

Inspected revision: `4af604f` (2024-03-19, "gitignore update") on `master`. That commit is `origin/HEAD`. There are no other remote branches.

This plan describes what the repository contains. It does not decide what the product should become.

Secrets in connection strings and in `CountCustomersLaundry.sendEmail` are omitted. They are called out under Security in `technical-documentation.md`.

## Product

`personal_laundry_20240415` is the operational linen system for Personal Laundry / Personal Cleaners. Hotel and similar customers declare a pickup on the web. The laundry floor then counts, packs, bags, and dispatches the linen, and the office exports deliveries to Pastel.

Provenance:

- **Documented** in `PL Current linen management system with sample documentation.docx`: count, pack, bag, then dispatch and invoice. Categories named in that document are Laundry, Linen, and F&B. The companion file `PL Current linen mngt system - Client Pick Up System Trail.docx` describes the client pickup screens.
- **Implemented** as three runnable applications in `PersonalLaundry/PersonalLaundry.sln`: the floor WinForms app `PersonalLaundry` (product name "Personal Laundry", ClickOnce `1.5.0.*`), the office WinForms app `PersonalAdmin` (ClickOnce `1.2.0.*`), and the ASP.NET site `PersonalWeb`.
- **Implemented** data model catalog name `PersonalLaundry` on SQL Server, via Entity Framework `DataModel` in `PersonalLaundry/Common`.

The public brochure site is a different repository, `personal_laundry_website`, already documented under `silicon_ark/personal_laundry_website/`. Domain `www.personallaundry.co.za` appears there. This repository's mail code uses `housekeeping@personallaundry.co.za` and `tk@personalcleaners.co.za`. Whether those brands are one legal entity is **Unknown / Requires Confirmation**.

No goal statement, success metric, or roadmap is written in the repository.

## Branch reality

| Branch | Tip | Date | What it is |
|---|---|---|---|
| `master` (only branch; `origin/HEAD`) | `4af604f` | 2024-03-19 | Full tree: floor app, admin app, website, EF model, vendored Json.NET, POS for .NET SDK, two Word process documents, a Pastel sample CSV, a `.7z` archive, and a photo |

History on `master`, oldest first. The Bitbucket history starts in 2020. Code comments and a Dropbox conflict filename date the application to 2012–2023, so this history is an import plus later edits, not the original development log.

1. `eb1db93` — 2020-10-26 — Abdurahmaan Ismail — "Initial commit".
2. `9e80cc2` — 2020-10-26 — maanie — "Initial commit".
3. `c98fb21` — 2023-09-04 — silmaanie — "added product code, active status and split customer menu". Adds `Customer.IsActive`, a `ProductCode` column on the `GetCustomerInventory` result, and splits the PersonalAdmin customer menu into Active and Inactive.
4. `978984e` — 2024-03-19 — Dewald Stander — "update gitignore".
5. `4af604f` — 2024-03-19 — Dewald Stander — "gitignore update". Ignores selected Visual Studio `obj` and `.vs` paths. `bin`, published ClickOnce output, and `PrecompiledWeb` remain in the tree.

## Scope in this repository

In scope of the tree at `4af604f`:

- Floor workflow: operator login, counting, packing, bagging, dispatch and invoice printing, receipt-printer output, count-variance and condemned-item email.
- Customer website: login, new and updated pickups, bag labels, invoices, dispatches, a mobile bag list, and an admin area for customers, operators, Pastel export, and settings.
- Office application: customers, customer logins, inventory prices, operators, a percentage price increase, two reports, and company settings.
- Shared EF model and stored-procedure imports in `PersonalLaundry/Common`.
- A sample Pastel Partner import file, `pastel excel import file layout.csv`.

Out of scope of what can be verified from git:

- The live SQL Server database, including status-name rows, role-name rows, inventory seed data, and the bodies of stored procedures. No `.sql` file is in the repository.
- Whether any of the committed connection strings still points at a live server.
- The contents of `Personal CURRENT linen management system.7z` (not opened).
- The website project `acme_v_2_1_3_html`, which the solution references under `AcmeTemplates` and which is not in the tree.
- `sonar-project.properties` and `sonarqube_scan.bat`. A 2026-09-28 directory listing of a scan-host working copy named those files. They are not in `4af604f`.

## System shape

```text
Customer browser (PersonalWeb)
        |  pickup, bag labels, invoices
        v
SQL Server database PersonalLaundry
        ^
        |  count, pack, bag, dispatch, print
Floor PC (PersonalLaundry WinForms + POS receipt printer)
        ^
        |  customers, prices, operators, reports
Office PC (PersonalAdmin WinForms)

Admin browser (PersonalWeb /admin)
        |  Pastel CSV download
        v
Pastel accounting import
```

Both desktop apps and the website use the same Entity Framework context, `Common.DataModel`. Workflow steps that change counts, create a workload, finish counting, create a package, or create a dispatch are stored procedures imported by the EDMX. Their SQL is not in git.

## Major components

| Component | Path | Role |
|---|---|---|
| Floor application | `PersonalLaundry/PersonalLaundry` | ClickOnce WinForms, .NET Framework 4.5, x86. Stations under `Station_01_Counting` through `Station_04_Dispatch` |
| Office application | `PersonalLaundry/PersonalAdmin` | ClickOnce WinForms, .NET Framework 4.5. Customer, operator, price, report, and settings screens |
| Shared model | `PersonalLaundry/Common` | EF 6.4.4 model `DataModel.edmx`. Entities, views, and function imports |
| Website | `PersonalWeb` | ASP.NET Web Site, .NET Framework 4.0, Forms authentication |
| Precompiled site | `PersonalLaundry/PrecompiledWeb` | Published copies `PersonalWeb` and `PersonalWebBeta` |
| Printer experiment | `PersonalLaundry/TestApp` | Console program that opens a POS printer named `PosPrinter` |
| Mail helper | `PersonalLaundry/PLFunctions/PLSendMail.cs` | CLR-style mail class. The solution still names `PLFunctions.sqlproj`, which is not in the tree; `PLFunctions.csproj` is |
| Empty shells | `PersonalFunctions`, `PointOfService` | Project files and `AssemblyInfo` only |
| Vendored libraries | `JSON/`, `Libraries/PosFor.Net/` | Newtonsoft.Json source and the Microsoft POS for .NET SDK, including samples |
| Process documents | repository root `.docx` files | Screen-by-screen description of counting through dispatch, and of the client pickup |

## Historical markers

These are dates written in source comments or in ClickOnce versions. They are not a signed project plan.

| When | Marker | Evidence |
|---|---|---|
| 2012-08-23 / 2012-08-24 | Dropbox conflict copies of the floor project and several forms | Filenames containing "Brett Meyerowitz's conflicted copy" |
| 2014-02-26 | Sample Pastel invoices IN100025 and IN100026 | `pastel excel import file layout.csv` |
| 2014-04-24 | Photo committed at the root | `20140424_195954.jpg` (contents not interpreted) |
| 2014-08-20 | Backup function import kept in the model | `GetWorkloadInventoryForInvoice_backup_20140820` |
| 2016-04-21 | Price Increase menu | Comment in `PersonalAdmin/ConsoleForm.cs` |
| 2016-05-09 | Price increase described as v1.2, including stain percent | Comment in `PriceIncreaseForm.cs` |
| 2016-06-02 / 2016-06-03 | Count-variance and condemned emails | Comments in `CountCustomersLaundry.cs` |
| 2016-09-16 | Email routing by three customer names | Same file |
| 2016 through 2019 | Pastel export columns, VAT from the database, wash type, condemned print flags, rewash null-check exception | Comments in `PastelExport.cs` and `PrintNotesForm.cs` |
| 2017-10-24 | Reports menu | `PersonalAdmin/ConsoleForm.cs` |
| 2018-01-09 | 10-minute idle logout, "specified by TK" | `PersonalLaundry/ConsoleForm.cs` |
| 2018-01-18 | Pickup reference mask, authorising operator, password check | `PersonalWeb/Pickup.aspx.cs` |
| 2023-08-31 | Active and inactive customer menus | Comment and commit `c98fb21` (committed 2023-09-04) |
| Floor app version | ClickOnce `1.5.0.*`, revision 87 | `PersonalLaundry.csproj` |
| Admin app version | ClickOnce `1.2.0.*`, revision 21 | `PersonalAdmin.csproj` |

## Dependencies

- Windows desktop with .NET Framework 4.5 for the two WinForms apps, and a host that can run ASP.NET 4.0 for `PersonalWeb`.
- SQL Server database `PersonalLaundry`. The active connection string in source `App.config` / `web.config` files names `sqlsrv02`. Other server names are commented. Which host is current is **Unknown / Requires Confirmation**.
- A Microsoft Point of Service receipt printer logical device on the floor PC. `TestApp` looks up the device name `PosPrinter`.
- SMTP. The floor app sends mail through `smtp.office365.com` port 587. Subject and body templates are `Settings` rows.
- Pastel (the accounting package). Export format matches the sample CSV: `Header` and `Detail` rows. There is no Pastel API client in the repository.
- Entity Framework 6.4.4 (`PersonalLaundry/Common/packages.config`).
- AjaxControlToolkit, registered in `PersonalWeb/web.config`.
- DigitalPersona fingerprint assemblies (`DPFP`) are referenced by `EnrollmentForm`, `VerificationForm`, and `CaptureForm`. The floor login form does not open them.

## Current status

The repository is a snapshot of a long-running internal system. The last two commits only change `.gitignore`. There is no open feature branch, no test project that asserts business behaviour, and no deployment script.

`PersonalAdmin` login loads operators whose `OperatorRoleId` is 3, then `PopulateMenu` replaces the logged-in operator with `OperatorLoginId` 2 before building the menu. That replacement is **Implemented Behaviour** and is recorded as a discrepancy in `business-rules.md`. Whether it is intentional is **Unknown / Requires Confirmation**.

The Word process document's closing section says discrepancy email, condemned items, and several invoice groupings were not yet in the system. The code contains discrepancy email, condemned counts, packages inside bags, and a `DeliveryId` that groups dispatches. Treat the Word file as an earlier process description, not as the current requirement set. Details are in `prd.md`.

## Known gaps

- Stored-procedure and view definitions are not in git, so status transitions inside `CreateWorkload`, `FinishCounting`, `CreatePackage`, and `CreateDispatch` cannot be stated beyond their call sites.
- Display names for `WorkloadStatus`, `InvoiceStatus`, `DispatchStatus`, `OperatorRoles`, and `WorkloadTypes` are database rows. Only some numeric ids are referenced in C#.
- No automated test suite for the laundry workflow. `JSON/Source` contains Newtonsoft.Json's own tests.
- Production host, current database, and whether the floor app is still the system of record are **Unknown / Requires Confirmation**.
