The v2 Work Order view as it ships (V1), plus GP$, GP%, GP-per-hour and a Below Goal flag on every group card and in the bottom bar, driven by two new shop settings. Everything below is what differs from work-order-view-v1.html; that page and every shared part are unchanged.
1Group header GP cluster New
Every group card, Ungrouped included — after the breakdown, against the subtotal
Suspension
Parts$1,836.90 · 23.13%Labor$1,049.00Sublets$450.00
Below GoalGP $1,26938.0%$195/hrest.
$3,335.90
- Below Goal pill: red, same shape as the status chip (10px/700 uppercase, radius 5px, padding 3px 9px). Only when a goal is set, revenue > 0 and GP% < goal.
- GP% turns red below goal. GP$ and GP/hr never do.
- GP/hr is hidden when the group has no billed labor hours (a parts-only group).
- est. (muted, dotted underline) whenever any labor in the group uses estimated cost. Hover: “Includes estimated labor: 1.5 unclocked hrs at $30/hr”, or with no estimate set, “1.5 unclocked hrs counted at $0 — set Estimated labor cost per hour in My Shop › Target Margin”.
- Empty group or $0 revenue: GP$ and GP% read —, never Below Goal. Negative GP reads −$120.
- At 1280px with a long name and all three types, the breakdown and title truncate with an ellipsis; the GP cluster, subtotal and icons never do.
2Bottom bar GP New
Left of the existing stat row (labor … total unchanged)
GP$2,436GP %41.8%GP / HR$244est.
| Labor $1,609.00 Parts $3,915.58 …
- Same label/value typography as the other stats. GP% red below goal; est. with the same tooltip logic. No Below Goal pill in the bar.
- Work Order scope subtracts the WO discounts (the bar’s Discounts figure) from revenue. Group scope is lines only.
- Empty WO: — for all three.
- Below 1440px the bar’s spacing tightens (gaps and side padding only) so the cluster fits at 1280 without wrapping ADD ITEMS. At 1440+ it is V1’s spacing.
3My Shop › Target Margin › Profitability New
“Shop settings” in the prototype bar opens a mock of the real page (Locations / Target Margin tabs, Parts and Sublets Target Margin grids with static rows). Below them, a new Profitability card:
| Field | Input | Blank means | Used for |
| GP% goal | 0–100, %, placeholder “No goal” | No Below Goal anywhere | Below Goal and the red GP% |
| Estimated labor cost per hour | $, placeholder “Not set” | Estimated hours cost $0 | Unclocked hours and hours clocked by a tech with no pay rate |
Save validates (goal > 100 or negatives are rejected inline) and the Work Order recalculates immediately.
4The maths
| Term | Rule |
| Revenue | Part = qty × quoted price · labor = fixed price if > 0, else hours × rate · sublet = price · warranty lines $0. WO scope only: less WO discounts. Fees, shipping and tax never count. |
| Cost | Part = qty × cost · sublet = cost · warranty lines keep their cost · labor = actual + estimate. |
| Labor actual | Per clock entry. Hourly tech: pay rate × clocked. Flat-rate tech: pay rate × billed if the line is Done, else pay rate × min(clocked, billed). No pay rate: nothing (hours go to the estimate). |
| Estimated hours | Clocked hours by no-pay-rate techs + (not Done, not Cancelled: max(billed − clocked, 0)) + (Done with nothing clocked: full billed). Cancelled: none. × Estimated labor cost per hour. |
| GP$ / GP% / GP/hr | Revenue − cost · GP$ ÷ revenue, 1dp, — if revenue ≤ 0 · GP$ ÷ billed labor hours (warranty included), whole dollars. |
| Below Goal | Goal set AND revenue > 0 AND GP% < goal. |
Recalculates live on any change to qty, cost, price, hours, rate, fixed price, warranty or status (single-cell edit, group bulk edit, scenario switches).
5Seed data (Standard WO, $30/hr estimate, 40% goal)
| Group | What it exercises | Revenue | Cost | GP | GP% | GP/hr |
| Exhaust | The brief’s worked example, verbatim: part 1 × $1,399 / $1,050; labor 3.5 h × $160, In Progress, hourly tech at $25/hr clocked 2.0 h (labor $50 actual + $45 est.) | $1,959.00 | $1,145.00 | $814 | 41.6% | $233 |
| Suspension | Just below goal: warranty part (revenue $0, cost kept), flat-rate Done line, fixed-price $249 line clocked by a tech with no pay rate, never-clocked line, sublet | $3,335.90 | $2,067.00 | $1,269 | 38.0% | $195 |
| HVAC | Parts only — GP/hr hidden, no est. | $679.68 | $176.80 | $503 | 74.0% | — |
| Work Order | Lines $5,974.58 less the $150 Loyalty Discount | $5,824.58 | $3,388.80 | $2,436 | 41.8% | $244 |
The Exhaust Gasket Set line from the canonical WO was dropped so Exhaust matches the worked example exactly. “Clearly above goal” is carried by HVAC (74.0%); Exhaust sits 1.6 pts above at the brief’s own figures. Empty WO and Nothing clocked yet (no clock entries, nothing Done — every labor line fully estimated) are the other two seeds.
6Brought in line with production Fidelity
- Parts margin % beside the Parts figure stays, computed as production does (
aggregate.ts weightedPartsMargin: warranty lines excluded on both sides, 2dp, hidden at 0). The V1 prototype never had it; production LedgerGroupCard does.
- Delete group trash icon after the bulk-edit pencil, as production renders it (not on Ungrouped). In the prototype it moves the group’s lines to Ungrouped.
- Labor Status column (Open / In Progress / Done / Cancelled,
WorkOrderLaborOperation::STATUSES) and Fixed Price column on by default; Logged Hrs now derives from clock entries (still in the column picker).
7Removed
- Cut The placeholder $45/hr tech cost and 40% goal constants, the old
gpChips() and its amber nw-flag.
- Cut Quote mode is not loaded on this page — SPD-2602 adds nothing to any quote page.
8Prototype-only controls Not product UI
- Role: Extended view sees everything. Standard view (tech) sees nothing profitability-related — no chips, no bar GP, no est., no parts margin %, no Show math.
- GP% goal 40% / not set · Estimate $30/hr / not set · Seed Standard / Empty / Nothing clocked yet.
- Show math: hovering any GP chip (group or bar) shows revenue, WO discounts, parts cost, sublet cost, labor actual, labor estimated and GP, labelled PROTOTYPE ONLY.
- Tech pay rates are mock data inside the maths. No pay rate is shown anywhere in the UI.
9For the PRD
- Standard view and the parts margin %. Production shows the group-header parts margin % without an Extended-view check, while the parts grid’s cost/margin columns are Extended-only. This prototype hides it in Standard view per “nothing profitability-related”; production would need the same gate.
- New backend: the two Profitability settings; a pay type + pay rate per tech readable by the GP calculation; clock entries per labor line per tech (time logs exist — the pay side is what is new); GP$ / GP% / GP/hr / Below Goal per group and per WO.
- Cost and margin columns still show in the prototype’s Standard view (the prototype has no per-column role gating); production already hides them.