Skip to content

Field Mapping — Navision, Ergonode and the New Backend (ZWE-391)

Pending Florian's review — not yet approved

This mapping has not been reviewed or signed off by Florian yet. Treat everything below as a draft proposal, not an approved source of truth, until that review happens and this notice is removed.

ZWE-391

Maps every real GetProduct field (Core Webshop Endpoints, NAV Field Inventory) to the new backend data model, alongside Ergonode's confirmed attribute codes (ZWE-496) and the backend's actual schema (products/product_attributes/orders). Needs review and approval from Florian before it's final.


Answering the open questions

1. Which system leads per field?

Data Leads Why
Price Navision GetSalesPrice/GetProduct.PriceIncludingVAT — real-time ERP pricing, not editorial
Stock Navision StockQuantity/StockQuantity2/GetRealStock — live inventory, changes constantly
Barcode Navision LSItemBarcodes[] — ERP is the barcode master
Article number Navision ItemNo is NAV-native; Ergonode's artikelnummer attribute mirrors this same value rather than originating it — see linking key below
Status / orderability Navision LSItemStatusLink.StatusCode / Blocked / NoStockPosting — already the source for NavStatusNormalizer (ZWE-486)
Title, description, images, category structure Ergonode Editorial/marketing content — matches the "Ergonode is the PIM" restructure note and the naam/product_media attributes confirmed in ZWE-496
Colour, size, material, gender (kleur/maat/materiaal/sekse) Ergonode Confirmed real Ergonode attribute codes (ZWE-496, from the real CSV export) — customer-facing product attributes, editorially maintained
Brand Ambiguous, flag for Florian NAV has Brand/BrandDescription as a code+description pair; Ergonode has a merk attribute. Unclear whether these use the same taxonomy/codes — needs checking before deciding which leads

2. NAV fields with no backend equivalent

Field Recommendation Reasoning
Cost / LastCost Drop Internal purchase cost, not customer-facing; not part of the webshop's canonical product model
SeasonCode Drop Ergonode's collectie attribute already covers seasonal/collection grouping — redundant
ItemCategoryCode / ProductGroupCode Drop Category structure is already sourced from Ergonode (ZWE-496); these NAV codes would be a second, conflicting category source
VendorItemNo Drop Vendor's own SKU, not customer-relevant; purchasing/admin concern only
Published Extend Not currently wired anywhere — but products.status (ProductStatus::Online/Offline) has no real source today. Worth wiring NAV.Published into it rather than leaving products.status unset by any real data
LSItemVariant.ColourCodeVendor Drop Vendor's raw colour code; Ergonode's kleur attribute is the customer-facing equivalent

3. How is a product identified and linked?

NAV.ItemNo is the real linking key across all three systems:

  • Navision: ItemNo (e.g. 003027608)
  • Ergonode: the artikelnummer attribute — confirmed via the real bulk CSV export (ZWE-496) to hold this exact same value
  • New backend: products.reference — should hold this same value, but currently doesn't

Known gap, already flagged on ZWE-396

The ZWE-396 seeder currently populates products.reference with slug-style values (e.g. SCARPA-RIBELLE-RUN-GTX), not real NAV ItemNo values — flagged as a known limitation in that PR. For the real sync-then-local-query flow (ZWE-495) to actually link a product to its NAV/Ergonode source, products.reference needs to be populated with the real ItemNo once real data replaces the seeded demo catalog.

Variant-level: NAV.LSItemVariant.Code is the equivalent linking key for variants, and already flows through the new backend's order_lines.variant_code field (used directly in NavOrderPayloadBuilder, ZWE-423).

4. Fields needing a check with the ERP administrator

  • Price vs PriceIncludingVAT on GetProduct — is Price a genuinely separate excl-VAT list price, or simply PriceIncludingVAT divided by the VAT rate? Not confirmed either way from the WSDL alone.
  • StockQuantity (item) vs StockQuantity2 (variant) vs GetRealStock's single value — this is the same terminology gap already flagged on ZWE-494 ("real/free/wholesale stock" not found as-is in the schema) — cross-referencing here rather than re-asking.
  • Brand taxonomy — see question 1 above.

Resolved: OrderStatus anomaly

Previously flagged here as open — confirmed by Jasper. SubmitOrder always sends OrderStatus=30 (Complete); NAV computes/overrides the status internally afterwards (its own picking/invoicing workflow), so the 20 (Processing) seen on a real queued order is NAV's own value, not POS-originated. The status sent by the webshop is advisory only. See the full explanation on Core Webshop Endpoints. This leaves a real decision for the backend: persist/act on NAV's OrderStatus/ShippingStatus, or keep reacting only to PaymentStatus as the legacy site does today — not yet decided.


Mapping table

NAV field (GetProduct) Target (backend) Transformation Source of truth
ItemNo products.reference direct — once real data replaces the seeded catalog, see the gap noted above Navision
Name / ShortDescription product_attributes (Title) direct, but see Q1 — Ergonode's naam should lead here in practice Ergonode
PriceIncludingVAT product_attributes (Price) direct Navision
Price (not mapped) see Q4 — ambiguous, needs ERP admin confirmation before mapping Navision
StockQuantity (item) product_stock.stock (item-level rows) direct, pending Q4 clarification Navision
LSItemVariant.StockQuantity2 product_stock.stock (variant-level rows) direct, pending Q4 clarification Navision
Blocked (item) / LSItemVariant.Blocked (variant, string) NavStatusNormalizer output → orderability already implemented, ZWE-486 Navision
NoStockPosting NavStatusNormalizer::ignoresStock() already implemented, ZWE-486 Navision
LSItemStatusLink.StatusCode NavArticleStatus enum already implemented, ZWE-486 (handles GEBLOKKEER truncation) Navision
Brand / BrandDescription brands.name / brands.slug pending Q1 - Ergonode's merk may supersede this Flagged - see Q1
LSItemVariant.Code order_lines.variant_code (and equivalent on product_attributes/product_stock variant rows) direct, already used in NavOrderPayloadBuilder (ZWE-423) Navision
LSItemVariant.Description order_lines.size / order_lines.colour (parsed) needs a parsing rule - variant descriptions observed as e.g. L/125 CANARY (size/colour combined) Navision (raw), parsing TBD
LSItemBarcodes[] order_lines.barcode direct Navision
Ergonode naam product_attributes (Title) direct Ergonode
Ergonode artikelnummer products.reference (linking key) must match NAV.ItemNo exactly Ergonode (mirrors Navision)
Ergonode sekse / kleur / maat / materiaal / waterdicht / collectie product_attributes (respective) direct, per the EAV pattern already used in DemoProductSeeder Ergonode
Ergonode product_media media (Spatie Media Library images collection) direct Ergonode
Cost / LastCost — dropped, see Q2 —
SeasonCode — dropped, see Q2 (superseded by collectie) —
ItemCategoryCode / ProductGroupCode — dropped, see Q2 (superseded by Ergonode categories) —
VendorItemNo — dropped, see Q2 —
Published products.status extend — not currently wired to any real source, see Q2 Navision
LSItemVariant.ColourCodeVendor — dropped, see Q2 (superseded by kleur) —

Core Webshop Endpoints NAV Field Inventory Legacy Integration