Magento – Change order date to invoice date on invoice PDF in Magento 2

dateinvoice-pdfmagento2

How to change the order date in the invoice PDF in Magento 2 to invoice date?
I think it's done in the AbstractPdf.php file, but cannot get the right code to pull the right data.
It's shown in the backend of Magento, how to get it on the PDF?

Best Answer

Title: Change order date to invoice date on invoice PDF in Magento 2

Text: How to change the order date in the invoice PDF in Magento 2 to invoice date?

Are you asking about how to change the text "Order Date" to say "Invoice Date" OR are you asking how to change the actual date value, e.g. "Aug 28, 2019" to reference the actual date the invoice was created?

I will assume you want to change both the text and value. For example, if an order was placed on Aug 4, 2019, but wasn't invoice until today Aug 28, 2019, you want the invoice printed PDF header area to reference when the invoice was created.

Change:

Invoice # INV-7190804364
Order # 7190804364
Order Date: Aug 4, 2019

To:

Invoice # INV-7190804364
Order # 7190804364
Invoice Date: Aug 28, 2019

One way you can make this change is to extend the \Magento\Sales\Model\Order\Pdf\Invoice class in your module. Below is a step-by-step example of how to create a simple module to do what you want.

Step 1: Create module directories

If you are familiar with cmd-line you can create the structure needed with one line:

mkdir -p ./ExampleVendor/InvoicePdfMod/Model/Order/Pdf

If you are creating the folders manually, we need the following dir structure:

./ExampleVendor
./ExampleVendor/InvoicePdfMod
./ExampleVendor/InvoicePdfMod/etc
./ExampleVendor/InvoicePdfMod/Model
./ExampleVendor/InvoicePdfMod/Model/Order
./ExampleVendor/InvoicePdfMod/Model/Order/Pdf

Step 2: Create the 4 files that make up the module

./ExampleVendor/InvoicePdfMod/registration.php
./ExampleVendor/InvoicePdfMod/etc/di.xml
./ExampleVendor/InvoicePdfMod/etc/module.xml
./ExampleVendor/InvoicePdfMod/Model/Order/Pdf/Invoice.php

The first three files are nothing fancy, just the basic stuff that sets up our module. The di.xml is where we tell Magento to use our custom class for the print invoice PDF action.

The registration.php file looks like this:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'ExampleVendor_InvoicePdfMod',
    __DIR__
);

The di.xml file looks 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="ExampleVendor\InvoicePdfMod\Model\Order\Pdf\Invoice" />
</config>

The module.xml file looks like this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="ExampleVendor_InvoicePdfMod" setup_version="0.0.1"/>
</config>

Now, that the basic stuff is setup we move on to the Invoice.php file. This is where we modify what gets printed in the PDF.

To keep things quick, I just copied the vendor\magento\module-sales\Model\Order\Pdf\Invoice.php and added code as needed. Looking at the core mage file, we see that Invoice class extends the AbstractPdf class that you referenced in your initial message. One thing that jumps out when looking at the AbstractPdf class is the method insertOrder that draws the text on invoice PDF. Since the core mage Invoice class uses that method we can just copy-paste that entire method into our custom Invoice class so we can edit it to do what we want.

That said there are two methods we are changing in our new Invoice class, insertOrder and getPdf. insertOrder is where the order number and order date get drawn in the PDF. getPdf is where the invoice number comes from. We are going to comment out some code in the insertOrder method and then add a couple of lines to the getPdf method.

The Invoice.php file looks like this:

<?php
/**
 * Some @Copy text here...
 */
namespace ExampleVendor\InvoicePdfMod\Model\Order\Pdf;

use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection;

