4

I tried to send an invoice email from frontend with pdf attached, by extending InvoiceSender like this:

namespace Namespage\Module\Model\Plugin\Order;

use Magento\Sales\Model\Order\Invoice;
use Magento\Framework\DataObject;
use Magento\Sales\Model\Order;

class InvoiceSender extends \Magento\Sales\Model\Order\Email\Sender\InvoiceSender
{
  public function send(Invoice $invoice, $forceSyncMode = false)
  {
      $invoice->setSendEmail(true);

      if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
          $order = $invoice->getOrder();

          $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

          //start attact pdf invoce
          $pdf = $objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf([$invoice]);
          $date = $objectManager->create('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
          $pdf->render();
          $message = $objectManager->get('Magento\Framework\Mail\Message');
          $message->createAttachment(
              $pdf->render(),
              \Zend_Mime::TYPE_OCTETSTREAM,
              \Zend_Mime::DISPOSITION_ATTACHMENT,
              \Zend_Mime::ENCODING_BASE64,
              'invoice-'.$invoice->getId().'.pdf'
          );
          //end attach pdf invoce

          $transport = [
              'order' => $order,
              'invoice' => $invoice,
              'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '',
              'billing' => $order->getBillingAddress(),
              'payment_html' => $this->getPaymentHtml($order),
              'store' => $order->getStore(),
              'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
              'formattedBillingAddress' => $this->getFormattedBillingAddress($order)
          ];
          $transportObject = new DataObject($transport);

          /**
           * 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;
          }
          return true;
      } else {
          $invoice->setEmailSent(null);
          $this->invoiceResource->saveAttribute($invoice, 'email_sent');
      }

      $this->invoiceResource->saveAttribute($invoice, 'send_email');

      return false;
  }

  protected function checkAndSend(Order $order)
  {
      $this->identityContainer->setStore($order->getStore());
      $this->prepareTemplate($order);

      /** @var SenderBuilder $sender */
      $sender = $this->getSender();

      try {
          $sender->send();
          $sender->sendCopyTo();
      } catch (\Exception $e) {
          $this->logger->error($e->getMessage());
      }

      return true;
  }
}

the problem seems occure when getPdf(...) function being called, and shows an error like this:

1 exception(s): Exception #0 (Magento\Framework\Exception\ValidatorException): Invalid template file: 'Magento_OfflinePayments::info/pdf/checkmo.phtml' in module: 'Magento_OfflinePayments' block's name: 'info\checkmo_0'

Exception #0 (Magento\Framework\Exception\ValidatorException): Invalid template file: 'Magento_OfflinePayments::info/pdf/checkmo.phtml' in module: 'Magento_OfflinePayments' block's name: 'info\checkmo_0'

1

Magento_OfflinePayments::info/pdf/checkmo.phtml file cannot be found.

This is due to a Core bug in 2.1, 2.2, maybe 2.3. Create a plugin to fix it :

  • In app\code\Namespace\Module\etc\di.xml

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\OfflinePayments\Block\Info\Checkmo">
            <plugin name="namespaceModuleCheckmo" 
                type="Namespace\Module\Plugin\Block\Info\CheckmoPlugin"
                sortOrder="1" 
            />
        </type>
    </config>
    
  • In app\code\Namespace\Module\Plugin\Block\Info\CheckmoPlugin.php

    <?php
    
    namespace Namespace\Module\Plugin\Block\Info;
    
    /**
     * Class CheckmoPlugin
     * @package Namespace\Module\Plugin\Block\Info
     */
    class CheckmoPlugin {
        /**
         * @param \Magento\OfflinePayments\Block\Info\Checkmo $subject
         * @param callable $proceed
         * @return \Magento\Framework\Phrase
         */
        public function aroundToPdf(\Magento\OfflinePayments\Block\Info\Checkmo $subject, callable $proceed) {
            return __('Check / Money order');
        }
    }
    
  • Finally, in command line :

    php bin/magento setup:di:compile
    php bin/magento setup:upgrade
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.