Skip to content

Noodkassa (Emergency POS)

Legacy implementatie

De noodkassa is een legacy implementatie bestaande uit twee gekoppelde CodeIgniter-applicaties. De werking hieronder beschrijft de bestaande situatie. Deze functionaliteit wordt herontworpen als onderdeel van de migratie naar de nieuwe Laravel-backend.


Doel

De noodkassa is een browser-based fallback kassasysteem dat in de fysieke winkel in Woerden gebruikt wordt wanneer het primaire K3/NAV kassasysteem niet beschikbaar is. Het systeem ondersteunt volledig offline gebruik: transacties worden lokaal opgeslagen en later gesynchroniseerd naar zwerfkei.nl zodra de internetverbinding hersteld is.


Systeemoverzicht

Het systeem bestaat uit twee applicaties die met elkaar communiceren:

Applicatie Repository Rol
zwerfkei_intern scripts/zwerfkei_intern POS-client op de winkelserver — kasinterface, lokale opslag, sync
zwerfkei.nl zwerfkei_bitbucket API-server — ontvangt transacties, maakt orders aan in NAV

Architectuur

sequenceDiagram
    actor Medewerker
    participant Kassa as zwerfkei_intern (browser)
    participant LocalDB as Lokale DB (winkelserver)
    participant API as zwerfkei.nl API
    participant PayNL as Pay.nl
    participant NAV as Microsoft Dynamics NAV

    Note over Kassa,LocalDB: Dagelijkse sync (of bij opstart)
    Kassa->>API: GET /api/webpostransaction?type=variant_lookup
    API-->>Kassa: Productdata (batches van 10.000)
    Kassa->>LocalDB: Sla op in variant_lookup + barcodes

    Note over Medewerker,LocalDB: Verkoop (online of offline)
    Medewerker->>Kassa: Scan barcode
    Kassa->>LocalDB: Zoek product in variant_lookup
    LocalDB-->>Kassa: Productdata
    Medewerker->>Kassa: Kies betaalmethode

    alt QR betaling (online vereist)
        Kassa->>API: GET /api/qr?type=payment_qr
        API->>PayNL: Maak betaling aan
        PayNL-->>API: QR-code URL
        API-->>Kassa: QR-code
        Medewerker->>PayNL: Klant scant QR
        Kassa->>API: GET /api/qr?type=is_paid (polling)
        API-->>Kassa: is_paid = true
    end

    Kassa->>LocalDB: Sla transactie op (pos_transactions)
    Kassa->>Kassa: Print bon (print queue)

    Note over Kassa,NAV: Synchronisatie (achtergrond)
    Kassa->>API: POST /api/webpostransaction (unsynced transacties)
    API->>API: Maak order aan (systeem-klant)
    API->>NAV: Stuur order door
    NAV-->>API: Bevestiging
    API-->>Kassa: { ordernr: "..." }
    Kassa->>LocalDB: Markeer transactie als synced

Huidige situatie (legacy)

Betaalmethoden

Methode Internet vereist Verificatie
Cash Nee Handmatig door medewerker
Pin Nee (standalone pinterminal) Handmatig door medewerker
QR (Pay.nl) Ja Automatisch via Pay.nl webhook

Betaaltype-mapping in de code:

public static $paymentTypes = array(19 => 'cash', 21 => 'pin', 26 => 'qr');

Kassasessie & artikelen toevoegen

Een sessie wordt opgestart via Pos::start('Noodkassa') en is gekoppeld aan de PHP-sessie. Artikelen worden toegevoegd via barcode-scan of zoekfunctie:

  • Barcode-scan — zoekt op barcodes.barcodevariant_lookup (lokale DB)
  • Zoekfunctie — full-text search op variant_lookup.search (merk + naam + kleur + maat)
  • Handmatige prijs — medewerker kan prijs overschrijven; negatieve prijs = retour (amount = -2)

