# Features — snell-cronjob

Evidence date: 2026-10-03. Revision: `master` `f092e9b` (2026-06-26).

No feature list exists in the source repository. Status below is from the VB project, `app.config`, `Scripts/`, and git history.

Planned features: **none are written down**. Commented blocks are inactive code, not a backlog.

## Current features

| Feature | Status | Where |
|---|---|---|
| Windows Forms host titled Snell Cronjob v1.0 | Current | `frmCronjob.Designer.vb` |
| Release: run once and close when setting `Debug` is false | Current | `frmCronjob_Load` |
| Debug: leave the form open; Run button calls `Run` | Current | `#If DEBUG`, `btnRun_Click` |
| Single-instance application | Current | `My Project/Application.myapp` |
| Copy `Free Stock Requisition.csv` from the AdvM download folder into `Imports\` | Current | `Process.DownloadFile` |
| Reject any extension other than `.csv` | Current | `Process.CheckLocalFile` |
| Truncate `stgFreeStockRequisition` and insert parsed rows | Current | `ClearStagingTable`, `sqlInsertStaging` |
| Delete the Imports file after a valid import | Current. Archive copy/move is commented out | `Process.ArchiveFile` |
| Create missing `fsrRequestType` rows via `sysQuery` 41 | Current. SQL text lives in the database | `FreeStockRequisition_AM_Process.Process` |
| Insert `fsrRequisition` as `Pending` and assign pink slip `ES` + 7 digits | Current | `sqlInsertFSR` |
| Insert `fsrItem` from staging joined to `dwdProduct`, total rounded to 4 decimal places | Current | item `INSERT` in `Process` |
| Queue `sysCronJob` type `FSR_NewRequisition` | Current | same method |
| Log staging rows that did not become requisitions (`sysQuery` 42) | Current | end of `Process` |
| Stale-file email method | Present. The clock comparison does not admit the send. See business rules | `CheckLocalFileUpdatedTime`, `EmailManager` |
| Midday chase of pending requisitions to alternate or executive manager | Current, 12:00–12:19, day difference > 1 | `frmCronjob.PreProcess` |
| Email + PDF for `FSR_NewRequisition` | Current | `frmCronjob.Run` |
| Email + PDF for `FSR_RequisitionApproved` | Current. This exe consumes the job; it does not create it | `frmCronjob.Run` |
| Manager versus executive choice from `SalesManagerMaxValue` (10000 in git) | Current | both mail cases and the chase |
| ReportViewer PDF `SubmittedRequisition_*.pdf` and `ApprovedRequisition_*.pdf` | Current | `ProjectFunctions.createPDF` |
| Requisition report definition | Current as a committed build output | `Snell Cronjob/bin/Release/Reports/RDLC/Requisition.rdlc` |
| 40-minute cap on the queue loop | Current | `intOpperationTimeMax` |
| Reset status containing `Processing` back to `New` | Current | end of `Run` |
| SAP export of approved unsent requisitions | Current in code, **off** unless settings say otherwise. Git default `FsrSapExportEnabled` = `False` | `FsrOrder_ESnell_Process` |
| ORDERS IDoc SOAP body | Current | `IdocGenerator.BuildFsrSoapXml` |
| SAP retry counter, last error, sent flag and timestamp | Current in the UPDATE statements. Columns are added by the SQL script, which is not a migration runner | `Scripts/AlterFsrRequisition_SapColumns.sql` |
| SAP failure email | Current when a notify address is set. Default `maanie@overdrive.co.za` | `SendFailureEmail` |
| Manual ESnell connectivity and sample POST | Current as an operator script, not part of the exe | `Scripts/SendEsnellFsrTest.ps1` |
| File log listener named `FileLogWriter` | Present in `app.config`. The cron path writes SQL logs, not this listener | `app.config` `system.diagnostics` |
| Progress bars for operation time and queue | Current on the form. Release runs usually close before a person sees them | `UpdateProgress` |

## CSV columns the import enforces

Header comment in `sqlInsertStaging`: UniqueID, Rep Code, RequestType, Date, Region, ExpenseType, BillToAccount, ShipToAccount, RequestDetail, ContactPerson, ContactNumber, Delivery, SKU, QTY_CASE, QTY_BOTTLE.

| Index | Check | Empty expense type |
|---|---|---|
| 0 UniqueID | Required | |
| 1 Rep code | Required | |
| 2 Request type | Required | |
| 3 Date | Length must be 10 | |
| 4 Region | Required | |
| 5 Expense type | Not required since the 2015-01-13 comment | Allowed blank |
| 6 Bill-to | Required | |
| 7 Ship-to | Required | |
| 8–11 Detail, contact, phone, delivery | Written through. No emptiness check | |
| 12 SKU | Required | |
| 13 Case qty | Required, and not both zero with bottle qty | |
| 14 Bottle qty | Required | |

`CleanString` runs on indexes 0–12 before the checks. Indexes 13 and 14 are inserted unquoted.

## Email features by job

| Mail | From (release) | To | CC | BCC | Attachment |
|---|---|---|---|---|---|
| Stale file | noreply@esnell.co.za | `StaleFileNotifyManagerEmail` | `StaleFileNotifyCCEmail` | none | none |
| New requisition | noreply@esnell.co.za | Manager if total `<= 10000`, else executive | Requester, release only | none (BCC loop commented out) | `SubmittedRequisition_{pink}.pdf` |
| Midday chase | noreply@esnell.co.za | Alternate if total `<= 10000`, else executive | Requester | none | same submitted PDF name |
| Approved | noreply@esnell.co.za | `SnellEmailAddress` | Requester and `SnellEmailAddress2` | maanie@overdrive.co.za | `ApprovedRequisition_{pink}.pdf` |
| SAP failure (release) | noreply@esnell.co.za | `SapFailureNotifyEmail` | none | none | none |

Debug compiles replace the SMTP client and send the FSR mails to `exiledbandit@gmail.com`. The SAP failure debug path uses the same Office 365 client. Secrets in those blocks are omitted from this document.

## SAP IDoc features

| Piece | Value the generator writes |
|---|---|
| Operation | `urn:ZRfcEdiIdocInputOrders` |
| Order type `Bsart` | Setting `FsrSapBsart`, default `OR` |
| Reason `Augru` | Setting `FsrSapAugru`, default `279` |
| Collection | When `blnDelivery` is false: `Bstzd` = `COLL`, `Lifsk` = `ZG`. Delivery leaves both empty |
| Sales org segments | Qualf 012 / 006 / 007 / 008 with org ids `OR`, `00`, `01`, `XZA1` |
| Dates | Document date as `yyyyMMdd` on iddat 002 and 022, and on the pink-slip reference |
| Bill-to / ship-to | `dwdCustomer.strSAPCode`, partner roles AG and WE, left-padded with zeros to 10 characters or truncated to the last 10 |
| Z1 | Partner `991`, name = `FsrSapZ1Email`, default `rgbcpda@esnell.co.za` |
| Z2 | Partner `992`, name = rep email, or `orders@esnell.co.za` when the rep email is empty |
| Customer reference | Pink slip in `Belnr` |
| Lines | One item per non-zero case quantity (`Pmene` `CS`) and one per non-zero bottle quantity (`Pmene` `BT`). Position starts at 1. Action `001` |
| Material | Product code with a trailing `S` or `F` removed |
| Description | `strLongProdDesc` trimmed to 30 characters and padded to 30 |

## Completed (present, and not described as future)

The behaviours in the current-features table are in `master`. The SAP work is the latest commit (`f092e9b`, 2026-06-26) and is complete as source. Turning it on is a configuration step, not an unwritten feature.

Earlier mail changes are already in the tree: noreply sender (`b626d84`, 2024-10-07), Lloyd's address updates (`e1d8785`, `6341e5b`).

## In development

Nothing in the branch list or the tree is marked in progress. `master` is the only branch.

## Planned

No roadmap, issue list, or TODO file. Comments that describe work which is not in the executable:

| Comment | What the code does instead |
|---|---|
| `ArchiveProduct` job, 2013-11-05 | No `Case` arm |
| Archive the CSV with a timestamp | `File.Delete` only |
| `SnellEmailAddress3` CC, 2021-10-20 | The `MailAddress` lines are commented out |
| BCC list from `BCCAddresses` | The split loop is commented out. `BCCAddresses` in git is empty |
| Partial-import deletes and `DeleteDW` | Calls are commented out in the FSR run |
| `tblDwf = tmp...` when live | Both debug and release use `dwf` + process id. The FSR class does not call `SetDeletes` |

## Recently changed

`f092e9b` (2026-06-26) adds `FsrOrder_ESnell_Process.vb`, `IdocGenerator.vb`, the SQL script, the PowerShell probe, SAP properties on `Settings.Designer.vb`, and the `PreProcess` call. The same commit touches the cron form (version comment `v1s.1.5`, 2026-06-12).

`Settings.settings` and `app.config` were not given the new SAP keys. Defaults on the designer attributes apply until a deployed config adds them.

## Deprecated or removed

| Item | Evidence |
|---|---|
| Sender `freestock@esnell.co.za` | Commented. Live string is `noreply@esnell.co.za` since `b626d84` |
| Mandatory expense type | Check commented, 2015-01-13 |
| 3-day alt-manager wait | Replaced in source by `DATEDIFF(day) > 1` |
| BCC to Beyersv@esnell.co.za and the `BCCAddresses` setting | Commented out in the mail builders |
| Sonar project files named by the 2026-09-28 scan | Not in git history |

## Code that compiles and is not on the run path

| Piece | Evidence |
|---|---|
| `Duodecimal` | No caller outside its own file |
| `LogginUser`, fiscal-period helpers | Defined on `SystemFunctions`. No cron caller |
| `sql_get_Users` | Used only by `LogginUser` |
| `db.MergeDataSets`, `doQueryAsync`, `doQueryXTab`, `CleanData` | No caller in the FSR or SAP classes |
| `SuperbowlDataSet` | Compiled. Only `SuperbowlDataSet.Designer.vb` names the type |
| `xdb` in `db.cls.vb` | Empty subclass |
| `bgwJob` | Never run |
| `StartTimer` / `Button1_Click_1` | No matching button on the form |

These look like leftovers from the Superbowl cron job the comments refer to. Treating them as live Snell features would be an inference the call graph does not support.

## Not features of this repository

- Staff login, draft, submit, approve, decline, and cancel. Those are `snell-freestock`.
- A test project or CI scan.
- ClickOnce updates. `UpdateEnabled` is false. `SignManifests` is false. `PublishUrl` is a desktop path under a user named pieter.
