Come mai Magento a volte calcola male gli arrotondamenti sui prezzi? Il problema si presenta più che altro in fase di carrello / checkout, quando un utente inserisce più pezzi dello stesso prodotto. Vi racconto qui la storia di un sabato pomeriggio passato dietro i centesimi e come ho risolto il problema.
Son abituato a correre dietro ai centesimi, visto che pratico atletica .Ma un sabato di giugno l'ho dovuto passare dietro ai centesimi dei prezzi di un negozio Magento, e forse è stato più faticoso di una serie di ripetute sui 400 metri. Vi riepilogo il problema e la soluzione, magari vi evito di passare altrettante ore ad occhi incrociati..
Mi ha scritto un cliente facendomi presente che i prezzi del suo catalogo, in fase di carrello /checkout, risultavano inspiegabilmente sbagliati. L'acquisto di 10 cd da 22 centesimi arrivava a costare 2 euro e 22 centesimi, anzichè i 2 euro e 20 che matematica dovrebbe imporre. Visto che il cliente inseriva i prodotti iva compresa, ho subito pensato ad un problema di scorporo dell'Iva, ipotizzando che Magento usasse un sistema misto arrotondamento/troncamento. I 22 centesimi potevano cosi diventare 21.. Ma le cose non torvano lo stesso.
Online ho visto che Magento soffre di un bug di arrotondamento , ben descritto sul una pagina di Erik Dannenberg su Github , sulla funzione "_deltaRound()" che in effetti è stata patchata nelle ultime versioni (ho verificato sulla 1.9). Quindi se avete un problema di questo tipo e non volete aggiornare Magento all'ultima versione, potete provare a patchare la funzione _deltaRounding(), presente in:
app/code/core/Mage/Tax/Model/Sales/Total/Quote/Subtotal.php
app/code/core/Mage/Tax/Model/Sales/Total/Quote/Tax.php
sostituendo la riga
$delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0;
con
$delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0.000001;
Tutto sommato, questa modifica non ha risolto i miei problemi, che erano quindi di altra natura.
La "lampadina" si è accesa quando il cliente mi ha segnalato che il problema ha iniziato a verificarsi a seguito del cambio di Iva, portata al 22% il primo ottobre 2013.
Nel pannello dei prodotti, il prezzo del cd risultava a 18 centesimi. 18 centesimi, "ivato" al 22%, corrisponde a 22 centesimi (precisamente a 0.2196 centesimi, ovviamente arrotondato a due decimali e quindi portato a 0.22).
Il problema è che il pannello dei prodotti presenta il prezzo arrotondato a 2 decimali, ma nel database (tabelle catalog_product_index_price e catalog_product_index_price_idx) il prezzo risulta a 4 decimali, ed è questo il prezzo che viene usato poi nel carrello! E infatti il prezzo memorizzato non era 0,18 ma 0.1818!
Cosa era accaduto?
Era accaduto che ai tempi dell'iva 21%, il mio cliente aveva inserito per la prima volta il prodotto (aveva scorporato l'iva dai 22 centesimi inserendo nel pannello il prezzo di 0.1818). Questo valore era stato memorizzato nel database.
Nel pannello prodotti però veniva mostrato il prezzo arrotondato (0.18). Quando l'iva è stata portata al 22%, il cliente aveva aperto il pannello per verificare il prezzo, ma l'iva calcolata su 18 centesimi lascia ancora il prezzo a 22 centesimi (era sua intenzione non modificare i prezzi con l'aumento dell'iva) , quindi per lui le cose stavano a posto cosi. In realtà nel database quel 0.1818, con iva 22%, andava ad alterare il risultato dei calcoli quando c'era più di un pezzo da aggiungere nel carrello, solo allora i centesimi andavano a modificare l'arrotondamento...
E questo spiega anche perchè il cliente se ne sia accorto dopo tanto tempo: per prodotti di costo maggiore, i centesimi incidono poco e comunque è difficile che un cliente metta in carrello piu di un pezzo, come accade con i cd.
Spero di avervi risparmiato qualche oretta da passare in modo più divertente.. ma tutto sommato, una volta trovato il problema, posso dire che è stato un pomeriggio interessante anche per me