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?
2 Answers
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
Thanks for this very detailed help! Created all files and folders through FTP, cleared all caches from the Magento backend.
I did create the files in the root of my server files, is that correct? All new files for the PDF mod are now in ./CUSTOMNAME/InvoicePdfMod/
One thing I need to get more info on is: "Make sure to clear your mage caches, di, and generation directories, then run the CLI commands to upgrade, compile (and deploy if needed)."
The website is running on shared hosting of my hosting provider. I have no access to the backend myselves, so I need to ask my host to do this for me? Any info on what to ask them exactly? I'm still pretty new to this Magento stuff, so excuse the dumb questions :)
Kind regards and thanks again!