Skip to content

Endpoint Inventory Verification Against the Legacy Codebase (ZWE-390)

ZWE-390

Verifies the ERP administrator's week-long, log-based endpoint inventory against the actual legacy codebase (zwerfkei-backoffice-legacy), now that it's accessible. Source data: Gebruik van WSDL endpoints in backend.xlsx (zwerfkei-nav-soap-test repo).

Numbers differ slightly from the ticket

The ticket states 58/82 in-app, 35/82 in-use from the log analysis. The actual spreadsheet found shows 61 in-app / 37 in-use — likely updated since the ticket was written. This page treats the spreadsheet as the current source of truth.


Summary

  • 82 endpoints across 3 services (Kei, LS, Nav)
  • 61 marked "in app" (present in the WSDL-derived spreadsheet as implemented)
  • 37 marked "in use" (seen in a week of live traffic logs)
  • 24 endpoints are in-app but never appeared in the log window — the real risk area this ticket is about

The ERP administrator's four open questions — answered

The DoD's four open questions for the ERP administrator (cart and reservation; price and stock via pull or push; coupons; scope of the Kei service) are a different set from this doc's own "Question 1-4" headers below (which answer the developer-facing questions from this ticket's own Context section). Answering the actual DoD four here, as far as possible from the code:

  1. Cart and reservation: confirmed on Reservation / Cart Flow (ZWE-445) — the flow only makes a live GetRealStock call to check stock; the reservation itself is saved purely locally (ClickAndCollect table) and never reaches NAV. ShoppingCartRequest and SubmitReservation are confirmed unused dead code.
  2. Price and stock, pull or push: confirmed on Core Webshop Endpoints — GetSalesPrice, GetPeriodicDiscount, GetProduct and GetOrderStatus all share the same paged pull request shape (queueEntryNo/cursor); GetRealStock is a direct single-item pull lookup. Nothing in this flow is push-based from NAV's side.
  3. Coupons: GetCoupon is not present in code (see the full endpoint table below) — no NAV-side coupon endpoint is called anywhere in the legacy codebase. Per SubmitOrder, giftcards/vouchers are handled as synthetic order lines with a fixed ItemNo, not through a coupon-specific NAV operation. Conclusion: coupons are not integrated with Navision at all today.
  4. Scope of the Kei service: see the new Kei endpoints — relevance decision section (added per ZWE-392) — Kei covers purchasing/physical-inventory administration (not webshop-relevant) plus loyalty/membership (real, but decoupled from the current order-submit/order-status scope). No Kei endpoint is customer-facing webshop functionality beyond GetRealStock.

Question 2: endpoints marked "in use" but not found in code?

None. Checked the reverse case directly against the spreadsheet: every endpoint marked "in use" is also marked "in app". No endpoint is being called from the point of sale or another system outside this codebase that isn't also present here.


Question 3: dynamic calls that a name search would miss?

Yes — confirmed with code, and this explains several of the "missing" endpoints structurally, not just by frequency.

application/components/k3retail/todo/Buffer.php drives a generic sync loop over a $tables config array (one entry per logical endpoint: product, salesPrice, offer, category, categoryItem, salesLineDiscount, periodicDiscount, orderStatus, itemAvailability). Every table is read via the same two literal SOAP operations, GetSyncBuffer and DeleteSyncBuffer, regardless of which logical endpoint it represents — the table number, not the operation name, distinguishes them on the wire.

When a queued item needs its actual data fetched, application/components/k3retail/todo/Request.php builds the operation and class name dynamically from the config key:

$requestCall = "get".ucfirst($this->method);                  // e.g. 'offer' -> 'getOffer'
$class = "\K3retail\classes\\".ucfirst($requestCall);          // e.g. \K3retail\classes\GetOffer
$response = \K3retail\Connection\Connection::$request("$requestCall", $item);

A literal text search for "GetOffer" finds zero results anywhere in the codebase — the string is assembled at runtime from 'offer'. The endpoint is genuinely wired and will fire whenever NAV pushes a queued entry of that type; it just can't be found by name search, and it won't show up in a log unless NAV happens to push that kind of change during the log window.

This affects Nav::GetCategory, Nav::GetCategoryItem, LS::GetOffer, Nav::GetSalesLineDiscount, Kei::PeriodicDiscountLines (same pattern, confirmed via PeriodicDiscountLine.php:25 returning the literal string 'PeriodicDiscountLines' used in this same dynamic dispatch) — all buffer-driven, all invisible to name search, all frequency-dependent on when NAV itself pushes a change.

Also found: Buffer.php's 'customer' table entry is commented out in the config:

//      'customer' => array(
//          'tableNo' => 5050,
//          'response' => 'NavCustomer'
//          ),

This is a concrete, non-speculative explanation for Nav::GetCustomer never appearing in logs — it was planned for buffer-sync and explicitly disabled, not just rare.


Question 1: endpoints in code but not in the logs — trigger and frequency

The 24 endpoints below are present in the codebase but never appeared in the week-long log window. Grouped by why:

Buffer-driven, dynamically named (see Question 3) — frequency depends entirely on when NAV pushes a change of that type

Endpoint Buffer table Notes
Nav::GetCategory category (tableNo 11176101) Comment in Buffer.php marks this // nog niet ingeregeld (not yet configured)
Nav::GetCategoryItem categoryItem (tableNo 11176102) Same "not yet configured" comment
LS::GetOffer offer (tableNo 99001502) Actively configured; fires only when an offer is queued in NAV
Nav::GetSalesLineDiscount salesLineDiscount (tableNo 7004) Actively configured; fires on line-discount changes
Kei::PeriodicDiscountLines shares the periodicDiscount flow PeriodicDiscountLine.php:25 — inherently tied to promotional campaign changes, genuinely seasonal

Explicitly disabled in config

Endpoint Evidence
Nav::GetCustomer Buffer.php's customer table entry is commented out

Admin/manual-action triggered (purchase-receiving workflow) — fires only when staff process a delivery, not on a schedule

Endpoint Call site
Kei::PurchaseHeader application/modules/backend/controllers/Pakbon_server.php:768, application/modules/backend/models/K3_article_import_journal.php:322,349,383
Kei::PurchaseLine Pakbon_server.php:780, application/modules/backend/models/K3_article_import_journal_line.php:520
Kei::ItemImportJournalLine Pakbon_server.php:530
Kei::GetItemImportJournalLines Pakbon_server.php:564,698,699
Kei::ItemImportJournalTemplate application/models/Inventory.php:202, Pakbon_server.php:165,324
Kei::GetBrands Pakbon_server.php:1232, K3_article_import_journal.php:535
Kei::DeleteExistingImportJournalLines application/components/k3retail/ItemImportJournalLine.php:36

Admin-triggered, per-article/per-action — low frequency by nature, not scheduled

Endpoint Call site Trigger
Kei::SyncItem application/models/K3_article.php:533 Per-article manual sync action
Kei::ItemLabelSetup K3_article.php:590 Print-label action
Kei::MemberPointAdjustment application/models/Customer.php:1319 Manual loyalty-point adjustment
Kei::GetActiveSession application/modules/widgets/controllers/private/Backend.php:30 POS session-status widget, on demand

Seasonal by nature — matches the ticket's own hypothesis exactly

Endpoint Call site Trigger
Kei::UpdateItemPrices application/modules/backend/controllers/Tax_change.php:80, application/modules/backend/models/PricesList.php:186 Only fires when VAT/tax rates change
Kei::UpdateStockkeepingUnits PricesList.php:193 (as StockkeepingUnit) Same pricing-admin workflow

Confirmed dead code — genuinely unused, not just rare

Endpoint Evidence
LS::GetStore Zero call sites found anywhere outside the class definition itself
LS::StoreStockRequest Implemented as Request::StoreStockRequest(), but zero callers anywhere else in the codebase

Not yet individually traced

Endpoint Note
Nav::GetSalesPrice Buffer's equivalent (salesPrice, tableNo 7002) is wired to wdsl: Ls, i.e. LS::GetSalesPrice — the separate Nav::GetSalesPrice row appears to be a distinct, unused duplicate on the Nav service; no direct call site found
Nav::SubmitOrderStatus No direct call site found; likely the inverse of GetOrderStatus (push a status back to NAV) — not seen wired up anywhere in this codebase

Question 4: how is the integration layer built?

  • WSDL definitions: 3 services — LS Retail (wsdlLs), NAV (wdslNav), Kei (wdslKei) — configured via K3retail_gateway config, fetched live from NAV at each service's endpoint URL
  • SOAP clients: K3retail\Connection\Connection is the shared client wrapper; requestCallWdslLs() / requestCallWdslNav() / requestCallWdslKei() are the three entry methods, selected dynamically per call (see Order.php's requestCallWdsl() for an example of this dispatch)
  • Wrapper classes: every actively-called operation has a thin request/response class in application/components/k3retail/classes/ (e.g. SubmitOrder.php, GetProduct.php) — a real, reliable signal for whether an operation is genuinely wired up (see Reservation / Cart Flow for how this was used to confirm ShoppingCartRequest/SubmitReservation are unused)
  • Credentials: K3retail_gateway.username / password config, basic auth
  • Buffer/queue layer: application/components/k3retail/todo/Buffer.php + Request.php — the generic, config-table-driven GetSyncBuffer/DeleteSyncBuffer polling mechanism described under Question 3, cron-driven via application/modules/cli/controllers/Cron.php

Full endpoint table

Legend: In App = present in the ERP administrator's spreadsheet as implemented. In Use = seen in the week-long log analysis. ✓ in the Verified column means a call site was directly confirmed in this codebase during this review.

Kei service

Endpoint In App In Use (logs) Verified Notes
ColourThemes ✓ ✓
CreateMemberAccount ✓ ✓
CreateMembershipCards ✓ ✓
DeleteExistingImportJournalLines ✓ ✓ See Question 1 — purchase workflow
GetActiveSession ✓ ✓ See Question 1 — POS widget
GetBrands ✓ ✓ See Question 1 — purchase workflow
GetItemImportJournalLines ✓ ✓ See Question 1 — purchase workflow
GetMemberAccount ✓ ✓
GetMemberAccounts ✓ ✓
GetMemberPointEntry ✓ ✓
GetOcpOrders Not present in code
GetOpenPhysInventory ✓ ✓
GetPurchaseHeader ✓ ✓
GetPurchaseLine ✓ ✓
GetRealStock ✓ ✓ ✓ Real-time stock check, confirmed via K3_article_variant.php:596 — also the endpoint used in Reserve & Collect (ZWE-445)
GetSeasons ✓ ✓
GetTransactions ✓ ✓
GetValueEntry ✓ ✓
GetWebTransactions Not present in code
InventoryBatches ✓ ✓
ItemFixMissingPostingGroup ✓ ✓
ItemImportJournalLine ✓ ✓ See Question 1 — purchase workflow
ItemImportJournalTemplate ✓ ✓ See Question 1 — purchase workflow
ItemLabelSetup ✓ ✓ See Question 1 — print-label action
MemberPointAdjustment ✓ ✓ See Question 1 — manual loyalty adjustment
PeriodicDiscount ✓ ✓
PeriodicDiscountDelete ✓ ✓
PeriodicDiscountLineDelete ✓ ✓
PeriodicDiscountLines ✓ ✓ See Question 3 — dynamically dispatched
PhysInventory ✓ ✓
POSStartStatussen ✓ ✓
PrintItemLabel ✓ ✓
PrintItemLabels ✓ ✓
PurchaseHeader ✓ ✓ See Question 1 — purchase workflow
PurchaseLine ✓ ✓ See Question 1 — purchase workflow
RunJobQueues ✓ ✓
RunMemberPosting ✓ ✓
SetItemStatusLink ✓ ✓
SetMemberAccount ✓ ✓
SyncItem ✓ ✓ See Question 1 — per-article manual sync
SyncItems ✓ ✓
UpdateItemBarcodes ✓ ✓
UpdateItemPrices ✓ ✓ See Question 1 — tax-change triggered
UpdateStockkeepingUnits ✓ ✓ See Question 1 — pricing-admin workflow
WebActive ✓ ✓

LS service

Endpoint In App In Use (logs) Verified Notes
DeleteSyncBuffer ✓ ✓ ✓ Buffer/queue layer, see Question 3/4
GetCoupon Not present in code
GetImage Not present in code
GetOffer ✓ ✓ See Question 3 — dynamically dispatched buffer table
GetPeriodicDiscount ✓ ✓
GetProduct ✓ ✓ ✓ Used by both the legacy site and the new backend (ZWE-495)
GetSalesPrice ✓ ✓
GetStore ✓ ✓ See Question 1 — no call sites found, dead code
GetSyncBuffer ✓ ✓ ✓ Buffer/queue layer, see Question 3/4
ShoppingCartRequest ✓ Confirmed unused — no wrapper class exists (see Reservation / Cart Flow)
StoreStockRequest ✓ ✓ See Question 1 — implemented but no callers, dead code
SubmitReservation ✓ Confirmed unused — no wrapper class exists
Version Not present in code
Endpoint In App In Use (logs) Verified Notes
DeleteSyncBuffer ✓ ✓ ✓ Also the target of the new backend's ZWE-495 work
GetCategory ✓ ✓ See Question 3 — dynamically dispatched, also "not yet configured" per Buffer.php comment
GetCategoryItem ✓ ✓ Same as above
GetCountry Not present in code
GetCurrency Not present in code
GetCustomer ✓ ✓ See Question 3 — buffer entry explicitly commented out
GetItemAvailability ✓ ✓ Confirmed real WSDL operation (see Reservation / Cart Flow); not the same call as Kei::GetRealStock, which is what Reserve & Collect actually uses
GetLanguage Not present in code
GetOrderStatus ✓ ✓ ✓ Used by the new backend too (ZWE-422)
GetProduct Not present as a Nav-service operation (LS's GetProduct is the one actually used)
GetRelatedItem Not present in code
GetReservationStatus Not present in code
GetSalesLineDiscount ✓ ✓ See Question 3 — dynamically dispatched buffer table
GetSalesPrice ✓ Not individually traced — appears to be an unused duplicate of LS::GetSalesPrice
GetSyncBuffer Interesting: not marked "in app" in this spreadsheet, but the new backend's NavConnection calls this operation successfully on the nav service (confirmed live, ZWE-495) — worth flagging as a spreadsheet gap, not a code gap
GetVATPostingSetup Not present in code
ItemAvailabilityRequest Not present in code
ShoppingCartRequest ✓ Confirmed unused
SubmitCustomer Not present in code
SubmitOrder ✓ ✓ ✓ Also the new backend's ZWE-423/424 work
SubmitOrderStatus ✓ Not individually traced — likely the inverse of GetOrderStatus, not found wired up anywhere
SubmitReservation ✓ Confirmed unused
Version Not present in code

Reservation / Cart Flow Legacy Integration Order-Push Flow Demo