The Legacy Dispatch Priority System (Work Order Manager)
How “what do I work on next” was decided on the shop floor before (and partly after) the July 2024 switch to date-based dispatch. Reconstructed 2026-09-01 from source: the WPF Work Order Manager (
PSI.All/PSI.WorkOrderManager), its WCF service (PSI.All/PSI.Service/…/WOService.cs), and the AFTEC BASIC batchPBSBASE/UPD.WIPROUTE.LINE(plaintext, authored JPT 2014, change log through 2025). Written to inform the macro/micro scheduling redesign — see Shop Floor Intelligence Vision.
The one-paragraph version
Every routing line got two numbers — Group Priority and Part Priority (lower = more urgent) —
resolved by a cascading override hierarchy that fell from a planner’s line-level edit down to the
job-level priority the PMO set. A planner-triggered batch (“Update ALL”, internally LOTR, program
UPD.WIPROUTE.LINE) flattened the hierarchy into a work file, and a second step (Publish Dispatch)
froze the result into the cached dispatch list operators saw. Dispatch order was
Group Priority ↑ → Part Priority ↑ → Due Date ↑ → WO ↑ — dates were only ever the tiebreak.
In ~July 2024 dispatching switched to the Date sort (Due ↑ → Group Priority ↑); the priority fields
still exist and still resolve.
The Group Priority cascade
Resolved per routing line by UPD.WIPROUTE.LINE in this order — first non-empty wins:
| # | Level | Field | Set by |
|---|---|---|---|
| 1 | Routing-line override | WIPROUTE.LINE.1287 attr 6 (GPRI.LN) | Planner editing the Grp Pri cell in WOM (medium-purple cell) |
| 2 | Work-order override | OPENWO.1287 attr 17 (GPRI.WO) | Planner, WO level (dark-purple cell) |
| 3 | Part-in-job | JOBPARTS.1287 attr 7 | Job planning |
| 4 | Job priority | JOBMASTER.1287 attr 9 (JOB.PRIOR) | PMO — the macro lever; one number per job |
| 5 | Sales order (non-job/stock work) | OPEN.ORD.HEAD.1287 attr 6 | Order entry |
| 6 | Default | 69 (“unplanned”) | Hardcoded |
Part Priority cascade (the tiebreak): PPRI.LN (WIPROUTE.LINE.1287 attr 5) → PPRI.WO
(OPENWO.1287 attr 1) → JOBPARTS.1287 attr 2 → default 99.
The result lands in WORK.WIPLINE.1287 attrs 45/46 (dict GRP.PRIOR / PART.PRIORITY), which is what
the grid actually sorts on. So the number an operator saw was usually the job priority, unless someone
above had overridden it closer to the line.
The meaning of the numbers
| Value | Meaning | UI |
|---|---|---|
| 0 / 1 | Hottest — also turns the Due Date cell red / orange | red/orange |
| ≤ 54 | Critical band | red |
| 55–100 | Warning band | orange |
| ≥ 101 | Normal | baseline |
| 69 | “Unplanned” default (was 11/999, then 99, then 69 — changed 2022) | |
| 999 | Parked / not yet needed |
Hardcoded heuristics inside the batch
UPD.WIPROUTE.LINE embeds shop rules that were tuned by hand over a decade (each with a change-log entry):
- Saw-outside: op 80 lines whose next op is 1130/1200/1202/1204 (outside processing) with no line override get Group Priority 70 (was 6, then 60).
- Assembly raw material (
#JOBsurrogate records): priority 999 until the job’s M&W-end date arrives, then bumps to 50 — a date-triggered priority escalation, i.e. the priority system quietly contained a dynamic, date-driven rule. - Non-assembly WOs with allocated material (
*WOrecords): priority 50 with synthetic dates (today+23/+30). - Outside-service ops (cost center 1000): queue/wait/move times overwritten to 4000/3000/500 to make the operation-date calculation behave — planner-tuned constants living inside a batch job.
- Operator completion propagation: an operator “C” status with a date flips the routing-line status to
Deven when AFTEC hasn’t closed the line.
The operating rhythm
- Update ALL (LOTR) — planner button in WOM; blocked 3:30–4:00 AM / 4:25–4:45 PM (nightly batch
windows). Runs
UPD.WIPROUTE.LINE+UPD.WO.MTL.STATon UniData, rebuildsWORK.WIPLINE.1287. - Publish Dispatch — snapshots the planner list into the cached dispatch list (
DispatchListLive) and broadcastsDispatchListPublished; operators’ grids refresh. Operators consume a frozen published list (Dispatch mode locks sort/filter) — priorities changed only when a planner published. - Focus window — control records
FOCUSPRIORITY/FOCUSPARTPRIORITYinJOBMASTER.1287define the planner’s horizon; rows outside (GrpPri > FocusPriorityand beyondDaysInFocus) render greyed. Changes broadcast live to every open WOM.
What this means for the future-state design
- It was never “a priority number” — it was an intent hierarchy with local overrides, plus hand-tuned escalation rules. That is structurally the same shape as the intent-based model (macro sets job intent, local overrides express exceptions); the failures were that the numbers were static between publishes, the rules were buried in a batch, and overrides never expired.
- The July 2024 “switch to dates” changed only the sort key, not the architecture: one static field replaced another. Neither regime recomputed against live shop state — that is the actual gap.
- BC migration gap (psi-dispatch #65):
GPRI.LN/PPRI.LNand the otherWIPROUTE.LINE.1287extension fields have no Business Central home yet. Decide deliberately — port the override capability, not the stale values. - Open question for planners who ran it: what conventions governed assigning
JOB.PRIORvalues (the 0/1 hot codes, band usage)? That was human practice, not code, and is not written down anywhere found so far.
Source provenance
| Artifact | Location |
|---|---|
| Priority resolution batch | \\ad.ptihome.com\DFS\Data\LinuxShare\pro3prog\PBSBASE\UPD.WIPROUTE.LINE (plaintext BASIC) |
| Material status batch | …\PBSBASE\UPD.WO.MTL.STAT |
| WCF service (Update ALL / Publish) | PSI.All/PSI.Service/trunk/PSI.UniData/PSI.UniDataService/WOService/WOService.cs |
| WOM client | PSI.All/PSI.WorkOrderManager/trunk/PSI.WorkOrderManager.View/ViewModels/WIPRouteViewModel.cs |
| UI inventory / color grammar | psi-dispatch/docs/legacy-wom-ui-inventory.md, docs/dispatch-grid-behavior.md |
Related: AFTEC Work Orders · psi-dispatch · Shop Floor Intelligence Vision