I am trying to override Magento 2 sales order totals block. I am setting preference for the same in my custom module as the function to be overridden is protected function, please find code below:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for='Magento\Sales\Block\Order\Totals' type='Company\Module\Block\Order\Totals'/>
</config>
The custom block file being used to override the same is as below:
<?php
namespace Company\Module\Block\Order;
use Magento\Sales\Model\Order;
class Totals extends \Magento\Sales\Block\Order\Totals
{
/**
* Associated array of totals
* array(
* $totalCode => $totalObject
* )
*
* @var array
*/
protected $_totals;
/**
* @var Order|null
*/
protected $_order = null;
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Framework\Registry $registry,
array $data = []
) {
parent::__construct($context, $registry, $data);
}
/**
* Initialize self totals and children blocks totals before html building
*
* @return $this
*/
protected function _beforeToHtml()
{
$this->_initTotals();
foreach ($this->getLayout()->getChildBlocks($this->getNameInLayout()) as $child) {
if (method_exists($child, 'initTotals') && is_callable([$child, 'initTotals'])) {
$child->initTotals();
}
}
return parent::_beforeToHtml();
}
/**
* Initialize order totals array
*
* @return $this
*/
protected function _initTotals()
{
$source = $this->getSource();
$this->_totals = [];
$this->_totals['subtotal'] = new \Magento\Framework\DataObject(
['code' => 'subtotal', 'value' => $source->getSubtotal(), 'label' => __('Subtotal')]
);
/**
* Add shipping
*/
if (!$source->getIsVirtual() && ((double)$source->getShippingAmount() || $source->getShippingDescription())) {
$this->_totals['shipping'] = new \Magento\Framework\DataObject(
[
'code' => 'shipping',
'field' => 'shipping_amount',
'value' => $this->getSource()->getShippingAmount(),
'label' => __('Shipping & Handling'),
]
);
}
/**
* Add discount
*/
if ((double)$this->getSource()->getDiscountAmount() != 0) {
if ($this->getSource()->getDiscountDescription()) {
$discountLabel = __('Discount (%1)', $source->getDiscountDescription());
} else {
$discountLabel = __('Discount');
}
$this->_totals['discount'] = new \Magento\Framework\DataObject(
[
'code' => 'discount',
'field' => 'discount_amount',
'value' => $source->getDiscountAmount(),
'label' => $discountLabel,
]
);
}
$this->_totals['grand_total'] = new \Magento\Framework\DataObject(
[
'code' => 'grand_total',
'field' => 'grand_total',
'strong' => true,
'value' => $source->getGrandTotal(),
'label' => __('Grand Total'),
]
);
/**
* Base grandtotal
*/
if ($this->getOrder()->isCurrencyDifferent()) {
$this->_totals['base_grandtotal'] = new \Magento\Framework\DataObject(
[
'code' => 'base_grandtotal',
'value' => $this->getOrder()->formatBasePrice($source->getBaseGrandTotal()),
'label' => __('Grand Total to be Charged'),
'is_formated' => true,
]
);
}
return $this;
}
}
I can see the function is overwritten and called via my custom block but it is not being rendered at orders total section. Order total section is gone blank, not sure why it is happening so. Please suggest me if anyone have idea on it.
Best Answer
You have to create layout sales_order_view and create block in container reference of order_totals.
Block for order_totals
Here i add custom field in order_totals reference block.