This Opencart tutorial shows how to change and customize email 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.

Open catalog/controller/mail/order.php and remove the alert method and replace with 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 customer, order alert to store administrator, edit order alert, register alert, register notification to 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. Enjoy!.

LEAVE A REPLY

Please enter your comment!
Please enter your name here