Passa al contenuto principale

Gestione e movimentazione stock

Overview​

SOH3 gestisce a livello di database:

  • Quantità disponibile (on hand)
  • Quantità logica disponibile per la vendita (available)
  • Transazioni sullo stock (ogni movimento è registrato)

La quantità impegnata (booked) viene calcolata a runtime.


Event-Driven Stock Management​

Lo stock è gestito tramite event listener su:

  • Order
  • OrderItem

Ogni variazione di stato viene intercettata dai listener che agiscono di conseguenza. La gestione è centralizzata, riducendo il rischio di rotture di stock.

Tutte le transazioni avvengono a livello di listener su ProductStock, garantendo la tracciabilità completa di ogni movimento.

In caso di aggiornamenti concorrenti sullo stesso ProductStock, il listener acquisisce un lock Redis in preUpdate e lo rilascia in postUpdate / postUpdateFailure. Durante il lock ricarica lo stock da database e ricalcola la quantità logica (availableQty) partendo dallo stato persistito, così un salvataggio non applica il delta su un availableQty in memoria già obsoleto.


Flusso con disponibilità logica​

Ordine con 1 prodotto, quantità 2:


Flusso senza disponibilità logica​

Ordine con 1 prodotto, quantità 2:

In questi flussi il servizio marca il ProductStock affinché il listener non auto-aggiusti availableQty al cambio di onHandQty (movimento solo fisico).


ProductStock come DataObject​

SOH3 utilizza il dataObject ProductStock per gestire le informazioni stock a livello di magazzino e prodotto.

Motivazioni rispetto alla gestione precedente (SOH2):

  • Centralizzazione dello stock come entità nobile (non più relazione)
  • Supporto al versioning
  • Gestione visuale in griglia tramite interfaccia dei dataObject

Stock predefinito su Warehouse​

Sul data object Warehouse, nella tab Stock, è disponibile il campo Default Stock Qty (defaultStockQty).

Alla creazione di un Product (oggetto o variante, non un parent con varianti):

  • Il sistema cerca i magazzini con defaultStockQty valorizzato (non null e diverso da 0)
  • Per ciascuno di essi crea automaticamente un ProductStock associato al prodotto, con quantità iniziale pari al valore configurato sul magazzino

Se il campo non è impostato o vale 0, nessun ProductStock viene creato per quel magazzino in fase di creazione prodotto.


Tabella Product Stock sul prodotto​

Sul data object Product la tab Stock mostra una tabella con lo stock per magazzino, modificabile direttamente.

Per un prodotto con varianti la tabella è limitata:

  • Sono elencate solo le righe con quantità fisica (onHandQty) maggiore di 0
  • Il numero massimo di righe è configurabile nelle Sintra Settings (tab Oms, campo variantsStockLimit), con valore predefinito 100

Se le righe con stock maggiore di 0 superano il limite, sotto la tabella compare un messaggio che invita ad aprire la variante del prodotto per consultare o aggiornare gli stock mancanti.


Tabella Stock Sync Info sul prodotto​

Sul data object Product, nella tab Synchronization Information, la tabella Stock Sync Info mostra lo stato di invio dello stock verso i canali di vendita.

Per ogni riga (prodotto e canale) sono riportati:

  • Channel: nome del canale di vendita, con l'icona della piattaforma
  • Sku (solo per prodotti con varianti)
  • Stock: ✔ se lo stock risulta inviato, ❌ altrimenti, con la data di invio
  • Last Qty Sent: ultima quantità inviata al canale
  • Location Qty Sent: quantità inviate per location, una sotto l'altra (id: quantità)

Il contenuto della tabella dipende dal tipo di prodotto:

  • Prodotto con varianti: sono elencate le righe di tutte le sue varianti, identificate dallo Sku
  • Variante o prodotto semplice: sono elencate solo le righe del prodotto stesso

Anche in questo caso il numero di varianti mostrate è limitato dal valore variantsStockLimit delle Sintra Settings (tab Oms, default 100); oltre il limite compare un messaggio che invita ad aprire la singola variante.


Flussi di modifica Stock e prenotazioni​

Inserimento nuovo ordine​

Alla creazione di un nuovo ordine:

  • Il listener su OrderItem individua i magazzini associati al prodotto.
  • Se useLogicalStock è attivo sul SalesChannel, viene decrementata la quantità logica, altrimenti quella fisica.
  • Se l’ordine è creato in stato canceled o fulfilled, non vengono associate quantità o magazzini.

Invio fulfillment al canale​

Se useLogicalStock è disattivato, nessuna operazione viene eseguita (la quantità fisica è già stata scalata).

Al salvataggio dell’ordine:

  • Il listener rileva le modifiche tra i nuovi e vecchi CarrierInfo
  • Decrementa la quantità fisica in base alle spedizioni effettuate

Modifica associazione magazzini​

Modificando la quantità o i magazzini:

  • Le prenotazioni sono aggiornate automaticamente
  • Non è possibile modificare quantità su ordini spediti o cancellati

Modifica associazione prodotto​

Se cambia il prodotto associato a un OrderItem:

  • La quantità viene restituita al prodotto precedente
  • La nuova quantità è prenotata sul nuovo prodotto

Eliminazione OrderItem​

Eliminando un OrderItem (o eliminando l’ordine padre):

  • Se l’ordine non è fulfillato o cancellato, le quantità prenotate vengono rimesse a stock

Cancellazione ordine​

Quando un ordine passa a stato canceled:

  • Se non è stato fulfillato:
  • I magazzini sono disassociati
  • Il sistema effettua il restock automatico

Rimborso​

Quando aumenta refundedQuantity sulla riga ordine (invio rimborso a shop o upsert da canale):

  • Vengono rilasciate solo le quantità non spedite
  • Con useLogicalStock si cancella la prenotazione (availableQty)
  • Senza quantità logica si incrementa l’on hand
  • Se il totale sulla riga non cambia, lo stock non viene mosso di nuovo

Dettaglio: Gestione Rimborsi

Errore durante l’import ordine​

In caso di errore durante l’import:

  • Il rollback ripristina o elimina gli OrderItem
  • I listener aggiornano coerentemente lo stock