Skip to main content

Varianti, Modificatori e Extra

Il sistema di varianti permette di personalizzare i prodotti al momento dell'ordine: scelta della cottura, aggiunta di ingredienti, selezione della taglia. Le varianti sono gestite tramite Gruppi Varianti (variant-groups), entita indipendenti che possono essere associate a uno o piu prodotti.

Concetti Fondamentali​

Gruppo Varianti​

Un gruppo varianti definisce un set di opzioni tra cui l'operatore (o il cliente) puo scegliere. Ogni gruppo ha:

CampoDescrizioneEsempio
groupIdIdentificativo univocogrp_cottura_carne
nameNome visualizzatoCottura
typeTipo di selezioneSINGLE o MULTIPLE
isRequiredObbligatorio per procederetrue
minSelectionSelezioni minime1
maxSelectionSelezioni massime1 (per SINGLE), 5 (per MULTIPLE)
errorMessageMessaggio d'errore personalizzato (validazione)Devi selezionare la dimensione del panino
hasNoneOptionAbilita l'opzione "Nessuno" (vedi sotto)false
noneLabelEtichetta della voce "Nessuno"Nessuno
nonePriceDeltaSovrapprezzo/sconto della scelta "Nessuno"0
noneIsDefault"Nessuno" preselezionato di defaultfalse
nonePrintOnComandaStampa la scelta "Nessuno" in comandafalse
noneComandaLabelTesto stampato in comanda per "Nessuno"senza contorno
accordionMostra il gruppo chiuso ("a fisarmonica", vedi sotto)false
optionsArray di opzioni disponibilivedi sotto

Tipo SINGLE vs MULTIPLE​

  • SINGLE: l'operatore deve scegliere esattamente una opzione (es. cottura: al sangue / media / ben cotta)
  • MULTIPLE: l'operatore puo scegliere piu opzioni simultaneamente (es. topping pizza: olive, funghi, prosciutto)

Visualizzazione a fisarmonica (accordion)​

Un gruppo con molte opzioni (es. Contorno con quindici voci) occupa da solo tutto lo schermo della cassa, rendendo scomodo raggiungere gli altri gruppi. Attivando Visualizzazione → "Mostra a fisarmonica (chiuso)" nella scheda del gruppo, il gruppo compare chiuso: si vede solo il titolo e, fra parentesi, il numero di opzioni gia scelte (es. CONTORNO (2)). Al tocco sulla testata il gruppo si apre e mostra tutte le opzioni come di consueto.

  • L'apertura e la chiusura sono manuali e indipendenti per gruppo: piu gruppi possono restare aperti contemporaneamente.
  • Cambiando prodotto si riparte con tutti i gruppi a fisarmonica chiusi.
  • Vale anche per i gruppi obbligatori: se si conferma senza aver completato la scelta, il gruppo incriminato si apre da solo insieme al messaggio d'errore.
  • L'impostazione e attiva su cassa, tavoli e asporto. Cameriere, chiosco e webapp mostrano il gruppo sempre aperto.

Opzione​

Ogni opzione all'interno di un gruppo contiene:

CampoDescrizioneEsempio
optionIdIdentificativo univocoopt_media
nameNome visualizzatoMedia Cottura
priceDeltaSovrapprezzo o sconto0 (nessun extra) o 1.50
actionModifica alla ricettaNONE, ADD, REMOVE, SUBSTITUTE
isDefaultSelezionata per defaultfalse
displayOrderOrdine di visualizzazione1

Scelta di Default​

