0

I have created a module which is used to send order information as attachment in order email like invoice attachment in invoice mail. I got order attachment in order email but I can't get Order items information in attachment. When I went through the process, I got order template variables of type interceptor like get_class(vars['order']) = Magento\Sales\Model\Order\Interceptor. So, How could I get template variable as type of order model.

Here, is my Code...

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Mail\Template\TransportBuilder">
        <plugin name="vendor_order_invoice_attachment" type="Vendor\OrderInvoiceAttachment\Plugin\SendAttachment" sortOrder="1" disabled="false"/>
    </type>
    <type name="Magento\Framework\Mail\MimeMessage">
        <plugin name="vendor-attachment-mimemessage" type="Vendor\OrderInvoiceAttachment\Plugin\MimeMessage"/>
    </type>
</config>

SendAttachment.php

<?php

namespace Vendor\OrderInvoiceAttachment\Plugin;

use Magento\Framework\App\RequestInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory;

class SendAttachment
{
    public $attachmentManager;
    public function __construct(
        \Vendor\OrderInvoiceAttachment\Model\AttachmentManager $attachmentManager
    )
    {
        $this->attachmentManager = $attachmentManager;
    }

    public function beforeSetTemplateIdentifier($subject, $templateId)
    {
        $this->attachmentManager->resetParts();
        $this->attachmentManager->setTemplateId($templateId);
        return [$templateId];
    }

    public function beforeSetTemplateVars($subject, $templateVars)
    {
        $this->attachmentManager->setTemplateVars($templateVars);
        return [$templateVars];
    }
}

AttachmentManager.php

<?php

namespace Vendor\OrderInvoiceAttachment\Model;

use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Container\InvoiceIdentity;
use Magento\Sales\Model\Order\Email\Container\OrderIdentity;

class AttachmentManager
{
    public $scopeConfig;

    public $invoicePdf;
    public $orderPdf;

    public $mimePartInterfaceFactory;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Sales\Model\Order\Pdf\Invoice $invoicePdf,
        \Magento\Framework\Mail\MimePartInterfaceFactory $mimePartInterfaceFactory,
        \Vendor\OrderInvoiceAttachment\Model\OrderPdf $orderPdf
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->invoicePdf = $invoicePdf;
        $this->orderPdf = $orderPdf;
        $this->mimePartInterfaceFactory = $mimePartInterfaceFactory;
    }

    private $templateId;

    private $templateVars = [];

    private $parts = null;

    public function setTemplateId($templateId)
    {
        $this->templateId = $templateId;
    }

    public function setTemplateVars($templateVars)
    {
        $this->templateVars = $templateVars;
    }

    public function getTemplateId()
    {
        return $this->templateId;
    }

    public function getTemplateVars()
    {
        return $this->templateVars;
    }

    public function resetParts()
    {
        $this->parts = null;
    }

    public function getParts()
    {
        return $this->parts;
    }

    public function addPart($part)
    {
        $this->parts[] = $part;
    }

    public function collectParts()
    {
        $this->parts = [];
        if ($this->templateId === 'sales_email_order_template') {
            $orderTemplateId = $this->getConfigValue(
                OrderIdentity::XML_PATH_EMAIL_TEMPLATE,
                $this->getStoreId()
            );

            $guestOrderTemplateId = $this->getConfigValue(
                OrderIdentity::XML_PATH_EMAIL_GUEST_TEMPLATE,
                $this->getStoreId()
            );

            switch ($this->getTemplateId()) {
                case $orderTemplateId:
                case $guestOrderTemplateId:
                    $this->attachOrderPDF();
                    break;
            }
        }
        else if ($this->templateId === 'sales_email_invoice_template') {
            $invoiceTemplateId = $this->getConfigValue(
                InvoiceIdentity::XML_PATH_EMAIL_TEMPLATE,
                $this->getStoreId()
            );

            $guestInvoiceTemplateId = $this->getConfigValue(
                InvoiceIdentity::XML_PATH_EMAIL_GUEST_TEMPLATE,
                $this->getStoreId()
            );

            switch ($this->getTemplateId()) {
                case $invoiceTemplateId:
                case $guestInvoiceTemplateId:
                    $this->attachInvoicePDF();
                    break;
            }
        }
    }

    public function getStoreId()
    {
        $vars = $this->getTemplateVars();
        if (!isset($vars['store'])) {
            return null;
        }

        $store = $vars['store'];
        return $store->getId();
    }

    public function getConfigValue($path, $store = null)
    {
        return $configValue = $this->scopeConfig->getValue(
            $path,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $store
        );
    }

    public function attachInvoicePDF()
    {
        $vars = $this->getTemplateVars();
        $invoice = $vars['invoice'];

        $fileContent = $this->invoicePdf->getPdf([$invoice])->render();
        $fileName = 'invoice.pdf';

        $attachmentPart = $this->mimePartInterfaceFactory->create(
            [
                'content' => $fileContent,
                'type' => 'application/pdf',
                'fileName' => $fileName,
                'disposition' => \Zend_Mime::DISPOSITION_ATTACHMENT,
                'encoding' => \Zend_Mime::ENCODING_BASE64
            ]
        );

        $this->addPart($attachmentPart);
    }
    public function attachOrderPDF()
    {
        $vars = $this->getTemplateVars();
        $order = $vars['order'];
        $fileContent = $this->orderPdf->getPdf([$order])->render();
        $fileName = 'order.pdf';

        $attachmentPart = $this->mimePartInterfaceFactory->create(
            [
                'content' => $fileContent,
                'type' => 'application/pdf',
                'fileName' => $fileName,
                'disposition' => \Zend_Mime::DISPOSITION_ATTACHMENT,
                'encoding' => \Zend_Mime::ENCODING_BASE64
            ]
        );

        $this->addPart($attachmentPart);
    }
}

