2

I'm trying to customize the pdf invoice template, so I want to override the class that generate the pdf.

I found that these class create the pdf:

  • Magento\Sales\Model\Order\Pdf\Invoice.php
  • Magento\Sales\Model\Order\Pdf\AbstractPdf.php
  • Magento\Sales\Model\Order\Pdf\Items\Invoice\DefaultInvoice.php

Then I check in the code and I found that the method I need to override are only in AbstractPdf.php and Invoice.php but the last one extend the abstract class so I decide to override the class Magento\Sales\Model\Order\Pdf\Invoice.php

To override what I need I created a module <Vendor>_<Module> with these files:

<Vendor>_<Module>\registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    '<Vendor>_<Module>',
    __DIR__
);

<Vendor>_<Module>\etc\module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="<Vendor>_<Module>" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Sales"/>
        </sequence>
    </module>
</config>

<Vendor>_<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">
    <preference type="Magento\Sales\Model\Order\Pdf\Invoice" for="<Vendor>\<Module>\Model\Order\Pdf\Invoice"/>
</config>

<Vendor>_<Module>\Model\Order\Pdf\Invoice.php

<?php

namespace <Vendor>\<Module>\Model\Order\Pdf;

use Magento\Sales\Model\Order\Pdf\Config;

class Invoice extends \Magento\Sales\Model\Order\Pdf\Invoice
{

    /**
     * InvoicePdf constructor.
     * @param \Magento\Payment\Helper\Data $paymentData
     * @param \Magento\Framework\Stdlib\StringUtils $string
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Framework\Filesystem $filesystem
     * @param Config $pdfConfig
     * @param \Magento\Sales\Model\Order\Pdf\Total\Factory $pdfTotalFactory
     * @param \Magento\Sales\Model\Order\Pdf\ItemsFactory $pdfItemsFactory
     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
     * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
     * @param array $data
     */
    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 = []
    )
    {
        parent::__construct(
            $paymentData,
            $string,
            $scopeConfig,
            $filesystem,
            $pdfConfig,
            $pdfTotalFactory,
            $pdfItemsFactory,
            $localeDate,
            $inlineTranslation,
            $addressRenderer,
            $storeManager,
            $localeResolver,
            $data
        );
    }

    /**
     * Draw header for item table
     *
     * @param \Zend_Pdf_Page $page
     * @return void
     */
    protected function _drawHeader(\Zend_Pdf_Page $page)
    {
        // my custom code
    }

    public function getPdf($invoices = [])
    {

        // my custom code
    }

    protected function insertOrder(&$page, $obj, $putOrderId = true)
    {
        // my custom code
    }

    /**
     * Return total list
     *
     * @return \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal[] Array of totals
     */
    protected function _getTotalsList()
    {
        // my custom code
    }

    /**
     * Insert totals to pdf page
     *
     * @param  \Zend_Pdf_Page $page
     * @param  \Magento\Sales\Model\AbstractModel $source
     * @return \Zend_Pdf_Page
     */
    protected function insertTotals($page, $source)
    {
        // my custom code
    }

    /**
     * Metodo per ottenere la data dell'ordine
     *
     * @param $order
     * @return string
     */
    protected function getOrderDate($order)
    {
        // my custom code
    }

}

Finally I called these command:

  • php bin/magento module:enable --clear-static-content <Vendor>_<Module>
  • php bin/magento setup:upgrade
  • php bin/magento setup:di:compile
  • php bin/magento cache:flush

But when I go to admin and I tryed to print an invoice I still get the original template. I also tryed to put a die on construct of my custom class, but nothing appends.

  • ,How you resolve error "Fatal error: Uncaught Error: Call to a member function render() on null in vendor/magento/module-sales/Controller/Adminhtml/Invoice/AbstractInvoice/PrintAction.php:59" – akgola Feb 12 '18 at 15:31
  • Have you overriden this file Magento\Sales\Model\Order\Pdf\AbstractPdf.php ? invoice.php file can be override easily but this file not working. – Sarfaraj Sipai Oct 26 '18 at 6:16
2

Use below code for 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\Sales\Model\Order\Pdf\Invoice" type="<Vendor>\<Module>\Model\Order\Pdf\Invoice"/>
</config>

I think you interchanged type and for

1

Check Your di.xml at

Vendor_Module\etc\di.xml

It should like this

<?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\Model\Order\Pdf\Invoice" type="<Vendor>\<Module>\Model\Order\Pdf\Invoice"/>
</config>

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.