Il campo isDefault su un'opzione la rende preselezionata all'apertura del pannello varianti: la voce appare gia scelta, come se l'operatore l'avesse selezionata, e puo comunque essere cambiata. Serve a velocizzare l'inserimento quando esiste una scelta "piu comune" (es. Dimensione panino default = Media).

  • La scelta di default e facoltativa: se nessuna opzione ha isDefault: true, il gruppo si apre senza preselezioni (l'operatore deve ragionare sulla scelta anche se il gruppo e obbligatorio).
  • Per i gruppi SINGLE, se per errore piu opzioni sono marcate default, viene preselezionata solo la prima.
  • Nella console admin il default si imposta con la spunta "Preselezionata di default" sull'opzione.

Il default viene applicato in tutti i punti di inserimento: banco cassa (layout default, gerarchico e "varianti visibili"), comanda tavoli, waiter, kiosk e webapp tavolo/asporto.

Opzione "Nessuno"​

Per i gruppi obbligatori e possibile abilitare una voce speciale "Nessuno" (hasNoneOption: true) che permette di "chiudere" l'obbligo senza effettuare una scelta reale. Esempio: un panino con contorno obbligatorio, dove il cliente puo scegliere di non prendere il contorno.

CampoDescrizione
hasNoneOptionAbilita la voce "Nessuno" come opzione selezionabile
noneLabelEtichetta mostrata nel pannello (default Nessuno)
nonePriceDeltaEventuale sovrapprezzo/sconto della scelta (di norma 0)
noneIsDefaultSe true, "Nessuno" e preselezionato
nonePrintOnComandaSe true, la scelta "Nessuno" viene stampata in comanda
noneComandaLabelTesto stampato in comanda quando la stampa e attiva (es. senza contorno)

Comportamento:

  • "Nessuno" appare come una normale opzione selezionabile e soddisfa l'obbligatorieta del gruppo (esclude le altre opzioni, come una scelta singola).
  • Le varianti reali vengono sempre stampate in comanda. Per la sola scelta "Nessuno" si decide con nonePrintOnComanda se stamparla e con quale testo (noneComandaLabel, es. "senza contorno").
  • Se nonePrintOnComanda e false, la scelta "Nessuno" chiude comunque l'obbligo ma non compare in comanda.

Creazione di un Gruppo Varianti​

Dalla Console Admin​

  1. Accedere a Catalogo > Gruppi Varianti > Nuovo Gruppo
  2. Compilare:
    • Nome: es. Cottura Carne
    • Tipo: SINGLE (scelta singola)
    • Obbligatorio: Si
    • Min selezioni: 1, Max selezioni: 1
  3. Aggiungere le opzioni:
    • Al Sangue -- priceDelta: 0
    • Media -- priceDelta: 0
    • Ben Cotta -- priceDelta: 0
  4. Salvare

Esempio: Extra con Sovrapprezzo​

Per un gruppo "Topping Pizza" con extra a pagamento:

  1. Creare gruppo con tipo MULTIPLE, isRequired: false, maxSelection: 5
  2. Aggiungere opzioni:
    • Mozzarella di Bufala -- priceDelta: 2.00, action: ADD
    • Prosciutto Crudo -- priceDelta: 1.50, action: ADD
    • Senza Olive -- priceDelta: 0, action: REMOVE

Associazione ai Prodotti​

I gruppi varianti si collegano ai prodotti tramite il campo variantGroups, un array di groupId:

{
"sku": "BISTECCA-FIORENTINA",
"name": "Bistecca alla Fiorentina",
"variantGroups": ["grp_cottura_carne", "grp_contorno"]
}

Quando l'operatore aggiunge il prodotto al carrello, il sistema presenta automaticamente i gruppi varianti associati. Se almeno un gruppo e isRequired: true, l'operatore non puo procedere senza completare la selezione.

Varianti Ereditate dalla Categoria​

Le categorie supportano il campo defaultVariantGroups: un array di groupId applicati automaticamente a tutti i prodotti della categoria. Questo evita di configurare le stesse varianti su ogni singolo prodotto.

Ad esempio, assegnando grp_cottura_carne alla categoria Carni alla Griglia, tutti i prodotti di quella categoria erediteranno il gruppo cottura.

Azioni sugli Ingredienti (BOM)​

Le opzioni con campo action diverso da NONE modificano la distinta base del prodotto:

AzioneEffettoCampi necessari
ADDAggiunge ingredienteingredientSku, quantity, uom
REMOVERimuove ingredienteingredientSku, quantity
SUBSTITUTESostituisce un ingrediente della ricettavariantId (la variante che entra), ingredientSkuToRemove (l'ingrediente di ricetta che esce)

Queste modifiche si propagano al magazzino quando il modulo warehouse e attivo, decrementando le giacenze in base alla ricetta modificata.

La sostituzione​

La sostituzione non mette a confronto due varianti: toglie un ingrediente dalla ricetta del prodotto e ci mette una variante. Esempio: sulla pizza margherita, la cui ricetta contiene mozzarella fiordilatte, si sceglie la variante Mozzarella di bufala e come ingrediente da sostituire il fiordilatte.

Per configurarla servono due cose:

  1. la variante che entra, scelta dall'anagrafica varianti come per ADD e REMOVE: porta con se nome, sovrapprezzo, canali di vendita e SKU di magazzino;
  2. l'ingrediente di ricetta che esce, scelto dall'anagrafica ingredienti.
L'opzione compare solo dove l'ingrediente c'e davvero

Un prodotto la cui ricetta non contiene quell'ingrediente non mostra l'opzione — e se il gruppo resta senza alternative, non mostra nemmeno il gruppo. E il motivo per cui lo stesso gruppo "Tipo di mozzarella" si puo assegnare a tutte le pizze senza preoccuparsi: appare solo su quelle che il fiordilatte lo hanno davvero. Un prodotto senza ricetta non mostra mai una sostituzione.

Quantita: entra la stessa quantita della riga di ricetta sostituita — 100 g di fiordilatte tolti, 100 g di bufala aggiunti — senza dover configurare nulla. Se serve una quantita diversa si valorizza Delta Quantita sulla variante (o l'override per gruppo), che vince.

Prezzo: la sostituzione costa quanto la variante che entra (deltaPriceAdd), oppure l'override di prezzo dell'opzione se valorizzato.

In comanda la riga si legge per esteso: Mozzarella di bufala al posto di Mozzarella fiordilatte.

Configurazioni fatte prima

Le sostituzioni configurate con la vecchia forma (una variante al posto di un'altra) continuano a funzionare. Lo script scripts/migrate-substitute-to-recipe-ingredient.js le converte alla forma nuova; quelle la cui variante "da rimuovere" non era collegata a nessuno SKU vanno riconfigurate a mano, e il pannello le segnala.

Collegare la variante a un ingrediente o a un prodotto​

Nell'anagrafica variante (Varianti > editor) il campo Collega a sceglie in quale anagrafica cercare lo SKU da scaricare:

Collega aQuando usarloCosa viene scaricato
Ingrediente (default)La variante aggiunge/toglie una materia prima o un semilavorato (es. mozzarella, prosciutto)Lo SKU dell'ingrediente
ProdottoLa variante corrisponde a un articolo a catalogo (es. gruppo "Bibita" con opzioni acqua / aranciata / birra su una torta)Lo SKU del prodotto; se il prodotto ha una ricetta, questa viene esplosa nei suoi ingredienti

La ricerca e server-side su nome o SKU in entrambi i casi. Il tipo scelto viene salvato sulla variante (skuKind) e serve a ri-aprire l'editor sull'anagrafica giusta: lo scarico a magazzino e comunque guidato dal solo sku.

Le varianti collegate a magazzino vengono scaricate anche quando il prodotto base non ha una ricetta (es. una torta venduta a pezzo con la bibita in abbinamento).

Una variante movimenta il magazzino solo con delta quantita > 0

Non basta collegare lo SKU: serve valorizzare Delta Quantita nella sezione AGGIUNTA (o SOTTRATTA). Con delta a 0 la variante modifica solo il prezzo. L'editor mostra un avviso quando lo SKU e collegato ma entrambi i delta quantita sono a 0.

Override per gruppo​

Una variante vive una volta sola in anagrafica, ma dentro un gruppo puo' comportarsi diversamente. Nell'editor del gruppo (Gruppi Varianti > modifica > riga dell'opzione) ci sono tre override, tutti con la stessa regola: campo vuoto = usa l'anagrafica.

OverrideA cosa serveEsempio
Override €Prezzo diverso in questo gruppo"+ Mozzarella" costa 1,50 sulle pizze e 1,00 sulle piadine
Override qta aggiunta / rimossaQuantita di scarico diversa in questo gruppo"+ Mozzarella" pesa 50 g sulle pizze e 30 g sulle piadine
Override canali di venditaVisibilita' diversa in questo gruppo"Bicchiere di carta" solo in asporto nel gruppo A, ovunque nel gruppo B

Senza questi override si dovrebbe duplicare la voce in anagrafica per ogni variazione.

Sugli override quantita, 0 non e' "vuoto"

Lasciare il campo vuoto significa "eredita dall'anagrafica". Scrivere 0 significa invece "in questo gruppo la variante non movimenta il magazzino": e' una scelta esplicita, utile quando la stessa variante altrove scarica.

Come si compongono i canali di vendita​

I canali si configurano su tre livelli, e si sommano in AND:

  1. Anagrafica variante — dove quella variante e' disponibile in generale.
  2. Gruppo — dove compare l'intero gruppo (es. "Bibite" nascosto in asporto).
  3. Override sull'opzione dentro il gruppo — sostituisce il livello 1, solo in quel gruppo.

Ovunque, elenco vuoto = disponibile su tutti i canali. Per rendere una variante disponibile ovunque solo in un certo gruppo non basta svuotare l'override (vorrebbe dire "eredita"): vanno selezionati esplicitamente tutti i canali.

I canali del gruppo restano vincolanti

L'override agisce dentro il gruppo, non sopra di esso. Se il gruppo esclude un canale, una variante con override su quel canale non compare comunque. Esempio: gruppo limitato a Banco, opzione con override Asporto → quell'opzione non si vede ne' al banco (l'override non include banco) ne' in asporto (il gruppo e' escluso). Se l'obiettivo e' mostrarla in asporto, va prima ampliato il canale del gruppo.

Il filtro e' applicato sul dispositivo per cassa, tavoli e palmare, perche' la stessa cassa passa da banco ad asporto a tavolo durante la giornata. Per il kiosk, che ha un canale fisso, il filtro e' applicato dal server: le varianti escluse non vengono proprio inviate al totem.

Calcolo Prezzo Finale​

Quando l'operatore seleziona le varianti, il sistema calcola il prezzo finale sommando tutti i priceDelta:

Prezzo base:  Margherita        8.00 EUR
+ Bufala: priceDelta +2.00 EUR
+ Crudo: priceDelta +1.50 EUR
---
Prezzo finale: 11.50 EUR

L'azione variant-groups.applyVariantsToProduct esegue questo calcolo lato server, restituendo originalPrice, finalPrice, priceDelta e le modifiche BOM.

Validazione Selezioni​

Il sistema valida automaticamente le selezioni dell'operatore:

  • Se isRequired: true e minSelection: 1, almeno un'opzione deve essere selezionata
  • Se maxSelection: 3, non si possono selezionare piu di 3 opzioni
  • Per tipo SINGLE, maxSelection e automaticamente 1
  • L'opzione "Nessuno" (se abilitata) conta come selezione valida e soddisfa l'obbligatorieta

In caso di violazione, il sistema mostra un errore e impedisce l'aggiunta al carrello.

Messaggio d'Errore Personalizzato​

Il campo errorMessage del gruppo permette di definire il testo mostrato quando la validazione fallisce (es. Devi selezionare la dimensione del panino). Se vuoto, viene usato un messaggio generato automaticamente dal nome del gruppo. Il messaggio compare come avviso nei pannelli varianti con pulsante di conferma e negli avvisi dei controlli configurabili (vedi sotto).

Momenti di Verifica (layout "varianti visibili")​

I pannelli varianti con pulsante di conferma (dialog banco, comanda tavoli, waiter, kiosk, webapp) validano sempre la scelta alla conferma. Il layout banco "varianti visibili" (Fast Variants) applica invece le varianti direttamente sulla riga senza un passo di conferma: per questo la verifica delle varianti obbligatorie e configurabile a livello di locale dalla console admin, in Configurazione Ristorante > Impostazioni Station > Verifica Varianti Obbligatorie (policy del ristorante, sincronizzata a tutte le casse). I tre interruttori sono selezionabili in modo indipendente:

  • Verifica all'invio in cucina: blocca l'invio comanda se una variante obbligatoria non e stata scelta.
  • Verifica al pagamento: blocca il pagamento in presenza di righe con varianti obbligatorie mancanti.
  • Verifica al cambio prodotto: quando si aggiunge un altro prodotto, verifica la riga precedente (pensato proprio per il layout "varianti visibili").

In tutti i casi viene mostrato il messaggio d'errore configurato sul gruppo.

Pressione Lunga in Cassa​

In cassa, la pressione lunga su un tasto prodotto (CART_ADD) forza l'apertura del pannello varianti anche se il prodotto non ha gruppi obbligatori. Questo permette all'operatore di aggiungere modifiche occasionali senza rendere le varianti obbligatorie per tutti gli ordini.

FAQ​

Posso usare lo stesso gruppo varianti per piu prodotti? Si. I gruppi varianti sono entita indipendenti. Lo stesso gruppo Cottura Carne puo essere associato a bistecca, hamburger e qualsiasi altro prodotto.

Come configuro taglie diverse con prezzi diversi? Creare un gruppo SINGLE con isRequired: true. Ogni opzione rappresenta una taglia con il suo priceDelta. Ad esempio: Piccola (0), Media (+1.00), Grande (+2.00).

Come gestisco "senza" un ingrediente (es. senza cipolle)? Creare un'opzione con action: REMOVE, ingredientSku corrispondente e priceDelta: 0. L'opzione apparira nella lista dei modificatori e, se il magazzino e attivo, non verranno scalate le cipolle dalla giacenza.

Le varianti appaiono sullo scontrino? Si. Le varianti selezionate vengono stampate sotto il nome del prodotto nella comanda cucina e nel preconto. La formattazione dipende dal template di stampa configurato. Le varianti reali sono sempre stampate; per la sola opzione "Nessuno" la stampa e controllata da nonePrintOnComanda / noneComandaLabel (vedi Opzione "Nessuno").

Come preseleziono una scelta senza renderla fissa? Impostare isDefault: true sull'opzione desiderata (spunta "Preselezionata di default" nella console). La voce appare gia scelta ma resta modificabile dall'operatore. Vedi Scelta di Default.

Come permetto di "chiudere" un gruppo obbligatorio senza una scelta reale (es. senza contorno)? Abilitare l'opzione "Nessuno" sul gruppo (hasNoneOption: true), impostando eventualmente etichetta, prezzo, testo comanda e se stamparla. Vedi Opzione "Nessuno".

Vedi Anche​

Questa pagina ti è stata utile?