QR-betaling (Pay.nl)

  1. Kassa genereert een unieke temp_reference via MySQL GET_LOCK() (voorkomt botsingen bij meerdere actieve kassa's)
  2. zwerfkei.nl maakt een betaalsessie aan bij Pay.nl en retourneert de QR-code
  3. Kassa pollt is_paid totdat betaling bevestigd is
  4. Bij checkout wordt de temp_reference meegestuurd zodat zwerfkei.nl het bestaande payment-record koppelt aan het nieuwe ordernummer

Lokale opslag & synchronisatie

Transacties worden altijd eerst lokaal opgeslagen, ongeacht of er internet is:

Lokale tabellen (zwerfkei_intern DB):

Tabel Doel
pos_articles Tijdelijke winkelwagen per sessie (wordt leeggemaakt na checkout)
pos_transactions Lokale transactielog (synced = NULL = nog niet gesynchroniseerd)
pos_transaction_lines Regelitems per transactie
variant_lookup Lokale kopie van productdata voor offline scannen
barcodes Barcodetabel gekoppeld aan variant_lookup (één product kan meerdere barcodes hebben)

Synchronisatie naar zwerfkei.nl:

De Sync-component stuurt alle transacties met synced IS NULL naar POST /api/webpostransaction. Bij succes wordt synced = time() en ordernr opgeslagen.

Order aanmaken op zwerfkei.nl

Elke gesynchroniseerde transactie resulteert in een reguliere order:

Veld Waarde
Klant Systeem-klant (Customer::zwerfkei_system_customer)
Verzendmethode afhalen (store pickup)
Betaald Ja (betaald = 1)
Notitie (adminopm) "noodkassa: {transaction.id}"
Negatief totaal Verwerkt als retour via createNegativeOrderToNav()

Bon printen

Na een succesvolle checkout genereert zwerfkei_intern een PDF-bon via Receipt::publish() en stuurt deze naar de print queue (printOutput('b5')). De bon bevat:

  • Bonnummer (webpos{datum}-{id})
  • Artikelrijen (aantal, barcode, omschrijving, maat, kleur, kortings%, prijs, netto)
  • Totaal incl. BTW
  • BTW-uitsplitsing (6%, 9%, 21%)
  • Betaalmethode

Monitoring & alerts

De Sync::checkSync() methode controleert twee zaken en stuurt bij problemen een e-mail naar floris@zwerfkei.nl + marcel@zwerfkei.nl:

Controle Trigger
Variant lookup ouderdom Lookup is ouder dan 2 dagen
Ongesynchroniseerde transacties Er staan transacties open met synced IS NULL

Relevante bestanden

zwerfkei_intern (scripts/zwerfkei_intern)

Bestand Doel
application/modules/pos/controllers/Kassa.php Kasinterface — barcode-scan, zoeken, checkout
application/modules/pos/models/Pos.php Sessielogica, artikelbeheer, QR-aanmaken, transactie opslaan
application/modules/pos/models/Transaction.php Lokale transactieopslag, bonafdruk
application/modules/pos/models/TransactionLine.php Regelitems per transactie
application/modules/pos/models/Lookup.php Lokale variant lookup
application/modules/pos/components/Sync.php Synchronisatie met zwerfkei.nl, connectiecheck, QR-betaling
application/modules/pos/components/Receipt.php PDF-bon generatie
application/migrations/20190522120047_create_pos_tables.php Aanmaken lokale POS-tabellen + initiële lookup sync

zwerfkei.nl (zwerfkei_bitbucket)

Bestand Doel
application/modules/api/controllers/Webpostransaction.php API — ontvangen transacties, lookup endpoint
application/models/Variant_lookup.php Variant lookup model + rebuild-logica
application/migrations/20190326124933_pos.php pos en pos_articles tabellen
application/migrations/20240215211731_add_payment_type_pos.php pos betaaltype

Target situatie

To be defined

De noodkassa-functionaliteit wordt opnieuw ontworpen als onderdeel van de migratie naar zwerfkei-backend. Vereisten en architectuur worden nog bepaald.

Bekende doelen

  • Integratie met de nieuwe orderflow in zwerfkei-backend
  • Behoud van offline-first werking (transacties lokaal opslaan, later sync)
  • Betere observeerbaarheid van sync-status (dashboard / alerts)
  • Modernere stack voor de POS-client (los van de legacy CodeIgniter-applicatie)

Verbinding met andere features