/**
 * Sales Order Invoice PDF model
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */

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

    /**
     * Insert order to pdf page
     *
     * @param \Zend_Pdf_Page &$page
     * @param \Magento\Sales\Model\Order $obj
     * @param bool $putOrderId
     * @return void
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    protected function insertOrder(&$page, $obj, $putOrderId = true)
    {
        if ($obj instanceof \Magento\Sales\Model\Order) {
            $shipment = null;
            $order = $obj;
        } elseif ($obj instanceof \Magento\Sales\Model\Order\Shipment) {
            $shipment = $obj;
            $order = $shipment->getOrder();
        }

        $this->y = $this->y ? $this->y : 815;
        $top = $this->y;

        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0.45));
        $page->setLineColor(new \Zend_Pdf_Color_GrayScale(0.45));
        $page->drawRectangle(25, $top, 570, $top - 55);
        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(1));
        $this->setDocHeaderCoordinates([25, $top, 570, $top - 55]);
        $this->_setFontRegular($page, 10);

        if ($putOrderId) {
            $page->drawText(__('Order # ') . $order->getRealOrderId(), 35, $top -= 30, 'UTF-8');
            $top +=15;
        }

        $top -=30;

        // COMMENT OUT THE ORDER DATE HERE, WE WILL PUT INVOICE DATE IN LATER
        /*
        $page->drawText(
            __('Order Date: ') .
            $this->_localeDate->formatDate(
                $this->_localeDate->scopeDate(
                    $order->getStore(),
                    $order->getCreatedAt(),
                    true
                ),
                \IntlDateFormatter::MEDIUM,
                false
            ),
            35,
            $top,
            'UTF-8'
        );
        */

        $top -= 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, $top, 275, $top - 25);
        $page->drawRectangle(275, $top, 570, $top - 25);

        /* Calculate blocks info */

        /* Billing Address */
        $billingAddress = $this->_formatAddress($this->addressRenderer->format($order->getBillingAddress(), 'pdf'));

        /* Payment */
        $paymentInfo = $this->_paymentData->getInfoBlock($order->getPayment())->setIsSecureMode(true)->toPdf();
        $paymentInfo = htmlspecialchars_decode($paymentInfo, ENT_QUOTES);
        $payment = explode('{{pdf_row_separator}}', $paymentInfo);
        foreach ($payment as $key => $value) {
            if (strip_tags(trim($value)) == '') {
                unset($payment[$key]);
            }
        }
        reset($payment);

        /* Shipping Address and Method */
        if (!$order->getIsVirtual()) {
            /* Shipping Address */
            $shippingAddress = $this->_formatAddress(
                $this->addressRenderer->format($order->getShippingAddress(), 'pdf')
            );
            $shippingMethod = $order->getShippingDescription();
        }

        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
        $this->_setFontBold($page, 12);
        $page->drawText(__('Sold to:'), 35, $top - 15, 'UTF-8');

        if (!$order->getIsVirtual()) {
            $page->drawText(__('Ship to:'), 285, $top - 15, 'UTF-8');
        } else {
            $page->drawText(__('Payment Method:'), 285, $top - 15, 'UTF-8');
        }

        $addressesHeight = $this->_calcAddressHeight($billingAddress);
        if (isset($shippingAddress)) {
            $addressesHeight = max($addressesHeight, $this->_calcAddressHeight($shippingAddress));
        }

        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(1));
        $page->drawRectangle(25, $top - 25, 570, $top - 33 - $addressesHeight);
        $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
        $this->_setFontRegular($page, 10);
        $this->y = $top - 40;
        $addressesStartY = $this->y;

        foreach ($billingAddress as $value) {
            if ($value !== '') {
                $text = [];
                foreach ($this->string->split($value, 45, true, true) as $_value) {
                    $text[] = $_value;
                }
                foreach ($text as $part) {
                    $page->drawText(strip_tags(ltrim($part)), 35, $this->y, 'UTF-8');
                    $this->y -= 15;
                }
            }
        }

        $addressesEndY = $this->y;

        if (!$order->getIsVirtual()) {
            $this->y = $addressesStartY;
            foreach ($shippingAddress as $value) {
                if ($value !== '') {
                    $text = [];
                    foreach ($this->string->split($value, 45, true, true) as $_value) {
                        $text[] = $_value;
                    }
                    foreach ($text as $part) {
                        $page->drawText(strip_tags(ltrim($part)), 285, $this->y, 'UTF-8');
                        $this->y -= 15;
                    }
                }
            }

            $addressesEndY = min($addressesEndY, $this->y);
            $this->y = $addressesEndY;

            $page->setFillColor(new \Zend_Pdf_Color_Rgb(0.93, 0.92, 0.92));
            $page->setLineWidth(0.5);
            $page->drawRectangle(25, $this->y, 275, $this->y - 25);
            $page->drawRectangle(275, $this->y, 570, $this->y - 25);

            $this->y -= 15;
            $this->_setFontBold($page, 12);
            $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
            $page->drawText(__('Payment Method'), 35, $this->y, 'UTF-8');
            $page->drawText(__('Shipping Method:'), 285, $this->y, 'UTF-8');

            $this->y -= 10;
            $page->setFillColor(new \Zend_Pdf_Color_GrayScale(1));

            $this->_setFontRegular($page, 10);
            $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));

            $paymentLeft = 35;
            $yPayments = $this->y - 15;
        } else {
            $yPayments = $addressesStartY;
            $paymentLeft = 285;
        }

        foreach ($payment as $value) {
            if (trim($value) != '') {
                //Printing "Payment Method" lines
                $value = preg_replace('/<br[^>]*>/i', "\n", $value);
                foreach ($this->string->split($value, 45, true, true) as $_value) {
                    $page->drawText(strip_tags(trim($_value)), $paymentLeft, $yPayments, 'UTF-8');
                    $yPayments -= 15;
                }
            }
        }

        if ($order->getIsVirtual()) {
            // replacement of Shipments-Payments rectangle block
            $yPayments = min($addressesEndY, $yPayments);
            $page->drawLine(25, $top - 25, 25, $yPayments);
            $page->drawLine(570, $top - 25, 570, $yPayments);
            $page->drawLine(25, $yPayments, 570, $yPayments);

            $this->y = $yPayments - 15;
        } else {
            $topMargin = 15;
            $methodStartY = $this->y;
            $this->y -= 15;

            foreach ($this->string->split($shippingMethod, 45, true, true) as $_value) {
                $page->drawText(strip_tags(trim($_value)), 285, $this->y, 'UTF-8');
                $this->y -= 15;
            }

            $yShipments = $this->y;
            $totalShippingChargesText = "("
                . __('Total Shipping Charges')
                . " "
                . $order->formatPriceTxt($order->getShippingAmount())
                . ")";

            $page->drawText($totalShippingChargesText, 285, $yShipments - $topMargin, 'UTF-8');
            $yShipments -= $topMargin + 10;

            $tracks = [];
            if ($shipment) {
                $tracks = $shipment->getAllTracks();
            }
            if (count($tracks)) {
                $page->setFillColor(new \Zend_Pdf_Color_Rgb(0.93, 0.92, 0.92));
                $page->setLineWidth(0.5);
                $page->drawRectangle(285, $yShipments, 510, $yShipments - 10);
                $page->drawLine(400, $yShipments, 400, $yShipments - 10);
                //$page->drawLine(510, $yShipments, 510, $yShipments - 10);

                $this->_setFontRegular($page, 9);
                $page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
                //$page->drawText(__('Carrier'), 290, $yShipments - 7 , 'UTF-8');
                $page->drawText(__('Title'), 290, $yShipments - 7, 'UTF-8');
                $page->drawText(__('Number'), 410, $yShipments - 7, 'UTF-8');

                $yShipments -= 20;
                $this->_setFontRegular($page, 8);
                foreach ($tracks as $track) {
                    $maxTitleLen = 45;
                    $endOfTitle = strlen($track->getTitle()) > $maxTitleLen ? '...' : '';
                    $truncatedTitle = substr($track->getTitle(), 0, $maxTitleLen) . $endOfTitle;
                    $page->drawText($truncatedTitle, 292, $yShipments, 'UTF-8');
                    $page->drawText($track->getNumber(), 410, $yShipments, 'UTF-8');
                    $yShipments -= $topMargin - 5;
                }
            } else {
                $yShipments -= $topMargin - 5;
            }

            $currentY = min($yPayments, $yShipments);

            // replacement of Shipments-Payments rectangle block
            $page->drawLine(25, $methodStartY, 25, $currentY);
            //left
            $page->drawLine(25, $currentY, 570, $currentY);
            //bottom
            $page->drawLine(570, $currentY, 570, $methodStartY);
            //right

            $this->y = $currentY;
            $this->y -= 15;
        }
    }

    /**
     * Return PDF document
     *
     * @param array|Collection $invoices
     * @return \Zend_Pdf
     */
    public function getPdf($invoices = [])
    {
        $this->_beforeGetPdf();
        $this->_initRenderer('invoice');

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

        // We need to get our $top coordinate again since we are
        // are adding new info
        $this->y = $this->y ? $this->y : 815;
        $top = $this->y;

        foreach ($invoices as $invoice) {
            if ($invoice->getStoreId()) {
                $this->_localeResolver->emulate($invoice->getStoreId());
                $this->_storeManager->setCurrentStore($invoice->getStoreId());
            }
            $page = $this->newPage();
            $order = $invoice->getOrder();
            /* Add image */
            $this->insertLogo($page, $invoice->getStore());
            /* Add address */
            $this->insertAddress($page, $invoice->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, __('Invoice # ') . $invoice->getIncrementId());

            // HERE IS WHERE WE ADD INVOICE createdAt() DATE */
            // The $top is the page coordinate to draw the text at, play with this value as you see fit
            $top -=90;
            // now we draw the invoice date text here
            $page->drawText(
                __('Invoice Date: ') .
                $this->_localeDate->formatDate(
                    $this->_localeDate->scopeDate(
                        $invoice->getStore(),
                        $invoice->getCreatedAt(),
                        true
                    ),
                    \IntlDateFormatter::MEDIUM,
                    false
                ),
                35,
                $top,
                'UTF-8'
            );

            /* Add table */
            $this->_drawHeader($page);
            /* Add body */
            foreach ($invoice->getAllItems() as $item) {
                if ($item->getOrderItem()->getParentItem()) {
                    continue;
                }
                /* Draw item */
                $this->_drawItem($item, $page, $order);
                $page = end($pdf->pages);
            }
            /* Add totals */
            $this->insertTotals($page, $invoice);
            if ($invoice->getStoreId()) {
                $this->_localeResolver->revert();
            }
        }
        $this->_afterGetPdf();
        return $pdf;
    }

    /**
     * Create new page and assign to PDF object
     *
     * @param  array $settings
     * @return \Zend_Pdf_Page
     */
    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;
    }
}

