<?php

/*
 * 2007-2014 Addonline
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 *  @author Addonline <contact@addonline.fr>
 *  @copyright  2007-2014 Addonline
 *  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

require_once(dirname(__FILE__) . '/../gls.php');

class GlsManagement extends Gls {

    private $_params = array();
    private $_filename = '';
    private $_resultList = array(
        'error' => array(),
        'success' => array());
    private $_aProductnoCorrespondance = array(
        'BP' => '02',
        'BP_international' => '01',
        'ADO' => '18',
        'ADO_international' => '19',
        'SHD' => '17',
        'EXP' => '16'
    );

    public function __construct($params) {
        $this->_params = $params;

        parent::__construct();
    }

    public function __destruct() {
        
    }

    public function uninstallDetail() {
        $html = '';

        switch ($this->_params['action']) {
            case 'showFancy':
                $html .= '
					<div id="PS_GLSAskBackupContent">
						<h2>' . $this->l('Uninstalling Gls') . '</h2>
						<div>
							' . $this->l('You\'re about to uninstall the module, do you want to remove the database') . ' ?
							<p id="PS_GLSUninstallListSelection">
									<input type="button" id="PS_GLS_BackupAction" href="javascript:void(0)" value="' . $this->l('Keep it and uninstall') . '"/>
									<br />
									<input type="button" id="PS_GLS_UninstallAction" href="javascript:void(0)" value="' . $this->l('Remove and uninstall') . '" />
									<br />
									<input type="button" id="PS_GLS_StopUninstall" href="javascript:void(0)" value="' . $this->l('Cancel') . '" />
									<br />
							</p>
						</div>
					</div>
				';
                $this->_resultList['html'] = $html;
                break;
            case 'backupAndUninstall':

                break;
            default:
        }
        return $this->_resultList;
    }

    public function GLSexportToWinExpe() {

        /*
         * Csv export configuration
         */
        $delimiter = ';';
        $encloser = '"';
        $this->_filename = 'GlsCmd_' . $this->udate('YmdHisu') . '.csv';

        /*
         * Get the export Folder
         */
        $glsConfiguration = Gls::getAccountDetail();
        ($glsConfiguration['GLS_EXPORT_FOLDER']) ? $exportFolder = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $glsConfiguration['GLS_EXPORT_FOLDER'] : $exportFolder = dirname(__FILE__) . '/../export/';

        (is_array($this->_params["orderIdList"])) ? $orderIdLists = implode(',', $this->_params["orderIdList"]) : $orderIdLists = '';

        $aWeightList = array();
        if (is_array($this->_params["weightList"]) && count($this->_params["weightList"]) > 0) {
            foreach ($this->_params["weightList"] as $weight) {
                $aTemp = explode('-', $weight);
                $aWeightList[$aTemp[1]] = $aTemp[0];
            }
        }

        if ($orderIdLists && $orderIdLists != '') {

            $query = '
				SELECT o.id_order,daddress.lastname, daddress.firstname,daddress.address1,daddress.address2,daddress.postcode,daddress.city,daddress.phone,carrier.external_module_name,SUM(od.product_weight*od.product_quantity) as order_weight,customer.id_customer,customer.email,gls.relay_warnbyphone,gls.relay_phone,country.iso_code,gls.relay_id,daddress.company,daddress.phone_mobile
				FROM `' . _DB_PREFIX_ . 'orders` o
				LEFT JOIN `' . _DB_PREFIX_ . 'address` daddress ON (o.id_address_delivery = daddress.id_address)
				LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON (o.id_order = od.id_order)
				LEFT JOIN `' . _DB_PREFIX_ . 'carrier` carrier ON (o.id_carrier = carrier.id_carrier)
				LEFT JOIN `' . _DB_PREFIX_ . 'customer` customer ON (o.id_customer = customer.id_customer)
				LEFT JOIN `' . _DB_PREFIX_ . 'GLS_delivery_info` gls ON (o.id_customer = gls.id_customer AND o.id_cart = gls.id_cart)
				LEFT JOIN `' . _DB_PREFIX_ . 'country` country ON (daddress.id_country = country.id_country)
				WHERE o.id_order in(' . $orderIdLists . ')
				GROUP BY o.id_order
				;';
        } else {
            $query = '
				SELECT o.id_order,daddress.lastname, daddress.firstname,daddress.address1,daddress.address2,daddress.postcode,daddress.city,daddress.phone,carrier.external_module_name,SUM(od.product_weight*od.product_quantity) as order_weight,customer.id_customer,customer.email,gls.relay_warnbyphone,gls.relay_phone,country.iso_code,gls.relay_id,daddress.company,daddress.phone_mobile
				FROM `' . _DB_PREFIX_ . 'orders` o
				LEFT JOIN `' . _DB_PREFIX_ . 'address` daddress ON (o.id_address_delivery = daddress.id_address)
				LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON (o.id_order = od.id_order)
				LEFT JOIN `' . _DB_PREFIX_ . 'carrier` carrier ON (o.id_carrier = carrier.id_carrier)
				LEFT JOIN `' . _DB_PREFIX_ . 'customer` customer ON (o.id_customer = customer.id_customer)
				LEFT JOIN `' . _DB_PREFIX_ . 'GLS_delivery_info` gls ON (o.id_customer = gls.id_customer AND o.id_cart = gls.id_cart)
				LEFT JOIN `' . _DB_PREFIX_ . 'GLS_orders_import_export` gls_ie ON (o.id_order = gls_ie.id_order)			
				LEFT JOIN `' . _DB_PREFIX_ . 'country` country ON (daddress.id_country = country.id_country)
				WHERE gls_ie.exported IS NULL
				GROUP BY o.id_order
				;';
        }

        //On teste la requete afin de créer la table si elle n'existe pas
        $aOrdersToExport = Db::getInstance()->executeS($query);

        if (!$aOrdersToExport) {
            //Test de la présence de la table
            if ($this->tableExists(_DB_PREFIX_ . 'GLS_orders_import_export')) {
                return false;
            } else {
                $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'GLS_orders_import_export` (
					  `id_order` int(10) NOT NULL,
					  `imported` tinyint(1) NULL,
					  `exported` tinyint(1) NULL,
					  PRIMARY KEY  (`id_order`)
					) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;';
                Db::getInstance()->execute($sql);

                $aOrdersToExport = Db::getInstance()->executeS($query);
            }
        }

        if (!is_array($aOrdersToExport))
            $aOrdersToExport = array();

        if (count($aOrdersToExport) <= 0) {
            return $this->l('Error : No order to export');
        }

        $aOrdersExported = array();

        // HEADERS of the file
        $aheaders = array('ORDERID', 'ORDERNAME', 'PRODUCTNO', 'ORDERWEIGHTTOT', 'CONSID', 'CONTACT', 'CONTACTMAIL', 'CONTACTMOBILE', 'CONTACTPHONE', 'STREET1', 'STREET2', 'STREET3', 'COUNTRYCODE', 'CITY', 'ZIPCODE', 'REFPR');
        $aOrdersExported[] = $aheaders;

        // Parsing of the orders
        foreach ($aOrdersToExport as $order) {
            $aRow = array();

            // ORDERID
            $aRow[] = $order['id_order'];

            //Test s'il y a un nom de société
            if ($order['company']) {
                $aRow[] = $order['company'];
            } else {
                $aRow[] = mb_strtoupper($order['firstname'] . ' ' . $order['lastname'], 'UTF-8');
            }

            // PRODUCTNO
            if ($order['external_module_name'] == 'gls') {
                $shippingMethod = 'EXP';
            } else {
                $shippingMethod = mb_strtoupper(Tools::substr($order['external_module_name'], 4, 3), 'UTF-8');
            }

            if (mb_strtoupper($order['iso_code'], 'UTF-8') != 'FR') {
                $aRow[] = $this->_aProductnoCorrespondance[$shippingMethod . '_international'];
            } else {
                $aRow[] = $this->_aProductnoCorrespondance[$shippingMethod];
            }

            // ORDERWEIGHTTOT
            if ($order['order_weight'] != $aWeightList[$order['id_order']]) {
                $aRow[] = str_pad(number_format($aWeightList[$order['id_order']] / 1000, 2, '.', ''), 5, "0", STR_PAD_LEFT);
            } else {
                $aRow[] = str_pad(number_format($order['order_weight'], 2, '.', ''), 5, "0", STR_PAD_LEFT);
            }

            // CONSID
            $aRow[] = $order['id_customer'];

            // CONTACT
            if ($order['company']) {
                $aRow[] = mb_strtoupper($order['firstname'] . ' ' . $order['lastname'], 'UTF-8');
            } else {
                if ($shippingMethod == 'EXP') {
                    /* If Shipping method is express, CONTACT field is always FIRSTNAME - LASTNAME */
                    $aRow[] = mb_strtoupper($order['firstname'] . ' ' . $order['lastname'], 'UTF-8');
                } else {
                    $aRow[] = '';
                }
            }

            // CONTACTMAIL
            $aRow[] = $order['email'];

            // CONTACTMOBILE
            if ($shippingMethod != 'SHD') {
                $aRow[] = $order['phone_mobile'];
            } else {
                $aRow[] = $order['relay_warnbyphone'] ? $order['relay_phone'] : '';
            }

            // CONTACTPHONE
            if (!$order['phone']) {
                $aRow[] = $order['phone_mobile'];
            } else {
                $aRow[] = $order['phone'];
            }

            if ($order['address1'] > 35 || Tools::strlen($order['address2']) > 35) {
                $street = $order['address1'] . ' ' . $order['address2'];
                $street = wordwrap($street, 35, ';', true);
                $aStreet = explode(';', $street);

                // STREET1
                $aRow[] = mb_strtoupper(isset($aStreet[0]) ? $aStreet[0] : null, 'UTF-8');
                // STREET2
                $aRow[] = mb_strtoupper(isset($aStreet[1]) ? $aStreet[1] : null, 'UTF-8');
            } else {
                // STREET1
                $aRow[] = mb_strtoupper($order['address1'], 'UTF-8');

                // STREET2
                $aRow[] = mb_strtoupper($order['address2'], 'UTF-8');
            }

            // STREET3
            $aRow[] = '';

            // COUNTRYCODE
            $aRow[] = mb_strtoupper($order['iso_code'], 'UTF-8');

            // CITY
            $aRow[] = mb_strtoupper($this->stripAccents($order['city']), 'UTF-8');

            // ZIPCODE
            $aRow[] = mb_strtoupper($order['postcode'], 'UTF-8');

            // REFPR (identifiant du point relais)
            $aRow[] = $order['relay_id'];

            // Adding the order to the export array
            $aOrdersExported[] = $aRow;

            if (!$orderIdLists == '') {

                $query = 'DELETE FROM `' . _DB_PREFIX_ . 'GLS_orders_import_export` WHERE `id_order` = ' . $order['id_order'] . ';';
                if (!Db::getInstance()->execute($query)) {
                    if (!$this->tableExists(_DB_PREFIX_ . 'GLS_orders_import_export')) {
                        $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'GLS_orders_import_export` (
					  `id_order` int(10) NOT NULL,
					  `imported` tinyint(1) NULL,
					  `exported` tinyint(1) NULL,
					  PRIMARY KEY  (`id_order`)
					) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;';
                        Db::getInstance()->execute($sql);

                        $query = 'DELETE FROM `' . _DB_PREFIX_ . 'GLS_orders_import_export` WHERE `id_order` = ' . $order['id_order'] . ';';
                        Db::getInstance()->execute($query);
                    } else {
                        return false;
                    }
                }
            }

            $query = 'INSERT INTO `' . _DB_PREFIX_ . 'GLS_orders_import_export` (`id_order`,
			`imported`,
			`exported`)
			VALUES
			(' . $order['id_order'] . ',
			0,
			1);';

            if (!Db::getInstance()->execute($query))
                return false;
        }

        /*
         * Save the file
         */
        $writeCsv = $this->array2csv($aOrdersExported, $this->_filename, $delimiter, $encloser, $exportFolder);
        ($writeCsv) ? $return = $writeCsv : $return = count($aOrdersExported) - 1 . ' ' . $this->l('orders exported');

        return _PS_BASE_URL_ . __PS_BASE_URI__ . DIRECTORY_SEPARATOR . $glsConfiguration['GLS_EXPORT_FOLDER'] . DIRECTORY_SEPARATOR . $this->_filename;
    }

    private function udate($format = 'u', $utimestamp = null) {
        if (is_null($utimestamp))
            $utimestamp = microtime(true);

        $timestamp = floor($utimestamp);
        $milliseconds = round(($utimestamp - $timestamp) * 1000000);
        $milliseconds = Tools::substr($milliseconds, 0, 2);
        return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp);
    }

    private function array2csv(array &$array, $filename, $delimiter = ';', $encloser = '"', $folder = 'modules/gls/export/') {
        if (count($array) == 0) {
            return null;
        }

        if (!file_exists($folder) and ! is_dir($folder)) {
            if (!@mkdir($folder, '777', true)) {
                $error = error_get_last();
                return $folder . ' ' . $error['message'];
            }
        }

        ob_start();
        try {
            $df = fopen($folder . DIRECTORY_SEPARATOR . $filename, 'w+');
        } catch (Exception $e) {
            return ($e->message());
        }
        foreach ($array as $row) {
            //WINEXPE attends de l'ISO-8859-1
            foreach (array_keys($row) as $key) {
                $row[$key] = iconv('UTF-8', 'ISO-8859-9', $row[$key]);
            }

            fputcsv($df, $row, $delimiter, $encloser);
        }
        fclose($df);
        return ob_get_clean();
    }

    public function GLSImportFromWinExpe() {


        Configuration::updateValue('GLS_ORDER_STATE_IMPORT', $this->_params["orderStateImport"]);

        /*
         * Get the import Folder
         */
        $glsConfiguration = Gls::getAccountDetail();
        ($glsConfiguration['GLS_IMPORT_FOLDER']) ? $importFolder = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $glsConfiguration['GLS_IMPORT_FOLDER'] : $importFolder = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR;

        if (!file_exists($importFolder) and ! is_dir($importFolder)) {
            return $importFolder . ' ' . $this->l('does not exist');
        }

        $dir = opendir($importFolder);
        $count = 0;

        //Parcour du dossier
        while ($file = readdir($dir)) {
            if ($file != '.' && $file != '..' && !is_dir($importFolder . $file) && strpos($file, 'GlsWinExpe6_') !== FALSE) {
                $aOrdersUpdated = array();
                // Parcour du fichier
                if (($handle = fopen($importFolder . DIRECTORY_SEPARATOR . $file, "r")) !== FALSE) {
                    $row = 0;
                    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
                        $num = count($data);
                        $row++;
                        if ($row > 1 && isset($data[4]) && $data[4]) {
                            // On récupère le champ 5 qui contient le numéro de la commande
                            // chargement de la commande
                            $order = new Order($data[4]);

                            $id_order_carrier = Db::getInstance()->getValue('SELECT `id_order_carrier`   FROM `' . _DB_PREFIX_ . 'order_carrier`    WHERE `id_order` = ' . (int) $data[4]);

                            //Si la commande n'existe pas
                            if (!$id_order_carrier)
                                continue;

                            $order_carrier = new OrderCarrier($id_order_carrier);

                            if (strpos($order_carrier->tracking_number, $data[17]) === false) {
                                if ($order_carrier->tracking_number) {
                                    $order_carrier->tracking_number = $order_carrier->tracking_number . ',' . pSQL($data[17]);
                                } else {
                                    $order_carrier->tracking_number = pSQL($data[17]);
                                }
                                $order_carrier->update();
                            }

                            // On met à jour le trackid avec le champ 18
                            try {
                                if (strpos($order->shipping_number, $data[17]) === false) {
                                    if ($order->shipping_number) {
                                        $order->shipping_number .= ',' . $data[17];
                                    } else {
                                        $order->shipping_number = $data[17];
                                    }

                                    $order->update();
                                }
                            } catch (Exception $e) {
                                return $this->l('Order ') . $data[4] . ' ' . $this->l('has no shipping number in the import file ');
                            }

                            try {
                                // Changement du status de la commande
                                $new_order_state = new OrderState($this->_params["orderStateImport"]);
                                $current_order_state = $order->getCurrentOrderState();
                                if ($current_order_state->id != $new_order_state->id) {
                                    // Create new OrderHistory
                                    $history = new OrderHistory();
                                    $history->id_order = $order->id;
                                    $history->id_order_state = $new_order_state->id;

                                    //Sauvegarde dans la base de donnée de l'import
                                    $query = 'UPDATE `' . _DB_PREFIX_ . 'GLS_orders_import_export` set imported = 1 WHERE `id_order` = ' . $data[4] . ';';
                                    if (!Db::getInstance()->execute($query)) {
                                        if (!$this->tableExists(_DB_PREFIX_ . 'GLS_orders_import_export')) {
                                            $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'GLS_orders_import_export` (
												  `id_order` int(10) NOT NULL,
												  `imported` tinyint(1) NULL,
												  `exported` tinyint(1) NULL,
												  PRIMARY KEY  (`id_order`)
												) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;';
                                            Db::getInstance()->execute($sql);

                                            $query = 'DELETE FROM `' . _DB_PREFIX_ . 'GLS_orders_import_export` WHERE `id_order` = ' . $order['id_order'] . ';';
                                            Db::getInstance()->execute($query);
                                        } else {
                                            return false;
                                        }
                                    }

                                    $use_existings_payment = false;
                                    if (!$order->hasInvoice())
                                        $use_existings_payment = true;
                                    $history->changeIdOrderState((int) $new_order_state->id, $order, $use_existings_payment);
                                    $history->addWithemail(true);
                                    $history->save();
                                }
                            } catch (Exception $e) {
                                Logger::addLog($e->getMessage());
                                return $this->l('Order ') . $data[4] . ' ' . $this->l('No change of status ');
                            }

                            $count++;
                        }
                    }
                    fclose($handle);

                    try {
                        unlink($importFolder . DIRECTORY_SEPARATOR . $file);
                    } catch (Exception $e) {
                        return ("Import : unable to delete file : " . $importFolder . $file);
                    }
                }
            }
        }

        closedir($dir);
        return $count . ' ' . $this->l('orders imported');
    }

    public function stripAccents($string) {
        return strtr($string, 'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ', 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
    }

    public function tableExists($tableName) {
        $tables = Db::getInstance()->executeS('SHOW TABLES');
        foreach ($tables as $key => $table) {
            if ($table == $tableName) {
                return true;
            }
        }
        return false;
    }

}
