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 Add Tooltip in Checkout Shipping Field in Magento 2?

Hello Magento Friends, In today’s blog, I will explain How to Add Tooltip in Checkout…

2 days ago

How to Integrate and Use MongoDB with Laravel?

MongoDB is a popular NoSQL database that offers flexibility and scalability when handling modern web…

4 days ago

NodeJS | Callback Function

In NodeJS, callbacks empower developers to execute asynchronous operations like reading files, handling requests, and…

4 days ago

How to Show SKU in Order Summary in Magento 2?

Hello Magento Friends, In today’s blog, we will learn How to Show SKU in Order…

6 days ago

Best Colors to Use for CTA Buttons

The "Buy Now" and "Add to Cart" buttons serve as the primary call-to-action (CTA) elements…

1 week ago

Magento 2: How to Save Custom Field Value to quote_address for Multi-Shipping Orders

Hello Magento Friends, In Magento 2, the checkout process allows customers to choose multiple shipping…

1 week ago