settings = $settings; $this->feedLangId = (int)Configuration::get('PS_LANG_DEFAULT'); $this->feedId = (int)$settings['id']; $this->currency = Currency::getCurrency(!empty($settings['currency_id']) ? $settings['currency_id'] : Configuration::get('PS_CURRENCY_DEFAULT')); $this->branchNames = $this->getBranchNames(); $this->loadAddressData(); $orders = $this->getOrders(); return $this->generateXml($orders); } protected function generateXml($orders) { $xml = $this->getDeepTagName($this->branchNames['orders-branch-name']); if (!empty($this->settings['extra_feed_row'])) { $xml .= $this->settings['extra_feed_row']; } if (!empty($this->settings['cdata_status'])) { $this->prefixStart = 'prefixEnd = ']]>'; } foreach ($orders as $order) { $xmlOrder = $this->getDeepTagName($this->branchNames['order-branch-name']); $productsBranch = $this->generateXmlAddProducts($order['order_id']); foreach ($order as $id => $val) { if (empty($this->fieldsName[$id])) { continue; } if ($this->isPriceField($id)) { $val = $this->getPriceFormat($val); } $xmlOrder .= $this->getDeepTagName($this->fieldsName[$id]).$this->prefixStart.$val.$this->prefixEnd.$this->getDeepTagName($this->fieldsName[$id], true); } foreach ($this->fieldsName as $fieldId => $fieldName) { if (strpos($fieldId, 'bl_extra_') !== 0) { continue; } $method = 'extraField'.str_replace(' ', '', ucwords(str_replace(array('bl_extra_', '_'), array('', ' '), $fieldId))); $xmlOrder .= $this->getDeepTagName($fieldName).$this->$method($order).$this->getDeepTagName($fieldName, true); } $xml .= $this->replaceXmlTree($xmlOrder); $xml .= $productsBranch; $xml .= $this->getDeepTagName($this->branchNames['order-branch-name'], true); } $xml .= $this->getDeepTagName($this->branchNames['orders-branch-name'], true); return $xml; } protected function generateXmlAddProducts($orderId) { $xml = ''; $this->totalProducts = 0; if (empty($this->fieldsNameAdditionTable['od'])) { return $xml; } $products = $this->getProducts($orderId); if (!empty($products)) { $this->totalProducts = count($products); $xml = $this->getDeepTagName($this->branchNames['products-branch-name']); foreach ($products as $product) { $xml .= $this->getDeepTagName($this->branchNames['product-branch-name']); $xmlOrder = ''; foreach ($product as $id => $val) { if ($this->isPriceField($id)) { $val = $this->getPriceFormat($val); } if ($this->isNumberField($id)) { $val = $this->getNumberFormat($val); } $xmlOrder .= $this->getDeepTagName($this->fieldsName[$id]).$this->prefixStart.$val.$this->prefixEnd.$this->getDeepTagName($this->fieldsName[$id], true); } $xml .= $this->replaceXmlTree($xmlOrder); $xml .= $this->getDeepTagName($this->branchNames['product-branch-name'], true); } $xml .= $this->getDeepTagName($this->branchNames['products-branch-name'], true); } return $xml; } protected function getOrders() { $field = $this->getFields(); return Db::getInstance()->ExecuteS('SELECT DISTINCT(o.id_order) AS order_id, ad.address1, ad.address2, ad.postcode, ad.city, ad.id_country, ad.id_state, ad.company, ad.phone, ad.phone_mobile, ad.vat_number, ad.firstname AS firstname_d, ad.lastname AS lastname_d, ai.address1 AS address1_i, ai.address2 AS address2_i, ai.postcode AS postcode_i, ai.city AS city_i, ai.id_country AS id_country_i, ai.id_state AS id_state_i, ai.company AS company_i, ai.phone AS phone_i, ai.phone_mobile AS phone_mobile_i, ai.vat_number AS vat_number_i, ai.firstname AS firstname_i, ai.lastname AS lastname_i, o.total_paid_tax_excl AS total_paid_t_e, o.total_paid_tax_incl AS total_paid_t_i'.pSQL($field).' FROM '._DB_PREFIX_.'orders o LEFT JOIN '._DB_PREFIX_.'order_state_lang sl ON (sl.id_order_state = o.current_state AND sl.id_lang = "'.(int)$this->feedLangId.'") LEFT JOIN '._DB_PREFIX_.'customer c ON c.`id_customer` = o.`id_customer` LEFT JOIN '._DB_PREFIX_.'address ad ON ad.id_address = o.id_address_delivery LEFT JOIN '._DB_PREFIX_.'address ai ON ai.id_address = o.id_address_invoice LEFT JOIN '._DB_PREFIX_.'carrier cr ON cr.id_carrier = o.id_carrier'.$this->getOrdersFilter()); } protected function getOrdersFilter() { $where = array(); if (!empty($this->settings['order_state_status']) && !empty($this->settings['order_state'])) { $where[] = 'sl.id_order_state IN ('.pSQL($this->settings['order_state']).')'; } if (!empty($this->settings['order_payments_status']) && !empty($this->settings['order_payment'])) { $where[] = 'o.module IN ("'.str_replace(',', '","', pSQL($this->settings['order_payment'])).'")'; } if (!empty($this->settings['filter_date_type'])) { $dateToday = pSQL(date('Y-m-d').' 00:00:00'); $filterByDate = array( OrderSettings::FILTER_DATE_NONE => '', OrderSettings::FILTER_DATE_TODAY => 'o.date_add >= "'.pSQL($dateToday).'"', OrderSettings::FILTER_DATE_YESTERDAY => 'o.date_add >= "'.pSQL(date('Y-m-d', strtotime('-1 day', strtotime($dateToday)))).' 00:00:00" AND o.date_add < "'.pSQL($dateToday).'"', OrderSettings::FILTER_DATE_THIS_WEEK => 'o.date_add >= "'.pSQL(date('Y-m-d', strtotime('this week', time()))).' 00:00:00"', OrderSettings::FILTER_DATE_THIS_MONTH => 'o.date_add >= "'.pSQL(date('Y-m-01')).' 00:00:00"', OrderSettings::FILTER_DATE_THIS_YEAR => 'o.date_add >= "'.pSQL(date('Y-01-01')).' 00:00:00"', OrderSettings::FILTER_DATE_CUSTOM_DAYS => 'o.date_add >= "'.pSQL(date('Y-m-d', strtotime('-'.(int)$this->settings['filter_custom_days'].' day', strtotime($dateToday)))).' 00:00:00"', OrderSettings::FILTER_DATE_DATE_RANGE => 'o.date_add >= "'.pSQL($this->settings['filter_date_from']).' 00:00:00" AND o.date_add <= "'.pSQL($this->settings['filter_date_to']).' 23:59:59" ', ); $where[] = $filterByDate[$this->settings['filter_date_type']]; } return !empty($where) ? ' WHERE '.implode(' AND ', $where) : ''; } protected function getProducts($orderId) { return Db::getInstance()->ExecuteS(' SELECT '.pSQL(trim($this->fieldsNameAdditionTable['od'], ',')).' FROM '._DB_PREFIX_.'order_detail od LEFT JOIN '._DB_PREFIX_.'product p ON p.`id_product` = od.`product_id` LEFT JOIN '._DB_PREFIX_.'order_detail_tax dt ON dt.id_order_detail = od.id_order_detail LEFT JOIN '._DB_PREFIX_.'tax t ON t.id_tax = dt.id_tax WHERE od.id_order = "'.(int)$orderId.'" ORDER BY od.id_order_detail ASC'); } protected function getFields() { $fields = Db::getInstance()->ExecuteS('SELECT `name`, `status`, `title_xml`, `table` FROM '._DB_PREFIX_.'blmod_xml_fields WHERE category = "'.(int)$this->feedId.'" AND status = "1" ORDER BY `table` ASC'); $field = ''; $tableMap = array( 'orders' => 'o', 'order_state_lang' => 'sl', 'customer' => 'c', 'order_detail' => 'od', 'address' => 'ad', 'product' => 'p', 'tax' => 't', 'carrier' => 'cr', ); if (!empty($fields)) { foreach ($fields as $f) { $this->fieldsName[$f['table'].'_'.$f['name']] = $f['title_xml']; if ($f['table'] == 'bl_extra') { continue; } $table = $tableMap[$f['table']]; if ($f['table'] == 'order_detail' || $f['table'] == 'product' || $f['table'] == 'tax') { if (empty($this->fieldsNameAdditionTable['od'])) { $this->fieldsNameAdditionTable['od'] = ''; } $this->fieldsNameAdditionTable['od'] .= $table.'.`'.$f['name'].'` AS '.$f['table'].'_'.$f['name'].','; continue; } $field .= $table.'.`'.$f['name'].'` AS '.$f['table'].'_'.$f['name'].','; } if (empty($field)) { return ''; } $field = ','.trim($field, ','); } return $field; } protected function extraFieldAddress($order, $prefix = '') { $final = array(); $final[] = $order['address1'.$prefix]; $final[] = $order['address2'.$prefix]; $final[] = $order['postcode'.$prefix]; $final[] = $order['city'.$prefix]; $final[] = !empty($this->stateList[$order['id_country'.$prefix]][$order['id_state'.$prefix]]) ? $this->stateList[$order['id_country'.$prefix]][$order['id_state'.$prefix]] : ''; $final[] = $order['postcode'.$prefix]; return implode(' ', array_filter($final)).(!empty($this->countryList[$order['id_country'.$prefix]]) ? ', '.$this->countryList[$order['id_country'.$prefix]] : ''); } protected function extraFieldDeliveryAddress($order) { $country = !empty($this->countryList[$order['id_country']]) ? $this->countryList[$order['id_country']] : ''; return ''.$this->prefixStart.$order['firstname_d'].$this->prefixEnd.' '.$this->prefixStart.$order['lastname_d'].$this->prefixEnd.' '.$this->prefixStart.$order['company'].$this->prefixEnd.' '.$this->prefixStart.$order['vat_number'].$this->prefixEnd.' '.$this->prefixStart.$order['address1'].$this->prefixEnd.' '.$this->prefixStart.$order['address2'].$this->prefixEnd.' '.$this->prefixStart.$order['postcode'].$this->prefixEnd.' '.$this->prefixStart.$order['city'].$this->prefixEnd.' '.$this->prefixStart.$country.$this->prefixEnd.' '.$this->prefixStart.$order['phone'].$this->prefixEnd.' '.$this->prefixStart.$order['phone_mobile'].$this->prefixEnd.''; } protected function extraFieldInvoiceAddress($order) { $country = !empty($this->countryList[$order['id_country_i']]) ? $this->countryList[$order['id_country_i']] : ''; return ''.$this->prefixStart.$order['firstname_i'].$this->prefixEnd.' '.$this->prefixStart.$order['lastname_i'].$this->prefixEnd.' '.$this->prefixStart.$order['company_i'].$this->prefixEnd.' '.$this->prefixStart.$order['vat_number_i'].$this->prefixEnd.' '.$this->prefixStart.$order['address1_i'].$this->prefixEnd.' '.$this->prefixStart.$order['address2_i'].$this->prefixEnd.' '.$this->prefixStart.$order['postcode_i'].$this->prefixEnd.' '.$this->prefixStart.$order['city_i'].$this->prefixEnd.' '.$this->prefixStart.$country.$this->prefixEnd.' '.$this->prefixStart.$order['phone_i'].$this->prefixEnd.' '.$this->prefixStart.$order['phone_mobile_i'].$this->prefixEnd.''; } protected function extraFieldCountry($order) { return (!empty($this->countryList[$order['id_country']]) ? $this->countryList[$order['id_country']] : ''); } protected function extraFieldCity($order) { return !empty($order['city']) ? $order['city'] : ''; } protected function extraFieldPostcode($order) { return !empty($order['postcode']) ? $order['postcode'] : ''; } protected function extraFieldCurrency($order) { return !empty($this->currency['iso_code']) ? $this->currency['iso_code'] : ''; } protected function extraFieldTaxTotalAmount($order) { return $this->getPriceFormat($order['total_paid_t_i'] - $order['total_paid_t_e']); } protected function extraFieldCustomerMessage($order) { return $this->getMessagesBranch($order['order_id']); } protected function extraFieldEmployeeMessage($order) { return $this->getMessagesBranch($order['order_id'], false); } protected function extraFieldVatNumberInvoice($order) { return !empty($order['vat_number_i']) ? $order['vat_number_i'] : ''; } protected function extraFieldTotalProducts($order) { if (!empty($this->totalProducts)) { return $this->totalProducts; } return Db::getInstance()->getValue('SELECT COUNt(od.id_order_detail) FROM '._DB_PREFIX_.'order_detail od WHERE od.id_order = '.(int)$order['order_id']); } protected function loadAddressData() { $countries = Db::getInstance()->ExecuteS('SELECT id_country, `name` FROM `'._DB_PREFIX_.'country_lang` WHERE `id_lang` = '.(int)$this->feedLangId); foreach ($countries as $c) { $this->countryList[$c['id_country']] = $c['name']; } $states = Db::getInstance()->ExecuteS('SELECT id_state, id_country, `name` FROM `'._DB_PREFIX_.'state`'); foreach ($states as $s) { $this->stateList[$s['id_country']][$s['id_state']] = $s['name']; } } protected function getMessagesBranch($orderId, $isCustomerMessages = true) { $xml = ''; $where = $isCustomerMessages ? '=' : '>'; $messages = Db::getInstance()->ExecuteS('SELECT ct.id_customer_thread, cm.`message`, cm.`date_add`, cm.`private` FROM '._DB_PREFIX_.'customer_thread ct LEFT JOIN '._DB_PREFIX_.'customer_message cm ON cm.id_customer_thread = ct.id_customer_thread WHERE ct.id_order = '.(int)$orderId.' AND cm.`id_employee` '.pSQL($where).' 0 ORDER BY cm.id_customer_message DESC'); if (!empty($messages)) { foreach ($messages as $m) { $xml .= ''; $xml .= ''.$this->prefixStart.$m['message'].$this->prefixEnd.''; $xml .= ''.$this->prefixStart.$m['date_add'].$this->prefixEnd.''; $xml .= ''.$this->prefixStart.$m['private'].$this->prefixEnd.''; $xml .= ''; } } return $xml; } protected function getBranchNames() { $branchNamesKey = array(); $branchNames = Db::getInstance()->ExecuteS('SELECT `name`, `value`, `category` FROM '._DB_PREFIX_.'blmod_xml_block WHERE category = "'.(int)$this->feedId.'" '); foreach ($branchNames as $bl) { $branchNamesKey[$bl['name']] = isset($bl['value']) ? $bl['value'] : $bl['name']; } return $branchNamesKey; } protected function replaceXmlTree($xml) { preg_match_all("'(.*?)'si", $xml, $categories); $levels = array(); if (empty($categories[1])) { return $xml; } foreach ($categories[1] as $k => $c) { preg_match("'(.*?)'si", $c, $name); $names = explode('_lBLMOD_', $name[1]); preg_match("'(.*?)'si", $c, $value); $levels[$names[0]][] = [ 'full' => $categories[0][$k], 'name' => $names[1], 'value' => $value[1], ]; } foreach ($levels as $branchName => $branch) { $xmlN = '<'.$branchName.'>'; $firstField = ''; foreach ($branch as $b) { $xmlN .= '<'.$b['name'].'>'; $xmlN .= $b['value']; $xmlN .= ''; if (empty($firstField)) { $firstField = $b['full']; } else { $xml = str_replace($b['full'], '', $xml); } } $xmlN .= ''; $xml = str_replace($firstField, $xmlN, $xml); } return $xml; } protected function getDeepTagName($tag = '', $close = false) { if (empty($tag)) { return ''; } if (strpos($tag, '/') === false) { return '<'.($close ? '/' : '').$tag.'>'; } if ($close) { return ''; } return ''.str_replace('/', '_lBLMOD_', $tag).''; } protected function getPriceFormat($price = 0) { if (!empty($this->settings['currency_id'])) { $price = Tools::convertPrice($price, $this->settings['currency_id']); } $price = PriceFormat::convertByType($price, $this->settings['price_format_id']); return $price.(!empty($this->settings['price_with_currency']) ? ' '.$this->currency['iso_code'] : ''); } protected function getNumberFormat($number = 0) { return Tools::ps_round($number, 3); } protected function isPriceField($field) { $priceFields = array( 'orders_total_paid', 'orders_total_paid_tax_incl', 'orders_total_paid_tax_excl', 'orders_total_wrapping', 'orders_total_discounts', 'orders_total_products', 'orders_total_shipping', 'orders_total_shipping_tax_incl', 'orders_total_shipping_tax_excl', 'order_detail_total_price_tax_incl', 'order_detail_total_price_tax_excl', 'order_detail_unit_price_tax_incl', 'order_detail_unit_price_tax_excl', ); return in_array($field, $priceFields); } protected function isNumberField($field) { $fields = array( 'tax_rate' ); return in_array($field, $fields); } }