Skip to content

VMS Feature Requests — Plans & Implementation

Source: 9 in-app support tickets from Selinda McCumbers (VMS CSR), 2026‑07‑17, during VMS’s approval‑only UAT. Triage separated training/discoverability from genuine gaps; this doc plans the real features. CSR‑facing guidance is in vms-csr-sop.md.

Decision (David, 2026‑07‑17): land all requested features at this stage — no YAGNI deferral. DRY is the constraint: each feature reuses existing machinery rather than adding a subsystem.

Context shaping every plan:

  • VMS is on Eclipse E4, in approval‑only mode (review_approval_only_mode): “Finished” approves in‑app, writes nothing to E4 yet.
  • The E4 connector syncs only customers, ship_to_links, orders, order_lines — no Material/product catalog (erp_pipeline/capabilities.py products=False, product_pricing=False).
  • ERP writes must be flag‑gated (AGENTS.md).

DRY map (what already exists — reuse, don’t rebuild)

Section titled “DRY map (what already exists — reuse, don’t rebuild)”
Feature The one thing to reuse Do NOT
F1 new‑item flag review‑v2 per‑line status machinery (stores/pdfOrder/review-v2.ts: deriveItemStatus/$itemsByStatus/$submitReadiness) + the NoErpMatch button slot + the uom-approve.ts persist/approve pattern use the parts table (dead scaffolding, zero readers/writers)
F2 revision/due‑date visibility resolveItemExtensionFields (packages/utils/src/extraction-schema.ts) + ItemSchemaFields renderer build a new field/panel; revision+dueDate are already extracted, stored, typed, and set visible:true for VMS
F3 price advisory order-item-pattern.ts (ItemPattern.lastOrderDate) + patternDivergence() amber advisory in PatternCard (already rendering) read/extend erp_effective_prices — it is empty for E4/VMS

A PO has a part not yet in E4. Today the CSR must abandon/park that line. Ask: onboard a new item from inside Ordermatic.

EPMS feasibility (researched against the vendor spec docs/poc/vms-epms-api/EPMS Connect.docx)

Section titled “EPMS feasibility (researched against the vendor spec docs/poc/vms-epms-api/EPMS Connect.docx)”
  • The vendor API does expose AddMaterialToDatabase (create material), but our eclipse-e4-service.ts createItem is a stub (comment: “AddMaterialToDatabase is available in docs”), there’s no mock, and — the real blocker — we never sync dbo.Material into bronze/Typesense, so a created part is invisible to us afterward.
  • E4 order lines require TemplateCode/FinGoodCode (no template‑create op). ANSWERED 2026-08-31 by live probe: a Material needs NO template to be orderable, as long as it is a finished good. Two SubmitOrder calls against prod E4 differing only in the identity slot: <TemplateCode>41260</TemplateCode> → Invalid Template sent.(Component)(1), no job created; <FinGoodCode>41260</FinGoodCode> → TST-999996-26, stored as ComponentType='FINGOOD'. 41260 has zero dbo.TemplateHeader rows. This is the norm, not an edge case: 6,508 of VMS’s 13,784 MaterialType='FG' materials have no template under any revision, and 9,200 of 11,555 live FINGOOD components carry a blank TemplateCode. A non‑FG part (MaterialType='PA') with no template is still unorderable — that one genuinely needs a template VMS creates in the E4 UI.
  • VMS writes are off (approval‑only). Full detail in memory eclipse-e4-write-path-state.

Phase 1 — “Pending new item” flag — ON HOLD. Paused pending VMS answers (see vms-new-item-onboarding-questions.md); implementation was started then stopped on branch claude/vms-pending-new-item. The design below is a proposal, not an approved build — do not start engineering before the questions are answered. No E4 write.

  • Add one nullable column to extractedOrderItems (a pendingNewItem flag) — not the parts table.
  • Add one NON‑blocking per‑line status to review-v2.ts (mirrors how customLineDefinitionId counts as resolved) so a flagged line doesn’t block “Finished.”
  • “Mark as new — needs setup in E4” button in NoErpMatch (ReviewCenterPane.tsx); small PATCH endpoint mirroring uom-approve.ts; surface pending items in ReviewIssuesRail.
  • Flag review_v2_pending_new_item_v1 (per‑connection). Effort: S–M.

