How To

How to Show Order Comments on the Invoice in Magento 2

Hello Magento folks,

I hope that the holidays are going great for you and your Magento store.

Last, We have learned about how you can Restrict Customers/Visitors to Access The Category Page on your website and redirect them to another page.

Today, I am going to explain to you how you can show the order comments on the invoice for Magento 2.

Many times, customers have purchased a product from your website and adds order comments. Admin can view that order comments of customers from the order view page. But there is no option to show those comments in the invoice generated in the back-end or in the form of PDF. This sometimes leads to blunders when delivering the order, which makes customers unsatisfied with the orders and your store.

To make this happen, we have developed a code for your Magento 2 store. These codes, if used, will ease your work and will show the order comments in the invoice and PDF. Thus, saving you from making any blunder and you will have more than a satisfied and happy customer, which is the key to success for any Ecommerce store.

1. First, you need to add di.xml file at the following path:

app\code\Vendor\Extension\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 for="Magento\Sales\Model\Order\Pdf\Invoice" type="Vendor\Extension\Model\Rewrite\Order\Pdf\Invoice" />
</config>

2. Now, you need to add Invoice.php at the following path:

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

<?php
namespace Vendor\Extension\Model\Rewrite\Order\Pdf;

use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection;
use Magento\Sales\Model\Order\Pdf\AbstractPdf;
use Magento\Sales\Model\Order\Pdf\Config;
use Magento\Sales\Model\Order\Pdf\Invoice as MagentoInvoice;

class Invoice extends MagentoInvoice
{

    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' => 375, '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($invoices = [])
    {
        $this->_beforeGetPdf();
        $this->_initRenderer('invoice');

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

        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());
            /* 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();
            }

            foreach ($invoice->getOrder()->getStatusHistoryCollection() as $status){
                $textChunk = wordwrap(strip_tags($status->getComment()), 120, "\n");
                foreach(explode("\n", $textChunk) as $textLine){
                    if ($textLine!=='') {
                        $page->drawText(strip_tags(ltrim($textLine)), 35, $this->y, 'UTF-8');
                        $this->y -= 15;
                    }
                }
            }
        }
        $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;
    }
}

3. Now, you need to create sales_order_invoice_view.xml file at the following path:

app\code\Vendor\Extension\view\adminhtml\layout\sales_order_invoice_view.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">
    <body>
        <referenceBlock name="order_comments">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Vendor_Extension::order/comments/view.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

4. Now You need to create view.phtml in the following path:

app\code\Vendor\Extension\view\adminhtml \templates\order\comments\ view.phtml

<?php if ($_entity = $block->getEntity()): ?>
    <div id="comments_block" class="edit-order-comments">
        <div class="order-history-block">
            <div class="admin__field field-row">
                <label class="admin__field-label"
                       for="history_comment"><?= /* @escapeNotVerified */ __('Comment Text') ?></label>
                <div class="admin__field-control">
                <textarea name="comment[comment]"
                          class="admin__control-textarea"
                          rows="3"
                          cols="5"
                          id="history_comment"></textarea>
                </div>
            </div>
            <div class="admin__field">
                <div class="order-history-comments-options">
                    <?php if ($block->canSendCommentEmail()): ?>
                        <div class="admin__field admin__field-option">
                            <input name="comment[is_customer_notified]"
                                   type="checkbox"
                                   class="admin__control-checkbox"
                                   id="history_notify"
                                   value="1" />
                            <label class="admin__field-label"
                                   for="history_notify"><?= /* @escapeNotVerified */ __('Notify Customer by Email') ?></label>
                        </div>
                    <?php endif; ?>
                    <div class="admin__field admin__field-option">
                        <input name="comment[is_visible_on_front]"
                               type="checkbox"
                               id="history_visible"
                               class="admin__control-checkbox"
                               value="1" />
                        <label class="admin__field-label"
                               for="history_visible"> <?= /* @escapeNotVerified */ __('Visible on Storefront') ?></label>
                    </div>
                </div>
                <div class="order-history-comments-actions">
                    <?= $block->getChildHtml('submit_button') ?>
                </div>
            </div>
        </div>

