I had to change prices to 4 decimals and it's OK. However, i have sometimes rounded cent in totals which is wrong. The explanation is that all calculations (subtotal, VAT and total) are on 4 decimals then rounded to 2 decimals. With rounding, subtotal + VAT is sometimes different for 1 cent from total.
To fix this, i need to :
But i can't figure how to do this. I tried multiple solutions and nothing is working : even with forcing subtotal/VAT and saving, it seems to be calculated again elsewhere and 4 decimals appear again.
Can you give me some piece of advice on how to achieve this ? Thanks !
I succeed in rewriting event sales_quote_collect_totals_after
Update : here is the code
in Myvendor/Mymodule/etc/events.xml :
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_quote_address_collect_totals_after">
<observer name="changeTotals" instance="Myvendor\Mymodule\Observer\ChangeTotals"/>
</event>
</config>
In Myvendor/Mymodule/Observer/ChangeTotals.php :
<?php
namespace Myvendor\Mymodule\Observer;
use Psr\Log\LoggerInterface as Logger;
use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer;
class ChangeTotals implements ObserverInterface
{
/**
* @var Logger
*/
protected $_logger;
/**
* [__construct ]
*
* @param Logger $logger
*/
public function __construct(
Logger $logger
) {
$this->_logger = $logger;
}
public function execute(Observer $observer)
{
/** @var Magento\Quote\Model\Quote\Address\Total */
$total = $observer->getData('total');
$subtotal = $total->getTotalAmount('subtotal');
$tax = $total->getTotalAmount('tax');
$grandTotal = $total->getGrandTotal();
/* $this->_logger->info('**** total_before **** ' , array($total->getData()));*/
/* the $total->getData() contains :
[subtotal] => 0
[weee] => 0
[discount] => 0
[shipping] => 0
[shipping_discount] => 0
[tax] => 0
[discount_tax_compensation] => 0
[shipping_discount_tax_compensation] => 0
[extra_tax] => 0
[weee_tax] => 0*/
// i round tax to 2 decimals
$tax = round($tax,2);
$total->setTotalAmount('tax', $tax);
$total->setBaseTaxAmount($tax);
/* recalculate grandTotal */
$grandTotal = round($subtotal,2) + $tax + $total->getTotalAmount('discount') + $total->getShippingAmount()
+$total->getShippingDiscountAmount() + $total->getDiscountTaxCompensation() + $total->getShippingDiscountTaxCompensation() + $total->getExtraTax(), 2);
/* recalculate baseGrandTotal */
$baseGrandTotal = round($total->getBaseSubtotal(),2) + $tax + $total->getBaseDiscount() + $total->getBaseShippingAmount()
+ $total->getBaseShippingDiscountAmount() + $total->getBaseDiscountTaxCompensation() + $total->getBaseShippingDiscountTaxCompensation() + $total->getBaseExtraTax(), 2);
/* update totals */
$total->setGrandTotal($grandTotal);
/*$total->setBaseGrandTotal($baseGrandTotal);
/* $this->_logger->info('**** total_after **** ' , array($total->getData())); */
return $this;
}
}