# Features — personal_laundry_20240415

Evidence date: 2026-10-06. Source: `git@bitbucket.org:overdrive/personal_laundry_20240415.git` at `4af604f` (`master`).

"Present" means the code is in this commit. "In use" on a live floor or website is **Unknown / Requires Confirmation** unless the code always runs when the app starts.

The public brochure site is not this repository. See `silicon_ark/personal_laundry_website/`.

## Current features

### Floor console

- WinForms shell. `Program.Main` opens `ConsoleForm`, which opens `LoginForm` and a POS printer.
- Home buttons: Count, Pack, Bag, Dispatch. Green when the matching count is above zero, otherwise grey.
- Workload status grid bound to `vwWorkloadStatusReportWithCounts`.
- Clock, logout via `Application.Restart`, and a 10-minute idle restart.
- Logo click checks for a ClickOnce update.
- Logs to `C:\LogFiles\logfile_ConsoleForm_{hour}.txt`.
- Location: `PersonalLaundry/PersonalLaundry/ConsoleForm.cs`, `Program.cs`.
- Status: present. ClickOnce identity `Personal Laundry` `1.5.0.*` revision 87.

### Floor login

- Username list is every operator whose role has `CanLogin`.
- Password keypad 0–9 plus backspace, and the Enter key.
- Calls `LoginOperator`.
- Location: `PersonalLaundry/PersonalLaundry/LoginForm.cs`.
- Status: present. This is the login `Program.cs` starts.

### Counting station

- Customers and bags waiting to be counted, then item counts by type.
- Bad / condemned quantity through `UpdateInvoiceItemBadCount`.
- Finish Counting calls `FinishCounting`, optionally prints trolley notes, then sends variance and condemned emails.
- Location: `PersonalLaundry/PersonalLaundry/Station_01_Counting/` (`CountingStation`, `CountCustomerBags`, `CountCustomersLaundry`, `CountLaundryType`, `CountCalculator`).
- Status: present.
- Older copies of the same forms, named as Brett Meyerowitz Dropbox conflicts from 2012-08-23, sit beside the live files and are not the project compile inputs that were verified.

### Packing station

- Lists work to pack and records a package quantity per item type.
- `CreatePackage` stored procedure. Package row stores `ItemCount` and `ItemCountStain`.
- Location: `PersonalLaundry/PersonalLaundry/Station_02_Packing/` (`CreatePackage`, `PackageInvoice`, `PackageInvoiceItem`, `PackageInvoiceType`).
- Status: present.
- A filter on invoice status 2 or 3 in `CreatePackage.cs` is commented out.

### Bagging station

- Puts packages into a delivery bag and captures `BagSeal`.
- Offers invoices in `InvoiceStatusId` 3, at most 100, newest workload first.
- Location: `PersonalLaundry/PersonalLaundry/Station_03_Bagging/` (`BagForm`, `BagInvoiceForm`).
- Status: present.

### Dispatch and print

- Selects dispatches in `DispatchStatusId` 2, confirms bag contents, prints invoice and delivery note.
- Sets or clears `CondemnedPrinted` for a dispatch or a delivery.
- Comment dated 2019-02-15: rewash does not use the null checks.
- Location: `PersonalLaundry/PersonalLaundry/Station_04_Dispatch/` (`DispatchForm`, `PrintNotesForm`).
- Status: present.
- `zzDispatchForm` and `zzPrintNotesForm` in the same folder are earlier copies. They are not the types the console opens.

### Receipt printing

- Microsoft Point of Service printer. Logo saved as `printerLogo.bmp` and sent with `SetBitmap`. Init retries up to five times when the device reports that it is not initialized.
- `ReceiptPrinter` in `PersonalLaundry/Common` prints trolley notes and the other slips the stations request.
- Location: `ConsoleForm.InitializePrinter`, `Common/ReceiptPrinter.cs`.
- Status: present. The physical device name used by the floor app was not read off the printer setup; `TestApp` asks for a device named `PosPrinter`.

### Count and condemned email

- After finish, emails a recon table when `vwInvoiceCountsRecon` has rows, and a condemned table when `vwInvoiceCountsCondemned` has rows.
- Recipient rule is hardcoded for three customer names, with a fallback and two BCC addresses. See `business-rules.md`.
- SMTP host in use is `smtp.office365.com` port 587, SSL. Two older hosts are commented.
- Location: `CountCustomersLaundry.sendEmail`.
- Status: present. The Word process document still describes this email as not built. The code is newer than that sentence.

