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:
- Cart and reservation: confirmed on Reservation / Cart Flow (ZWE-445) — the flow only makes a live
GetRealStockcall to check stock; the reservation itself is saved purely locally (ClickAndCollecttable) and never reaches NAV.ShoppingCartRequestandSubmitReservationare confirmed unused dead code. - Price and stock, pull or push: confirmed on Core Webshop Endpoints —
GetSalesPrice,GetPeriodicDiscount,GetProductandGetOrderStatusall share the same paged pull request shape (queueEntryNo/cursor);GetRealStockis a direct single-item pull lookup. Nothing in this flow is push-based from NAV's side. - Coupons:
GetCouponis 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 fixedItemNo, not through a coupon-specific NAV operation. Conclusion: coupons are not integrated with Navision at all today. - 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 viaK3retail_gatewayconfig, fetched live from NAV at each service's endpoint URL - SOAP clients:
K3retail\Connection\Connectionis the shared client wrapper;requestCallWdslLs()/requestCallWdslNav()/requestCallWdslKei()are the three entry methods, selected dynamically per call (seeOrder.php'srequestCallWdsl()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 confirmShoppingCartRequest/SubmitReservationare unused) - Credentials:
K3retail_gateway.username/passwordconfig, basic auth - Buffer/queue layer:
application/components/k3retail/todo/Buffer.php+Request.php— the generic, config-table-drivenGetSyncBuffer/DeleteSyncBufferpolling mechanism described under Question 3, cron-driven viaapplication/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 |
Nav service¶
| 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 |
Related pages¶
Reservation / Cart Flow Legacy Integration Order-Push Flow Demo