当前位置: 技术文章>> Magento 2:如何在订单电子邮件中添加下载发票按钮?

文章标题:Magento 2:如何在订单电子邮件中添加下载发票按钮?
  • 文章分类: Magento
  • 18885 阅读
系统学习magento二次开发,推荐小册:《Magento中文全栈二次开发 》

本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。


在Magento 2中的订单电子邮件中添加下载发票按钮的步骤:

步骤1:首先,转到以下文件路径

app\code\Vendor\Extension\view\frontend\layout\sales_email_order_items.xml

然后添加代码,如下所示

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Email Order Items List" design_abstraction="custom">
    <body>
        <referenceBlock name="items">
            <action method="setTemplate">
                <argument name="template" translate="true" xsi:type="string">Vendor_Extension::email/items.phtml</argument>
            </action>
        </referenceBlock>      
    </body>
</page>

步骤2:接下来,移至文件路径,如下所示

app\code\Vendor\Extension\view\frontend\templates\email\items.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
 
// phpcs:disable Magento2.Templates.ThisInTemplate
 
/** @var $block \Magento\Sales\Block\Order\Email\Items */
?>
<?php $_order = $block->getOrder() ?>
<?php if ($_order) : ?>
    <?php $_items = $_order->getAllItems(); ?>
        <?php foreach ($_items as $_item) : ?>
            <?php if (!$_item->getParentItem()) : ?>
                    <?= $block->getItemHtml($_item) ?>
            <?php endif; ?>
        <?php endforeach; ?>
        <tr>
            <td style="font-size: 18px;font-weight: bold;border-bottom: 1px solid #ccc;padding-bottom: 10px;font-family: Arial, Helvetica, sans-serif;">
                Order Total
            </td>
        </tr>
 
        <tr class="order-totals">
            <?= $block->getChildHtml('order_totals') ?>
        </tr>
       <?php if(count($_order->getInvoiceCollection())):
        $objectManager =  \Magento\Framework\App\ObjectManager::getInstance(); 
 
        $storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
        $store = $storeManager->getStore();
        $baseUrl = $store->getBaseUrl();
        ?>
        <tr>
            <td style="text-align: center;font-family: Arial, Helvetica, sans-serif;">
                <a href="<?= $baseUrl ?>emailcustomisation/invoice/printinvoice/order_id/<?= $_order->getId() ?>" class="download" >Download
                </a>
            </td>
        </tr>
        <?php endif; ?>
    <?php if ($this->helper(\Magento\GiftMessage\Helper\Message::class)
            ->isMessagesAllowed('order', $_order, $_order->getStore())
        && $_order->getGiftMessageId()
    ) : ?>
        <?php $_giftMessage = $this->helper(\Magento\GiftMessage\Helper\Message::class)
            ->getGiftMessage($_order->getGiftMessageId()); ?>
        <?php if ($_giftMessage) : ?>
            <br />
            <table class="message-gift">
                <tr>
                    <td>
                        <h3><?= $block->escapeHtml(__('Gift Message for this Order')) ?></h3>
                        <strong><?= $block->escapeHtml(__('From:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getSender()) ?>
                        <br /><strong><?= $block->escapeHtml(__('To:')) ?></strong> <?= $block->escapeHtml($_giftMessage->getRecipient()) ?>
                        <br /><strong><?= $block->escapeHtml(__('Message:')) ?></strong>
                        <br /><?= $block->escapeHtml($_giftMessage->getMessage()) ?>
                    </td>
                </tr>
            </table>
        <?php endif; ?>
    <?php endif; ?>
<?php endif; ?>

步骤3:现在导航到以下文件路径

app\code\Vendor\Extension\etc\frontend\routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="yourrouteid" frontName="yourfrountname">
            <module name="Vendor_Extension" />
        </route>
    </router>
</config>

步骤4:接下来,您需要转到下面提到的文件路径

app\code\Vendor\Extension\Controller\Invoice\Printinvoice.php

<?php
 
namespace Vendor\Extension\Controller\Invoice;
 
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
 
class Printinvoice extends \Magento\Framework\App\Action\Action
{
    /**
     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Magento_Sales::sales_invoice';
 
    /**
     * @var \Magento\Framework\App\Response\Http\FileFactory
     */
    protected $_fileFactory;
 
    /**
     * @var \Magento\Backend\Model\View\Result\ForwardFactory
     */
    protected $resultForwardFactory;
 
    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
     * @param \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory,
        \Magento\Sales\Model\OrderFactory $order)
    {
        $this->_fileFactory = $fileFactory;
        parent::__construct($context);
        $this->resultForwardFactory = $resultForwardFactory;
        $this->order = $order;
    }
 
    /**
     * @return ResponseInterface|void
     * @throws \Exception
     */
    public function execute()
    {
       $orderId = $this->getRequest()->getParam('order_id');
       $orderdetails = $this->order->create()->load($orderId);
        $invoiceId = 0;
        foreach ($orderdetails->getInvoiceCollection() as $invoice)
        {
            $invoiceId = $invoice->getId();
        }
        if ($invoiceId != 0)
        {
            $invoice = $this->_objectManager->create(
                \Magento\Sales\Api\InvoiceRepositoryInterface::class
            )->get($invoiceId);
            if ($invoice)
            {
                $pdf = $this->_objectManager->create(\Magento\Sales\Model\Order\Pdf\Invoice::class)->getPdf([$invoice]);
                $date = $this->_objectManager->get(
                    \Magento\Framework\Stdlib\DateTime\DateTime::class
                )->date('Y-m-d_H-i-s');
                $fileContent = ['type' => 'string', 'value' => $pdf->render(), 'rm' => true];
 
                return $this->_fileFactory->create(
                    'invoice' . $date . '.pdf',
                    $fileContent,
                    DirectoryList::VAR_DIR,
                    'application/pdf'
                );
            }
        }
        else
        {
            return;
            return $this->resultForwardFactory->create()->forward('noroute');
        }
    }
}

步骤5:在此步骤中,移至以下文件路径

app\code\Vendor\Extension\Model\Order\Pdf\Invoice.php

<?php
 
namespace Vendor\Extension\Model\Order\Pdf;
 
use PHPQRCode\QRcode;
 
class Invoice extends \Magento\Sales\Model\Order\Pdf\Invoice
{
    protected function _setFontBold($object, $size = 7)
    {
        $font = \Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }
 
    public function newPage(array $settings = [])
    {
        $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;
    }
 
    protected function _drawHeader(\Zend_Pdf_Page $page)
    {
        $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));
 
        $taxableAmountText = $this->string->split('Taxable Amount', 8);
        $lines[0][] = ['text' => __('Products'), 'feed' => 35];
       
        $lines[0][] = ['text' => __('Qty'), 'feed' => 150, 'align' => 'right'];
 
        $lines[0][] = ['text' => __('Price'), 'feed' => 185, 'align' => 'right'];
 
        $lines[0][] = ['text' => __('Subtotal'), 'feed' => 235, 'align' => 'right'];
        $lines[0][] = ['text' => __('Discount'), 'feed' => 290, 'align' => 'right'];
 
        $lines[0][] = ['text' => __('Tax Amt'), 'feed' => 345, 'align' => 'right'];
        $lines[0][] = ['text' => __('Custom'), 'feed' => 400, 'align' => 'right'];
   
        $lines[0][] = ['text' => __('Row Total'), 'feed' => 570, 'align' => 'right'];
 
        $lineBlock = ['lines' => $lines, 'height' => 5, $this->y];
 
        $this->drawLineBlocks($page, [$lineBlock], ['table_header' => true]);
        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
        $this->y -= 20;
    }
 
    protected function _setFontRegular($object, $size = 7)
    {
        $font = \Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }
 
   protected function _drawFooter(\Zend_Pdf_Page $page)
   {
        $this->_setFontRegular($page, 10);
        $this->y -= 10;
        $page->setFillColor(new \Zend_Pdf_Color_RGB(0, 0, 0));
    }
    protected function _setFontItalic($object, $size = 7)
    {
        $font = \Zend_Pdf_Font::fontWithPath($this->getFontPath());
        $object->setFont($font, $size);
        return $font;
    }
}

