Introduzione
Se hai trascorso del tempo a lavorare con Odoo, probabilmente hai incontrato campi che calcolano automaticamente il loro valore. Un campo computato memorizzato porta questo un passo oltre: calcola il valore e lo salva direttamente nel database.
Questa distinzione è più importante di quanto possa sembrare a prima vista. Un campo che calcola solo al volo non può essere cercato, filtrato, raggruppato o esportato in modo efficiente. Un campo computato memorizzato può. Si comporta come una normale colonna di database pur essendo guidato dalla logica che definisci.
Questa guida copre tutto ciò che devi sapere sui campi computati memorizzati in Odoo: come funzionano all'interno del modello dati Odoo, come crearli utilizzando Odoo Studio o Python, casi d'uso aziendali reali e gli errori più comuni da evitare.
Che cos'è un Campo Computato Memorizzato in Odoo
Nell'ORM di Odoo, ogni campo su un modello contiene un pezzo di dati. La maggior parte dei campi memorizza ciò che l'utente inserisce manualmente. Un campo computato è diverso: il suo valore è generato da una funzione Python piuttosto che inserito da un utente.
Un campo calcolato memorizzato è semplicemente un campo calcolato con store=True. Quando le sue dipendenze cambiano, Odoo esegue la funzione di calcolo e scrive il risultato nella colonna del database. Il valore è quindi disponibile proprio come qualsiasi altro campo.
In Python, il modello di base appare così:
total_amount = fields.Float(
string='Importo Totale',
compute='_compute_total_amount',
store=True,
)
@api.depends('quantity', 'unit_price')
def _compute_total_amount(self):
for record in self:
record.total_amount = record.quantity * record.unit_price
Il parametro store=True è ciò che separa un campo calcolato memorizzato da un campo calcolato regolare. Senza di esso, il valore viene ricalcolato ogni volta che il campo viene letto ma non viene mai memorizzato nel database.
Nell'interfaccia di Odoo, un campo calcolato memorizzato appare esattamente come qualsiasi altro campo. Gli utenti lo vedono su moduli, viste elenco e report. Possono filtrarlo, raggruppare i record utilizzandolo e includerlo nelle esportazioni. Non c'è alcun indicatore visivo che il valore sia calcolato piuttosto che inserito.
Campi Calcolati Memorizzati vs Non Memorizzati
Comprendere questa differenza è essenziale per qualsiasi lavoro di sviluppo Odoo:
- Campo calcolato non memorizzato: Calcolato al volo quando viene letto. Non può essere utilizzato in filtri, ricerche o raggruppamenti. Più leggero in termini di spazio di archiviazione ma non disponibile per le query del database.
- Campo calcolato memorizzato: Calcolato quando cambiano le dipendenze e salvato nel database. Ricercabile, filtrabile, esportabile. Occupa spazio nel database come qualsiasi colonna regolare.
La scelta tra i due non riguarda quale sia migliore in generale. Dipende da ciò di cui hai bisogno per il campo. Se lo visualizzi solo su un singolo modulo, il non memorizzato va bene. Se hai bisogno di filtrare, ordinare o aggregare in base a esso, usa il memorizzato.
Come Funziona il Campo
Quando definisci un campo calcolato memorizzato in Odoo, il ORM imposta i trigger di ricalcolo automatici basati sui campi elencati nel decoratore @api.depends().
Ogni volta che uno di quei campi dipendenti cambia su un record, Odoo contrassegna quel record come bisognoso di ricalcolo. Il metodo di calcolo viene eseguito e il risultato viene scritto di nuovo nella colonna del database per quel campo.
Il Ciclo di Ricalcolo
Ecco cosa succede passo dopo passo:
- Un utente o un processo automatizzato modifica un campo che è elencato in
@api.depends(). - Odoo rileva la modifica e identifica tutti i record che dipendono da questo campo.
- Il metodo di calcolo viene chiamato per quei record.
- Il valore calcolato viene scritto nella colonna del database.
- Il campo è ora disponibile per la ricerca, il filtro e l'esportazione con il valore aggiornato.
Nella maggior parte dei casi, questo ricalcolo avviene immediatamente all'interno della stessa transazione. Per operazioni batch di grandi dimensioni, Odoo può posticipare alcuni ricalcoli e elaborarli in background.
Dipendenze Tra Modelli Correlati
Il decoratore @api.depends() supporta percorsi puntati per accedere ai campi sui modelli correlati. Ad esempio:
@api.depends('partner_id.country_id.name')
def _compute_country_name(self):
for record in self:
record.country_name = record.partner_id.country_id.name or ''
In questo caso, Odoo tiene traccia delle modifiche su partner_id, country_id e name tra i modelli. Se il nome del paese cambia su un partner, tutti i record correlati vengono automaticamente ricalcolati. Questo è uno degli aspetti più potenti del framework Odoo.
Impatto sul Database
Poiché il campo è memorizzato, Odoo crea una vera e propria colonna nella tabella del database PostgreSQL. Ciò significa che il campo partecipa direttamente alle query SQL. Le ricerche e i filtri sui campi calcolati memorizzati sono veloci ed efficienti, proprio come le ricerche sui campi normali.
Casi d'Uso Aziendali
I campi calcolati memorizzati appaiono in tutte le aree di Odoo. Ecco cinque esempi pratici tratti da flussi di lavoro aziendali reali.
1. Vendite: Percentuale di Margine sulle Linee d'Ordine
Un team di vendita desidera vedere la percentuale di margine su ciascuna linea d'ordine senza aprire una calcolatrice. Un campo calcolato memorizzato prende il prezzo unitario e il prezzo di costo, calcola il margine e lo memorizza sulla linea. Il responsabile vendite può quindi filtrare gli ordini per percentuale di margine, trovare istantaneamente le linee non redditizie e raggruppare per bande di margine nelle viste pivot.
2. CRM: Giorni Senza Attività su un Lead
Un campo calcolato memorizzato sul modello di lead CRM può tenere traccia di quanti giorni sono passati dall'ultima attività programmata. Abbina questo a un'azione programmata che attiva la ricalcolo ogni mattina, e il tuo team di vendita può filtrare i lead in base alla soglia di inattività. Nessun tracciamento manuale richiesto.
3. Inventario: Quantità Netta Disponibile
Per i prodotti con regole di stock complesse, un campo calcolato memorizzato può contenere un valore pre-calcolato come la quantità disponibile meno la quantità riservata. Poiché il valore è memorizzato, i responsabili di prodotto possono ordinare e filtrare l'elenco dei prodotti in base alla disponibilità senza che Odoo esegua calcoli complessi sullo stock in tempo reale per ogni riga sullo schermo.
4. Contabilità: Conteggio delle Fatture Scadute per Cliente
Sul modello cliente, un campo calcolato memorizzato può contare quante fatture sono attualmente scadute. Quando il team contabile apre l'elenco dei contatti, può ordinare i clienti in base al conteggio delle fatture scadute con un solo clic. Questo è possibile solo perché il conteggio è memorizzato nel database piuttosto che calcolato al volo per ogni riga.
5. Manifattura: Durata Totale Stimata del Lavoro
In una distinta di materiali, un campo calcolato memorizzato può sommare la durata stimata di tutte le operazioni del centro di lavoro collegate al BOM. I pianificatori di produzione possono quindi filtrare e ordinare i BOM in base al tempo totale di lavoro, il che è utile per la pianificazione della capacità e la programmazione. Ogni volta che un'operazione viene aggiunta o modificata, il totale si aggiorna automaticamente.
Creazione o Personalizzazione del Campo
Ci sono due modi principali per creare campi calcolati memorizzati in Odoo: utilizzare Odoo Studio per casi semplici, oppure scrivere codice Python in un modulo personalizzato per avere il pieno controllo.
Utilizzando Odoo Studio
Odoo Studio ti consente di aggiungere campi calcolati senza scrivere alcun codice. Quando crei un nuovo campo di tipo Intero, Float o Monetario in Studio, puoi abilitare un'opzione formula che accetta un'espressione simile a Python. Studio gestisce il tracciamento delle dipendenze dietro le quinte.
I campi calcolati in Studio sono adatti quando la logica è un'espressione aritmetica semplice tra campi dello stesso record. Sono facili da configurare e non richiedono un ambiente di sviluppo. Tuttavia, hanno limiti reali. Se la tua logica coinvolge campi di modelli correlati, rami condizionali o aggregazione tra record figli, Studio non sarà sufficiente. Avrai bisogno di un modulo personalizzato.
Questa è una distinzione importante quando pianifichi la tua personalizzazione di Odoo: Studio è veloce per casi semplici, ma Python ti offre piena flessibilità quando la logica diventa complessa.
Utilizzando un Modulo Python Personalizzato
Per qualsiasi cosa oltre le formule di base, definisci il campo in Python all'interno di un modulo Odoo personalizzato. Ecco un esempio concreto che aggiunge un campo percentuale di margine alle righe dell'ordine di vendita:
from odoo import models, fields, api
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
x_margin_pct = fields.Float(
string='Margine %',
compute='_compute_margin_pct',
store=True,
digits=(5, 2),
)
@api.depends('price_unit', 'purchase_price')
def _compute_margin_pct(self):
for line in self:
if line.price_unit:
line.x_margin_pct = (
(line.price_unit - line.purchase_price) / line.price_unit
) * 100
else:
line.x_margin_pct = 0.0
Quando questo modulo è installato, Odoo crea la colonna x_margin_pct nel database, esegue il metodo di calcolo per tutti i record esistenti e inizia a tracciare le modifiche a price_unit e purchase_price da quel momento in poi.
Il prefisso del campo x_ è la convenzione per i campi personalizzati in Odoo per evitare conflitti con i campi core. Questa è una prassi standard nello sviluppo di Odoo.
Rendere un Campo Calcolato Memorizzato Modificabile
Per impostazione predefinita, i campi calcolati sono di sola lettura. Se desideri che gli utenti possano sovrascrivere manualmente il valore calcolato, puoi definire un metodo inverse insieme al tuo metodo di calcolo. Il metodo inverso viene eseguito quando un utente scrive direttamente nel campo e può aggiornare i campi sorgente di conseguenza. Questo schema è utile per i campi in cui il valore calcolato è un buon valore predefinito ma a volte necessita di una sovrascrittura manuale.
Campi di Odoo Studio e API XML-RPC
Per i team che gestiscono campi del database Odoo tramite l'API XML-RPC, puoi creare campi standard tramite il modello ir.model.fields. Tuttavia, per i campi calcolati memorizzati con logica Python personalizzata, il metodo di calcolo stesso deve risiedere nel codice lato server. L'approccio API funziona bene per la fornitura di campi semplici come parte di distribuzioni automatizzate, ma la logica dietro un campo calcolato richiede sempre un modulo personalizzato installato sul server.
Migliori Pratiche
Ecco le pratiche che i consulenti Odoo esperti seguono quando lavorano con campi calcolati memorizzati.
Dichiarare Tutte le Dipendenze con Precisione
Il decoratore @api.depends() deve elencare ogni campo che il tuo metodo di calcolo legge. Se ne dimentichi uno, il campo non si aggiornerà quando quella dipendenza cambia. Controlla il tuo metodo di calcolo riga per riga e assicurati che ogni accesso al campo sia elencato nel decoratore.
Mantieni Veloci i Metodi di Calcolo
Il tuo metodo di calcolo viene eseguito su ogni record che è influenzato da un cambiamento di dipendenza. In un'istanza Odoo occupata, questo può significare migliaia di record contemporaneamente. Evita le query al database all'interno dei metodi di calcolo quando possibile. Se hai bisogno di accedere a dati correlati, utilizza i campi che sono già caricati piuttosto che eseguire ulteriori ricerche.
Usa solo store=True Quando Ne Hai Bisogno
I campi memorizzati consumano spazio nel database e attivano operazioni di scrittura a ogni ricalcolo. Se hai solo bisogno di visualizzare il campo in una vista modulo e non lo filtri mai o non lo raggruppi, un campo calcolato non memorizzato è l'opzione più leggera. Prendi questa decisione in modo deliberato piuttosto che impostare di default su memorizzato per tutto.
Gestisci i Casi Limite nel Metodo di Calcolo
Considera sempre valori vuoti o mancanti all'interno del tuo metodo di calcolo. La divisione per zero, record correlati mancanti e valori nulli sono cause comuni di errori silenziosi nei campi calcolati. Aggiungi controlli espliciti e imposta valori predefiniti sicuri quando il calcolo normale non può procedere.
Pianifica la ricomputazione iniziale su grandi tabelle
Quando installi un modulo che aggiunge un nuovo campo calcolato memorizzato, Odoo lo ricompone per ogni record esistente nella tabella. Su una tabella con centinaia di migliaia di righe, questo può richiedere un tempo significativo. Testa la tua migrazione prima in un ambiente di staging e pianifica un potenziale downtime o un'elaborazione in background quando distribuisci in produzione.
Evita le dipendenze circolari
Se il campo A dipende dal campo B e il campo B dipende dal campo A, Odoo genererà un errore quando il modulo viene caricato. Progetta le dipendenze dei tuoi campi calcolati in modo che fluiscano in una sola direzione.
Trappole Comuni
Dimenticare store=True
Questo è l'errore più comune. Il campo viene visualizzato correttamente nella vista del modulo, quindi tutto sembra a posto durante i test. Poi qualcuno prova ad aggiungerlo come filtro o a includerlo in un report, e non funziona. Prima di scrivere qualsiasi logica di calcolo, decidi in anticipo se hai bisogno che il campo sia ricercabile. Se sì, aggiungi store=True fin dall'inizio.
Mancanza di una dipendenza in @api.depends
Se il tuo metodo di calcolo legge partner_id.country_id ma il tuo decoratore elenca solo partner_id, il campo non si aggiornerà quando il paese cambia nel record del partner. Traccia il percorso completo di ogni accesso al campo nel tuo metodo e elenca ogni passaggio esplicitamente nel decoratore.
Errori silenziosi nel metodo di calcolo
Se il tuo metodo di calcolo genera un'eccezione per un record, Odoo salta silenziosamente la ricomputazione per quel record e mantiene il valore memorizzato precedente. L'errore può apparire nei log del server, ma nulla viene mostrato all'utente. Questo può portare a valori obsoleti o errati che sono difficili da rintracciare. Testa sempre il tuo metodo di calcolo contro record che hanno dati mancanti o insoliti.
Degradazione delle prestazioni su grandi dataset
Un metodo di calcolo che funziona bene durante lo sviluppo può diventare un serio collo di bottiglia in produzione se la tabella cresce fino a decine di migliaia di record. Fai attenzione a quante query al database il tuo metodo di calcolo attiva per record. Una singola query extra per record moltiplicata per diecimila record è diecimila query per una singola operazione di salvataggio.
Utilizzare sudo() all'interno dei metodi di calcolo
Chiamare sudo() all'interno di un metodo di calcolo per bypassare i diritti di accesso è un rischio per la sicurezza. Se il valore calcolato espone dati che l'utente attuale non dovrebbe vedere, restituirlo tramite un metodo di calcolo vanifica il modello di permessi di Odoo. Utilizzare sudo() all'interno dei metodi di calcolo solo quando si è riflettuto deliberatamente sulle implicazioni di sicurezza.
Aspettarsi una ricomputazione immediata in tutti i contesti
Nella maggior parte delle operazioni interattive, la ricomputazione è sincrona. Ma durante importazioni in batch, lavori in background o alcune operazioni ORM con flag di contesto, Odoo può rinviare la ricomputazione. Non costruire logica aziendale che presuppone che il valore memorizzato sia sempre aggiornato nel momento esatto in cui viene scritto un record. Verificare il comportamento nel contesto specifico in cui il campo verrà utilizzato.
Conclusione
I campi calcolati memorizzati sono uno degli strumenti più utili disponibili quando si costruisce o si estende Odoo. Consentono di automatizzare i calcoli, mantenere i dati coerenti e rendere i record ricercabili ed esportabili senza alcun lavoro manuale da parte degli utenti.
I punti chiave da ricordare:
- Utilizzare
store=Truequando è necessario che il campo sia ricercabile, filtrabile o esportabile. - Dichiarare sempre tutte le dipendenze in
@api.depends(), comprese le strade tra modelli. - Mantenere i metodi di calcolo veloci e gestire esplicitamente i casi limite.
- Per formule semplici, Odoo Studio è un'opzione rapida. Per qualsiasi cosa più complessa, scrivere in Python.
- Pianificare la ricomputazione iniziale quando si distribuisce in produzione su grandi tabelle.
Che tu stia costruendo un nuovo modulo personalizzato, estendendo un modello Odoo esistente o esplorando tipi di campo Odoo per la prima volta, i campi calcolati memorizzati meritano di essere compresi a fondo. Si trovano all'incrocio tra l'ORM di Odoo, il livello del database e la tua logica aziendale.
Hai bisogno di aiuto con la tua implementazione di Odoo?
Dasolo aiuta le aziende a implementare, personalizzare e ottimizzare Odoo per una vasta gamma di esigenze aziendali. Che tu abbia bisogno di aggiungere campi calcolati al tuo modello di dati, costruire report basati su valori calcolati, o portare il tuo Sviluppo Odoo oltre, il nostro team ha l'esperienza per aiutarti.
Contattaci se hai bisogno di supporto per il tuo progetto Odoo. Siamo felici di discutere il tuo caso d'uso e trovare l'approccio giusto per la tua azienda.