### Customer website — pickup

- Forms login. Customer cookie is the login GUID. Pickup list, new pickup, update, view.
- Categories on the form: `Laundry`, `Linen`, `Food and Bev`.
- Reference padded to 8 digits, duplicate reference blocked, operator password required, total bags stored, then bag labels.
- Location: `PersonalWeb/Login.aspx`, `Pickups.aspx`, `Pickup.aspx`, `BagLabels.aspx`, `BagLabelsPrint.aspx`. Routes in `Global.asax`.
- Status: present.

### Customer website — invoices and dispatches

- Lists and detail pages. Invoice detail prints a condemned line when `BadCount > 0`.
- Location: `Invoices.aspx`, `Invoice.aspx`, `Dispatch.aspx`, `Reports/Pickup.aspx`.
- Status: present.

### Mobile bag list

- Operator login on a phone is redirected to `/Mobile/`.
- A customer page lists bags on workloads in status 1, split by whether `OperatorLoginId` is 1.
- Location: `PersonalWeb/Mobile/`.
- Status: present.

### Website administration

- Customers and edit customer, including Pastel code (`admin/customers`, `admin/customers/{customerId}`).
- Operators (`admin/operators`). New operators are saved with role id 2.
- Pastel export (`admin/export`). Non-mobile operator login lands here.
- Settings (`admin/settings`).
- Location: `PersonalWeb/Admin/`.
- Status: present.

### Pastel file export

- Builds Header and Detail lines per delivery. See FR-023 in `prd.md` for the column rules.
- Also writes an export log that includes `GetDuplicatePrelists`.
- Location: `PersonalWeb/App_Code/PastelExport.cs`, `Admin/Export.aspx`.
- Sample layout, not produced by this class: `pastel excel import file layout.csv` (dated 2014-02-26 in the sample rows).
- Status: present.

### Barcode HTTP handler

- `Handlers/BarcodeHandler.ashx` returns a JPEG for `type` and integer `value`.
- Status: present.

### Office application

- Login limited to `OperatorRoleId` 3 with `CanLogin`.
- Menus: Active Customers, Inactive Customers, Operators, Price Increase, Reports, Settings.
- Customer editor stores `IsActive` (comment 2023-08-31, commit `c98fb21`).
- Inventory grid shows category, type, size, costs, and `ProductCode`. Save calls `UpdateInventoryItemType(category, type, size, id)` and does not pass `ProductCode`.
- Price increase applies `UpdateCustomerInventoryByPercentages` and tells the user the change cannot be undone.
- Reports: Outstanding Order, Bag Recon (pickups and deliveries), ReportViewer, local RDLC.
- Settings: company name, address, phone, email, VAT number.
- ClickOnce `1.2.0.*` revision 21.
- Location: `PersonalLaundry/PersonalAdmin/`.
- Status: present.
- Discrepancy: after login, `PopulateMenu` replaces the operator with `OperatorLoginId` 2. See `business-rules.md`.

### Shared database model

- EF 6.4.4 context `DataModel` over catalog `PersonalLaundry`.
- Tables, views, and function imports listed in `technical-documentation.md`.
- Location: `PersonalLaundry/Common/DataModel.edmx`.
- A second model, `PLModel.edmx`, is an older shape (no packages table, `DispatchItems` instead of `DispatchPackages`). The running apps construct `DataModel`, not the older context.
- Status: `DataModel` is the model the applications use. `PLModel` is present and unused by `Program.cs`.

### Published website copies

- `PersonalLaundry/PrecompiledWeb/PersonalWeb` and `PersonalWebBeta`.
- The solution's website project compiles `PersonalWeb` to `PrecompiledWeb\PersonalWebBeta` with virtual path `/PersonalWebBeta`.
- Status: present as build output checked into git. It can drift from `PersonalWeb` source. Treat `PersonalWeb/*.aspx` as the source.

### Fingerprint capture

- `EnrollmentForm`, `CaptureForm`, `VerificationForm` using DigitalPersona `DPFP`.
- Stored procedure import `SaveFingerprint`.
- Status: present, not opened by the floor login or console. In use: **Unknown**.

### Printer test console

- `PersonalLaundry/TestApp` opens POS device `PosPrinter` and prints a sample header from `Settings`.
- Status: present. It is a manual harness, not a test suite.

## Completed features

These are in the current tree and are called out because a comment or an older document marks the date they were added.