步骤6:最后,转到以下文件路径

app\code\Vendor\Extension\Model\Sales\Order\Pdf\Items\Invoice.php

<?php
namespace Vendor\Extension\Model\Sales\Order\Pdf\Items;
use Magento\Bundle\Model\Sales\Order\Pdf\Items\Invoice as InvoiceDefualt;
class Invoice extends InvoiceDefualt
{
    public function draw()
    {
 $draw = $this->drawChildrenItems();
         $draw = $this->drawCustomOptions($draw);
 $page = $this->getPdf()->drawLineBlocks($this->getPage(), $draw, ['table_header' => true]);
 $this->setPage($page);
    }
    private function drawChildrenItems(): array
    {
        $this->_setFontRegular();
        $prevOptionId = '';
        $drawItems = [];
        $optionId = 0;
        $lines = [];
        foreach ($this->getChildren($this->getItem()) as $childItem)
        {
            $index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0;
            $attributes = $this->getSelectionAttributes($childItem);
            if (is_array($attributes))
            {
                $optionId = $attributes['option_id'];
            }
            if (!isset($drawItems[$optionId]))
            {
                $drawItems[$optionId] = ['lines' => [], 'height' => 15];
            }
            if ($childItem->getOrderItem()->getParentItem() && $prevOptionId != $attributes['option_id'])
            {
                $lines[$index][] = [
                    'font' => 'italic',
                    'text' => $this->string->split($attributes['option_label'], 35, true, true),
                    'feed' => 35,
                ];
                $index++;
                $prevOptionId = $attributes['option_id'];
            }
            if ($childItem->getOrderItem()->getParentItem())
            {
                $feed = 30;
                $name = $this->getValueHtml($childItem)."<br /> SKU :".$childItem- >getSku();
            }
            else
            {
                $feed = 25;
                $name = $childItem->getName();
            }
            $lines[$index][] = ['text' => $this->string->split($name, 15, true, true), 'feed' => $feed];
            if ($this->canShowPriceInfo($childItem))
            {
             $tax = $this->getOrder()->formatPriceTxt($childItem->getTaxAmount());
             $item = $this->getItem();
             $this->_item = $childItem;
             $feedPrice = 140;
             $feedSubtotal = $feedPrice + 185;
             foreach ($this->getItemPricesForDisplay() as $priceData)
             {
                 if (isset($priceData['label']))
                 {
                     // draw Price label
                     $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right'];
 
                     // draw Subtotal label
                     $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right'];
                     $index++;
                 }
                 $lines[$index][] = [
                     'text' => round($childItem->getQty(), 2),
                     'feed' => $feedPrice,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
                 // draw Price
                 $lines[$index][] = [
                     'text' => $priceData['price'],
                     'feed' => $feedPrice+40,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
                 // draw Subtotal
                 $lines[$index][] = [
                     'text' => $priceData['subtotal'],
                     'feed' => $feedPrice+90,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
                 $lines[$index][] = [
                     'text' => round($childItem->getDiscountAmount(), 2),
                     'feed' => $feedPrice+130,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
 
                 $lines[$index][] = [
                     'text' => $tax,
                     'feed' => $feedPrice+200,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
                 $lines[$index][] = [
                 'text' => "Custom",
                 'feed' => $feedPrice+260,
                 'font' => 'bold',
                 'align' => 'right',
                 ];
                 $lines[$index][] = [
                     'text' => $this->getOrder()->formatPriceTxt($childItem->getRowTotal()+$childItem->getTaxAmount()),
                     'feed' => $feedSubtotal+230,
                     'font' => 'bold',
                     'align' => 'right',
                 ];
                 $index++;
             }
             $this->_item = $item;
         }
         /* drawPrices End */
        }
        $drawItems[$optionId]['lines'] = $lines;
        return $drawItems;
    }
 
    private function drawCustomOptions(array $draw): array
    {
        $options = $this->getItem()->getOrderItem()->getProductOptions();
        if ($options && isset($options['options']))
        {
            foreach ($options['options'] as $option)
            {
                $lines = [];
                $lines[][] = [
                    'text' => $this->string->split(
                        $this->filterManager->stripTags($option['label']),
                        40,
                        true,
                        true
                    ),
                    'font' => 'italic',
                    'feed' => 35,
                ];
                if ($option['value'])
                {
                    $text = [];
                    $printValue = $option['print_value'] ?? $this->filterManager->stripTags($option['value']);
                    $values = explode(', ', $printValue);
                    foreach ($values as $value)
                    {
                        foreach ($this->string->split($value, 30, true, true) as $subValue)
                        {
                            $text[] = $subValue;
                        }
                    }
                    $lines[][] = ['text' => $text, 'feed' => 40];
                }
                $draw[] = ['lines' => $lines, 'height' => 15];
            }
        }
        return $draw;
    }
}

步骤7:最后,运行以下命令

php bin/magento cache:flush
php bin/magento setup:di:compile

结论:

借助上述步骤,您可以轻松添加下载发票按钮来订购电子邮件并改善用户体验。


推荐文章