<?php
/**
 * NOTICE OF LICENSE.
 *
 * This source file is subject to a commercial license from Common-Services Co., Ltd.
 * Use, copy, modification or distribution of this source file without written
 * license agreement from the SARL SMC is strictly forbidden.
 * In order to obtain a license, please contact us: support.mondialrelay@common-services.com
 * ...........................................................................
 * INFORMATION SUR LA LICENCE D'UTILISATION
 *
 * L'utilisation de ce fichier source est soumise a une licence commerciale
 * concedee par la societe Common-Services Co., Ltd.
 * Toute utilisation, reproduction, modification ou distribution du present
 * fichier source sans contrat de licence ecrit de la part de la Common-Services Co. Ltd. est
 * expressement interdite.
 * Pour obtenir une licence, veuillez contacter Common-Services Co., Ltd. a l'adresse:
 *            support.mondialrelay@common-services.com
 * ...........................................................................
 *
 * @author    Alexandre D.
 * @copyright Copyright (c) 2011-2015 Common Services Co Ltd - 90/25 Sukhumvit 81 - 10260 Bangkok - Thailand
 * @license   Commercial license
 * Support by mail  :  support.mondialrelay@common-services.com
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

if (!class_exists('ConfigureMessage')) {
    require_once _PS_MODULE_DIR_.'mondialrelayadvanced/classes/shared/configure_message.class.php';
}
require_once _PS_MODULE_DIR_.'mondialrelayadvanced/classes/MondialRelayCarrier.php';
require_once _PS_MODULE_DIR_.'mondialrelayadvanced/classes/MondialRelayTools.php';
require_once _PS_MODULE_DIR_.'mondialrelayadvanced/classes/MondialRelayOTP.php';
require_once _PS_MODULE_DIR_.'mondialrelayadvanced/classes/MondialRelaySQLFormatter.php';

class MondialRelayAdvanced extends CarrierModule
{
    const ADD = 'a';
    const REMOVE = 'd';
    const UPDATE = 'u';

    public $ps17x;
    public $ps16x;
    public $ps15x;
    public $id_carrier;
    public $id_lang;
    public $context;
    public $protocol;
    public $url;

    protected $carrier_delivery_countries = array('FR', 'BE', 'LU', 'ES', 'DE', 'AT', 'GB', 'IT', 'PT');

    protected $carrier_delivery_mode = array();

    protected $carrier_insurance = array();

    public function __construct()
    {
        $this->name = 'mondialrelayadvanced';
        $this->tab = 'shipping_logistics';
        $this->version = '1.0.11';
        $this->author = 'Common-Services';
        $this->need_instance = 0;
        $this->bootstrap = true;
        $this->protocol = Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://';
        $this->url = $this->protocol.htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT, 'UTF-8').
            __PS_BASE_URI__.'modules/'.$this->name.'/';
        $this->module_key = '7d977bd9cc79daa0da9a321da814f397';

        parent::__construct();

        $this->displayName = $this->l('Mondial Relay Advanced');
        $this->description = $this->l('Deliver your package in Mondial Relay Pickup Point.');
        $this->confirmUninstall = $this->l('Are you sure you want to uninstall the module ?');

        $this->ps17x = version_compare(_PS_VERSION_, '1.7', '>=');
        $this->ps16x = version_compare(_PS_VERSION_, '1.6', '>=');
        $this->ps15x = version_compare(_PS_VERSION_, '1.5', '>=');

        if (!$this->ps16x && !$this->ps15x) {
            require_once _PS_MODULE_DIR_.$this->name.'/backward_compatibility/backward.php';
            $this->local_path = _PS_MODULE_DIR_.$this->name.'/';
        }

        $this->context = Context::getContext();
        $this->id_lang = isset($this->context->language) && Validate::isLoadedObject($this->context->language) ?
            $this->context->language->id : Configuration::get('PS_LANG_DEFAULT');

        $this->init();
    }

    public function init()
    {
        // Translate delivery mode
        $this->carrier_delivery_mode = array(
            '24R' => sprintf($this->l('Delivery in relay %s'), $this->l('standard')),
            '24L' => sprintf($this->l('Delivery in relay %s'), 'XL'),
            '24X' => sprintf($this->l('Delivery in relay %s'), 'XXL'),
            'DRI' => $this->l('Colis Drive delivery'),
            'LD1' => sprintf($this->l('Home delivery %dKg with appointment %d person'), 70, 1),
            'LDS' => sprintf($this->l('Home delivery %dKg with appointment %d person'), 130, 2),
            'HOM' => $this->l('Home delivery %dKg without appointment'),
            'HOC' => $this->l('Home delivery (specific to Spain)'),
            'HOD' => $this->l('Home delivery (specific to Spain)')
        );

        // Translate insurance
        $this->carrier_insurance = array(
            $this->l('No insurance'),
            sprintf($this->l('Complementary insurance %s'), 'N1'),
            sprintf($this->l('Complementary insurance %s'), 'N2'),
            sprintf($this->l('Complementary insurance %s'), 'N3'),
            sprintf($this->l('Complementary insurance %s'), 'N4'),
            sprintf($this->l('Complementary insurance %s'), 'N5')
        );
    }

    public function install()
    {
        require_once dirname(__FILE__).'/sql/install.php';

        $pass = parent::install();
        $pass &= $this->setHooks(self::ADD);
        $pass &= $this->setTabs(self::ADD);

        Configuration::updateValue('MRA_CONF', serialize(array(
            'trading_name' => '',
            'brand_code' => '',
            'ws_key' => '',
            'sticker_lang' => 1,
            'debug_mode' => 0,
            'test_mode' => 0,
            'Expe_Ad1' => Configuration::get('PS_SHOP_NAME'),
            'Expe_Ad2' => Configuration::get('PS_SHOP_ADDR2'),
            'Expe_Ad3' => Configuration::get('PS_SHOP_ADDR1'),
            'Expe_Ad4' => '',
            'Expe_CP' => Configuration::get('PS_SHOP_CODE'),
            'Expe_Ville' => Configuration::get('PS_SHOP_CITY'),
            'Expe_Pays' => 1,
            'Expe_Tel1' => Configuration::get('PS_SHOP_PHONE'),
            'Expe_Mail' => Configuration::get('PS_SHOP_EMAIL'),
            'new_order_state' => (int)Db::getInstance()->getValue(
                'SELECT `id_order_state`
				FROM `'._DB_PREFIX_.'order_state`
				WHERE `logable` = 1
				'.(!$this->ps15x ? '-- ' : ' ').'AND `paid` = 1
				AND `delivery` = 1
				'.(!$this->ps15x ? '-- ' : ' ').'AND `shipped` = 0'
            ),
            'google_map' => 1,
            'printing_format' => 'A4',

            'cost_auto' => 0
        )));
        
        Configuration::updateValue('MRA_TOKEN', md5(time().rand()));

        return (bool)$pass;
    }

    private function setHooks($action = false)
    {
        if ($this->ps15x) {
            $expected_hooks = array(
                'actionCarrierUpdate',
                'actionValidateOrder',
                'displayBeforeCarrier',
                'displayAdminOrder',
                'displayFooter',
                'displayHeader'
            );
        } else {
            $expected_hooks = array(
                'updateCarrier',
                'newOrder',
                'beforeCarrier',
                'adminOrder',
                'footer',
                'header'
            );
        }

        $pass = true;

        if ($action == self::ADD) {
            foreach ($expected_hooks as $expected_hook) {
                if (!$this->isRegisteredInHook($expected_hook)) {
                    if (!$this->registerHook($expected_hook)) {
                        ConfigureMessage::error($this->l('Unable to Register Hook').':'.$expected_hook);
                        $pass = false;
                    }
                }
            }
        }

        if ($action == self::REMOVE) {
            foreach ($expected_hooks as $expected_hook) {
                if ($this->isRegisteredInHook($expected_hook)) {
                    if (!$this->unregisterHook($expected_hook)) {
                        ConfigureMessage::error($this->l('Unable to Unregister Hook').':'.$expected_hook);
                        $pass = false;
                    }
                }
            }
        }

        return $pass;
    }

    private function setTabs($action = false)
    {
        require_once dirname(__FILE__).'/classes/shared/tab.class.php';

        $parent_tab = $this->ps17x ? 'AdminParentOrders' : 'AdminOrders';
        $controller = $this->ps15x ? 'AdminOrdersMondialRelayAdvanced' : 'OrdersMondialRelayAdvanced';

        return (bool)CommonServicesTab::setup(
            $action,
            $controller,
            $this->displayName,
            $parent_tab
        );
    }

    public function uninstall()
    {
        Configuration::deleteByName('MRA_CONF');
        Configuration::deleteByName('MRA_STATUS');
        Configuration::deleteByName('MRA_LAST_SESSION_USED');
        Configuration::deleteByName('MRA_TRACKING');
        Configuration::deleteByName('MRA_TOKEN');

        require_once dirname(__FILE__).'/sql/uninstall.php';

        $this->deleteMondialRelayCarriers();

        return parent::uninstall();
    }

    private function deleteMondialRelayCarriers()
    {
        $id_carriers = MondialRelayCarrier::getMondialRelayCarriersID(true, false, false);

        if (is_array($id_carriers) && count($id_carriers)) {
            foreach ($id_carriers as $id_carrier) {
                $carrier = new Carrier((int)$id_carrier);
                if (Validate::isLoadedObject($carrier)) {
                    $carrier->delete();
                }
            }
        }
    }

    public function getContent()
    {
        $this->postProcess();

        return $this->displayForm();
    }

    protected function postProcess()
    {
        if (Tools::isSubmit('submit'.$this->name)) {
            require_once dirname(__FILE__).'/sql/install.php';

            $success = true;
            $success &= Configuration::updateValue(
                'MRA_CONF',
                serialize(array_map(array('MondialRelayTools', 'sanitize'), Tools::getValue('configuration', array())))
            );
            $success &= Configuration::updateValue('MRA_STATUS', serialize(Tools::getValue('filtered_status', array())));
            $success &= Configuration::updateValue('MRA_TRACKING', serialize(Tools::getValue('tracking', array())));

            $success &= $this->setTabs(self::UPDATE);
            $success &= $this->setHooks(self::ADD);

            $token = '';
            if (array_key_exists('trading_name', Tools::getValue('configuration', array())) &&
                array_key_exists('ws_key', Tools::getValue('configuration', array()))) {
                $configuration = Tools::getValue('configuration', array());

                $token = Tools::strtoupper(md5(
                    $configuration['trading_name'].
                    $configuration['ws_key']
                ));
            }
            $success &= Configuration::updateValue('MRA_TOKEN', $token);

            if ($success) {
                ConfigureMessage::success($this->l('Configuration saved successfully.'));
            } else {
                ConfigureMessage::error($this->l('An error occured during configuration update.'));
            }
        }
    }

    public function displayForm()
    {
        require_once dirname(__FILE__).'/classes/shared/configure_tab.class.php';

        $html = '';

        $alert_class = array();
        $alert_class['danger'] = $this->ps16x ? 'alert alert-danger' : 'error';
        $alert_class['warning'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        $alert_class['success'] = $this->ps16x ? 'alert alert-success' : 'conf';
        $alert_class['info'] = $this->ps16x ? 'alert alert-info' : 'info';

        $token = Configuration::get('MRA_TOKEN');

        $this->context->smarty->assign(array(
            'ps16x' => $this->ps16x,
            'alert_class' => $alert_class,
            'ps_version' => _PS_VERSION_,
            'img_url' => $this->url.'views/img/',
            'module_dir' => dirname(__FILE__),
            'mondialrelayadvanced_version' => $this->version,
            'mondialrelayadvanced_description' => $this->description,
            'selected_tab' => Tools::getValue('selected_tab') ? Tools::getValue('selected_tab') : '0',
            'mondialrelayadvanced_info' => $this->informations(),
            'mondialrelayadvanced_carriers' => $this->carriers(),
            'mondialrelayadvanced_conf' => MondialRelayTools::unSerialize(Configuration::get('MRA_CONF')),
            'mondialrelayadvanced_tracking' => MondialRelayTools::unSerialize(Configuration::get('MRA_TRACKING')),
            'mondialrelayadvanced_status' => $this->status(),
            'ps_countries' => Country::getCountries($this->context->language->id),
            'available_lang' => Language::getLanguages(),
            'create_mr_carrier_url' => $this->url.'functions/create_mr_carrier.php?token='.$token,
            'cron_mr_tracking' => $this->url.'functions/cron_mr_tracking.php?token='.$token,
            'get_delivery_points_url' => $this->url.'functions/get_delivery_points.php?token='.$token,
            'install_cron_jobs' => $this->url.'functions/install_cron_jobs.php?token='.$token,
            'cronjobs_is_installed' => $this->moduleCronjobsIsInstalled()
        ));

        $tab_list = array();
        $tab_list[] = array(
            'id' => 'mondialrelayadvanced',
            'img' => 'mondialrelayadvanced',
            'name' => 'Mondial Relay Advanced',
            'selected' => true
        );
        $tab_list[] = array(
            'id' => 'informations',
            'img' => 'information',
            'name' => 'Informations',
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'credentials',
            'img' => 'account_functions',
            'name' => $this->l('Credentials'),
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'address',
            'img' => 'house',
            'name' => $this->l('Address'),
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'filters',
            'img' => 'filter',
            'name' => $this->l('Status filter'),
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'carriers',
            'img' => 'lorry',
            'name' => $this->l('Carriers'),
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'tracking',
            'img' => 'location_pin',
            'name' => $this->l('Tracking'),
            'selected' => false
        );
        $tab_list[] = array(
            'id' => 'settings',
            'img' => 'cog_edit',
            'name' => $this->l('Settings'),
            'selected' => false
        );

        $this->addCSS($this->_path.'views/css/configure.css', 'all');
        $this->addCSS($this->_path.'views/css/jquery.qtip.min.css', 'all');
        $this->addJS($this->_path.'views/js/configure.js');
        $this->addJS($this->_path.'views/js/jquery.qtip.min.js');
        $this->addJS($this->_path.'views/js/printme.js');

        $html .= ConfigureMessage::display();
        $html .= $this->context->smarty->fetch(dirname(__FILE__).'/views/templates/admin/header.tpl');
        $html .= ConfigureTab::generateTabs($tab_list);
        $html .= $this->context->smarty->fetch(dirname(__FILE__).'/views/templates/admin/configure.tpl');
        $html .= $this->context->smarty->fetch(dirname(__FILE__).'/views/templates/admin/glossary.tpl');

        return $html;
    }

    private function informations()
    {
        if ((bool) Configuration::get('PS_FORCE_SMARTY_2') == true) {
            die(
                sprintf(
                    '<div class="error">%s</span>',
                    Tools::displayError(
                        'This module is not compatible with Smarty v2. Please switch to Smarty v3 in Preferences Tab.'
                    )
                )
            );
        }

        $php_infos = array();
        $module_infos = array();
        $prestashop_infos = array();

        $module_configuration = MondialRelayTools::unSerialize(Configuration::get('MRA_CONF'));
        if (!isset($module_configuration['trading_name']) || !$module_configuration['trading_name']) {
            $module_infos['username']['message'] = $this->l('Trading name is missing.');
            $module_infos['username']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }
        if (!isset($module_configuration['ws_key']) || !$module_configuration['ws_key']) {
            $module_infos['ws_key']['message'] = $this->l('Web Service Private Key is missing.');
            $module_infos['ws_key']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }
        if (!$module_configuration['Expe_Ad1'] || !$module_configuration['Expe_Ad3'] ||
            !$module_configuration['Expe_CP'] || !$module_configuration['Expe_Ville'] ||
            !$module_configuration['Expe_Pays'] || !$module_configuration['Expe_Tel1'] ||
            !$module_configuration['Expe_Mail']) {
            $module_infos['address']['message'] = $this->l('Your adresse is not filled completely.');
            $module_infos['address']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }
        $module_carrier = MondialRelayCarrier::getMondialRelayCarriers(true);
        if (!is_array($module_carrier) || !count($module_carrier)) {
            $module_infos['carriers']['message'] = $this->l('You did not create any carrier yet.');
            $module_infos['carriers']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        if ($this->ps15x && is_array($module_carrier) && count($module_carrier)) {
            foreach ($module_carrier as $carrier) {
                $carrier_id_shop = Db::getInstance()->executeS(
                    'SELECT `id_shop`
					FROM `'._DB_PREFIX_.'carrier_shop`
					WHERE `id_carrier` = '.(int)$carrier['id_carrier']
                );
                $carrier_id_shop = array_map(create_function('$arr', 'return $arr["id_shop"];'), $carrier_id_shop);

                if (!in_array($this->context->shop->id, $carrier_id_shop)) {
                    $module_infos['carrier_shop_'.$carrier['id_carrier']]['message'] = sprintf(
                        '%s (#%s) [ %s ] %s',
                        $this->l('The carrier'),
                        $carrier['id_carrier'],
                        $carrier['name'],
                        $this->l('is not enabled for this shop context.')
                    );
                    $module_infos['carrier_shop_'.$carrier['id_carrier']]['level'] = $this->ps16x ?
                        'alert alert-warning' : 'warn';
                }
            }
        }
        if (!$this->active) {
            $module_infos['inactive']['message'] = $this->l(
                'Be careful, your module is inactive, this mode stops all
                pending operations for this module, please change the status to "Enable" in your module list.'
            );
            $module_infos['inactive']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        if (!is_writable(_PS_MODULE_DIR_.$this->name.'/download')) {
            $module_infos['download']['message'] = sprintf(
                '%s [ %s ] %s.',
                $this->l('The directory'),
                _PS_MODULE_DIR_.$this->name.'/download',
                $this->l('is not writable, please fix it')
            );
            $module_infos['download']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }
        if (!isset($module_configuration['google_map']) || !$module_configuration['google_map']) {
            $module_infos['google_map']['message'] = $this->l(
                'Google Maps is not enable, please make sure you do not need it in Front-Office.'
            );
            $module_infos['google_map']['level'] = $this->ps16x ? 'alert alert-info' : 'info';
        }

        // PHP
        if (($max_execution_time = ini_get('max_execution_time')) && $max_execution_time < 60) {
            $php_infos['max_execution_time']['message'] = sprintf(
                $this->l(
                    'PHP value: max_execution_time recommended value is at least 60. '.
                    'Your limit is currently set to %d'
                ),
                $max_execution_time
            );
            $php_infos['max_execution_time']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        $memory_limit = $this->toMegaBytes(ini_get('memory_limit'));
        if ($memory_limit < 128) {
            $php_infos['memory']['message'] = sprintf(
                $this->l(
                    'PHP value: memory_limit recommended value is at least 128MB. '.
                    'Your limit is currently set to %sMB'
                ),
                $memory_limit
            );
            $php_infos['memory']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        if (in_array(@Tools::strtolower(ini_get('display_errors')), array('1', 'on'))) {
            $php_infos['display_errors']['message'] = $this->l('PHP variable display_errors is On.');
            $php_infos['display_errors']['level'] = $this->ps16x ? 'alert alert-info' : 'info';
        }
        if (!method_exists('DOMDocument', 'createElement')) {
            $php_infos['curl']['message'] = $this->l(
                'PHP DOMDocument (XML Library) must be installed on this server.
                The module require this library and can\'t work without it'
            );
            $php_infos['curl']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }

        // Prestashop
        if (!(int) Configuration::get('PS_SHOP_ENABLE')) {
            $prestashop_infos['maintenance']['message'] = $this->l(
                'Be carefull, your shop is in maintenance mode, the module might not work in that mode'
            );
            $prestashop_infos['maintenance']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        if (_PS_MODE_DEV_) {
            $prestashop_infos['dev_mode']['message'] = $this->l('The Prestashop constant _PS_MODE_DEV_ is enabled.');
            $prestashop_infos['dev_mode']['level'] = $this->ps16x ? 'alert alert-info' : 'info';
        }
        if (Configuration::get('PS_CATALOG_MODE')) {
            $prestashop_infos['catalog_mode']['message'] = $this->l(
                'Your shop is in catalog mode, the module can not work in this mode.'
            );
            $prestashop_infos['catalog_mode']['level'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        }
        if (count(MondialRelayTools::getOverrides())) {
            $prestashop_infos['overrides']['message'] = $this->l(
                'Your Prestashop potentially runs some overrides.
                    This information is necessary only in case of support.'
            );
            $prestashop_infos['overrides']['level'] = 'info '.($this->ps16x ? 'alert alert-info' : '');
        }

        // Ajax
        $pass = true;
        if (version_compare(_PS_VERSION_, '1.5', '>=')) {
            if (Shop::isFeatureActive()) {
                $shop = Context::getContext()->shop;

                if ($_SERVER['HTTP_HOST'] != $shop->domain && $_SERVER['HTTP_HOST'] != $shop->domain_ssl) {
                    $pass = false;
                }
            } else {
                $urls = ShopUrl::getShopUrls($this->context->shop->id)->where('main', '=', 1)->getFirst();
                if ($_SERVER['HTTP_HOST'] != $urls->domain && $_SERVER['HTTP_HOST'] != $urls->domain_ssl) {
                    $pass = false;
                }
            }
        } elseif (version_compare(_PS_VERSION_, '1.4', '>=')) {
            if ($_SERVER['HTTP_HOST'] != Configuration::get('PS_SHOP_DOMAIN') &&
                $_SERVER['HTTP_HOST'] != Configuration::get('PS_SHOP_DOMAIN_SSL')) {
                $pass = false;
            }
        }

        if (!$pass) {
            $prestashop_infos['wrong_domain']['message'] = $this->l(
                'Your are currently connected with the following domain name:'
            ).' <span style="color:navy">'.$_SERVER['HTTP_HOST'].'</span><br />'.
            $this->l('This one is different from the main shop domain name set in "Preferences > SEO & URLs":').
            ' <span style="color:green">'.Configuration::get('PS_SHOP_DOMAIN').'</span>';
            $prestashop_infos['wrong_domain']['level'] = $this->ps16x ? 'alert alert-danger' : 'error';
        }

        if (!count($prestashop_infos)) {
            $prestashop_info_ok = true;
        } else {
            $prestashop_info_ok = false;
        }

        if (!count($php_infos)) {
            $php_info_ok = true;
        } else {
            $php_info_ok = false;
        }

        if (!count($module_infos)) {
            $module_info_ok = true;
        } else {
            $module_info_ok = false;
        }

        $view_params = array();
        $view_params['module_infos'] = $module_infos;
        $view_params['module_info_ok'] = $module_info_ok;
        $view_params['php_infos'] = $php_infos;
        $view_params['php_info_ok'] = $php_info_ok;
        $view_params['prestashop_infos'] = $prestashop_infos;
        $view_params['prestashop_info_ok'] = $prestashop_info_ok;

        ob_start();
        phpinfo(INFO_ALL & ~INFO_CREDITS & ~INFO_LICENSE & ~INFO_ENVIRONMENT & ~INFO_VARIABLES);
        $phpinfos = ob_get_clean();
        $phpinfos = preg_replace(
            '/(a:link.*)|(body, td, th, h1, h2.*)|(img.*)|(td, th.*)|(a:hover.*)|(class="center")/',
            '',
            $phpinfos
        );
        $view_params['phpinfo_str'] = $phpinfos;
        $view_params['psinfo_str'] = $this->prestashopInfo();
        $view_params['dbinfo_str'] = $this->dbInfo();

        return $view_params;
    }

    public function toMegaBytes($memsize)
    {
        $unit = Tools::strtolower(Tools::substr($memsize, -1));
        $val = preg_replace('[^0-9]', '', $memsize);
        switch ($unit) {
            case 'g':
                $val = $val * 1024 * 1024 * 1024;
                break;
            case 'm':
                $val = $val * 1024 * 1024;
                break;
            case 'k':
                $val = $val * 1024;
                break;
            default:
                $val = false;
        }

        $memsize = $val / (1024 * 1024);

        return $memsize;
    }

    public function prestashopInfo()
    {
        $prestashop_info = '';

        if ($this->ps15x) {
            $sort = ' ORDER by `name`, `id_shop`';
        } else {
            $sort = ' ORDER by `name`';
        }

        $results = Db::getInstance()->executeS(
            'SELECT *
            FROM `'._DB_PREFIX_.'configuration`
            WHERE `name` LIKE "PS_%" OR `name` LIKE "MRA%"'.
            $sort
        );
        $ps_configuration = null;

        foreach ($results as $result) {
            if (strpos($result['name'], 'KEY') || strpos($result['name'], 'EMAIL') ||
                strpos($result['name'], 'PASSWORD') || strpos($result['name'], 'PASSWD') ||
                strpos($result['name'], 'CONTEXT_DATA')) {
                continue;
            }

            $value = $result['value'];

            if (@serialize(@MondialRelayTools::unSerialize($value)) == $value) {
                $value = '<div class="print_r">'.print_r(MondialRelayTools::unSerialize($value), true).'</div>';
            } else {
                $value = Tools::strlen($result['value']) > 128 ?
                    Tools::substr($result['value'], 0, 128).'...' : $result['value'];
            }

            if ($this->ps15x) {
                $ps_configuration .= sprintf(
                    '%-50s %03d %03d : %s'."\n",
                    $result['name'],
                    $result['id_shop'],
                    $result['id_shop_group'],
                    $value
                );
            } else {
                $ps_configuration .= sprintf('%-50s : %s'."\n", $result['name'], $value);
            }
        }

        $prestashop_info .= '<h1>Prestashop</h1>';
        $prestashop_info .= '<pre>';
        $prestashop_info .= 'Version: '._PS_VERSION_."\n\n";
        $prestashop_info .= sprintf('Module Version: %s/%s', $this->displayName, $this->version)."\n";
        $prestashop_info .= 'Mode DEV: '.(defined('_PS_MODE_DEV_') && _PS_MODE_DEV_ ? 'Yes' : 'No')."\n\n";

        $prestashop_info .= 'Max input vars: '.ini_get('max_input_vars')."\n";
        $prestashop_info .= 'Max execution time: '.ini_get('max_execution_time')."\n";
        $prestashop_info .= 'Memory limit: '.ini_get('memory_limit')."\n\n";

        $prestashop_info .= 'Overrides:'."\n";
        foreach (MondialRelayTools::getOverrides() as $override) {
            $prestashop_info .= $override."\n";
        }
        $prestashop_info .= "\n";

        if (defined('Carrier::ALL_CARRIERS')) {
            $all_carriers = Carrier::ALL_CARRIERS;
        } elseif (defined('ALL_CARRIERS')) {
            $all_carriers = ALL_CARRIERS;
        } else {
            $all_carriers = 5;
        }

        $prestashop_info .= 'Carriers'."\n";
        $carriers = Carrier::getCarriers($this->id_lang, false, false, false, null, $all_carriers);
        $sql_formatter = new MondialRelaySQLFormatter(
            array_keys($carriers[0]),
            $carriers
        );
        $prestashop_info .= $sql_formatter->fetch();
        $prestashop_info .= "\n";

        $prestashop_info .= 'OrderStates'."\n";
        $orders_state = OrderState::getOrderStates($this->id_lang);
        $sql_formatter = new MondialRelaySQLFormatter(
            array_keys($orders_state[0]),
            $orders_state
        );
        $prestashop_info .= $sql_formatter->fetch();
        $prestashop_info .= "\n";

        $prestashop_info .= $ps_configuration;

        $prestashop_info .= '</pre>'."\n\n";

        return $prestashop_info;
    }

    public function dbInfo()
    {
        try {
            $query = Db::getInstance()->executeS('SHOW TABLES');
            $tables = array();
            foreach ($query as $rows) {
                foreach ($rows as $t) {
                    $tables[$t] = 1;
                }
            }

            $db_info = '<h1>'.$this->l('Database').'</h1>';
            $db_info .= '<pre>';

            $table = _DB_PREFIX_.'mr_method';
            $order_by = 'id_mr_method';

            if (!isset($tables[$table])) {
                ConfigureMessage::error(
                    $this->l(
                        'No Mondial Relay table found in your database.
                         Please save configuration to create the table and check again.'
                    ).' : '.$table
                );

                return false;
            }

            $results = Db::getInstance()->executeS('SELECT * FROM `'.$table.'` ORDER BY `'.$order_by.'` DESC LIMIT 5');
            $sql_formatter = new MondialRelaySQLFormatter(
                array_key_exists(0, $results) ? array_keys($results[0]) : array(),
                $results
            );
            $db_info .= '> '.$table.'<br>';
            $db_info .= $sql_formatter->fetch();
            $db_info .= '<br>';

            ////////////////////////////

            $table = _DB_PREFIX_.'mr_method_shop';
            $order_by = 'id_mr_method_shop';

            if (!isset($tables[$table])) {
                ConfigureMessage::error(
                    $this->l(
                        'No Mondial Relay table found in your database. 
                        Please save configuration to create the table and check again.'
                    ).' : '.$table
                );

                return false;
            }

            $results = Db::getInstance()->executeS('SELECT * FROM `'.$table.'` ORDER BY `'.$order_by.'`');
            $sql_formatter = new MondialRelaySQLFormatter(
                array_key_exists(0, $results) ? array_keys($results[0]) : array(),
                $results
            );
            $db_info .= '> '.$table.'<br>';
            $db_info .= $sql_formatter->fetch();
            $db_info .= '<br>';

            ////////////////////////////

            $table = _DB_PREFIX_.'mr_selected';
            $order_by = 'id_mr_selected';

            if (!isset($tables[$table])) {
                ConfigureMessage::error(
                    $this->l(
                        'No Mondial Relay table found in your database.
                        Please save configuration to create the table and check again.'
                    ).' : '.$table
                );

                return false;
            }

            $results = Db::getInstance()->executeS('SELECT * FROM `'.$table.'` ORDER BY `'.$order_by.'` DESC LIMIT 5');
            $sql_formatter = new MondialRelaySQLFormatter(
                array_key_exists(0, $results) ? array_keys($results[0]) : array(),
                $results
            );
            $db_info .= '> '.$table.'<br>';
            $db_info .= $sql_formatter->fetch();
            $db_info .= '<br>';

            ////////////////////////////

            $table = _DB_PREFIX_.'mr_session';
            $order_by = 'id_session';

            if (!isset($tables[$table])) {
                ConfigureMessage::error(
                    $this->l(
                        'No Mondial Relay table found in your database.
                        Please save configuration to create the table and check again.'
                    ).' : '.$table
                );

                return false;
            }

            $results = Db::getInstance()->executeS('SELECT * FROM `'.$table.'` ORDER BY `'.$order_by.'` DESC LIMIT 5');
            $sql_formatter = new MondialRelaySQLFormatter(
                array_key_exists(0, $results) ? array_keys($results[0]) : array(),
                $results
            );
            $db_info .= '> '.$table.'<br>';
            $db_info .= $sql_formatter->fetch();
            $db_info .= '<br>';

            ////////////////////////////

            $table = _DB_PREFIX_.'mr_session_detail';
            $order_by = 'id_session_detail';

            if (!isset($tables[$table])) {
                ConfigureMessage::error(
                    $this->l(
                        'No Mondial Relay table found in your database.
                        Please save configuration to create the table and check again.'
                    ).' : '.$table
                );

                return false;
            }

            $results = Db::getInstance()->executeS('SELECT * FROM `'.$table.'` ORDER BY `'.$order_by.'` DESC LIMIT 5');
            $sql_formatter = new MondialRelaySQLFormatter(
                array_key_exists(0, $results) ? array_keys($results[0]) : array(),
                $results
            );
            $db_info .= '> '.$table.'<br>';
            $db_info .= $sql_formatter->fetch();

            $db_info .= '</pre>';
        } catch (Exception $excp) {
            $db_info = '<pre>'.$excp->getMessage().'</pre>';
        }

        return $db_info;
    }

    private function carriers()
    {
        $view_params = array();
        $delivery_country = array();

        foreach ($this->carrier_delivery_countries as $country) {
            $delivery_country[$country] = Country::getNameById($this->id_lang, Country::getByIso($country));
        }

        $view_params['mr_carriers'] = array_merge(
            array(),
            MondialRelayCarrier::getMondialRelayCarriers(),
            MondialRelayCarrier::getMondialRelayCarriers(false)
        );
        $view_params['delivery_mode'] = $this->carrier_delivery_mode;
        $view_params['delivery_country'] = $delivery_country;
        $view_params['delivery_insurance'] = $this->carrier_insurance;

        return $view_params;
    }

    private function status()
    {
        $status = OrderState::getOrderStates($this->id_lang);
        $filtered_status = MondialRelayTools::unSerialize(Configuration::get('MRA_STATUS'));
        $available_status = array();
        $selected_status = array();

        if (!is_array($filtered_status)) {
            $filtered_status = array();
        }

        foreach ($status as $state) {
            if (!in_array($state['id_order_state'], $filtered_status)) {
                $available_status[] = $state;
            } else {
                $selected_status[] = $state;
            }
        }

        $view_params = array();
        $view_params['available'] = $available_status;
        $view_params['filtered'] = $selected_status;
        $view_params['all'] = $status;

        return $view_params;
    }

    private function moduleCronjobsIsInstalled()
    {
        $is_installed = is_dir(_PS_MODULE_DIR_.'cronjobs/') && Module::isInstalled('cronjobs');

        if ($is_installed && method_exists('Module', 'isEnabled')) {
            $is_installed &= Module::isEnabled('cronjobs');
        } elseif ($is_installed) {
            $is_installed &= (bool)Db::getInstance()->getValue(
                'SELECT `active`
                FROM `'._DB_PREFIX_.'module`
                WHERE `name` = "cronjobs"'
            );
        }

        return $is_installed;
    }

    private function addCSS($url, $media = 'all')
    {
        if ($this->ps15x) {
            $this->context->controller->addCSS($url, $media);
        } else {
            echo '<link rel="stylesheet" href="'.$url.'" type="text/css" media="all">';
        }
    }

    private function addJS($url)
    {
        if ($this->ps15x) {
            $this->context->controller->addJS($url);
        } else {
            echo '<script type="text/javascript" src="'.$url.'"></script>';
        }
    }

    public function getOrderShippingCost($params, $shipping_cost)
    {
        if (!$this->active || $shipping_cost < 0) {
            return false;
        }

        if (!isset($this->context->customer) || !Validate::isLoadedObject($this->context->customer)) {
            return (float)$shipping_cost;
        }

        $address_delivery = new Address((int)$params->id_address_delivery);
        if (!Validate::isLoadedObject($address_delivery)) {
            return (float)$shipping_cost;
        }

        $country_iso = Tools::strtoupper(Country::getIsoById((int)$address_delivery->id_country));

        if (!in_array($country_iso, $this->carrier_delivery_countries) ||
            !in_array($country_iso, MondialRelayCarrier::getDeliveryCountriesForCarrier($this->id_carrier))) {
            return false;
        }

        return (float)$shipping_cost;
    }

    public function getOrderShippingCostExternal($params)
    {
        unset($params);

        return 0;
    }

    public function hookUpdateCarrier($params)
    {
        $this->hookActionCarrierUpdate($params);
    }

    public function hookActionCarrierUpdate($params)
    {
        require_once dirname(__FILE__).'/classes/MondialRelayCarrier.php';

        $carriers = MondialRelayCarrier::getMondialRelayCarriersID(null, null, false);

        if (is_array($carriers) && in_array($params['id_carrier'], $carriers)) {
            MondialRelayCarrier::updateMondialRelayCarrierID($params['id_carrier'], $params['carrier']->id);
        }
    }

    public function hookNewOrder($params)
    {
        return $this->hookActionValidateOrder($params);
    }

    /**
     * @param $params Cart[]|Order[]|Customer[]|Currency[]|OrderState[]
     * @return bool
     */
    public function hookActionValidateOrder($params)
    {
        if (Tools::strtolower($params['order']->payment) == 'cdiscount') {
            return false;
        }

        require_once dirname(__FILE__).'/classes/MondialRelayCarrier.php';
        require_once dirname(__FILE__).'/classes/MondialRelayDelivery.php';

        $mr_carriers = MondialRelayCarrier::getMondialRelayCarriersID(1, 0, false);
        $id_cart = $params['cart']->id;
        $id_customer = $params['cart']->id_customer;

        if (Tools::strtolower($params['order']->module) == 'sdevmanomano' &&
            in_array($params['order']->id_carrier, $mr_carriers)) {
            return $this->addManoManoOrderToMrTable($params);
        }

        if (!in_array($params['order']->id_carrier, $mr_carriers) &&
            MondialRelayDelivery::deliveryExists($id_cart, $id_customer)) {
            MondialRelayDelivery::deleteDelivery($id_cart, $id_customer);
        } else {
            $delivery_address = new Address($params['order']->id_address_delivery);
            if (Validate::isLoadedObject($delivery_address) && strpos($params['order']->payment, 'BeezUP') !== false &&
                Tools::strtolower(Tools::substr($delivery_address->company, 0, 5)) == 'relay') {
                return $this->addBeezUpOrderToMrTable($params, $delivery_address);
            }

            $mr_delivery = new MondialRelayDelivery(null, $id_cart, $id_customer);

            if (MondialRelayCarrier::isHomeDelivery((int)$params['order']->id_carrier)) {
                $delivery_address = new Address((int)$params['cart']->id_address_delivery);
                if (!Validate::isLoadedObject($delivery_address)) {
                    return false;
                }

                $mr_delivery->id_cart = $id_cart;
                $mr_delivery->id_customer = $id_customer;
                $mr_delivery->id_method = Db::getInstance()->getValue(
                    'SELECT `id_mr_method`
                    FROM `'._DB_PREFIX_.'mr_method`
                    WHERE `id_carrier` = '.(int)$params['order']->id_carrier
                );
                $mr_delivery->id_order = $params['order']->id;
                $mr_delivery->mr_poids = sprintf('%05d', $params['order']->getTotalWeight() * 1000);
                $mr_delivery->mr_insurance = Db::getInstance()->getValue(
                    'SELECT `insurance`
                    FROM `'._DB_PREFIX_.'mr_method`
                    WHERE `id_carrier` = '.(int) $params['order']->id_carrier
                );
                $mr_delivery->mr_selected_num = null;
                $mr_delivery->mr_selected_lgadr1 = '';
                $mr_delivery->mr_selected_lgadr2 = '';
                $mr_delivery->mr_selected_lgadr3 = $delivery_address->address1;
                $mr_delivery->mr_selected_lgadr4 = $delivery_address->address2;
                $mr_delivery->mr_selected_cp = $delivery_address->postcode;
                $mr_delivery->mr_selected_ville = $delivery_address->city;
                $mr_delivery->mr_selected_pays = Tools::strtoupper(Country::getIsoById($delivery_address->id_country));

                $mr_delivery->save();
            } else {
                if (!$mr_delivery->validate()) {
                    // Not a Mondial Relay order
                    MondialRelayDelivery::deleteDelivery($id_cart, $id_customer);
                    return false;
                }

                $id_new_delivery_address = $mr_delivery->createAddressForPickUpPoint(
                    (int)$params['cart']->id_address_delivery
                );

                if (!$id_new_delivery_address) {
                    return false;
                }

                $params['order']->id_address_delivery = $id_new_delivery_address;
                $params['order']->save();

                $mr_delivery->id_order = $params['order']->id;
                $mr_delivery->save();
            }
        }

        return true;
    }

    /**
     * @param Cart[]|Order[]|Customer[]|Currency[]|OrderState[] $params
     * @param Address $delivery_address
     * @return bool
     */
    public function addBeezUpOrderToMrTable($params, $delivery_address)
    {
        $id_cart = $params['cart']->id;
        $id_customer = $params['cart']->id_customer;
        $mr_delivery = new MondialRelayDelivery(null, $id_cart, $id_customer);

        if (!$mr_delivery->validate()) {
            // Mondial Relay order not saved in `ps_mr_selected`
            $mr_delivery->id_cart = $id_cart;
            $mr_delivery->id_customer = $id_customer;
            $mr_delivery->id_method = Db::getInstance()->getValue(
                'SELECT `id_mr_method`
                FROM `'._DB_PREFIX_.'mr_method`
                WHERE `id_carrier` = '.(int)$params['order']->id_carrier
            );
            $mr_delivery->id_order = $params['order']->id;
            $mr_delivery->mr_poids = sprintf('%05d', $params['order']->getTotalWeight() * 1000);
            $mr_delivery->mr_insurance = Db::getInstance()->getValue(
                'SELECT `insurance`
                FROM `'._DB_PREFIX_.'mr_method`
                WHERE `id_carrier` = '.(int) $params['order']->id_carrier
            );
            $mr_delivery->mr_selected_num = filter_var($delivery_address->company, FILTER_SANITIZE_NUMBER_INT);
            $mr_delivery->mr_selected_lgadr1 = '';
            $mr_delivery->mr_selected_lgadr2 = '';
            $mr_delivery->mr_selected_lgadr3 = $delivery_address->address1;
            $mr_delivery->mr_selected_lgadr4 = $delivery_address->address2;
            $mr_delivery->mr_selected_cp = $delivery_address->postcode;
            $mr_delivery->mr_selected_ville = $delivery_address->city;
            $mr_delivery->mr_selected_pays = Tools::strtoupper(Country::getIsoById($delivery_address->id_country));

            return (bool)$mr_delivery->save();
        }

        return true;
    }

    /**
     * @param Cart[]|Order[]|Customer[]|Currency[]|OrderState[] $params
     * @return bool
     */
    public function addManoManoOrderToMrTable($params)
    {
        $delivery_address = new Address((int)$params['order']->id_address_delivery);
        if (!Validate::isLoadedObject($delivery_address)) {
            return false;
        }

        require_once dirname(__FILE__).'/classes/MondialRelayPickupPoint.php';

        $mr_pickup = new MondialRelayPickupPoint();
        $iso_code = Country::getIsoById($delivery_address->id_country);
        $pickup = $mr_pickup->getRelayInformations(
            $delivery_address->other,
            $iso_code
        );

        if (!$pickup) {
            return false;
        }

        $params = array(
            'id_customer' => (int)$params['cart']->id_customer,
            'id_method' => (int)Db::getInstance()->getValue(
                'SELECT `id_mr_method`
                FROM `'._DB_PREFIX_.'mr_method`
                WHERE `id_carrier` = '.(int)$params['order']->id_carrier
            ),
            'id_cart' => (int)$params['cart']->id,
            'id_order' => (int)$params['order']->id,
            'MR_poids' => (float)$params['order']->getTotalWeight(),
            'MR_insurance' => (int)0,
            'MR_Selected_Num' => pSQL($pickup['Num']),
            'MR_Selected_LgAdr1' => pSQL($pickup['LgAdr1']),
            'MR_Selected_LgAdr2' => pSQL($pickup['LgAdr2']),
            'MR_Selected_LgAdr3' => pSQL($pickup['LgAdr3']),
            'MR_Selected_LgAdr4' => pSQL($pickup['LgAdr4']),
            'MR_Selected_CP' => pSQL($pickup['CP']),
            'MR_Selected_Ville' => pSQL($pickup['Ville']),
            'MR_Selected_Pays' => pSQL($iso_code),
            'url_suivi' => null,
            'url_etiquette' => null,
            'exp_number' => null,
            'date_add' => pSQL(date('Y-m-d H:i:s')),
            'date_upd' => pSQL(date('Y-m-d H:i:s'))
        );

        if ($this->ps15x) {
            return Db::getInstance()->insert('mr_selected', $params);
        }

        return Db::getInstance()->autoExecute(_DB_PREFIX_.'mr_selected', $params, 'INSERT');
    }

    public function hookBeforeCarrier($params)
    {
        return $this->hookDisplayBeforeCarrier($params);
    }

    public function hookDisplayBeforeCarrier($params)
    {
        if (!count(MondialRelayCarrier::getMondialRelayCarriers())) {
            return false;
        }

        $pass = true;

        $delivery_address = new Address((int) $params['cart']->id_address_delivery);
        if (!Validate::isLoadedObject($delivery_address)) {
            $pass = false;
        }

        if ($pass && !in_array(
            Tools::strtoupper(Country::getIsoById((int)$delivery_address->id_country)),
            $this->carrier_delivery_countries
        )) {
            return false;
        }

        $relay_carriers = MondialRelayCarrier::getMondialRelayCarriersID();
        $home_carriers = array_diff(
            MondialRelayCarrier::getMondialRelayCarriersID(1, 0, false),
            $relay_carriers
        );

        if (!count(array_merge($relay_carriers, $home_carriers))) {
            return false;
        }

        $this->context->smarty->assign(array(
            'img_url' => $this->url.'views/img/',
            'delivery_address' => array(
                'company' => $delivery_address->company,
                'firstname' => $delivery_address->firstname,
                'lastname' => $delivery_address->lastname,
                'address1' => $delivery_address->address1,
                'address2' => $delivery_address->address2,
                'postcode' => $delivery_address->postcode,
                'city' => $delivery_address->city,
                'phone' => $delivery_address->phone_mobile,
                'country' => Country::getNameById($this->id_lang, $delivery_address->id_country),
            ),
            'mr_relay_carriers_id' => $relay_carriers,
            'mr_relay_carriers_mode' => MondialRelayCarrier::getMondialRelayCarriersDeliveryMode($relay_carriers),
            'mr_home_carriers_id' => $home_carriers,
            'mr_id_customer' => $params['cart']->id_customer,
            'mr_id_cart' => $params['cart']->id,
            'get_delivery_points_url' => $this->url.'functions/get_delivery_points.php',
            'save_delivery_point_url' => $this->url.'functions/save_delivery_point.php',
            'get_otp_for_opc_url' => $this->url.'functions/get_otp_for_opc.php'
        ));

        $module_conf = (array)MondialRelayTools::unSerialize(Configuration::get('MRA_CONF'));

        if ($this->ps17x && $this->active && isset($module_conf['google_map']) && $module_conf['google_map']) {
            // Does not load through Controller on PS 1.7, dont know why.
//                $this->addJS(
//                    'https://maps.google.com/maps/api/js?libraries=places&key='.
//                    (isset($module_conf['google_map_key']) ? $module_conf['google_map_key'] : '')
//                );
            echo '<script type="text/javascript" src="https://maps.google.com/maps/api/js?libraries=places&key='.
                (isset($module_conf['google_map_key']) ? $module_conf['google_map_key'] : '').'"></script>';

            // OTP coz hookDisplayFooter is not called
            $this->context->smarty->assign(
                'mr_otp',
                MondialRelayOTP::createOTPStatic((int)$params['cart']->id_customer)
            );

            return $this->display(__FILE__, 'views/templates/front/displayBeforeCarrier.tpl').
                $this->display(__FILE__, 'views/templates/front/displayFooter.tpl');
        }

        return $this->display(__FILE__, 'views/templates/front/displayBeforeCarrier.tpl');
    }

    public function hookFooter($params)
    {
        return $this->hookDisplayFooter($params);
    }


    public function hookDisplayFooter($params)
    {
        $allowed_controllers = array('OrderController', 'OrderOpcController', 'ControllerBackwardModule');

        if (in_array(get_class($this->context->controller), $allowed_controllers)) {
            $this->context->smarty->assign(array(
                'mr_otp' => MondialRelayOTP::createOTPStatic((int)$params['cart']->id_customer)
            ));

            return $this->display(__FILE__, 'views/templates/front/displayFooter.tpl');
        }

        return false;
    }

    public function hookHeader()
    {
        return $this->hookDisplayHeader();
    }

    public function hookDisplayHeader()
    {
        $allowed_controllers = array('OrderController', 'OrderOpcController', 'ControllerBackwardModule');

        if (in_array(get_class($this->context->controller), $allowed_controllers)) {
            $module_conf = (array)MondialRelayTools::unSerialize(Configuration::get('MRA_CONF'));

            if ($this->ps15x) {
                $this->addCSS($this->url.'views/css/jquery.qtip.min.css', 'all');
                $this->addJS($this->url.'views/js/jquery.qtip.min.js');
            }

            $this->addCSS($this->url.'views/css/front.css', 'all');
            $this->addJS($this->url.'views/js/front.js');

            if (!$this->ps17x && $this->active && isset($module_conf['google_map']) && $module_conf['google_map']) {
                // Does not load through Controller on PS 1.7, dont know why, so 1.7 is done in hook
                $this->addJS(
                    'https://maps.google.com/maps/api/js?libraries=places&key='.
                    (isset($module_conf['google_map_key']) ? $module_conf['google_map_key'] : '')
                );
            }
        }
    }

    public function hookAdminOrder($params)
    {
        return $this->hookDisplayAdminOrder($params);
    }

    public function hookDisplayAdminOrder($params)
    {
        require_once dirname(__FILE__).'/classes/MondialRelayDelivery.php';

        if (!$this->ps15x && !$this->ps16x) {
            $params['cart'] = Cart::getCartByOrderId($params['id_order']);
            if (!Validate::isLoadedObject($params['cart'])) {
                return false;
            }
            $this->context->smarty->assign('mr_ps14x', true);
        }

        $id_cart = (int)$params['cart']->id;
        $id_customer = (int)$params['cart']->id_customer;

        $mr_customer = new Customer($id_customer);
        if (!Validate::isLoadedObject($mr_customer)) {
            return false;
        }

        $order = new Order((int) $params['id_order']);
        if (!Validate::isLoadedObject($order)) {
            return false;
        }

        $customer_address = new Address($order->id_address_delivery);
        if (!Validate::isLoadedObject($customer_address)) {
            return false;
        }

        $mr_delivery = new MondialRelayDelivery(null, $id_cart, $id_customer);
        if (!$mr_delivery->validate() && Tools::strtolower($order->payment) == 'cdiscount' &&
            (int)filter_var($customer_address->other, FILTER_SANITIZE_NUMBER_INT)) {
            // Create order for CDiscount
            $mr_delivery->id_mr_selected = null;
            $mr_delivery->id_customer = $id_customer;
            $mr_delivery->id_cart = $id_cart;
            $mr_delivery->id_method = Db::getInstance()->getValue(
                'SELECT `id_mr_method`
                FROM `'._DB_PREFIX_.'mr_method`
                WHERE `id_carrier` = '.(int)$order->id_carrier
            );
            $mr_delivery->id_order = $order->id;
            $mr_delivery->mr_poids = sprintf('%05d', $order->getTotalWeight() * 1000);
            $mr_delivery->mr_insurance = Db::getInstance()->getValue(
                'SELECT `insurance`
                FROM `'._DB_PREFIX_.'mr_method`
                WHERE `id_carrier` = '.(int)$order->id_carrier
            );
            $mr_delivery->mr_selected_num = (int)filter_var($customer_address->other, FILTER_SANITIZE_NUMBER_INT);
            $mr_delivery->mr_selected_lgadr1 = '';
            $mr_delivery->mr_selected_lgadr2 = '';
            $mr_delivery->mr_selected_lgadr3 = $customer_address->address1;
            $mr_delivery->mr_selected_lgadr4 = $customer_address->address2;
            $mr_delivery->mr_selected_cp = $customer_address->postcode;
            $mr_delivery->mr_selected_ville = $customer_address->city;
            $mr_delivery->mr_selected_pays = Tools::strtoupper(Country::getIsoById($customer_address->id_country));
            $mr_delivery->url_etiquette = null;
            $mr_delivery->url_suivi = null;
            $mr_delivery->exp_number = null;
            $mr_delivery->date_add = date('Y-m-d H:i:s');
            $mr_delivery->date_upd = date('Y-m-d H:i:s');

            $id_mr_selected = $mr_delivery->save();
            if ($id_mr_selected) {
                $mr_delivery->id_mr_selected = (int)$id_mr_selected;
            }
        }

        if (!$mr_delivery->validate()) {
            // ppp($mr_delivery);
            return false;
        }

        // Update tracking URL with postcode
        // Required to see the tracking on http://www.mondialrelay.fr/suivi-de-colis
        // Else seller needs to type in the postcode
        $mr_delivery->url_suivi = strtr(
            'http://www.mondialrelay.fr/suivi-de-colis?numeroExpedition={exp_number}&CodePostal={postcode}',
            array(
                '{exp_number}' => $mr_delivery->exp_number,
                '{postcode}' => $mr_delivery->mr_selected_cp
            )
        );

        $cookie = new Cookie('mra_current_employee', '/', time() + (86400 * 30));
        $cookie->variable_name = $this->context->employee->id;

        $alert_class = array();
        $alert_class['danger'] = $this->ps16x ? 'alert alert-danger' : 'error';
        $alert_class['warning'] = $this->ps16x ? 'alert alert-warning' : 'warn';
        $alert_class['success'] = $this->ps16x ? 'alert alert-success' : 'conf';
        $alert_class['info'] = $this->ps16x ? 'alert alert-info' : 'info';

        $this->context->smarty->assign(array(
            'img_url' => $this->url.'views/img/',
            'folder_path' => $this->_path,
            'mr_id_customer' => $params['cart']->id_customer,
            'mr_id_cart' => $params['cart']->id,
            'mr_delivery' => $mr_delivery,
            'mr_delivery_country' => Country::getNameById(
                $this->context->language->id,
                (int)Country::getByIso($mr_delivery->mr_selected_pays)
            ),
            'mr_customer' => $mr_customer,
            'mr_address' => $customer_address,
            'mr_get_delivery_label_url' => $this->url.'functions/get_delivery_label.php?token='.
                Configuration::get('MRA_TOKEN'),
            'mr_get_tracking_url' => $this->url.'functions/get_tracking.php?token='.Configuration::get('MRA_TOKEN'),
            'alert_class' => $alert_class,
            'is_home_delivery' => MondialRelayCarrier::isHomeDelivery($order->id_carrier),
            'mr_weight' => $params['cart']->getTotalWeight(),
            'mr_weight_unit' => Configuration::get('PS_WEIGHT_UNIT')
        ));

        $this->addCSS($this->_path.'views/css/ps-icon-pack.min.css', 'all');
        $this->addCSS($this->_path.'views/css/admin_orders.css', 'all');
        $this->addJS($this->_path.'views/js/admin_orders.js');
        $this->addJS($this->_path.'views/js/plug.min.js');

        return $this->display(__FILE__, 'views/templates/hook/displayAdminOrder.tpl');
    }
}
