4

I am having a dilemma on how to send a different email content when an order is Shipped based on the Shipping Method chosen.

For example: If there is Delivery / Pick Up / Shipping as shipping methods then:

If Delivery:

  • "Your order is on the road!"

If Pickup:

  • "Your order is ready for Pickup!"

If Shipping:

  • (Default email template with tracking code)

More details: I am using the FlatRate shipping method for Pickup orders and the Table Rates as Delivery.

Thanks!

3 Answers 3

6

You can create some variables to use in the email template to add some messages based on the shipping method.

Add the variables to the template by creating a plugin for Magento\Sales\Model\Order\Email\Container\Template's setTemplateVars method. For example:

class ShippingVars
{
    public function beforeSetTemplateVars(\Magento\Sales\Model\Order\Email\Container\Template $subject, array $vars)
    { 
        /** @var Order $order */
        $order = $vars['order'];
        $method = $order->getShippingMethod();

        $vars['is_pickup'] = $method === 'flatrate_flatrate';

        return [$vars];
    }
}

In the email template:

{{if is_pickup}}
<p>Your order is ready for Pickup!</p>
{{else}}
<p>Your order is on the road!</p>
{{/if}}
5
  • Hi Aaron, is there anything else I need to do on the email template for it to display? I created the observer and, but it seems that the values are not transported to the template. Feb 17, 2017 at 21:14
  • I was wrong about using an event, you need to use a plugin. I've updated the answer and tested it and it's working. Feb 18, 2017 at 4:46
  • I thought it would be worth if i just mentioned here that you need to define the plugin in the etc/frontend/di.xml instead of the etc/di.xml of your module. This made me scratch my head.
    – Quinten
    Jan 23, 2020 at 10:19
  • I have a shipping module and would love to get this to work for my email. Can anyone clarify a little more how to get this to work? Where in the plugin folder does it go? Are there any other dependencies that need to be called? Any other helpful information would be appreciated. I have my question here - magento.stackexchange.com/questions/321545/… Thanks!
    – stanhook
    Sep 4, 2020 at 17:56
  • Thanks its help me, It would be very nice if the di.xml part and plugging file's full content was published here.
    – Mujahidh
    Mar 9, 2021 at 10:50
1

I took another approach to solving this issue:

I extended the Magento\Sales\Model\Order\Email\Sender\Shipment Sender's send method and added my own variables directly onto the transport.

My approach was a result of a 3rd party extension also injecting their own variables through the ShipmentSender.

class ShipmentSender extends BaseShipmentSender
{
    public function send(Shipment $shipment, $forceSyncMode = false)
    {
        $shipment->setSendEmail(true);

        if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
            $order = $shipment->getOrder();

            $transport = [
                'order' => $order,
                'shipment' => $shipment,
                'comment' => $shipment->getCustomerNoteNotify() ? $shipment->getCustomerNote() : '',
                'billing' => $order->getBillingAddress(),
                'payment_html' => $this->getPaymentHtml($order),
                'store' => $order->getStore(),
                'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
                'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
                'shipping_arrival_date' => $order->getShippingArrivalDate(),
                'delivery_time_slot' => $order->getShippingArrivalTimeslot(),
                'shipping_arrival_comments' => $order->getShippingArrivalComments(),
                'is_pickup' => $order->getShippingMethod() == "flatrate_flatrate",
                'is_delivery' => $order->getShippingMethod() == "shippingtable_shippingtable1",
                'is_shipment' => ($order->getShippingMethod() != "flatrate_flatrate" && $order->getShippingMethod() != "shippingtable_shippingtable1"),
                'is_pickup_or_delivery' => ($order->getShippingMethod() == "flatrate_flatrate" || $order->getShippingMethod() == "shippingtable_shippingtable1"),
            ];

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

            $this->templateContainer->setTemplateVars($transport);

            if ($this->checkAndSend($order)) {
                $shipment->setEmailSent(true);
                $this->shipmentResource->saveAttribute($shipment, ['send_email', 'email_sent']);
                return true;
            }
        }

        $this->shipmentResource->saveAttribute($shipment, 'send_email');

        return false;
    }

Due to this change, I was able to reference it like this in my shipment_new.html template.

            {{if is_pickup}}
                {{trans "Your %store_name order is ready for Pickup!"  store_name=$store.getFrontendName()}}
            {{/if}}
            {{if is_delivery}}
                {{trans "Your %store_name order is on the road!"  store_name=$store.getFrontendName()}}
            {{/if}}
            {{if is_shipment}}
                {{trans "Your %store_name order has shipped!" store_name=$store.getFrontendName()}}
            {{/if}}
0

Could you do it in Magento 2? I had used it and found nothing. Please can someone help me?

Your Answer

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

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