Phase 2 — Material read/index pipeline. Add a products/Material entity to the E4 connector (dbo.Material, PK MaterialCode), get SELECT dbo.Material granted to the read account, wire bronze→silver→Typesense, flip capabilities.products=True. Closes the loop so an added part auto‑matches next time. Effort: M.

Phase 3 — Write‑back AddMaterialToDatabase. Implement createItem (SOAP envelope) + mock, gate behind eclipse_e4_material_write_v1. Depends on Phase 2 + VMS answering the template/permission questions. Effort: M, gated.

EPMS Connect login write perms? Template/FinGoodCode model for a new Material to be orderable? Default MaterialType/CategoryCode/CostingMethod for custom‑mfg parts?


2. Revision + due‑date visibility (T‑109 + T‑111) — one root‑cause fix

Section titled “2. Revision + due‑date visibility (T‑109 + T‑111) — one root‑cause fix”

CSR can’t verify revision alongside price (T‑109) and says the due date “doesn’t appear” (T‑111).

Both fields are already extracted/stored/typed and are set visible:true in VMS’s connection extraction_schema. But resolveItemExtensionFields (packages/utils/src/extraction-schema.ts) does if (raw == null || raw === '') continue; — a visible field with an empty value renders nothing, so the CSR can’t tell “no revision on this PO” from “the system dropped it.” One line explains both tickets.

Add an opt‑in showWhenEmpty?: boolean to the extraction‑schema field config; when set, resolveItemExtensionFields emits the field with a muted “—” placeholder instead of skipping. Keeps current behavior for every other org (CK/Genfit/WhereFour have overrides too). Then set showWhenEmpty:true for revision+dueDate in VMS’s extraction_schema. Effort: S. Fixes both tickets at the root in one shared function.

VMS conn extra_config.extraction_schema.itemFields: add showWhenEmpty:true to the revision and dueDate entries (and the dueDate rootField). Apply via the admin ExtractionSchemaEditor.


CSR wants to verify a line’s price is current (~last 3 months), from finished‑goods pricing.

erp_effective_prices is empty for VMS/E4 (capabilities.py product_pricing=False) — building on it is dead code. The right source is order-item-pattern.ts, which reads our historical accepted orders and already returns lastUnitPrice + lastOrderDate. And patternDivergence() in ReviewCenterPane.tsx already renders an amber advisory in PatternCard.

Extend patternDivergence() with a “last seen > 90 days ago” clause using pattern.lastOrderDate (+ optionally flag any price change beyond PRICE_TOLERANCE_USD). Non‑blocking; reuses the existing advisory UI. Window is a named constant; flag price_effectivity_advisory_v1 (per‑connection). Effort: S–M — a few lines in one tested function.

Confirm the exact rule with Selinda (staleness vs. change) — the “3‑month” phrasing came via an AI‑paraphrased ticket.


# Feature Branch First slice Effort
2 revision/due‑date empty‑field fix claude/vms-show-empty-extension-fields whole thing S
1 new‑item flag (Phase 1) claude/vms-pending-new-item (paused) ON HOLD — VMS answers S–M
3 price‑effectivity advisory claude/vms-price-effectivity staleness clause S–M
1 new‑item Phase 2/3 (later) Material sync → write‑back M+M, gated by VMS

Status: #2 and #3 are open PRs (#2399, #2400); #1 (new‑item) is on hold pending VMS answers. Next once answered: #1 Phase 2 (Material sync — needed regardless) → Phase 3 write‑back.

Caveat: these plans came from AI‑paraphrased ticket summaries. Confirm the E4 template model (#1 Phase 3) and the exact price rule (#3) with Selinda / the verbatim Plain threads before finalizing.