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 batch PBSBASE/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:

#LevelFieldSet by
1Routing-line overrideWIPROUTE.LINE.1287 attr 6 (GPRI.LN)Planner editing the Grp Pri cell in WOM (medium-purple cell)
2Work-order overrideOPENWO.1287 attr 17 (GPRI.WO)Planner, WO level (dark-purple cell)
3Part-in-jobJOBPARTS.1287 attr 7Job planning
4Job priorityJOBMASTER.1287 attr 9 (JOB.PRIOR)PMO — the macro lever; one number per job
5Sales order (non-job/stock work)OPEN.ORD.HEAD.1287 attr 6Order entry
6Default69 (“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

ValueMeaningUI
0 / 1Hottest — also turns the Due Date cell red / orangered/orange
≤ 54Critical bandred
55–100Warning bandorange
≥ 101Normalbaseline
69“Unplanned” default (was 11/999, then 99, then 69 — changed 2022)
999Parked / 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 (#JOB surrogate 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 (*WO records): 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 D even when AFTEC hasn’t closed the line.

The operating rhythm

  1. 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.STAT on UniData, rebuilds WORK.WIPLINE.1287.
  2. Publish Dispatch — snapshots the planner list into the cached dispatch list (DispatchListLive) and broadcasts DispatchListPublished; operators’ grids refresh. Operators consume a frozen published list (Dispatch mode locks sort/filter) — priorities changed only when a planner published.
  3. Focus window — control records FOCUSPRIORITY / FOCUSPARTPRIORITY in JOBMASTER.1287 define the planner’s horizon; rows outside (GrpPri > FocusPriority and beyond DaysInFocus) 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.LN and the other WIPROUTE.LINE.1287 extension 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.PRIOR values (the 0/1 hot codes, band usage)? That was human practice, not code, and is not written down anywhere found so far.

Source provenance

ArtifactLocation
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 clientPSI.All/PSI.WorkOrderManager/trunk/PSI.WorkOrderManager.View/ViewModels/WIPRouteViewModel.cs
UI inventory / color grammarpsi-dispatch/docs/legacy-wom-ui-inventory.md, docs/dispatch-grid-behavior.md

Related: AFTEC Work Orders · psi-dispatch · Shop Floor Intelligence Vision