| Feature | Dated evidence | Commit if any |
|---|---|---|
| Active / inactive customer menus and `Customer.IsActive` | Comment 2023-08-31 | `c98fb21` (2023-09-04) |
| `ProductCode` on `GetCustomerInventory` and the admin grid | Same commit | `c98fb21` |
| Pickup reference mask, authorising operator, total bags | Comments 2018-01-18 and 2018-11-12 in `Pickup.aspx.cs` | Inside the 2020 initial import |
| 10-minute idle logout | Comment 2018-01-09 | Inside the 2020 initial import |
| VAT rate from the `VAT` table, wash type and shift on the Pastel header, stained quantity added to Pastel quantity | Comments 2017-12-29 through 2018-05-16 in `PastelExport.cs` | Inside the 2020 initial import |
| Reports menu | Comment 2017-10-24 | Inside the 2020 initial import |
| Price increase | Comments 2016-04-21 and 2016-05-09 | Inside the 2020 initial import |
| Variance email and condemned email | Comments 2016-06-02 and 2016-06-03 | Inside the 2020 initial import |
| Duplicate pre-list check | Comment 2016-10-20 | Inside the 2020 initial import |

## In development

No branch other than `master`. No `TODO` or unfinished project that the solution builds was identified as the current work. The last commit (`4af604f`, 2024-03-19) only updates `.gitignore`.

`PersonalAdmin` version is still `1.2.0.*` while the floor app is `1.5.0.*`. That is a version-number fact, not evidence of an unfinished release.

## Planned, as written, and not matched to later code

The Word file `PL Current linen management system with sample documentation.docx` ends with items "currently NOT in our system":

| Written gap | Later code |
|---|---|
| Email when the laundry count differs from the hotel count | **Present** (`sendEmail`, recon section) |
| Record a condemned piece on the count and return it unwashed | Count and email are **present**. A distinct "do not wash / return uncleaned" state was not found in C# |
| Several packages in one bag | **Present** |
| Several bags on one invoice | **Inferred** from `Dispatches.InvoiceId`. Procedure not in git |
| Several invoices on one delivery note | **Inferred** from `Dispatches.DeliveryId`. Procedure not in git |

No other roadmap document is in the repository.

## Deprecated or leftover

| Item | Evidence | Status |
|---|---|---|
| `zzDispatchForm`, `zzPrintNotesForm` | Same folder as the live dispatch forms. Console opens `DispatchForm` and the print form opens `PrintNotesForm` | Leftover. Not the path the console starts |
| Dropbox conflict files from 2012-08-23 and 2012-08-24 | Filenames in `PersonalLaundry/PersonalLaundry` | Leftover copies |
| `GetWorkloadInventoryForInvoice_backup_20140820` | Function import on `DataModel` | Leftover import. Call sites were not found in the stations |
| `PLModel.edmx` | Older entity set (no `Packages`) | Leftover model |
| Commented connection strings | `App.config` and `web.config` | Historical servers. The uncommented string is the one the app will use |
| Commented SMTP hosts | `CountCustomersLaundry.sendEmail` | Not used |
| `PersonalFunctions` and `PointOfService` projects | Assembly info only | Empty shells. `PointOfService` is not the POS SDK; that SDK is under `Libraries/PosFor.Net` |
| Solution project `acme_v_2_1_3_html` | `PersonalLaundry.sln` points at `..\AcmeTemplates\acme_v_2_1_3_html` | **Missing from the tree** |
| Solution project `PLFunctions.sqlproj` | `PersonalLaundry.sln` | **Missing.** The directory contains `PLFunctions.csproj` and `PLSendMail.cs` instead |
| Private-network auto login as `test@test.com` | `Login.aspx.cs` | Present. It behaves as a bypass, not as a documented product feature |
| Vendored `JSON/` Newtonsoft.Json source and `Libraries/PosFor.Net` samples | Repository root | Third-party trees, not Personal Laundry features |
| `Personal CURRENT linen management system.7z` | Repository root | Archive. Not opened. Contents **Unknown** |
| `20140424_195954.jpg` | Repository root | Image. Not interpreted |

## Recently changed

Relative to the imported history, the only product change after the 2020-10-26 initial commits is `c98fb21` (2023-09-04): active flag, product code on the inventory query result, and the split customer menu. The 2024-03-19 commits change gitignore only.

## Removed features

Nothing in the five-commit history deletes a feature. Older behaviour survives as commented code and `zz` forms rather than as a recorded removal.