OrderPdf.php

<?php
namespace Vendor\OrderInvoiceAttachment\Model;


use Magento\Sales\Model\Order\Pdf\AbstractPdf;
use Magento\Sales\Model\Order\Pdf\Config;
use Magento\Sales\Model\OrderFactory;
use Magento\TestFramework\ObjectManager;

class OrderPdf extends AbstractPdf
{

    protected $_localeResolver;
    protected $_storeManager;
    protected $factory;

    public function __construct(
        \Magento\Payment\Helper\Data $paymentData,
        \Magento\Framework\Stdlib\StringUtils $string,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Filesystem $filesystem,
        Config $pdfConfig,
        \Magento\Sales\Model\Order\Pdf\Total\Factory $pdfTotalFactory,
        \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
        \Magento\Sales\Model\Order\Address\Renderer $addressRenderer,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Locale\ResolverInterface $localeResolver,
        array $data = []
    ) {
        $this->_storeManager = $storeManager;
        $this->_localeResolver = $localeResolver;
        parent::__construct(
            $paymentData,
            $string,
            $scopeConfig,
            $filesystem,
            $pdfConfig,
            $pdfTotalFactory,
            $pdfItemsFactory,
            $localeDate,
            $inlineTranslation,
            $addressRenderer,
            $data
        );
    }

