Skip to main contentSkip to footer

Change email send to the administrator of the opencart store when they get an order

Rupak Nepali
Share:
Change email send to the administrator of the opencart store when they get an order

This Opencart tutorial shows how to change and customize emails send out to the store administrator when they get the new order in the OpenCart store. Normally Opencart just sends an email with fewer details like below:

You have received an order.

Order ID: 1088
Date Added: 11/02/2019
Order Status: Complete

Products
1x .... $0.00

Order Totals
Sub-Total: $0.00
Total: $0.00

Let’s change that email to send full details like the one that customers get.

Change admin order alert email

Open catalog/controller/mail/order.php and remove the alert method and replace it with the below alert method.

// Admin Alert Mail
public function alert(&$route, &$args) {
    if (isset($args[0])) {
        $order_id = $args[0];
    } else {
        $order_id = 0;
    }
    
    if (isset($args[1])) {
        $order_status_id = $args[1];
    } else {
        $order_status_id = 0;
    }	
    
    if (isset($args[2])) {
        $comment = $args[2];
    } else {
        $comment = '';
    }
    
    if (isset($args[3])) {
        $notify = $args[3];
    } else {
        $notify = '';
    }

    $order_info = $this->model_checkout_order->getOrder($order_id);
    
    if ($order_info && !$order_info['order_status_id'] && $order_status_id && in_array('order', (array)$this->config->get('config_mail_alert'))) {	

        // Check for any downloadable products
    $download_status = false;

    $order_products = $this->model_checkout_order->getOrderProducts($order_info['order_id']);
    
    foreach ($order_products as $order_product) {
        // Check if there are any linked downloads
        $product_download_query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "product_to_download` WHERE product_id = '" . (int)$order_product['product_id'] . "'");

        if ($product_download_query->row['total']) {
            $download_status = true;
        }
    }
    
    // Load the language for any mails that might be required to be sent out
    $language = new Language($order_info['language_code']);
    $language->load($order_info['language_code']);
    $language->load('mail/order_add');
$this->load->language('mail/order_alert');

    // HTML Mail
    $data['title'] = sprintf($language->get('text_subject'), $order_info['store_name'], $order_info['order_id']);

    $data['text_greeting'] = sprintf($language->get('text_greeting'), $order_info['store_name']);
    $data['text_link'] = $language->get('text_link');
    $data['text_download'] = $language->get('text_download');
    $data['text_order_detail'] = $language->get('text_order_detail');
    $data['text_instruction'] = $language->get('text_instruction');
    $data['text_order_id'] = $language->get('text_order_id');
    $data['text_date_added'] = $language->get('text_date_added');
    $data['text_payment_method'] = $language->get('text_payment_method');
    $data['text_shipping_method'] = $language->get('text_shipping_method');
    $data['text_email'] = $language->get('text_email');
    $data['text_telephone'] = $language->get('text_telephone');
    $data['text_ip'] = $language->get('text_ip');
    $data['text_order_status'] = $language->get('text_order_status');
    $data['text_payment_address'] = $language->get('text_payment_address');
    $data['text_shipping_address'] = $language->get('text_shipping_address');
    $data['text_product'] = $language->get('text_product');
    $data['text_model'] = $language->get('text_model');
    $data['text_quantity'] = $language->get('text_quantity');
    $data['text_price'] = $language->get('text_price');
    $data['text_total'] = $language->get('text_total');
    $data['text_footer'] = $language->get('text_footer');

    $data['logo'] = $order_info['store_url'] . 'image/' . $this->config->get('config_logo');
    $data['store_name'] = $order_info['store_name'];
    $data['store_url'] = $order_info['store_url'];
    $data['customer_id'] = $order_info['customer_id'];
    $data['link'] = $order_info['store_url'] . 'index.php?route=account/order/info&order_id=' . $order_info['order_id'];

    if ($download_status) {
        $data['download'] = $order_info['store_url'] . 'index.php?route=account/download';
    } else {
        $data['download'] = '';
    }

    $data['order_id'] = $order_info['order_id'];
    $data['date_added'] = date($language->get('date_format_short'), strtotime($order_info['date_added']));
    $data['payment_method'] = $order_info['payment_method'];
    $data['shipping_method'] = $order_info['shipping_method'];
    $data['email'] = $order_info['email'];
    $data['telephone'] = $order_info['telephone'];
    $data['ip'] = $order_info['ip'];

    $order_status_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "' AND language_id = '" . (int)$order_info['language_id'] . "'");

    if ($order_status_query->num_rows) {
        $data['order_status'] = $order_status_query->row['name'];
    } else {
        $data['order_status'] = '';
    }

    if ($comment && $notify) {
        $data['comment'] = nl2br($comment);
    } else {
        $data['comment'] = '';
    }

    if ($order_info['payment_address_format']) {
        $format = $order_info['payment_address_format'];
    } else {
        $format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
    }

    $find = array(
        '{firstname}',
        '{lastname}',
        '{company}',
        '{address_1}',
        '{address_2}',
        '{city}',
        '{postcode}',
        '{zone}',
        '{zone_code}',
        '{country}'
    );

    $replace = array(
        'firstname' => $order_info['payment_firstname'],
        'lastname'  => $order_info['payment_lastname'],
        'company'   => $order_info['payment_company'],
        'address_1' => $order_info['payment_address_1'],
        'address_2' => $order_info['payment_address_2'],
        'city'      => $order_info['payment_city'],
        'postcode'  => $order_info['payment_postcode'],
        'zone'      => $order_info['payment_zone'],
        'zone_code' => $order_info['payment_zone_code'],
        'country'   => $order_info['payment_country']
    );

    $data['payment_address'] = str_replace(array("\r\n", "\r", "\n"), '<br />', preg_replace(array("/\s\s+/", "/\r\r+/", "/\n\n+/"), '<br />', trim(str_replace($find, $replace, $format))));

    if ($order_info['shipping_address_format']) {
        $format = $order_info['shipping_address_format'];
    } else {
        $format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
    }

    $find = array(
        '{firstname}',
        '{lastname}',
        '{company}',
        '{address_1}',
        '{address_2}',
        '{city}',
        '{postcode}',
        '{zone}',
        '{zone_code}',
        '{country}'
    );

    $replace = array(
        'firstname' => $order_info['shipping_firstname'],
        'lastname'  => $order_info['shipping_lastname'],
        'company'   => $order_info['shipping_company'],
        'address_1' => $order_info['shipping_address_1'],
        'address_2' => $order_info['shipping_address_2'],
        'city'      => $order_info['shipping_city'],
        'postcode'  => $order_info['shipping_postcode'],
        'zone'      => $order_info['shipping_zone'],
        'zone_code' => $order_info['shipping_zone_code'],
        'country'   => $order_info['shipping_country']
    );

    $data['shipping_address'] = str_replace(array("\r\n", "\r", "\n"), '<br />', preg_replace(array("/\s\s+/", "/\r\r+/", "/\n\n+/"), '<br />', trim(str_replace($find, $replace, $format))));

    $this->load->model('tool/upload');

    // Products
    $data['products'] = array();

    foreach ($order_products as $order_product) {
        $option_data = array();

        $order_options = $this->model_checkout_order->getOrderOptions($order_info['order_id'], $order_product['order_product_id']);

        foreach ($order_options as $order_option) {
            if ($order_option['type'] != 'file') {
                $value = $order_option['value'];
            } else {
                $upload_info = $this->model_tool_upload->getUploadByCode($order_option['value']);

                if ($upload_info) {
                    $value = $upload_info['name'];
                } else {
                    $value = '';
                }
            }

            $option_data[] = array(
                'name'  => $order_option['name'],
                'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
            );
        }

        $data['products'][] = array(
            'name'     => $order_product['name'],
            'model'    => $order_product['model'],
            'option'   => $option_data,
            'quantity' => $order_product['quantity'],
            'price'    => $this->currency->format($order_product['price'] + ($this->config->get('config_tax') ? $order_product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']),
            'total'    => $this->currency->format($order_product['total'] + ($this->config->get('config_tax') ? ($order_product['tax'] * $order_product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value'])
        );
    }

    // Vouchers
    $data['vouchers'] = array();

    $order_vouchers = $this->model_checkout_order->getOrderVouchers($order_info['order_id']);

    foreach ($order_vouchers as $order_voucher) {
        $data['vouchers'][] = array(
            'description' => $order_voucher['description'],
            'amount'      => $this->currency->format($order_voucher['amount'], $order_info['currency_code'], $order_info['currency_value']),
        );
    }

    // Order Totals
    $data['totals'] = array();
    
    $order_totals = $this->model_checkout_order->getOrderTotals($order_info['order_id']);

    foreach ($order_totals as $order_total) {
        $data['totals'][] = array(
            'title' => $order_total['title'],
            'text'  => $this->currency->format($order_total['value'], $order_info['currency_code'], $order_info['currency_value']),
        );
    }

    $this->load->model('setting/setting');
    
    $from = $this->model_setting_setting->getSettingValue('config_email', $order_info['store_id']);
    
    if (!$from) {
        $from = $this->config->get('config_email');
    }


        $mail = new Mail($this->config->get('config_mail_engine'));
        $mail->parameter = $this->config->get('config_mail_parameter');
        $mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname');
        $mail->smtp_username = $this->config->get('config_mail_smtp_username');
        $mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8');
        $mail->smtp_port = $this->config->get('config_mail_smtp_port');
        $mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout');

        $mail->setTo($this->config->get('config_email'));
        $mail->setFrom($this->config->get('config_email'));
        $mail->setSender(html_entity_decode($order_info['store_name'], ENT_QUOTES, 'UTF-8'));
        $mail->setSubject(html_entity_decode(sprintf($this->language->get('text_subject'), $this->config->get('config_name'), $order_info['order_id']), ENT_QUOTES, 'UTF-8'));
        $mail->setHtml($this->load->view('mail/order_alert', $data));
        $mail->send();

        // Send to additional alert emails
        $emails = explode(',', $this->config->get('config_mail_alert_email'));

        foreach ($emails as $email) {
            if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $mail->setTo($email);
                $mail->send();
            }
        }
    }
}

Then go to catalog/view/theme/YOUR_THEME/template/mail/order_mail.twig and remove all the code and replace with the following codes:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{ title }}</title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: #000000;">
<div style="width: 680px;"><a href="{{ store_url }}" title="{{ store_name }}"><img src="{{ logo }}" alt="{{ store_name }}" style="margin-bottom: 20px; border: none;" /></a>
  <p style="margin-top: 0px; margin-bottom: 20px;">{{ text_greeting }}</p>
  
  {% if download %}
  <p style="margin-top: 0px; margin-bottom: 20px;">{{ text_download }}</p>
  <p style="margin-top: 0px; margin-bottom: 20px;"><a href="{{ download }}">{{ download }}</a></p>
  <{% endif %}
  <table style="border-collapse: collapse; width: 100%; border-top: 1px solid #DDDDDD; border-left: 1px solid #DDDDDD; margin-bottom: 20px;">
    <thead>
      <tr>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;" colspan="2">{{ text_order_detail }}</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;"><b>{{ text_order_id }}</b> {{ order_id }}<br />
          <b>{{ text_date_added }}</b> {{ date_added }}<br />
          <b>{{ text_payment_method }}</b> {{ payment_method }}<br />
          {% if shipping_method %} <b>{{ text_shipping_method }}</b> {{ shipping_method }}
          {% endif %}</td>
        <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;"><b>{{ text_email }}</b> {{ email }}<br />
          <b>{{ text_telephone }}</b> {{ telephone }}<br />
          <b>{{ text_ip }}</b> {{ ip }}<br />
          <b>{{ text_order_status }}</b> {{ order_status }}<br /></td>
      </tr>
    </tbody>
  </table>
  {% if comment %}
  <table style="border-collapse: collapse; width: 100%; border-top: 1px solid #DDDDDD; border-left: 1px solid #DDDDDD; margin-bottom: 20px;">
    <thead>
      <tr>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;">{{ text_instruction }}</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ comment }}</td>
      </tr>
    </tbody>
  </table>
  {% endif %}
  <table style="border-collapse: collapse; width: 100%; border-top: 1px solid #DDDDDD; border-left: 1px solid #DDDDDD; margin-bottom: 20px;">
    <thead>
      <tr>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;">{{ text_payment_address }}</td>
        {% if shipping_address %}
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;">{{ text_shipping_address }}</td>
        {% endif %} </tr>
    </thead>
    <tbody>
      <tr>
        <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ payment_address }}</td>
        {% if shipping_address %}
        <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ shipping_address }}</td>
        {% endif %} </tr>
    </tbody>
  </table>
  <table style="border-collapse: collapse; width: 100%; border-top: 1px solid #DDDDDD; border-left: 1px solid #DDDDDD; margin-bottom: 20px;">
    <thead>
      <tr>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;">{{ text_product }}</td>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: left; padding: 7px; color: #222222;">{{ text_model }}</td>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: right; padding: 7px; color: #222222;">{{ text_quantity }}</td>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: right; padding: 7px; color: #222222;">{{ text_price }}</td>
        <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background-color: #EFEFEF; font-weight: bold; text-align: right; padding: 7px; color: #222222;">{{ text_total }}</td>
      </tr>
    </thead>
    <tbody>
    
    {% for product in products %}
    <tr>
      <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ product.name }}
        {% for option in product.option %}<br />
         <small> - {{ option.name }}: {{ option.value }}</small>{% endfor %}</td>
      <td style="font-size: 12px; border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ product.model }}</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ product.quantity }}</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ product.price }}</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ product.total }}</td>
    </tr>
    {% endfor %}
    {% for voucher in vouchers %}
    <tr>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;">{{ voucher.description }}</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: left; padding: 7px;"></td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">1</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ voucher.amount }}</td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ voucher.amount }}</td>
    </tr>
    {% endfor %}
      </tbody>
    
    <tfoot>
    
    {% for total in totals %}
    <tr>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;" colspan="4"><b>{{ total.title }}:</b></td>
      <td style="font-size: 12px;	border-right: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; text-align: right; padding: 7px;">{{ total.text }}</td>
    </tr>
    {% endfor %}
      </tfoot>
    
  </table>
  <p style="margin-top: 0px; margin-bottom: 20px;">{{ text_footer }}</p>
</div>
</body>
</html>

With these changes, you can get the customized full detail email for Admin as well.

If you want to change the email design for the affiliate alert, affiliate welcome email, forgotten password email, order notification to the customer, order alert to store administrator, edit order alert, register alert, register notification to the customer, transaction alert, voucher alert, you can change them at catalog/view/theme/YOUR_TEME/template/mail where you can change your design as per your need.

Let us know if you find any difficulties or need any help from us. Likewise, you can see other Opencart tips and tricks.

Comments

Join the conversation and share your thoughts

Leave a Comment

Your comment will be reviewed before publishing.

Be the first to comment on this post!

Innovation

Let's Make Something Amazing Together

We always provide our best creative ideas at the highest level. Tell us about your project and we will make it work.

InnovateBringing innovative solutions to complex problems
AutomateStreamlining processes through automation
DominateLeading the market with exceptional results
Build Smarter and Launch FasterEfficient development for rapid deployment