6

I am new to Magento. I want to override the new order email template and add custom details in the order email. Please help.

Steps I have done

1. I have created a new email template and assign it to a new order in from the admin panel and a section for custom details. it is working fine. But I don't know how to bind custom value

2. I have created an observer after order success action and save custom data in sales_order against order id.

  public function execute(\Magento\Framework\Event\Observer $observer)
  {
   /* get customer store and restaurant data */
   $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
   $customerSession = $objectManager->get('Magento\Customer\Model\Session');

   $c_id = $customerSession->getCustomer()->getId();
   $c_store_id = $customerSession->getCustomer()->getData('stores');

   $store= $objectManager->get('Vendor\Store\Model\Template');
   $store_name = ($store->load($c_store_id)->getName());
   $store_restaurant_id = ($store->load($c_store_id)->getRestaurantId());

   $restaurant = $objectManager->get('Vendor\Restaurant\Model\Template');
   $restaurant_name = ($restaurant->load($store_restaurant_id)->getName());

    $orderids = $observer->getOrderIds();
    $orderId = ""; 
 
        foreach($orderids as $orderid){
            $order = $this->_order->load($orderid);
                $orderId = $orderid;
        }
    // Here I am saving custom data     
    $order->setData('restaurant_name', $restaurant_name )
            ->setData('res_store_name', $store_name);
  }
3

2 Answers 2

28

(Update 2.3)

use transportObject Use transportObject instead of transport

$this->eventManager->dispatch(
    'email_order_set_template_vars_before',
    ['sender' => $this, 'transport' => $transportObject, 'transportObject' => $transportObject]
);

[Update] Add custom data in order email in Magento 2

At magento2 have an event which fire when order Prepare an email template with variables.

$this->eventManager->dispatch( 'email_order_set_template_vars_before', ['sender' => $this, 'transport' => $transport] );

So, at this event, you can add new parameter via transport to template

Just like: events.xml

<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="email_order_set_template_vars_before">
        <observer name="add_Custom_variable_to_Order" 
            instance="[Vendor]\[ModuleName]\Observer\ObserverforAddCustomVariable" />
    </event>
</config>

Observer file:

<?php
namespace [Vendor]\[ModuleName]\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class ObserverforAddCustomVariable implements ObserverInterface
{

    public function __construct(
    ) {
    }

    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Framework\App\Action\Action $controller */
        $transport = $observer->getTransport();
        $transport['CustomVariable1'] = 'Your Value1 ';
        $transport['CustomVariable2'] = 'Your Value2';
    }
}

At the email template , you can get this custom variables CustomVariable1,CustomVariable2 using {{var CustomVariable1|raw}},{{var CustomVariable2|raw}}

Answer for saving custom data in sales_order at success page

Magento fire an event when a customer goes to order success page the event is :

checkout_onepage_controller_success_action

this event provides order id, So using this event you can save custom data in sales_order against order.

Also, in order save field you need to call repository \Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface and also add save() function for saving the data

   protected    $_orderRepositoryInterface ;
    public function __construct(
    ...
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface
    ....
    ) {
    .......
        $this->_orderRepositoryInterface = $orderRepositoryInterface;
    }
    
    
    public function execute(\Magento\Framework\Event\Observer $observer)
      {
       /* get customer store and restaurant data */
       $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
       $customerSession = $objectManager->get('Magento\Customer\Model\Session');
    
       $c_id = $customerSession->getCustomer()->getId();
       $c_store_id = $customerSession->getCustomer()->getData('stores');
    
       $store= $objectManager->get('Vendor\Store\Model\Template');
       $store_name = ($store->load($c_store_id)->getName());
       $store_restaurant_id = ($store->load($c_store_id)->getRestaurantId());
    
       $restaurant = $objectManager->get('Vendor\Restaurant\Model\Template');
       $restaurant_name = ($restaurant->load($store_restaurant_id)->getName());
    
        $orderids = $observer->getOrderIds();
        $orderId = ""; 
    
            foreach($orderids as $orderid){
                $order = $this->_orderRepositoryInterface->getById($orderid);
                $order->setData('restaurant_name', $restaurant_name )
                     ->setData('res_store_name', $store_name); 
                $order->save()             
            }
        
      
      }
9
  • Amit, I am able to save custom data in sales_order. My question is how to send these data in new order email to customer.
    – Abhishek
    Commented Mar 12, 2017 at 13:46
  • It works for me. But one thing here. I have to create events.xml in etc folder. Earlier it was under etc/frontend folder.
    – Abhishek
    Commented Mar 15, 2017 at 11:10
  • $transport is a \Magento\Framework\DataObject I don't think you can thread it like an array. More like $transport->setCustomVariable1('Hello'); Commented Oct 20, 2017 at 15:15
  • I didn't get the custom variable value in order email templates. Observer is running fine. Commented Oct 31, 2017 at 12:58
  • Observer can not call in order success. @Amit Commented May 18, 2018 at 7:05
0

for get order in this event the next

<?php
namespace RoiUp\Order\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Directory\Model\Country;
use Magento\Directory\Model\CountryFactory;

class AddCountry implements ObserverInterface
{

    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    /**
     * @var Country
     */
    private $countryFactory;

    public function __construct(
        \Psr\Log\LoggerInterface $logger,
        CountryFactory $countryFactory
    ) {
        $this->logger = $logger;
        $this->countryFactory = $countryFactory;
    }
    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $transport = $observer->getEvent()->getTransport();
         //get order
        $order = $transport->getOrder();
        $billingCountry = $this->getCountryName($order->getBillingAddress()->getCountryId());
        $shippingcountry = $this->getCountryName($order->getShippingAddress()->getCountryId());
        $this->logger->debug('billingCountry: '.$billingCountry);

        // add new paremter country
        $transport->setData('shipping_country', $billingCountry);
        $transport['billing_country'] = $shippingcountry;

    }

    /**
     * country full name
     *
     * @return string
     */
    public function getCountryName($countryId): string
    {
        $countryName = '';
        $country = $this->countryFactory->create()->loadByCode($countryId);
        if ($country) {
            $countryName = $country->getName();
        }
        return $countryName;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.