Step 3: Compile and test the module

Magento Developer Page Reference:

https://devdocs.magento.com/extensions/install/

Make sure to clear your mage caches, di, and generation directories, then run the CLI commands to upgrade, compile (and deploy if needed).

An example of how to manually clear all your cache using an SSH connection is below. Be careful because if you do not know what you are doing you can seriously damage your server. Make sure to run the commands from your Magento root install directory and as a user who has permissions to write to the Magento file system.

For example, if your user name was nginx and if Magento was installed to /var/www/html/magento2, the commands would look like the following:

Use at your own risk, ssh commands can be dangerous

Once connected via SSH:

su nginx
cd /var/www/html/magento2
rm -rf ./var/cache/*
rm -rf ./var/page_cache/*
rm -rf ./var/generation/*
rm -rf ./var/di/*
php -f ./bin/magento setup:upgrade
php -f ./bin/magento setup:di:compile
php -f ./bin/magento setup:static-content:deploy -f
php -f ./bin/magento cache:clean

Once that is done, Login to Magento admin area, go to an order and print the invoice to confirm the change is good. It should work from the order list page (Action > Print Invoice) as well as the individual order detail invoice page.

Done!

Additional Notes

You can get creative with the Invoice.php file to include both the Original Order Date, and the invoice date, etc., just need to play around a bit with the insertOrder and getPdf methods and the $top coordinate values for that area.

For example, you could do something like this:

Invoice #                                               Order#
Invoice Date:                                           Order Date:

That's all I got. Let me know if this works for you

Related Topic