    protected function _drawHeader(\Zend_Pdf_Page $page)
    {
        /* Add table head */
        $this->_setFontRegular($page, 10);
        $page->setFillColor(new \Zend_Pdf_Color_Rgb(0.93, 0.92, 0.92));
        $page->setLineColor(new \Zend_Pdf_Color_GrayScale(0.5));
        $page->setLineWidth(0.5);
        $page->drawRectangle(25, $this->y, 570, $this->y - 15);
        $this->y -= 10;
        $page->setFillColor(new \Zend_Pdf_Color_Rgb(0, 0, 0));

        //columns headers
        $lines[0][] = ['text' => __('Products'), 'feed' => 35];

        $lines[0][] = ['text' => __('SKU'), 'feed' => 290, 'align' => 'right'];

        $lines[0][] = ['text' => __('Qty'), 'feed' => 435, 'align' => 'right'];

        $lines[0][] = ['text' => __('Price'), 'feed' => 360, 'align' => 'right'];

        $lines[0][] = ['text' => __('Tax'), 'feed' => 495, 'align' => 'right'];

        $lines[0][] = ['text' => __('Subtotal'), 'feed' => 565, 'align' => 'right'];

        $lineBlock = ['lines' => $lines, 'height' => 5];

        $this->drawLineBlocks($page, [$lineBlock], ['table_header' => true]);
        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
        $this->y -= 20;
    }


    public function getPdf($orders = [])
    {
        $this->_beforeGetPdf();
        $this->_initRenderer('invoice');

        $pdf = new \Zend_Pdf();
        $this->_setPdf($pdf);
        $style = new \Zend_Pdf_Style();
        $this->_setFontBold($style, 10);

        foreach ($orders as $order) {
            if ($order->getStoreId()) {
                $this->_localeResolver->emulate($order->getStoreId());
                $this->_storeManager->setCurrentStore($order->getStoreId());
            }
            $page = $this->newPage();
            /* Add image */
            $this->insertLogo($page, $order->getStore());
            /* Add address */
            $this->insertAddress($page, $order->getStore());
            /* Add head */
            $this->insertOrder(
                $page,
                $order,
                $this->_scopeConfig->isSetFlag(
                    self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID,
                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
                    $order->getStoreId()
                )
            );
            /* Add document text and number */
            $this->insertDocumentNumber($page, __('Order # ') . $order->getIncrementId());
            /* Add table */
            $this->_drawHeader($page);
            /* Add body */
            foreach ($order->getAllItems() as $item) {
                if ($item->getOrderItem()->getParentItem()) {
                    continue;
                }
                /* Draw item */
                $this->_drawItem($item, $page, $order);
                $page = end($pdf->pages);
            }
            /* Add totals */
            $this->insertTotals($page, $order);
            if ($order->getStoreId()) {
                $this->_localeResolver->revert();
            }
        }
        $this->_afterGetPdf();
        return $pdf;
    }

    public function newPage(array $settings = [])
    {
        /* Add new table head */
        $page = $this->_getPdf()->newPage(\Zend_Pdf_Page::SIZE_A4);
        $this->_getPdf()->pages[] = $page;
        $this->y = 800;
        if (!empty($settings['table_header'])) {
            $this->_drawHeader($page);
        }
        return $page;
    }
}

1 Answer 1

0

Override \Magento\Framework\Mail\Template\TransportBuilder in 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">
    <preference for="\Magento\Framework\Mail\Template\TransportBuilder" type="TM\ShipmentEmail\Model\Mail\Template\TransportBuilder" />
</config>

Define this constant if you need in overrides file and add following data

const MIME_TYPES = [
        'png' => 'image/png',
        'jpg' => 'image/jpg'
    ];
    
  //check file type  
protected function prepareMessage()
{
$snapshotFileTypes = self::MIME_TYPES[ (string) substr($snapshot, strrpos($snapshot, '.') + 1); ];

 //call for attachment in custom function    
        $this->addAttachment(file_get_contents($fullSnapshotPath), $endSnap, $snapshotFileType );
}
       // finally add attachment in this funtion

        public function addAttachment(?string $content, ?string $fileName, ?string $fileType)
        {
            $attachmentPart = $this->partFactory->create();
            $attachmentPart->setContent($content)
                ->setType($fileType)
                ->setFileName($fileName)
                ->setDisposition(Mime::DISPOSITION_ATTACHMENT)
                ->setEncoding(Mime::ENCODING_BASE64);
            $this->attachments[] = $attachmentPart;
    
            return $this;
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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