I tried to override InvoiceSender (in /app/code/UFS/Sales/Model/Order/Email/Sender/InvoiceSender.php) but it doesn’t work and I don’t understand why. I added “‘created_at_formatted’ => $order->getCreatedAtFormatted(3)”.
My di.xml looks like:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="MagentoSalesModelOrderEmailSender" type="UFSSalesModelOrderEmailSender" />
</config>
My InvoiceSender.php looks like:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace MagentoSalesModelOrderEmailSender;
use MagentoFrameworkAppArea;
use MagentoFrameworkAppObjectManager;
use MagentoFrameworkDataObject;
use MagentoFrameworkEventManagerInterface;
use MagentoPaymentHelperData as PaymentHelper;
use MagentoSalesModelOrder;
use MagentoSalesModelOrderAddressRenderer;
use MagentoSalesModelOrderEmailContainerInvoiceIdentity;
use MagentoSalesModelOrderEmailContainerTemplate;
use MagentoSalesModelOrderEmailSender;
use MagentoSalesModelOrderInvoice;
use MagentoSalesModelResourceModelOrderInvoice as InvoiceResource;
use MagentoStoreModelAppEmulation;
/**
* Sends order invoice email to the customer.
*
* @api
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class InvoiceSender extends MagentoSalesModelOrderEmailSender
{
/**
* @var PaymentHelper
*/
protected $paymentHelper;
/**
* @var InvoiceResource
*/
protected $invoiceResource;
/**
* Global configuration storage.
*
* @var MagentoFrameworkAppConfigScopeConfigInterface
*/
protected $globalConfig;
/**
* @var Renderer
*/
protected $addressRenderer;
/**
* Application Event Dispatcher
*
* @var ManagerInterface
*/
protected $eventManager;
/**
* @var Emulation
*/
private $appEmulation;
/**
* @param Template $templateContainer
* @param InvoiceIdentity $identityContainer
* @param OrderEmailSenderBuilderFactory $senderBuilderFactory
* @param PsrLogLoggerInterface $logger
* @param Renderer $addressRenderer
* @param PaymentHelper $paymentHelper
* @param InvoiceResource $invoiceResource
* @param MagentoFrameworkAppConfigScopeConfigInterface $globalConfig
* @param ManagerInterface $eventManager
* @param Emulation|null $appEmulation
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Template $templateContainer,
InvoiceIdentity $identityContainer,
MagentoSalesModelOrderEmailSenderBuilderFactory $senderBuilderFactory,
PsrLogLoggerInterface $logger,
Renderer $addressRenderer,
PaymentHelper $paymentHelper,
InvoiceResource $invoiceResource,
MagentoFrameworkAppConfigScopeConfigInterface $globalConfig,
ManagerInterface $eventManager,
Emulation $appEmulation = null
) {
parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer);
$this->paymentHelper = $paymentHelper;
$this->invoiceResource = $invoiceResource;
$this->globalConfig = $globalConfig;
$this->addressRenderer = $addressRenderer;
$this->eventManager = $eventManager;
$this->appEmulation = $appEmulation ?: ObjectManager::getInstance()->get(Emulation::class);
}
/**
* Sends order invoice email to the customer.
*
* Email will be sent immediately in two cases:
*
* - if asynchronous email sending is disabled in global settings
* - if $forceSyncMode parameter is set to TRUE
*
* Otherwise, email will be sent later during running of
* corresponding cron job.
*
* @param Invoice $invoice
* @param bool $forceSyncMode
* @return bool
* @throws Exception
*/
public function send(Invoice $invoice, $forceSyncMode = false)
{
$this->identityContainer->setStore($invoice->getStore());
$invoice->setSendEmail($this->identityContainer->isEnabled());
if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
$order = $invoice->getOrder();
if ($this->checkIfPartialInvoice($order, $invoice)) {
$order->setBaseSubtotal((float) $invoice->getBaseSubtotal());
$order->setBaseTaxAmount((float) $invoice->getBaseTaxAmount());
$order->setBaseShippingAmount((float) $invoice->getBaseShippingAmount());
}
$this->appEmulation->startEnvironmentEmulation($order->getStoreId(), Area::AREA_FRONTEND, true);
$transport = [
'order' => $order,
'order_id' => $order->getId(),
'invoice' => $invoice,
'invoice_id' => $invoice->getId(),
'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '',
'billing' => $order->getBillingAddress(),
'payment_html' => $this->getPaymentHtml($order),
'store' => $order->getStore(),
'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
'created_at_formatted' => $order->getCreatedAtFormatted(3),
'order_data' => [
'customer_name' => $order->getCustomerName(),
'is_not_virtual' => $order->getIsNotVirtual(),
'email_customer_note' => $order->getEmailCustomerNote(),
'frontend_status_label' => $order->getFrontendStatusLabel()
]
];
$transportObject = new DataObject($transport);
$this->appEmulation->stopEnvironmentEmulation();
/**
* Event argument `transport` is @deprecated. Use `transportObject` instead.
*/
$this->eventManager->dispatch(
'email_invoice_set_template_vars_before',
['sender' => $this, 'transport' => $transportObject->getData(), 'transportObject' => $transportObject]
);
$this->templateContainer->setTemplateVars($transportObject->getData());
if ($this->checkAndSend($order)) {
$invoice->setEmailSent(true);
$this->invoiceResource->saveAttribute($invoice, ['send_email', 'email_sent']);
return true;
}
} else {
$invoice->setEmailSent(null);
$this->invoiceResource->saveAttribute($invoice, 'email_sent');
}
$this->invoiceResource->saveAttribute($invoice, 'send_email');
return false;
}
/**
* Return payment info block as html
*
* @param Order $order
* @return string
* @throws Exception
*/
protected function getPaymentHtml(Order $order)
{
return $this->paymentHelper->getInfoBlockHtml(
$order->getPayment(),
$this->identityContainer->getStore()->getStoreId()
);
}
/**
* Check if the order contains partial invoice
*
* @param Order $order
* @param Invoice $invoice
* @return bool
*/
private function checkIfPartialInvoice(Order $order, Invoice $invoice): bool
{
$totalQtyOrdered = (float) $order->getTotalQtyOrdered();
$totalQtyInvoiced = (float) $invoice->getTotalQty();
return $totalQtyOrdered !== $totalQtyInvoiced;
}
}