Sending a different email template based on selected shipping method - Magento 2.2.3 Ultimo theme

Hello @digitalstartup ,

I first want to say big thanks for all your hard work in helping people and sharing knowledge with them - you are a :star2:!

Will try keep it to the point:

My setup

  1. Magento 2.2.3
  2. Ultimo
  3. Shared server hosted on Siteground
  4. Followed Craig’s ‘Let’s build’ series which have helped me significantly!

What I’m trying to do

I have been trying for some time now to send a different email template based on what customers have selected as a shipping method.

For example: If there is ‘Royal Mail’ / ‘MNX Midnite Express’ / ‘Click & Collect’ as shipping methods then:

If Royal Mail:

  • “Your order is on the road!”

If Click & Collect (‘is_pickup’ var in the code below):

  • “Your order is ready for Pickup!”

If MNX Midnite Express:

  • “Your order is on the road!”

More details: I am using the FlatRate shipping method for Click&Collect (Pickup) orders and the Matrix Table Rates as Royal Mail.

What I’ve already tried

While teaching myself on the internet as to how this could be achieved I came across an article where people managed to reproduce exactly what I am after with a piece of PHP code which doesn’t really work for me. I’ve tried creating some variables to use in the newly created email template(see screenshot below) to add some messages based on the shipping method.

Added the variables to the template by creating a plugin for vendor\Magento\Sales\Model\Order\Email\Container\Template 's setTemplateVars method using the code from below:

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

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

        return [$vars];
    }
}

and this is how I called it 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}}

The issue that I have
…is that I only get the else statement appearing in the Email that is sent to customers after new order even if they selected the flat rate shipping method(which I am using for ‘Click & Collect’).

2nd attempt - I didn’t let go and tried a different approach: :upside_down_face:

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

‘is_pickup’ => $order->getShippingMethod() == “flatrate_flatrate”,

see below the full code: :

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",
            ];

            $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 tried to reference it like this in my Email Template:

 {{if is_pickup}}
                {{trans "Your %store_name order is ready for Pickup!"  store_name=$store.getFrontendName()}}
            {{else}}
{{trans "Your %store_name order is on the ROOOOOOAD!"  store_name=$store.getFrontendName()}}
{{/if}}

but unfortunately no success again.

Then I tried using the Free Shipping method for a ‘Click & Collect’ service with swapping the ‘flatrate_flatrate’ code for ‘free’ but also didn’t do the trick for me.

My Question
Can you @digitalstartup point me to the right direction once more, please?!

I realise it’s a case of having slightly more knowledge/expertise in javascript/PHP which I still don’t so any advise or recommendations would be highly appreciated.

Best regards :pray::trophy:,
Teo

That’s quite a smart idea. In the past, we normally just added all of the information to an email and let the customer work out which was relevant based on the subheadings.

Having both Shipping and Collection under different modules is clever as this should make it much easier to achieve what you need.

Just so we’re on the same page, my PHP isn’t amazing either but I try to get by :slight_smile:

Shouldn’t {{is_pickup}} have some sort or argument to check whether it’s TRUE or FALSE? Like is_pickup == XYZ. Your second method might be making things more complicated than they need to be.

I’m super busy with work right now, but if you aren’t in a hurry I’d like to spend a few hours digging into this in the evenings this week to try and solve this. Looks like you’ve done 90% of the work so shouldn’t be too difficult to get you across the line.

@digitalstartup Thank you for your reply and I am not in a hurry. It’s just been buggering me for a while and am thinking that from a customer-friendly point of view I’d like to be able to sent different emails. I will also look into it further in the next few evenings and if manage to solve it will definitely post the solution here :slight_smile:

Regards,
Teo

Do you have any reference links for your first attempt? I’d like to see if I can solve that method first.

Hi @digitalstartup https://magento.stackexchange.com/questions/160382/magento-2-send-different-email-templates-for-ship-based-on-shipping-method-cho that’s one

If any other details are needed - happy to send them in a private message :slight_smile:

Thank you so much for your time once again :sunny:

FYI: I haven’t forgot about you. I’ve just been really busy trying to fix our Checkout on our Production site, because Daylight Savings has broken it :tired_face: When this issue is resolved, I’ll have time to come back to you on this one.

Hopefully, I’ll have an answer by the weekend. I brought someone else in to give me a second opinion who said they’ll take a look in a couple of days. Fingers crossed :crossed_fingers:

Sounds good! I’ve been completely stuck on it tbh so any help will be greatly appreciated! @digitalstartup
Kind regards,
Teo

@digitalstartup Any progress on that?

Sorry… My “backup” dev kept giving me the runaround. “I’ll have a look for you next week, I’m super busy” was the response I got every week. So last week they suggested to give it a couple of months when their schedule frees up :roll_eyes:

I’m trying out another company right now, but their hourly rate doesn’t warrant me asking them to have a look… Sorry