Current File : /var/www/vinorea/modules/ipexportimport/classes/export/EIAOrdersExport.php
<?php
/**
 *
 * NOTICE OF LICENSE
 *
 *  @author    SmartPresta <tehran.alishov@gmail.com>
 *  @copyright 2024 SmartPresta
 *  @license   http://opensource.org/licenses/afl-3.0.php Commercial License!
 */

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

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

class EIAOrdersExport extends EIAExport
{
    protected $xmlMainTag = 'Order';
    protected $xmlMainTagPl = 'Orders';

    public function __construct($module)
    {
        parent::__construct($module);
        $this->entityNamePl = $module->l('Orders', 'EIAOrdersExport');
    }

    protected function getDataFromDb()
    {
        Db::getInstance()->execute('SET SQL_BIG_SELECTS=1');
        Db::getInstance()->execute('SET SESSION group_concat_max_len = 1000000');
        
        // Columns that do not exist directly in the DB
        $absentColumns = array(
            'product_image' => 'product.product_id',
            'attribute_image' => 'CONCAT_WS("-", product.product_id, product.product_attribute_id, `order`.id_shop)',
        );

        $del = !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "order_detail` LIKE 'id_tax_rules_group'"));
        $newColumns = [
            'product.product_isbn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "order_detail` LIKE 'product_isbn'")),
            'product.product_mpn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "order_detail` LIKE 'product_mpn'")),
            'product_attribute.isbn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "product_attribute` LIKE 'isbn'")),
            'product_attribute.mpn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "product_attribute` LIKE 'mpn'")),
            'product.original_wholesale_price' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "order_detail` LIKE 'original_wholesale_price'")),
            'product.id_tax_rules_group' => $del,
            'tax_rules_group.name' => $del
        ];

        if (in_array($this->fileType, ['csv', 'xml', 'json'])) {
            if (isset($this->selectedColumns['product_image'])) {
                unset($this->selectedColumns['product_image']);
            }
            if (isset($this->selectedColumns['attribute_image'])) {
                unset($this->selectedColumns['attribute_image']);
            }
        }

        // Get the inputs and filters
        if ($this->auto) {
            $products = pSQL(implode(',', $this->datatables['products']['data']));
            $productsType = $this->datatables['products']['type'];
            
            $carriersWithout = $this->inputs['carrier_without'];
            $carriers = pSQL(implode(',', $this->datatables['carriers']['data']));
            $carriersType = $this->datatables['carriers']['type'];

            $suppliersWithout = $this->inputs['supplier_without'];
            $suppliers = pSQL(implode(',', $this->datatables['suppliers']['data']));
            $suppliersType = $this->datatables['suppliers']['type'];

            $cartRulesWithout = $this->inputs['cartRules_without'];
            $cartRules = pSQL(implode(',', $this->datatables['cartRules']['data']));
            $cartRulesType = $this->datatables['cartRules']['type'];

            $shops = pSQL(implode(',', $this->datatables['shops']['data']));
            $shopsType = $this->datatables['shops']['type'];

            $orders = pSQL(implode(',', $this->datatables['orders']['data']));
            $ordersType = $this->datatables['orders']['type'];

            $orderStates = pSQL(implode(',', $this->datatables['orderStates']['data']));
            $orderStatesType = $this->datatables['orderStates']['type'];

            $paymentMethods = pSQL(implode(',', $this->datatables['paymentMethods']['data']));
            $paymentMethodsType = $this->datatables['paymentMethods']['type'];

            $customerWithout = $this->inputs['customer_without'];
            $customers = pSQL(implode(',', $this->datatables['customers']['data']));
            $customersType = $this->datatables['customers']['type'];

            $groupWithout = $this->inputs['group_without'];
            $groups = pSQL(implode(',', $this->datatables['groups']['data']));
            $groupsType = $this->datatables['groups']['type'];

            $manufacturerWithout = $this->inputs['manufacturer_without'];
            $manufacturers = pSQL(implode(',', $this->datatables['manufacturers']['data']));
            $manufacturersType = $this->datatables['manufacturers']['type'];
        } else {
            $products = pSQL(Tools::getValue('products_data'));
            $productsType = Tools::getValue('products_type');

            $carriersWithout = Tools::getValue('carrier_without');
            $carriers = pSQL(Tools::getValue('carriers_data'));
            $carriersType = Tools::getValue('carriers_type');

            $suppliersWithout = Tools::getValue('supplier_without');
            $suppliers = pSQL(Tools::getValue('suppliers_data'));
            $suppliersType = Tools::getValue('suppliers_type');

            $cartRulesWithout = Tools::getValue('cartRules_without');
            $cartRules = pSQL(Tools::getValue('cartRules_data'));
            $cartRulesType = Tools::getValue('cartRules_type');

            $shops = pSQL(Tools::getValue('shops_data'));
            $shopsType = Tools::getValue('shops_type');

            $orders = pSQL(Tools::getValue('orders_data'));
            $ordersType = Tools::getValue('orders_type');

            $orderStates = pSQL(Tools::getValue('orderStates_data'));
            $orderStatesType = Tools::getValue('orderStates_type');

            $paymentMethods = pSQL(Tools::getValue('paymentMethods_data'));
            $paymentMethodsType = Tools::getValue('paymentMethods_type');

            $customerWithout = Tools::getValue('customer_without');
            $customers = pSQL(Tools::getValue('customers_data'));
            $customersType = Tools::getValue('customers_type');

            $groupWithout = Tools::getValue('group_without');
            $groups = pSQL(Tools::getValue('groups_data'));
            $groupsType = Tools::getValue('groups_type');

            $manufacturerWithout = Tools::getValue('manufacturer_without');
            $manufacturers = pSQL(Tools::getValue('manufacturers_data'));
            $manufacturersType = Tools::getValue('manufacturers_type');
        }
        
        $eIHelper = new EIAHelper($this->module);

        // Build the SELECT SQL
        $this->sql = '
            SELECT SQL_CALC_FOUND_ROWS ';
        if (in_array($this->fileType, ['xml'])) {
            $fieldsInTree = $eIHelper->getFieldsInTree('orders');
            foreach ($this->selectedColumns as $k => $col) {
                if (array_key_exists($k, $absentColumns)) {
                    $this->sql .= "
                    {$absentColumns[$k]} `{$fieldsInTree[$k]}`, ";
                } elseif (array_key_exists($k, $newColumns) && !$newColumns[$k]) {
                    $this->sql .= "
                    '' `{$fieldsInTree[$k]}`, ";
                } elseif ($this->fracPart !== -1 && (
                        strpos($k, 'rate') !== false ||
                        strpos($k, 'total') !== false ||
                        strpos($k, 'weight') !== false ||
                        strpos($k, 'price') !== false ||
                        strpos($k, 'percent') !== false ||
                        strpos($k, 'amount') !== false ||
                        strpos($k, 'reduction') !== false ||
                        strpos($k, 'discount') !== false ||
                        strpos($k, 'ecotax') !== false
                        )) {
                    $this->sql .= "
                        ROUND($k, $this->fracPart) `{$fieldsInTree[$k]}`, ";
                } else {
                    $this->sql .= "
                        $k `{$fieldsInTree[$k]}`, ";
                }
            }
        } else {
            foreach ($this->selectedColumns as $k => $col) {
                if (array_key_exists($k, $absentColumns)) {
                    $this->sql .= "
                    {$absentColumns[$k]} `$col`, ";
                } elseif (array_key_exists($k, $newColumns) && !$newColumns[$k]) {
                    $this->sql .= "
                    '' `$col`, ";
                } elseif ($this->fracPart !== -1 && (
                        strpos($k, 'rate') !== false ||
                        strpos($k, 'total') !== false ||
                        strpos($k, 'weight') !== false ||
                        strpos($k, 'price') !== false ||
                        strpos($k, 'percent') !== false ||
                        strpos($k, 'amount') !== false ||
                        strpos($k, 'reduction') !== false ||
                        strpos($k, 'discount') !== false ||
                        strpos($k, 'ecotax') !== false
                        )) {
                    $this->sql .= "
                        ROUND($k, $this->fracPart) `$col`, ";
                } else {
                    $this->sql .= "
                        $k `$col`, ";
                }
            }
        }

        $this->sql = rtrim($this->sql, ', ');

        // Filter By Carrier
        $carriersCond = $carriersCond2 = '';
        if ($carriers) {
            if ($carriersType === 'unselected') {
                $carriersCond = ' AND carrier.id_reference NOT IN (' . $carriers . ')';
            } else {
                $carriersCond = ' AND carrier.id_reference IN (' . $carriers . ')';
            }
            $carriersCond2 .= 'carrier.id_order IS NOT NULL';
            if ($carriersWithout !== '0') {
                $carriersCond2 .= ' OR for_null_carrier.id_order IS NULL';
            }
            $carriersCond2 = ' 
                AND (' . $carriersCond2 . ')';
        } else {
            if ($carriersWithout !== '0' && $carriersType === 'selected') {
                $carriersCond2 .= ' 
                    AND (for_null_carrier.id_order IS NULL)';
            } elseif ($carriersWithout === '0' && $carriersType === 'unselected') {
                $carriersCond2 .= ' 
                    AND (for_null_carrier.id_order IS NOT NULL)';
            }
        }

        // Filter By Cart Rules
        $cartRulesCond = $cartRulesCond2 = '';
        if ($cartRules) {
            if ($cartRulesType === 'unselected') {
                $cartRulesCond = ' AND id_cart_rule NOT IN (' . $cartRules . ')';
            } else {
                $cartRulesCond = ' AND id_cart_rule IN (' . $cartRules . ')';
            }
            $cartRulesCond2 .= 'cart_rule.id_order IS NOT NULL';
            if ($cartRulesWithout !== '0') {
                $cartRulesCond2 .= ' OR for_null_cart_rule.id_order IS NULL';
            }
            $cartRulesCond2 = ' 
                AND (' . $cartRulesCond2 . ')';
        } else {
            if ($cartRulesWithout !== '0' && $cartRulesType === 'selected') {
                $cartRulesCond2 .= ' 
                    AND (for_null_cart_rule.id_order IS NULL)';
            } elseif ($cartRulesWithout === '0' && $cartRulesType === 'unselected') {
                $cartRulesCond2 .= ' 
                    AND (for_null_cart_rule.id_order IS NOT NULL)';
            }
        }

        // Filter By Supplier
        $suppliersCond = $suppliersCond2 = '';
        if ($suppliers) {
            if ($suppliersType === 'unselected') {
                $suppliersCond = ' AND id_supplier NOT IN (' . $suppliers . ')';
            } else {
                $suppliersCond = ' AND id_supplier IN (' . $suppliers . ')';
            }
            $suppliersCond2 .= 'supplier.id_product IS NOT NULL';
            if ($suppliersWithout !== '0') {
                $suppliersCond2 .= ' OR for_null_supplier.id_product IS NULL';
            }
            $suppliersCond2 = ' 
                AND (' . $suppliersCond2 . ')';
        } else {
            if ($suppliersWithout !== '0' && $suppliersType === 'selected') {
                $suppliersCond2 .= ' 
                    AND (for_null_supplier.id_product IS NULL)';
            } elseif ($suppliersWithout === '0' && $suppliersType === 'unselected') {
                $suppliersCond2 .= ' 
                    AND (for_null_supplier.id_product IS NOT NULL)';
            }
        }

        $this->sql .= '
            FROM 
            ' . _DB_PREFIX_ . 'orders `order`
            LEFT JOIN ' . _DB_PREFIX_ . 'order_detail `product` USING(id_order) 
            LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute product_attribute ON product.product_attribute_id = product_attribute.id_product_attribute
            LEFT JOIN (
                SELECT 
                    order_reference,
                    GROUP_CONCAT(id_order_payment ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") id_order_payment,
                    GROUP_CONCAT(payment.id_currency ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") id_currency,
                    GROUP_CONCAT(currency.iso_code ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") `currency_iso_code`,
                    GROUP_CONCAT(ROUND(amount, ' . $this->fracPart . ') ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") `amount`,
                    GROUP_CONCAT(payment_method ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") payment_method,
                    GROUP_CONCAT(payment.conversion_rate ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") conversion_rate,
                    GROUP_CONCAT(transaction_id ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") transaction_id,
                    GROUP_CONCAT(card_number ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") card_number,
                    GROUP_CONCAT(card_brand ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") card_brand,
                    GROUP_CONCAT(card_expiration ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") card_expiration,
                    GROUP_CONCAT(card_holder ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") card_holder,
                    GROUP_CONCAT(`date_add` ORDER BY `date_add` DESC SEPARATOR "' . $this->multivalueSeparator . '") `payment_dt_add`
                FROM ' . _DB_PREFIX_ . 'order_payment payment
                LEFT JOIN ' . _DB_PREFIX_ . 'currency `currency` ON `currency`.id_currency = `payment`.id_currency
                GROUP BY order_reference
            ) `payment` ON `order`.reference = payment.order_reference
            LEFT JOIN (
                SELECT 
                    id_order, 
                    GROUP_CONCAT(oi.id_order_invoice SEPARATOR "' . $this->multivalueSeparator . '") id_order_invoice,
                    GROUP_CONCAT(`number` SEPARATOR "' . $this->multivalueSeparator . '") `number`,
                    GROUP_CONCAT(delivery_number SEPARATOR "' . $this->multivalueSeparator . '") delivery_number,
                    GROUP_CONCAT(delivery_date SEPARATOR "' . $this->multivalueSeparator . '") `delivery_date`,
                    GROUP_CONCAT(ROUND(total_discount_tax_excl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_discount_tax_excl`,
                    GROUP_CONCAT(ROUND(total_discount_tax_incl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_discount_tax_incl`,
                    GROUP_CONCAT(ROUND(total_paid_tax_excl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_paid_tax_excl`,
                    GROUP_CONCAT(ROUND(total_paid_tax_incl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_paid_tax_incl`,
                    GROUP_CONCAT(ROUND(total_products, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_products`,
                    GROUP_CONCAT(ROUND(total_products_wt, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_products_wt`,
                    GROUP_CONCAT(ROUND(total_shipping_tax_excl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_shipping_tax_excl`,
                    GROUP_CONCAT(ROUND(total_shipping_tax_incl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_shipping_tax_incl`,
                    GROUP_CONCAT(shipping_tax_computation_method SEPARATOR "' . $this->multivalueSeparator . '") shipping_tax_computation_method,
                    GROUP_CONCAT(ROUND(total_wrapping_tax_excl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_wrapping_tax_excl`,
                    GROUP_CONCAT(ROUND(total_wrapping_tax_incl, ' . $this->fracPart . ') SEPARATOR "' . $this->multivalueSeparator . '") `total_wrapping_tax_incl`,
                    GROUP_CONCAT(shop_address SEPARATOR "' . $this->multivalueSeparator . '") shop_address,
                    # GROUP_CONCAT(invoice_address SEPARATOR "' . $this->multivalueSeparator . '") invoice_address,
                    # GROUP_CONCAT(delivery_address SEPARATOR "' . $this->multivalueSeparator . '") delivery_address,
                    GROUP_CONCAT(note SEPARATOR "' . $this->multivalueSeparator . '") note,
                    GROUP_CONCAT(`date_add` SEPARATOR "' . $this->multivalueSeparator . '") `date_add`,
                    GROUP_CONCAT(`invoice_tax` SEPARATOR "' . $this->multivalueSeparator . '") `invoice_tax`,
                    GROUP_CONCAT(`id_invoice_payment` SEPARATOR "' . $this->multivalueSeparator . '") `id_invoice_payment`
                FROM ' . _DB_PREFIX_ . 'order_invoice oi
                LEFT JOIN (
                    SELECT 
                        id_order_invoice,
                        GROUP_CONCAT(CONCAT_WS(" : ", `type`, order_invoice_tax.`id_tax`, `name`, `amount`) SEPARATOR " & ") invoice_tax
                    FROM ' . _DB_PREFIX_ . 'order_invoice_tax order_invoice_tax
                    LEFT JOIN ' . _DB_PREFIX_ . 'tax_lang tax_lang ON order_invoice_tax.id_tax = tax_lang.id_tax AND tax_lang.id_lang = ' . $this->langId . '
                    GROUP BY id_order_invoice
                ) oit ON oi.`id_order_invoice` = oit.`id_order_invoice`
                LEFT JOIN (
                    SELECT 
                        id_order_invoice,
                        GROUP_CONCAT(id_order_payment SEPARATOR " & ") id_invoice_payment
                    FROM ' . _DB_PREFIX_ . 'order_invoice_payment order_invoice_payment
                    GROUP BY id_order_invoice
                ) oip ON oi.`id_order_invoice` = oip.`id_order_invoice`
                GROUP BY id_order
            ) `order_invoice` ON `order`.id_order = order_invoice.id_order
            LEFT JOIN (
                SELECT 
                    id_order, 
                    GROUP_CONCAT(CONCAT_WS(" ! ", `id_order_state`, `date_add`) SEPARATOR "' . $this->multivalueSeparator . '") history
                FROM ' . _DB_PREFIX_ . 'order_history
                GROUP BY id_order
            ) order_history ON `order`.id_order = order_history.id_order
            LEFT JOIN ' . _DB_PREFIX_ . 'order_state_lang `order_state` ON current_state = id_order_state AND `order_state`.id_lang = ' . $this->langId . '
            LEFT JOIN ' . _DB_PREFIX_ . 'customer `customer` USING(id_customer)
            LEFT JOIN ' . _DB_PREFIX_ . 'carrier default_carrier ON `order`.id_carrier = default_carrier.id_carrier
            LEFT JOIN (
                SELECT
                    order_carrier.id_order id_order,
                    GROUP_CONCAT(order_carrier.id_order_carrier SEPARATOR "' . $this->multivalueSeparator . '") id_order_carrier,
                    GROUP_CONCAT(order_carrier.id_carrier SEPARATOR "' . $this->multivalueSeparator . '") id_carrier,
                    GROUP_CONCAT(carrier.`id_reference` SEPARATOR "' . $this->multivalueSeparator . '") id_reference,
                    GROUP_CONCAT(carrier.`name` SEPARATOR "' . $this->multivalueSeparator . '") name,
                    GROUP_CONCAT(order_carrier.weight SEPARATOR "' . $this->multivalueSeparator . '") weight,
                    GROUP_CONCAT(tracking_number SEPARATOR "' . $this->multivalueSeparator . '") tracking_number,
                    GROUP_CONCAT(shipping_cost_tax_incl SEPARATOR "' . $this->multivalueSeparator . '") shipping_cost_tax_incl,
                    GROUP_CONCAT(shipping_cost_tax_excl SEPARATOR "' . $this->multivalueSeparator . '") shipping_cost_tax_excl,
                    GROUP_CONCAT((shipping_cost_tax_incl - shipping_cost_tax_excl) SEPARATOR "' . $this->multivalueSeparator . '") shipping_cost_tax_amount,
                    GROUP_CONCAT(`date_add` SEPARATOR "' . $this->multivalueSeparator . '") `date_add`,
                    GROUP_CONCAT(id_order_invoice SEPARATOR "' . $this->multivalueSeparator . '") id_order_invoice
                FROM (
                    SELECT DISTINCT id_order
                    FROM ' . _DB_PREFIX_ . 'order_carrier order_carrier
                    JOIN ' . _DB_PREFIX_ . 'carrier carrier ON order_carrier.id_carrier = carrier.id_carrier
                    WHERE 1 ' . $carriersCond . '
                ) sub_carr
                JOIN ' . _DB_PREFIX_ . 'order_carrier order_carrier ON order_carrier.id_order = sub_carr.id_order
                JOIN ' . _DB_PREFIX_ . 'carrier carrier ON order_carrier.id_carrier = carrier.id_carrier
                GROUP BY id_order
            ) `carrier` ON `carrier`.id_order = `order`.id_order
            LEFT JOIN (
                SELECT DISTINCT id_order
                FROM ' . _DB_PREFIX_ . 'order_carrier
            ) for_null_carrier ON order.id_order = for_null_carrier.id_order
            LEFT JOIN ' . _DB_PREFIX_ . 'carrier `carrier_name` ON `carrier_name`.id_carrier = `carrier`.id_carrier
            LEFT JOIN ' . _DB_PREFIX_ . 'currency `currency` ON `currency`.id_currency = `order`.id_currency
            LEFT JOIN ' . _DB_PREFIX_ . 'address `address_delivery` ON 
                `address_delivery`.id_address = id_address_delivery
            LEFT JOIN ' . _DB_PREFIX_ . 'address `address_invoice` ON `address_invoice`.id_address = id_address_invoice
            LEFT JOIN ' . _DB_PREFIX_ . 'country `delivery_country` ON `delivery_country`.id_country = `address_delivery`.id_country 
            LEFT JOIN ' . _DB_PREFIX_ . 'country_lang `delivery_country_lang` 
                ON `delivery_country_lang`.id_country = `address_delivery`.id_country 
                AND `delivery_country_lang`.id_lang = ' . $this->langId . '
            LEFT JOIN ' . _DB_PREFIX_ . 'state `delivery_state` ON 
                `delivery_state`.id_state = `address_delivery`.id_state
            LEFT JOIN ' . _DB_PREFIX_ . 'country `invoice_country` ON `invoice_country`.id_country = `address_invoice`.id_country
            LEFT JOIN ' . _DB_PREFIX_ . 'country_lang `invoice_country_lang` ON 
                `invoice_country_lang`.id_country = `address_invoice`.id_country AND 
                `invoice_country_lang`.id_lang = ' . $this->langId . '
            LEFT JOIN ' . _DB_PREFIX_ . 'state `invoice_state` ON `invoice_state`.id_state = `address_invoice`.id_state
            LEFT JOIN ' . _DB_PREFIX_ . 'shop `shop` ON `shop`.id_shop = `order`.id_shop
            LEFT JOIN ' . _DB_PREFIX_ . 'shop_group `shop_group` ON `shop_group`.id_shop_group = `shop`.id_shop_group
            LEFT JOIN ' . _DB_PREFIX_ . 'lang `lang` ON `order`.id_lang = `lang`.id_lang
            LEFT JOIN ' . _DB_PREFIX_ . 'gender_lang gender_lang ON `customer`.id_gender = `gender_lang`.id_gender
                AND gender_lang.id_lang = ' . $this->langId . '
            LEFT JOIN (SELECT 
                    od.id_order_detail,
                    pl.`name`,
                    pl.`description_short`,
                    pl.`description`,
                    GROUP_CONCAT(CONCAT(agl.`id_attribute_group`, ": ", a.`id_attribute`) SEPARATOR "' . $this->multivalueSeparator . '") attribute_ids,
                    GROUP_CONCAT(CONCAT(agl.`name`, ": ", al.`name`) SEPARATOR "' . $this->multivalueSeparator . '") attributes
                FROM ' . _DB_PREFIX_ . 'order_detail od
                LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON od.product_attribute_id = pac.id_product_attribute
                LEFT JOIN ' . _DB_PREFIX_ . 'attribute a USING(id_attribute)
                LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON a.id_attribute = al.id_attribute AND al.id_lang = ' . $this->langId . '
                LEFT JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON a.id_attribute_group = agl.id_attribute_group AND agl.id_lang = ' . $this->langId . '
                LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl ON od.product_id = pl.id_product AND od.id_shop = pl.id_shop AND pl.id_lang = ' . $this->langId . '
                GROUP BY od.id_order_detail
            ) `order_detail_lang` ON `product`.id_order_detail = `order_detail_lang`.id_order_detail
            LEFT JOIN (SELECT
                    id_product,
                    GROUP_CONCAT(CONCAT(' . _DB_PREFIX_ . "feature_lang.`name`, ': ', "
                . _DB_PREFIX_ . "feature_value_lang.`value`) SEPARATOR ', ') features
               FROM " . _DB_PREFIX_ . 'feature_product
               LEFT JOIN ' . _DB_PREFIX_ . 'feature_lang ON ' . _DB_PREFIX_ . 'feature_product.id_feature = '
                . _DB_PREFIX_ . 'feature_lang.id_feature AND ' . _DB_PREFIX_ . 'feature_lang.id_lang = ' . $this->langId . '
               LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang ON '
                . _DB_PREFIX_ . 'feature_product.id_feature_value = '
                . _DB_PREFIX_ . 'feature_value_lang.id_feature_value 
                   AND ' . _DB_PREFIX_ . 'feature_value_lang.id_lang = ' . $this->langId . '
               GROUP BY ' . _DB_PREFIX_ . 'feature_product.id_product
            ) product_features ON `product`.product_id = product_features.id_product
            LEFT JOIN ' . _DB_PREFIX_ . 'product prod ON prod.id_product = product.product_id
            LEFT JOIN ' . _DB_PREFIX_ . 'supplier default_supplier ON default_supplier.id_supplier = prod.id_supplier
            LEFT JOIN (
                SELECT 
                    ps.id_product
                FROM (
                    SELECT DISTINCT id_product
                    FROM ' . _DB_PREFIX_ . 'product_supplier
                    WHERE id_product_attribute = 0' . $suppliersCond . '
                ) sub_supp
                JOIN ' . _DB_PREFIX_ . 'product_supplier ps ON sub_supp.id_product = ps.id_product
                LEFT JOIN ' . _DB_PREFIX_ . 'supplier s ON ps.id_supplier = s.id_supplier
                WHERE ps.id_product_attribute = 0
                GROUP BY id_product
            ) supplier ON supplier.id_product = prod.id_product
            LEFT JOIN (
                SELECT DISTINCT id_product
                FROM ' . _DB_PREFIX_ . 'product_supplier
                WHERE id_product_attribute = 0
            ) for_null_supplier ON prod.id_product = for_null_supplier.id_product
            LEFT JOIN ' . _DB_PREFIX_ . 'manufacturer manufacturer 
                ON manufacturer.id_manufacturer = prod.id_manufacturer 
            LEFT JOIN (
                SELECT 
                    id_order_detail, 
                    GROUP_CONCAT(order_detail_tax.id_tax SEPARATOR "' . $this->multivalueSeparator . '") id_tax,
                    GROUP_CONCAT(`name` SEPARATOR "' . $this->multivalueSeparator . '") `name`, 
                    GROUP_CONCAT(`unit_amount` SEPARATOR "' . $this->multivalueSeparator . '") unit_amount_tax, 
                    GROUP_CONCAT(`total_amount` SEPARATOR "' . $this->multivalueSeparator . '") total_amount_tax 
                FROM ' . _DB_PREFIX_ . 'order_detail_tax order_detail_tax 
                LEFT JOIN ' . _DB_PREFIX_ . 'tax_lang tax_lang ON order_detail_tax.id_tax = tax_lang.id_tax AND tax_lang.id_lang = ' . $this->langId . '
                GROUP BY id_order_detail
            ) order_details_tax ON 
                order_details_tax.id_order_detail = product.id_order_detail 
            LEFT JOIN (
                SELECT id_order, GROUP_CONCAT(CONCAT_WS(" ! ", private, message) SEPARATOR ";; ") message
                FROM ' . _DB_PREFIX_ . 'message
                #WHERE `private` = 0
                GROUP BY id_order) order_messages ON `order`.id_order = order_messages.id_order 
            LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON prod.id_category_default = cl.id_category 
                    AND cl.id_shop = `order`.id_shop AND cl.id_lang = ' . $this->langId . ' 
            #LEFT JOIN (SELECT 
            #        cp.id_product, 
            #        cl.id_shop, 
            #        GROUP_CONCAT(cl.id_category SEPARATOR "' . $this->multivalueSeparator . '") ids, 
            #        GROUP_CONCAT(cl.`name` SEPARATOR "' . $this->multivalueSeparator . '") names
            #    FROM ' . _DB_PREFIX_ . 'category_product cp
            #    LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON cp.id_category = cl.id_category AND cl.id_lang = ' . $this->langId . '
            #    GROUP BY cp.id_product, cl.id_shop) cat ON prod.id_product = cat.id_product AND `order`.id_shop = cat.id_shop
            LEFT JOIN (
                SELECT 
                    ocr.id_order id_order,
                    GROUP_CONCAT(ocr.id_cart_rule SEPARATOR "' . $this->multivalueSeparator . '") id_cart_rule,
                    GROUP_CONCAT(ocr.`name` SEPARATOR "' . $this->multivalueSeparator . '") `name`,
                    GROUP_CONCAT(ocr.`value` SEPARATOR "' . $this->multivalueSeparator . '") `value`,
                    GROUP_CONCAT(ocr.value_tax_excl SEPARATOR "' . $this->multivalueSeparator . '") value_tax_excl,
                    GROUP_CONCAT(ocr.free_shipping SEPARATOR "' . $this->multivalueSeparator . '") free_shipping,
                    GROUP_CONCAT(cr.code SEPARATOR "' . $this->multivalueSeparator . '") `code`
                FROM (
                    SELECT DISTINCT id_order
                    FROM ' . _DB_PREFIX_ . 'order_cart_rule order_cart_rule
                    WHERE 1 ' . $cartRulesCond . '
                ) sub_cart_rule
                JOIN ' . _DB_PREFIX_ . 'order_cart_rule ocr ON ocr.id_order = sub_cart_rule.id_order
                LEFT JOIN ' . _DB_PREFIX_ . 'cart_rule cr ON ocr.id_cart_rule = cr.id_cart_rule
                GROUP BY id_order
            ) cart_rule ON `order`.id_order = cart_rule.id_order
            LEFT JOIN (
                SELECT DISTINCT id_order
                FROM ' . _DB_PREFIX_ . 'order_cart_rule
            ) for_null_cart_rule ON `order`.id_order = for_null_cart_rule.id_order
            LEFT JOIN ' . _DB_PREFIX_ . 'group_lang def_group ON 
                    `customer`.id_default_group = def_group.id_group AND def_group.id_lang = ' . $this->langId . '
            LEFT JOIN (
                    SELECT 
                        c.id_customer, 
                        GROUP_CONCAT(cg.id_group SEPARATOR "' . $this->multivalueSeparator . '") group_ids, 
                        GROUP_CONCAT(gl.`name` SEPARATOR "' . $this->multivalueSeparator . '") group_names
                    FROM ' . _DB_PREFIX_ . 'customer c
                    LEFT JOIN ' . _DB_PREFIX_ . 'customer_group cg ON c.id_customer = cg.id_customer
                    LEFT JOIN ' . _DB_PREFIX_ . 'group_lang gl ON 
                        cg.id_group = gl.id_group AND gl.id_lang = ' . $this->langId . '
                    GROUP BY c.id_customer
                ) groupp ON `customer`.id_customer = groupp.id_customer
            LEFT JOIN (
                SELECT id_order,
                    GROUP_CONCAT(id_order_slip ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") id_order_slip,
                    GROUP_CONCAT(`date_add` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `date_add`,
                    GROUP_CONCAT(`total_products_tax_excl` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `total_products_tax_excl`,
                    GROUP_CONCAT(`total_products_tax_incl` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `total_products_tax_incl`,
                    GROUP_CONCAT(`total_shipping_tax_excl` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `total_shipping_tax_excl`,
                    GROUP_CONCAT(`total_shipping_tax_incl` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `total_shipping_tax_incl`,
                    GROUP_CONCAT(`amount` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `amount`,
                    GROUP_CONCAT(`shipping_cost` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `shipping_cost`,
                    GROUP_CONCAT(`shipping_cost_amount` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `shipping_cost_amount`,
                    GROUP_CONCAT(`partial` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `partial`,
                    GROUP_CONCAT(`order_slip_type` ORDER BY id_order_slip SEPARATOR "' . $this->multivalueSeparator . '") `order_slip_type`
                FROM ' . _DB_PREFIX_ . 'order_slip
                GROUP BY id_order
            ) order_slip ON `order`.id_order = order_slip.id_order
            LEFT JOIN (
                SELECT id_order_detail,
                    GROUP_CONCAT(product_quantity SEPARATOR "' . $this->multivalueSeparator . '") product_quantity,
                    GROUP_CONCAT(unit_price_tax_excl SEPARATOR "' . $this->multivalueSeparator . '") unit_price_tax_excl,
                    GROUP_CONCAT(unit_price_tax_incl SEPARATOR "' . $this->multivalueSeparator . '") unit_price_tax_incl,
                    GROUP_CONCAT(total_price_tax_excl SEPARATOR "' . $this->multivalueSeparator . '") total_price_tax_excl,
                    GROUP_CONCAT(total_price_tax_incl SEPARATOR "' . $this->multivalueSeparator . '") total_price_tax_incl,
                    GROUP_CONCAT(amount_tax_excl SEPARATOR "' . $this->multivalueSeparator . '") amount_tax_excl,
                    GROUP_CONCAT(amount_tax_incl SEPARATOR "' . $this->multivalueSeparator . '") amount_tax_incl
                FROM ' . _DB_PREFIX_ . 'order_slip_detail
                GROUP BY id_order_detail
            ) order_slip_detail ON `product`.id_order_detail = order_slip_detail.id_order_detail
                ';

        if (version_compare(_PS_VERSION_, '1.6.1.0') > -1) {
            $this->sql .= ' LEFT JOIN ' . _DB_PREFIX_ . 'tax_rules_group tax_rules_group ON 
                            `product`.id_tax_rules_group = tax_rules_group.id_tax_rules_group ';
        } else {
            $this->sql .= ' LEFT JOIN ' . _DB_PREFIX_ . 'tax_rules_group tax_rules_group ON 
                            `prod`.id_tax_rules_group = tax_rules_group.id_tax_rules_group ';
        }

        $this->sql .= '
                WHERE 1
            ';

        // Filter By Carrier
        $this->sql .= $carriersCond2;

        // Filter By Supplier
        $this->sql .= $suppliersCond2;

        // Filter By Cart rule
        $this->sql .= $cartRulesCond2;
        
        // Filter By Shop
        $shops_cond = '';
        if ($shops) {
            if ($shopsType === 'unselected') {
                $shops_cond = 'order.id_shop NOT IN (' . $shops . ')';
            } else {
                $shops_cond = 'order.id_shop IN (' . $shops . ')';
            }
        }
        if ($shops_cond) {
            $this->sql .= ' 
                AND (' . $shops_cond . ') ';
        }

        // Filter By Order
        $orders_cond = '';
        if ($orders) {
            if ($ordersType === 'unselected') {
                $orders_cond = 'order.id_order NOT IN (' . $orders . ')';
            } else {
                $orders_cond = 'order.id_order IN (' . $orders . ')';
            }
        }
        if ($orders_cond) {
            $this->sql .= ' 
                            AND (' . $orders_cond . ') ';
        }
        
        // Filter By Order State
        $order_states_cond = '';
        if ($orderStates) {
            if ($orderStatesType === 'unselected') {
                $order_states_cond = 'order.current_state NOT IN (' . $orderStates . ')';
            } else {
                $order_states_cond = 'order.current_state IN (' . $orderStates . ')';
            }
        }
        if ($order_states_cond) {
            $this->sql .= ' 
                AND (' . $order_states_cond . ') ';
        }
        
        // Filter By Product
        $products_cond = '';
        if ($products) {
            if ($productsType === 'unselected') {
                $products_cond = 'product.product_id NOT IN (' . $products . ')';
            } else {
                $products_cond = 'product.product_id IN (' . $products . ')';
            }
        }
        if ($products_cond) {
            $this->sql .= ' 
                            AND (' . $products_cond . ') ';
        }
        
        // Filter By Group
        $groupCond = '';
        if ($groups) {
            if ($groupsType === 'unselected') {
                $groupCond = 'order.id_customer NOT IN (
                                            SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_
                        . 'customer_group WHERE id_group IN (' . $groups . '))';
                if ($groupWithout === '0') {
                    if ($groupCond) {
                        $groupCond .= ' AND ';
                    }
                    $groupCond .= 'order.id_customer IN (
                                                SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_ . 'customer_group)';
                }
            } else {
                $groupCond = 'order.id_customer IN (
                                            SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_
                        . 'customer_group WHERE id_group IN (' . $groups . '))';
                if ($groupWithout !== '0') {
                    if ($groupCond) {
                        $groupCond .= ' OR ';
                    }
                    $groupCond .= 'order.id_customer NOT IN (
                                                SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_ . 'customer_group)';
                }
            }
        } elseif ($groupWithout === '1' && $groupsType === 'selected') {
            $groupCond .= 'order.id_customer NOT IN (
                            SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_ . 'customer_group)';
        } elseif ($groupWithout === '0' && $groupsType === 'unselected') {
            $groupCond .= 'order.id_customer IN (
                            SELECT DISTINCT id_customer FROM ' . _DB_PREFIX_ . 'customer_group)';
        }

        if ($groupCond) {
            $this->sql .= ' 
                AND (' . $groupCond . ') ';
        }

        // Filter By Customer
        $customerCond = '';
        if ($customers) {
            if ($customersType === 'unselected') {
                $customerCond = 'order.id_customer NOT IN (' . $customers . ')';
                if ($customerWithout === '0') {
                    if ($customerCond) {
                        $customerCond .= ' AND ';
                    }
                    $customerCond .= 'order.id_customer IS NOT NULL AND order.id_customer != 0';
                }
            } else {
                $customerCond = 'order.id_customer IN (' . $customers . ')';
                if ($customerWithout !== '0') {
                    if ($customerCond) {
                        $customerCond .= ' OR ';
                    }
                    $customerCond .= 'order.id_customer IS NULL OR order.id_customer = 0';
                }
            }
        } elseif ($customerWithout === '1' && $customersType === 'selected') {
            $customerCond .= 'order.id_customer IS NULL OR order.id_customer = 0';
        } elseif ($customerWithout === '0' && $customersType === 'unselected') {
            $customerCond .= 'order.id_customer IS NOT NULL AND order.id_customer != 0';
        }

        if ($customerCond) {
            $this->sql .= ' 
                AND (' . $customerCond . ') ';
        }

        // Filter By Payment Method
        $payment_methods_cond = '';
        if ($paymentMethods) {
            if ($paymentMethodsType === 'unselected') {
                $payment_methods_cond = "CONCAT(IFNULL(order.module, ''), '_#&_', IFNULL(order.payment, '')) NOT IN ('" . $paymentMethods . "')";
            } else {
                $payment_methods_cond = "CONCAT(IFNULL(order.module, ''), '_#&_', IFNULL(order.payment, '')) IN ('" . $paymentMethods . "')";
            }
        }
        if ($payment_methods_cond) {
            $this->sql .= '
                
                AND (' . $payment_methods_cond . ') ';
        }

        // Filter By Manufacturer
        $manufacturerCond = '';
        if ($manufacturers) {
            if ($manufacturersType === 'unselected') {
                $manufacturerCond = 'prod.id_manufacturer NOT IN (' . $manufacturers . ')';
                if ($manufacturerWithout === '0') {
                    if ($manufacturerCond) {
                        $manufacturerCond .= ' AND ';
                    }
                    $manufacturerCond .= 'prod.id_manufacturer IS NOT NULL AND prod.id_manufacturer != 0';
                }
            } else {
                $manufacturerCond = 'prod.id_manufacturer IN (' . $manufacturers . ')';
                if ($manufacturerWithout !== '0') {
                    if ($manufacturerCond) {
                        $manufacturerCond .= ' OR ';
                    }
                    $manufacturerCond .= 'prod.id_manufacturer IS NULL OR prod.id_manufacturer = 0';
                }
            }
        } elseif ($manufacturerWithout === '1' && $manufacturersType === 'selected') {
            $manufacturerCond .= 'prod.id_manufacturer IS NULL OR prod.id_manufacturer = 0';
        } elseif ($manufacturerWithout === '0' && $manufacturersType === 'unselected') {
            $manufacturerCond .= 'prod.id_manufacturer IS NOT NULL AND prod.id_manufacturer != 0';
        }

        if ($manufacturerCond) {
            $this->sql .= ' 
                        AND (' . $manufacturerCond . ') ';
        }
        
        // Filter by fields data
        $this->sql .= $eIHelper->getFieldsFilterString($this->auto, $this->inputs);

        // Sort By ...
        $this->sql .= ' ORDER BY ' . $this->sort . $this->sortWay;
        if ($this->sort !== 'order.id_order') {
            $this->sql .= ', order.id_order ASC';
        }

        $this->sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit;
//            die($this->sql);
        return Db::getInstance()->executeS($this->sql);
    }

    protected function writeToExcel()
    {
        require_once dirname(__FILE__) . '/../../vendor/autoload.php';

        if (file_exists($this->file)) {
            $spreadsheet = IOFactory::load($this->file);
            $sheet = $spreadsheet->getActiveSheet();
            $excelColumns = EIAHelper::createColumnsArray(count($this->data[0]));
        } else {
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();

            // Set document properties
            $spreadsheet->getProperties()->setCreator('Tehran Alishov')
                    ->setLastModifiedBy('Tehran Alishov')
                    ->setTitle('Office 2007 XLSX Orders Document')
                    ->setSubject('Office 2007 XLSX Orders Document')
                    ->setDescription('Orders document for Office 2007 XLSX, generated using PHP classes.')
                    ->setKeywords('office 2007 openxml php')
                    ->setCategory('Orders result file');
            $spreadsheet->setActiveSheetIndex(0);

            if (empty($this->data)) {
                $sheet->setCellValue('A1', $this->module->l('No Data', 'EIAOrdersExport'));
            } else {
                $excelColumns = EIAHelper::createColumnsArray(count($this->data[0]));
                $sheet->getDefaultColumnDimension()->setWidth(21);
                if (isset($this->selectedColumns['cover_image'])) {
                    $sheet->getDefaultRowDimension()->setRowHeight(42);
                } else {
                    $sheet->getDefaultRowDimension()->setRowHeight(30);
                }

                $spreadsheet->getDefaultStyle()->getAlignment()
                        ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)
                        ->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);

                $sheet->getStyle('A1:' . end($excelColumns) . (count($this->data)))
                        ->getAlignment()->setWrapText(true);

                $sheet->getStyle('A1:' . end($excelColumns) . '1')
                        ->getFont()->setBold(true);
                $sheet->getStyle('A1:' . end($excelColumns) . '1')
                        ->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
                        ->getStartColor()->setARGB('FFDCF0FF');
                $sheet->getStyle('A1:' . end($excelColumns) . '1')->getBorders()
                        ->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);

                // Rename worksheet
                $sheet->setTitle($this->module->l('Orders', 'EIAOrdersExport'));

                $headers = array_keys($this->data[0]);
                foreach ($headers as $key => $header) {
                    $sheet->setCellValue($excelColumns[$key] . '1', $header);
                }

                if (isset($this->selectedColumns['product_image'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['product_image'], $headers)])->setWidth(9);
                }
                if (isset($this->selectedColumns['attribute_image'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['attribute_image'], $headers)])->setWidth(9);
                }
                if (isset($this->selectedColumns['order_detail_lang.description_short'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['order_detail_lang.description_short'], $headers)])->setWidth(40);
                }
                if (isset($this->selectedColumns['order_detail_lang.description'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['order_detail_lang.description'], $headers)])->setWidth(50);
                }
            }
        }

        $small_image = $this->getImageType('small');
        foreach ($this->data as $key => $value) {
            $i = 0;
            foreach ($value as $k => $val) {
                if (isset($this->selectedColumns['product_image']) && $k === $this->selectedColumns['product_image'] && $val) {
                    $image = ImageCore::getCover($val);
                    if ($image) {
                        $img = new Image($image['id_image']);
                        $image_path = realpath(_PS_PROD_IMG_DIR_ . $img->getImgPath() . '-' . $small_image . '.jpg');
                        if (file_exists($image_path)) {
                            $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
                            // $drawing->setName('Order_' . $val);
                            $drawing->setPath($image_path);
                            $drawing->setResizeProportional(false);
                            $drawing->setWidth(62);
                            $drawing->setHeight(55);
                            $drawing->setCoordinates($excelColumns[$i] . ($this->offset + $key + 2));
                            $drawing->setWorksheet($sheet);
                            $drawing->getShadow()->setVisible(true);
                        }
                    }
                } elseif (isset($this->selectedColumns['attribute_image']) && $k === $this->selectedColumns['attribute_image'] && $val) {
                    $val = explode('-', $val);
                    if (method_exists('Image', 'getBestImageAttribute')) {
                        // Get image data of the given product id
                        $image = Image::getBestImageAttribute(
                                        isset($val[2]) ? $val[2] : 0,
                                        $this->langId,
                                        isset($val[0]) ? $val[0] : 0,
                                        isset($val[1]) ? $val[1] : 0
                        );
                    } else {
                        $image = Image::getImages(
                                        $this->langId,
                                        isset($val[0]) ? $val[0] : 0,
                                        isset($val[1]) ? $val[1] : 0
                        );
                        $image = isset($image[0]) ? $image[0] : null;
                    }
                    if ($image) {
                        $img = new Image($image['id_image']);
                        $image_path = realpath(_PS_PROD_IMG_DIR_ . $img->getImgPath() . '-' . $small_image . '.jpg');
                        $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
                        // $drawing->setName('Product_' . $value['Product ID']);
                        $drawing->setPath(realpath($image_path));
                        $drawing->setResizeProportional(false);
                        $drawing->setWidth(62);
                        $drawing->setHeight(55);
                        $drawing->setCoordinates($excelColumns[$i] . ($this->offset + $key + 2));
                        $drawing->setWorksheet($sheet);
                        $drawing->getShadow()->setVisible(true);
                    }
                } elseif(isset($this->selectedColumns['product.product_ean13']) && $k === $this->selectedColumns['product.product_ean13'] && $val ||
                        isset($this->selectedColumns['product_attribute.ean13']) && $k === $this->selectedColumns['product_attribute.ean13'] && $val) {
                    $sheet->setCellValueExplicit($excelColumns[$i] . ($this->offset + $key + 2), $val, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
                } else {
                    $sheet->setCellValue($excelColumns[$i] . ($this->offset + $key + 2), $val);
                }
                $i++;
            }
        }

        $sheet->setSelectedCell('A1');

        // Write to file
        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
        $writer->save($this->file);
    } 
}