La risposta breve
Un prodotto non ha alcun prezzo. Il prezzo si trova su un record di collegamento tra il prodotto e un listino prezzi, e contiene l'importo, la sua valuta e un'impostazione di accesso che può riservare il listino a ruoli specifici. Due listini, due righe, un prodotto, due prezzi.
Due cose la coglieranno di sorpresa. La creazione di un listino prezzi non crea righe di prezzo per i prodotti già esistenti — avviene solo il contrario. E l'API non ricava mai un prezzo da un listino: una voce di riga creata senza un prezzo esplicito riceve zero, anche quando il prodotto ha un prezzo sul listino predefinito.
Il problema di business
Lo stesso prodotto non costa lo stesso a tutti. Un distributore acquista a un prezzo, un cliente diretto a un altro. Un contratto quadro fissa un prezzo per un anno. Una regione ha il proprio listino perché il mercato sostiene un prezzo diverso. Un livello per i partner ottiene una struttura di sconti che il team di vendita diretta non dovrebbe poter vedere, tanto meno inserire in un preventivo.
Che cosa significa in pratica:
- una voce di catalogo per prodotto — non quattro quasi-duplicati con prezzi diversi, che è il modo in cui la cosa va storta;
- più prezzi per prodotto, ciascuno appartenente a un listino con un nome;
- il prezzo giusto applicato quando un venditore crea un preventivo, senza che debba cercarlo;
- alcuni listini visibili solo ad alcune persone;
- e una traccia, a posteriori, di che cosa è stato proposto e su quale base.
Perché l'approccio ovvio non funziona
Duplicare il prodotto per ogni prezzo
"Widget (EMEA)", "Widget (Partner)", "Widget (Contract A)". Funziona il primo giorno e si deteriora subito: quattro record da mantenere allineati ogni volta che cambia una specifica, quattro SKU dove l'azienda ne ha uno, e una reportistica che non sa rispondere a «quanto Widget abbiamo venduto?» senza una tabella di corrispondenza che qualcuno mantiene a mano.
Mettere il prezzo sul prodotto come campo personalizzato
Un campo personalizzato per livello — prezzo di listino, prezzo partner, prezzo contrattuale — mette l'intera matrice dei prezzi su un unico modulo, visibile a chiunque possa vedere il prodotto, e richiede una modifica dello schema ogni volta che si aggiunge un livello. Inoltre aggira completamente la meccanica delle voci di riga, quindi nulla porta il prezzo su un preventivo al posto suo.
Dare per scontato che il prezzo sia una proprietà del prodotto
Non lo è, ed è questo il fatto strutturale da interiorizzare. Leggendo lo
schema dell'entità Product, price compare nel suo elenco di campi chiave —
ma sull'entità non esiste alcun attributo prezzo. Se crea un prodotto, il record
torna con un nome, uno SKU, un simbolo di unità, un tipo e nessun prezzo da nessuna parte.
Il prezzo è un record separato: un collegamento tra il prodotto e un listino prezzi. Ogni sorpresa del §6 discende da questo solo fatto.
Modello dati
Tre entità, una delle quali in molti non sanno che esiste.
| Entità | Contiene |
|---|---|
| Product | La voce di catalogo — nome, SKU, unità, tipo, categoria. Nessun prezzo. |
| Price list | Un listino con un nome — "List Price", "EMEA", "Partner Tier". Ha un tipo e un flag active. |
| Price-list price (il collegamento) | Il prezzo stesso, più la sua valuta, più un'impostazione di accesso. Una riga per ogni combinazione prodotto × listino. |
Quindi «questo prodotto costa 100 sul listino predefinito e 85 sul listino EMEA» sono due record di collegamento, non due campi e non due prodotti.
Fonte. Centro assistenza di Coevera, Price lists, per la vista dell'amministratore sulla stessa struttura.
Il collegamento porta con sé il controllo degli accessi. Ogni riga di prezzo ha un'impostazione di accesso con un elenco di ruoli facoltativo. È questo il meccanismo per un livello riservato ai partner o a uso solo interno: la restrizione si trova sul prezzo, non sul prodotto e non sul nome del listino. È anche facile non accorgersene affatto, perché nulla nel nome di un listino prezzi suggerisce che le autorizzazioni siano associate a un livello sottostante.
Con che cosa parte uno spazio nuovo
- Un listino prezzi, chiamato "List Price", contrassegnato come protetto dall'eliminazione — non è possibile rimuoverlo.
- Quel listino arriva con il flag active impostato su false, il che sorprende chi presume che il listino predefinito sia pronto all'uso.
- Una valuta, la valuta di base, protetta dall'eliminazione.
Voci di riga
Un prodotto arriva in una trattativa come voce di riga — un collegamento tra l'opportunità e il prodotto, che contiene price, quantity e un amount calcolato. I prezzi per voce di riga esistono sia su Quote sia su Opportunity; un'opportunità non è limitata a un unico valore riepilogativo.
L'opportunità ha inoltre una propria valuta dei prodotti, separata dalla valuta del suo valore principale, e un flag che indica se quel valore principale è derivato dalle voci di riga o inserito a mano.
La configurazione
- Creare prima i listini prezziPrima del catalogo, se possibile. L'ordine conta — veda il §6.
- AttivarliCompreso quello predefinito integrato, che non arriva attivo.
- Creare i prodottiCiascuno riceve automaticamente una riga di prezzo per ogni listino già esistente, con valore predefinito zero.
- Impostare i prezziUna riga per prodotto per listino. È il grosso del lavoro e la parte che conviene automatizzare con uno script.
- Impostare l'accesso sulle righe da limitareNon sul listino — sulle righe di prezzo al suo interno.
- Verificare tramite il tasso di riempimentoContare le righe di prezzo per listino e confrontarle con il numero di prodotti. Un listino con meno righe che prodotti ha dei buchi, e un buco si legge come un prezzo pari a zero.
Il passaggio 6 esiste a causa dell'asimmetria descritta nel §6, ed è il controllo che intercetta il modo più comune in cui questa configurazione resta incompleta senza che nessuno se ne accorga.
Applicare il prezzo giusto
L'API non ricava un prezzo da un listino prezzi. Verificato: una voce di riga
creata senza prezzo è tornata con price: 0, su un prodotto che aveva
un prezzo di 100 sul listino predefinito. Nessun errore, nessun valore predefinito, nessuna ricerca.
La selezione del listino è una funzionalità dell'interfaccia. Sul percorso dell'API, decidere quale listino si applica e leggerne il prezzo è compito del chiamante.
Per un'integrazione o un'importazione, ciò significa che la logica di risoluzione spetta a lei scriverla e mantenerla corretta: determinare il listino applicabile a partire da ciò che lo determina — la regione dell'account, il suo livello, un riferimento contrattuale —, leggere la riga di prezzo per quel prodotto e quel listino, e scrivere il valore sulla voce di riga.
E nessuno dei campi della voce di riga letti tramite l'API registra da quale listino proviene il prezzo. Nessuno contiene un riferimento al listino. Quindi, una volta che una riga esiste, nulla nei dati riletti dice se 85 era il prezzo EMEA, uno sconto negoziato o un errore di battitura. Se la base di un prezzo conta per la reportistica o l'audit, la registri lei stesso in un campo personalizzato sulla voce di riga nel momento in cui imposta il prezzo — dopo è troppo tardi.
Limiti e compromessi
La creazione delle righe di prezzo funziona in una sola direzione
La creazione di un prodotto crea una riga di prezzo per ogni listino esistente. La creazione di un listino non crea nulla per i prodotti esistenti. Verificato in entrambe le direzioni.
Quindi la sequenza naturale — costruire il catalogo, poi aggiungere un listino regionale quando l'attività si espande — lascia ogni prodotto esistente senza prezzo sul nuovo listino, e una riga senza prezzo è indistinguibile da un prezzo pari a zero. Aggiunga i listini prima dei prodotti quando possibile; quando non lo è, completi deliberatamente le righe mancanti e verifichi il conteggio.
I valori calcolati sono in ritardo rispetto alla risposta alla scrittura
L'amount di una voce di riga è calcolato come prezzo × quantità, ma il valore nella
risposta alla sua stessa scrittura non è aggiornato. Subito dopo aver impostato il prezzo 85 su una
quantità di 2, la scrittura ha restituito amount: 0; una nuova lettura ha restituito
170. Il calcolo è corretto — l'eco no.
Non affermi mai il valore di un campo calcolato sulla base di una risposta alla scrittura. Lo stesso schema compare nel Blueprint 002.
I campi di sconto sono leggibili ma non scrivibili
La voce di riga espone un valore di sconto e una percentuale di sconto, e l'API rifiuta i tentativi di scrivere l'uno o l'altra — li segnala come attributi che l'entità non possiede. Sembrano essere derivati anziché impostabili, quindi uno sconto deve essere espresso modificando il prezzo anziché registrando uno sconto.
Non verificato: il consolidamento del valore dell'opportunità
Con il flag di calcolo automatico dell'opportunità impostato su true e una voce di riga il cui importo è calcolato correttamente, il valore principale dell'opportunità resta a zero in letture ripetute e dopo una modifica deliberata del record. Il risultato è lo stesso con il flag impostato alla creazione, prima che esista qualsiasi voce di riga: l'importo della voce di riga è calcolato in 1.000 e il valore dell'opportunità resta zero.
Non è stabilito se si tratti di un difetto: la spiegazione che resta, non verificata qui, è che il consolidamento venga calcolato dall'interfaccia anziché dal server. È stabilito invece che nessuno dei due ordinamenti produce un valore sul server, quindi un'integrazione non può contare sulle voci di riga per determinare il valore dell'opportunità — imposti il valore esplicitamente se le serve, e verifichi il comportamento dell'interfaccia prima di presumere il contrario.
Più valute
Ogni riga di prezzo ha una propria valuta, quindi un listino può essere espresso in una valuta diversa da un altro. Ciò che non è nativo è conservare il tasso di cambio applicato in un determinato momento — uno storico dei tassi di cambio al momento della transazione deve essere gestito tramite automazione, se l'azienda ne ha bisogno. Non lo abbiamo verificato in uno spazio con più valute; è riportato sulla base di un'analisi precedente anziché di un'osservazione.
Verifica
- Conti le righe di prezzo per listino rispetto al numero di prodotti. È il singolo controllo più prezioso qui, perché un prodotto senza prezzo su un listino ha esattamente lo stesso aspetto di un prodotto con prezzo zero.
- Rilegga i prezzi dai record di collegamento, non dal prodotto — sul prodotto non c'è nulla da leggere.
- Crei una voce di riga dall'inizio alla fine e confermi che il prezzo che vi arriva è quello che intendeva, soprattutto se è un'integrazione a occuparsi della risoluzione.
- Rilegga gli importi calcolati dopo un intervallo di assestamento. Mai dalla risposta alla scrittura.
- Verifichi le restrizioni di accesso con un utente limitato, non come amministratore — la stessa disciplina del controllo sul blocco dei record nel Blueprint 004. Un amministratore non può vedere la restrizione in funzione.
- Confermi che il listino predefinito sia attivo prima di chiedersi perché nulla abbia un prezzo.
Che cosa segnalerebbe una regressione: voci di riga che arrivano a zero, il che significa che il passaggio di risoluzione è stato saltato; un listino prezzi il cui numero di righe scende sotto il numero di prodotti dopo un'aggiunta al catalogo; oppure prezzi nei preventivi che non corrispondono più ad alcun listino, il che significa che qualcuno ha modificato direttamente le voci di riga.
Domande frequenti
Come si assegnano a un prodotto prezzi diversi per regioni o segmenti di clientela diversi?
Con i listini prezzi. In Coevera CRM un prodotto non ha alcun prezzo — il prezzo si trova su un record di collegamento tra il prodotto e un listino prezzi, che contiene l'importo e la relativa valuta. Creare un secondo listino e una seconda riga di prezzo per lo stesso prodotto dà a quel prodotto due prezzi, uno per listino. Il record di collegamento contiene anche un'impostazione di accesso, per cui un listino può essere riservato a ruoli specifici: è così che un livello di prezzo per i partner o a uso solo interno viene tenuto lontano dal team di vendita più ampio.
Perché il mio prodotto non mostra alcun prezzo dopo che ho creato un nuovo listino prezzi?
Perché la creazione automatica delle righe di prezzo funziona in una sola direzione. La creazione di un prodotto genera una riga di prezzo per ogni listino già esistente, con valore predefinito zero. La creazione di un listino non genera righe per i prodotti già esistenti. Quindi aggiungere un listino regionale o contrattuale dopo che il catalogo è stato popolato lascia ogni prodotto esistente senza prezzo su quel listino, finché le righe non vengono create esplicitamente, una per prodotto.
L'API di un CRM applica automaticamente il prezzo del listino quando si aggiunge un prodotto a una trattativa?
In Coevera, no. Creare una voce di riga tramite l'API senza fornire un prezzo produce una riga con prezzo zero, anche quando il prodotto ha un prezzo sul listino predefinito. La selezione del listino è una funzionalità dell'interfaccia, non una regola di risoluzione lato server, quindi qualsiasi integrazione che crea voci di riga deve decidere quale listino si applica e fornire essa stessa il prezzo. Inoltre nessuno dei campi della voce di riga letti tramite l'API fa riferimento al listino da cui proviene, per cui la provenienza di un prezzo non vi viene registrata.
Sia i preventivi sia le opportunità possono avere prezzi per voce di riga?
Sì. In Coevera i prezzi per voce di riga sono disponibili sia sui record Quote sia sui record Opportunity, quindi un'opportunità non è limitata a un unico valore riepilogativo. L'opportunità ha una propria valuta dei prodotti accanto alla valuta del suo valore principale, e un flag che stabilisce se quel valore principale deriva dalle voci di riga anziché essere inserito direttamente.