        <h3> Order Comments </h3>
        <ul class="note-list">
            <?php foreach ($_entity->getOrder()->getStatusHistoryCollection() as $status): ?>
                <?php  if ($status->getComment()): ?>
                    <span class="note-list-date"><?= /* @noEscape */ $block->formatDate($status->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
                    <span class="note-list-time"><?= /* @noEscape */ $block->formatTime($status->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
                    <span class="note-list-customer">
                <?= /* @escapeNotVerified */ __('Customer') ?>
                        <?php if ($status->getIsCustomerNotified()): ?>
                            <span class="note-list-customer-notified"><?= /* @escapeNotVerified */ __('Notified') ?></span>
                        <?php else: ?>
                            <span class="note-list-customer-not-notified"><?= /* @escapeNotVerified */ __('Not Notified') ?></span>
                        <?php endif; ?>
            </span>
                    <div class="note-list-comment"><?= $block->escapeHtml($status->getComment(), ['b', 'br', 'strong', 'i', 'u', 'a']) ?></div>
                <?php endif; ?>
            <?php endforeach; ?>
        </ul>
        <h3> Invoice Comments </h3>
        <ul class="note-list">
            <?php foreach ($_entity->getCommentsCollection(true) as $_comment): ?>
                <li>
                    <span class="note-list-date"><?= /* @noEscape */ $block->formatDate($_comment->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
                    <span class="note-list-time"><?= /* @noEscape */ $block->formatTime($_comment->getCreatedAt(), \IntlDateFormatter::MEDIUM) ?></span>
                <span class="note-list-customer">
                    <?= /* @escapeNotVerified */ __('Customer') ?>
                    <?php if ($_comment->getIsCustomerNotified()): ?>
                        <span class="note-list-customer-notified"><?= /* @escapeNotVerified */ __('Notified') ?></span>
                    <?php else: ?>
                        <span class="note-list-customer-not-notified"><?= /* @escapeNotVerified */ __('Not Notified') ?></span>
                    <?php endif; ?>
                </span>
                    <div class="note-list-comment"><?= $block->escapeHtml($_comment->getComment(), ['b', 'br', 'strong', 'i', 'u', 'a']) ?></div>
                </li>
            <?php endforeach; ?>
        </ul>
    </div>
    <script>
        require(['prototype'], function(){

            submitComment = function() {
                submitAndReloadArea($('comments_block').parentNode, '<?= /* @escapeNotVerified */ $block->getSubmitUrl() ?>')
            }

            if ($('submit_comment_button')) {
                $('submit_comment_button').observe('click', submitComment);
            }

        });
    </script>
<?php endif; ?>

So, using these codes, you will be able to show the order comments in the invoice as well as in PDF also. If you like this article, then share this with your Magneto friends and colleagues. Also, let us know the thoughts in the comments below. If something goes wrong while implementing the codes, then you can contact our support desk at any time, and we will be happy to help you.

Lastly, We want to wish you Happy New Year 2020 in advance?

Happy Reading?

 

Click to rate this post!
[Total: 7 Average: 5]
Dhiren Vasoya

Dhiren Vasoya is a Director and Co-founder at MageComp, Passionate 🎖️ Certified Magento Developer👨‍💻. He has more than 9 years of experience in Magento Development and completed 850+ projects to solve the most important E-commerce challenges. He is fond❤️ of coding and if he is not busy developing then you can find him at the cricket ground, hitting boundaries.🏏

View Comments

Recent Posts

How to Delete Product Variant in a Shopify Remix App using GraphQL Mutations?

Managing a Shopify store efficiently involves keeping your product catalog organized. This includes removing outdated…

12 mins ago

6 Innovative Tools Revolutionizing E-Commerce Operations

E-commerce has transformed the way consumers shop for products and services and interact with businesses.…

2 days ago

How Upcoming Cookie Changes Will Affect Your E-commerce Website?

The e-commerce world is constantly in flux. New tech and strategies emerge daily to help…

2 days ago

Magento 2: How to Add Header and Footer in Checkout

Hello Magento Friends, In today’s blog, we will discuss adding a header and footer to…

3 days ago

Understanding Flexbox Layout in React Native

Hello React Native Friends, Building a visually appealing and responsive mobile app is crucial in…

5 days ago

HYVÄ Themes Releases: 1.3.6 & 1.3.7 – What’s New

We have brought exciting news for Magento store owners. Hyvä Themes recently released 1.3.6 and…

5 days ago