· 6 years ago · Jan 03, 2020, 10:18 AM
1<?php
2/**
3 * NOTICE OF LICENSE
4 *
5 * This file is licenced under the Software License Agreement.
6 * With the purchase or the installation of the software in your application
7 * you accept the licence agreement.
8 *
9 * You must not modify, adapt or create derivative works of this source code
10 *
11 * @author Icommkt
12 * @copyright Icommkt
13 * @license GPLv3
14 *
15 */
16
17if (!defined('_PS_VERSION_')) {
18 exit;
19}
20
21class Icommktconnector extends Module
22{
23 protected $config_form = false;
24
25 public function __construct()
26 {
27 $this->name = 'icommktconnector';
28 $this->tab = 'emailing';
29 $this->version = '1.2.0';
30 $this->author = 'icommkt';
31 $this->need_instance = 0;
32
33 /**
34 * Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
35 */
36 $this->bootstrap = true;
37
38 parent::__construct();
39
40 $this->displayName = $this->l('ICOMMKT Connector');
41 $this->description = $this->l('Enabled API service to connect to ICOMMKT service');
42 }
43
44 public function install()
45 {
46 return parent::install() &&
47 $this->installDb() &&
48 $this->addNewColumn() &&
49 $this->registerHook('moduleRoutes');
50 }
51
52 public function uninstall()
53 {
54
55 return parent::uninstall() && $this->uninstallDb() && $this->uninstallColumns();
56 }
57
58 public function installDb()
59 {
60 $sql = Tools::file_get_contents(dirname(__FILE__) . '/install.sql');
61 $sql = str_replace('PREFIX_', _DB_PREFIX_, $sql);
62 $sql = preg_split("/;\s*[\r\n]+/", $sql);
63 foreach ($sql as $query) {
64 Db::getInstance()->Execute($query);
65 }
66 return true;
67 }
68
69 public function addNewColumn()
70 {
71 if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '>=') == true) {
72 $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'emailsubscription ADD COLUMN is_send_icommkt BOOLEAN';
73 $sql2 = 'ALTER TABLE ' . _DB_PREFIX_ . 'emailsubscription ADD COLUMN date_send_icommkt DATETIME';
74 } else {
75 $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'newsletter ADD COLUMN is_send_icommkt BOOLEAN';
76 $sql2 = 'ALTER TABLE ' . _DB_PREFIX_ . 'newsletter ADD COLUMN date_send_icommkt DATETIME';
77 }
78 Db::getInstance()->execute($sql);
79 Db::getInstance()->execute($sql2);
80 return true;
81 }
82
83 public function uninstallColumns()
84 {
85 if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '>=') == true) {
86 $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'emailsubscription DROP COLUMN is_send_icommkt';
87 $sql2 = 'ALTER TABLE ' . _DB_PREFIX_ . 'emailsubscription DROP COLUMN date_send_icommkt';
88 } else {
89 $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'newsletter DROP COLUMN is_send_icommkt';
90 $sql2 = 'ALTER TABLE ' . _DB_PREFIX_ . 'newsletter DROP COLUMN date_send_icommkt';
91 }
92 Db::getInstance()->execute($sql);
93 Db::getInstance()->execute($sql2);
94 return true;
95 }
96
97 public function uninstallDb()
98 {
99 Db::getInstance()->Execute('DROP TABLE `' . _DB_PREFIX_ . 'commktconnector_abandomentcarts`');
100 Db::getInstance()->Execute('DROP TABLE `' . _DB_PREFIX_ . 'commktconnector_abandomentcarts_error`');
101
102 return true;
103 }
104
105 /**
106 * Load the configuration form
107 */
108 public function getContent()
109 {
110 /**
111 * If values have been submitted in the form, process.
112 */
113 if (((bool)Tools::isSubmit('submitIcommktconnectorModule')) == true) {
114 $this->postProcess();
115 }
116
117 /* Mostrar en el backoffice las URLs de ejemplo para ejecutar las distintas funciones del módulo */
118 $load_cart_url = $this->getFormattedLink(array(
119 'action' => 'load_cart',
120 'secure_token' => '[secure_token]',
121 'id_cart' => '[id_cart]'
122 ));
123 $send_abandoment_cart_url = $this->getFormattedLink(array(
124 'action' => 'sendAbandomentcarts',
125 'secure_token' => '[secure_token]',
126 ));
127
128 $send_icommkt_user = $this->getFormattedLinkUser(array(
129 'action' => 'sendtoicommktuser',
130 'secure_token' => '[secure_token]',
131 ));
132
133 $this->context->smarty->assign(array(
134 'module_dir' => $this->_path,
135 'load_cart_url' => $load_cart_url,
136 'send_abandoment_cart_url' => $send_abandoment_cart_url,
137 'send_icommkt_user' => $send_icommkt_user
138 ));
139
140 $this->context->smarty->assign('module_dir', $this->_path);
141
142 $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/configure.tpl');
143
144 return $output . $this->renderForm();
145 }
146
147 /**
148 * Create the form that will be displayed in the configuration of your module.
149 */
150 protected function renderForm()
151 {
152 $helper = new HelperForm();
153
154 $helper->show_toolbar = false;
155 $helper->table = $this->table;
156 $helper->module = $this;
157 $helper->default_form_language = $this->context->language->id;
158 $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);
159
160 $helper->identifier = $this->identifier;
161 $helper->submit_action = 'submitIcommktconnectorModule';
162 $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
163 . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
164 $helper->token = Tools::getAdminTokenLite('AdminModules');
165
166 $helper->tpl_vars = array(
167 'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */
168 'languages' => $this->context->controller->getLanguages(),
169 'id_language' => $this->context->language->id,
170 );
171
172 return $helper->generateForm(array($this->getConfigForm()));
173 }
174
175 /**
176 * Create the structure of your form.
177 */
178 protected function getConfigForm()
179 {
180 return array(
181 'form' => array(
182 'legend' => array(
183 'title' => $this->l('Settings'),
184 'icon' => 'icon-cogs',
185 ),
186 'input' => array(
187 array(
188 'col' => 3,
189 'type' => 'text',
190 'prefix' => '<i class="icon icon-gear"></i>',
191 'desc' => $this->l('You can custom this value as you wish'),
192 'name' => 'ICOMMKT_APPKEY',
193 'label' => $this->l('App KEY'),
194 ),
195 array(
196 'col' => 3,
197 'type' => 'text',
198 'prefix' => '<i class="icon icon-gear"></i>',
199 'desc' => $this->l('You can custom this value as you wish'),
200 'name' => 'ICOMMKT_APPTOKEN',
201 'label' => $this->l('App TOKEN'),
202 ),
203 array(
204 'col' => 3,
205 'type' => 'text',
206 'prefix' => '<i class="icon icon-gear"></i>',
207 'desc' => $this->l('API KEY code from the account icommkt'),
208 'name' => 'ICOMMKT_APIKEY',
209 'label' => $this->l('API Key'),
210 ),
211 array(
212 'col' => 3,
213 'type' => 'text',
214 'class' => 'newsletter',
215 'prefix' => '<i class="icon icon-gear"></i>',
216 'desc' => $this->l('Code obtained from the account profile'),
217 'name' => 'ICOMMKT_PROFILEKEY',
218 'label' => $this->l('Profile Key'),
219 ),
220 array(
221 'col' => 3,
222 'type' => 'text',
223 'prefix' => '<i class="icon icon-gear"></i>',
224 'desc' => $this->l('Profile key code where to send Cart Abandon'),
225 'name' => 'ICOMMKT_PROFILEKEY_ABANDON',
226 'label' => $this->l('Profile Key Cart Abandon'),
227 ),
228 array(
229 'col' => 3,
230 'type' => 'text',
231 'prefix' => '<i class="icon icon-gear"></i>',
232 'desc' => $this->l('Required parameter to send the data.Parameter Customizable'),
233 'name' => 'ICOMMKT_SECURE_TOKEN',
234 'label' => $this->l('Secure TOKEN'),
235 ),
236 array(
237 'col' => 3,
238 'type' => 'text',
239 'prefix' => '<i class="icon icon-gear"></i>',
240 'desc' => $this->l('Time that goes by to consider an abandoned cart'),
241 'name' => 'ICOMMKT_DAYS_TO_ABANDON',
242 'label' => $this->l('Days to abandon'),
243 ),
244 array(
245 'type' => 'radio',
246 'label' => 'Friendly URL',
247 'name' => 'ICOMMKT_FRIENDLY_URL',
248 'values' => array(
249 array(
250 'id' => 'active_on',
251 'value' => 1,
252 'label' => 'Enabled'
253 ),
254 array(
255 'id' => 'active_off',
256 'value' => 0,
257 'label' => 'Disabled'
258 )
259 )
260 )
261 ),
262 'submit' => array(
263 'title' => $this->l('Save'),
264 ),
265 ),
266 );
267 }
268
269 /**
270 * Set values for the inputs.
271 */
272 protected function getConfigFormValues()
273 {
274 $icommkt_days_to_abandon = Configuration::get('ICOMMKT_DAYS_TO_ABANDON', null);
275
276 return array(
277 'ICOMMKT_APPKEY' => Configuration::get('ICOMMKT_APPKEY', null),
278 'ICOMMKT_APPTOKEN' => Configuration::get('ICOMMKT_APPTOKEN', null),
279 'ICOMMKT_APIKEY' => Configuration::get('ICOMMKT_APIKEY', null),
280 'ICOMMKT_PROFILEKEY' => Configuration::get('ICOMMKT_PROFILEKEY', null),
281 'ICOMMKT_PROFILEKEY_ABANDON' => Configuration::get('ICOMMKT_PROFILEKEY_ABANDON', null),
282 'ICOMMKT_SECURE_TOKEN' => Configuration::get('ICOMMKT_SECURE_TOKEN', null),
283 'ICOMMKT_DAYS_TO_ABANDON' => !empty($icommkt_days_to_abandon) ? $icommkt_days_to_abandon : '1',
284 'ICOMMKT_FRIENDLY_URL' => Configuration::get('ICOMMKT_FRIENDLY_URL', null),
285 );
286 }
287
288 /**
289 * Save form data.
290 */
291 protected function postProcess()
292 {
293 $form_values = $this->getConfigFormValues();
294
295 foreach (array_keys($form_values) as $key) {
296 Configuration::updateValue($key, Tools::getValue($key));
297 }
298 }
299
300 public function getApiBodyRequest()
301 {
302 $input_xml = null;
303 $putresource = fopen("php://input", "r");
304 while ($putData = fread($putresource, 1024)) {
305 $input_xml .= $putData;
306 }
307 fclose($putresource);
308 return $input_xml;
309 }
310
311 private function getallheaders()
312 {
313 $headers = array();
314 foreach ($_SERVER as $name => $value) {
315 if (Tools::subst($name, 0, 5) == 'HTTP_') {
316 $name = Tools::strtolower(str_replace('_', ' ', Tools::subst($name, 5)));
317 $headers[str_replace(' ', '-', ucwords($name))] = $value;
318 }
319 }
320 return $headers;
321 }
322
323 public function authorizeRequest()
324 {
325 $headers = $this->getallheaders();
326 $headerKey = '';
327 $headerToken = '';
328 foreach ($headers as $key => $value) {
329 if (Tools::strtoupper($key) == 'X-VTEX-API-APPKEY') {
330 $headerKey = $value;
331 }
332 if (Tools::strtoupper($key) == 'X-VTEX-API-APPTOKEN') {
333 $headerToken = $value;
334 }
335 }
336 if (!empty($headerKey) && !empty($headerToken)) {
337 $shopCondition = 'id_shop IS NULL';
338 if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') && Shop::getTotalShops() > 1) {
339 $shopCondition = 'id_shop IS NOT NULL';
340 }
341
342 $query = sprintf("SELECT * FROM " . _DB_PREFIX_ . "configuration WHERE name='ICOMMKT_APPKEY' "
343 . "AND value='%s' AND " . $shopCondition, pSQL($headerKey));
344
345 $result = Db::getInstance()->getRow($query);
346 if ($result) {
347 $this->context_id_shop = $result['id_shop'];
348 $this->context_id_shop_group = $result['id_shop_group'];
349 } else {
350 $this->setError(
351 'Cannot find store for ICOMMKT_APPKEY - ' . $headerKey,
352 400,
353 json_encode($headers),
354 false
355 );
356 header("HTTP/1.1 400 Forbidden");
357 die();
358 }
359 }
360 $apiKey = Configuration::get('ICOMMKT_APPKEY', null, $this->context_id_shop_group, $this->context_id_shop);
361 $apiToken = Configuration::get('ICOMMKT_APPTOKEN', null, $this->context_id_shop_group, $this->context_id_shop);
362
363 if (empty($headerKey) || empty($headerToken) || $headerKey != $apiKey || $headerToken != $apiToken) {
364 $this->setError('Bad credentials', 403, json_encode($headers), false);
365 header("HTTP/1.1 403 Forbidden");
366 die();
367 }
368 }
369
370 public function controllerSetRespondeHeaders()
371 {
372 if (ob_get_level() && ob_get_length() > 0) {
373 ob_end_clean();
374 }
375 header('Content-type: application/json');
376 header('Cache-Control: no-store, no-cache');
377 }
378
379 public function setError($message, $level, $additional_data = false, $stop = true)
380 {
381 PrestaShopLogger::addLog('ICOMMKTCONNECTOR - ERROR: ' . $message . ' - ' . $additional_data, 4, $level);
382 $this->controllerSetRespondeHeaders();
383 //http_response_code($level);
384 if ($stop) {
385 exit(json_encode(array('error' => $message)));
386 }
387 }
388
389 public function hookModuleRoutes($params)
390 {
391 $result = array(
392 'oms_list_status' => array(
393 //List Orders
394 'controller' => 'oms',
395 'keywords' => array(),
396 'rule' => 'icommkt/oms/pvt/status_list',
397 'params' => array(
398 'fc' => 'module',
399 'module' => $this->name
400 ),
401 ),
402 'oms_list_orders' => array(
403 //List Orders
404 'controller' => 'oms',
405 'keywords' => array(
406 'id_order' => array('regexp' => '[0-9]+', 'param' => 'id_order'),
407 ),
408 'rule' => 'icommkt/oms/pvt/orders{/:id_order}',
409 'params' => array(
410 'fc' => 'module',
411 'module' => $this->name
412 ),
413 ),
414 'master_data_search' => array(
415 //List Orders
416 'controller' => 'masterdata',
417 'keywords' => array(
418 'entity_code' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'entity_code'),
419 ),
420 'rule' => 'icommkt/dataentities/{entity_code}/search',
421 'params' => array(
422 'fc' => 'module',
423 'module' => $this->name
424 ),
425 ),
426 );
427
428 if (Configuration::get('ICOMMKT_FRIENDLY_URL', null) == 1) {
429 $result[$this->name.'-abandomentcart'] = array(
430 //List Orders
431 'controller' => 'abandomentcart',
432 'keywords' => array(
433 'action' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'action'),
434 'secure_token' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'secure_token'),
435 'id_cart' => array('regexp' => '[0-9\pL\pS-]*', 'param' => 'id_cart'),
436 ),
437 'rule' => 'abandomentcart/{action}/{secure_token}{/:id_cart}',
438 'params' => array(
439 'fc' => 'module',
440 'module' => $this->name
441 ),
442 );
443 }
444
445 $result[$this->name.'-send_to_icommkt'] = array(
446 'controller' => 'sendtoicommkt',
447 'keywords' => array(
448 'action' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'action'),
449 'secure_token' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'secure_token'),
450 ),
451 'rule' => 'sendtoicommkt/{action}{secure_token}',
452 'params' => array(
453 'fc' => 'module',
454 'module' => $this->name
455 ),
456 );
457
458 return $result;
459 }
460
461 public function getSingleOrder($id_order)
462 {
463 $order = $this->getOrderInformation($id_order);
464 $cart_rules = $this->getCartRules($id_order);
465 if (!$cart_rules) {
466 $cart_rules = array(
467 array(
468 "code" => '',
469 "name" => ''
470 )
471 );
472 }
473
474 if (!$order) {
475 exit('order not found');
476 }
477
478 $currency = Currency::getCurrency(Configuration::get('PS_CURRENCY_DEFAULT'));
479 $data = array(
480 'orderId' => $order['id_order'],
481 'sequence' => $order['id_order'],
482 'marketPlaceOrderId' => $order['id_order'],
483 'marketplaceServicesEndpoint' => null,
484 'sellerOrderId' => $order['id_order'],
485 'origin' => null,
486 'affiliateId' => null,
487 'salesChannel' => 1,
488 'merchantName' => null,
489 'status' => $order['state_name'],
490 'statusId' => $order['current_state'],
491 'statusDescription' => $order['state_name'],
492 'value' => $order['total_paid'],
493 'creationDate' => gmdate("c", strtotime($order['date_add'])),
494 'lastChange' => gmdate("c", strtotime($order['date_upd'])),
495 'orderGroup' => null,
496 'totals' => array(
497 array(
498 'id' => 'Items',
499 'name' => 'Total de los items',
500 'values' => $order['total_products_wt'],
501 ),
502 array(
503 'id' => 'Discounts',
504 'name' => 'Total de descuentos',
505 'values' => $order['total_discounts_tax_incl'],
506 ),
507 array(
508 'id' => 'Shipping',
509 'name' => 'Costo total del envío',
510 'values' => $order['total_shipping_tax_incl'],
511 ),
512 ),
513 'items' => $this->formatProductList($order['id_order'], true),
514 'marketplaceItems' => array(),
515 'clientProfileData' => array(
516 'id' => $order['id_customer'],
517 'email' => $order['email'],
518 'firstName' => $order['firstname'],
519 'lastName' => $order['lastname'],
520 'documentType' => 'nif',
521 'document' => $order['dni'],
522 'phone' => ($order['phone'] != '' ? $order['phone'] : $order['phone_mobile']),
523 'corporateName' => $order['company'],
524 'tradeName' => null,
525 'corporateDocument' => null,
526 'stateInscription' => null,
527 'corporatePhone' => null,
528 'isCorporate' => false,
529 'userProfileId' => $order['id_customer'],
530 'customerClass' => null,
531
532 ),
533 'giftRegistryData' => null,
534 'marketingData' => array(
535 'id' => 'marketingData',
536 'utmSource' => $cart_rules[0]['name'],
537 'utmPartner' => null,
538 'utmMedium' => '',
539 'utmCampaign' => '',
540 'coupon' => $cart_rules[0]['code'],
541 'utmiCampaign' => '',
542 'utmipage' => '',
543 'utmiPart' => '',
544 'marketingTags' => array(),
545 ),
546 'ratesAndBenefitsData' => array(
547 'id' => 'ratesAndBenefitsData',
548 'rateAndBenefitsIdentifiers' => array(),
549 ),
550 'shippingData' => array(
551 'id' => 'shippingData',
552 'address' => array(
553 'addressType' => "residential",
554 'receiverName' => $order['firstname'] . ' ' . $order['lastname'],
555 'addressId' => $order['id_address'],
556 'postalCode' => $order['postcode'],
557 'city' => $order['city'],
558 'state' => State::getNameById($order['id_state']),
559 'country' => Country::getNameById($order['id_lang'], $order['id_state']),
560 'street' => $order['address1'],
561 'number' => null,
562 'neighborhood' => null,
563 'complement' => $order['address2'],
564 'reference' => null,
565 'geoCoordinates' => array(),
566 ),
567 'logisticsInfo' => $this->getLogisticInfo($id_order),
568 'trackingHints' => null,
569 'selectedAddresses' => array(
570 array(
571 'addressId' => $order['id_address_delivery'],
572 'addressType' => "residential",
573 'receiverName' => $order['firstname'] . ' ' . $order['lastname'],
574 'street' => $order['address1'],
575 'number' => null,
576 'complement' => $order['address2'],
577 'neighborhood' => null,
578 'postalCode' => $order['postcode'],
579 'city' => $order['city'],
580 'state' => State::getNameById($order['id_state']),
581 'country' => Country::getNameById($order['id_lang'], $order['id_state']),
582 'reference' => null,
583 'geoCoordinates' => array(),
584 ),
585 ),
586 ),
587 'paymentData' => array(
588 'transactions' => array(
589 array(
590 'isActive' => true,
591 'transactionId' => "",
592 'merchantName' => Configuration::get('PS_SHOP_NAME'),
593 'payments' => $this->getDataPayment($order['reference']),
594 ),
595 ),
596 ),
597 'packageAttachment' => array(
598 'packages' => array(),
599 ),
600 'sellers' => array(
601 array(
602 'id' => "",
603 'name' => "",
604 'logo' => "",
605 ),
606 ),
607 'callCenterOperatorData' => null,
608 'followUpEmail' => "",
609 'lastMessage' => null,
610 'hostname' => Configuration::get('PS_SHOP_NAME'),
611 'changesAttachment' => null,
612 'openTextField' => null,
613 'roundingError' => 0,
614 'orderFormId' => "",
615 'commercialConditionData' => null,
616 'isCompleted' => true,
617 'customData' => null,
618 'storePreferencesData' => array(
619 'countryCode' => Country::getIsoById(Configuration::get('PS_SHOP_COUNTRY_ID')),
620 'currencyCode' => (isset($currency['iso_code']) ? $currency['iso_code'] : 'undefined'),
621 'currencyFormatInfo' => array(
622 'CurrencyDecimalDigits' => 2,
623 'CurrencyDecimalSeparator' => ",",
624 'CurrencyGroupSeparator' => ".",
625 'CurrencyGroupSize' => 3,
626 'StartsWithCurrencySymbol' => true,
627 ),
628 'currencyLocale' => null,
629 'currencySymbol' => (isset($currency['sign']) ? $currency['sign'] : 'undefined'),
630 'timeZone' => Configuration::get('PS_TIMEZONE'),
631 ),
632 'allowCancellation' => true,
633 'allowEdition' => false,
634 'isCheckedIn' => false,
635 'marketplace' => array(
636 'baseURL' => Configuration::get('PS_SHOP_DOMAIN'),
637 'isCertified' => null,
638 'name' => Configuration::get('PS_SHOP_NAME'),
639 ),
640 );
641
642 exit(json_encode($data));
643 }
644
645 public function getOrders()
646 {
647 $orderField = null;
648 $orderType = null;
649 $limit = 1;
650 $page = 1;
651 $date_range = array();
652 $date_updated = array();
653 $order_states = array();
654
655 if (Tools::getValue('page') && is_numeric(Tools::getValue('page'))) {
656 $page = (int)Tools::getValue('page');
657 }
658
659 if (Tools::getValue('per_page') && is_numeric(Tools::getValue('per_page'))) {
660 $limit = (int)Tools::getValue('per_page');
661 }
662
663 if (Tools::getValue('current_state') && is_array(Tools::getValue('current_state'))) {
664 $order_states = Tools::getValue('current_state');
665 }
666
667 if ($orderBy = Tools::getValue('orderBy')) {
668 $orderParams = explode(',', $orderBy);
669 $field = $orderParams[0];
670
671 switch ($field) {
672 case 'orderId':
673 $orderField = 'id_order';
674 break;
675 case 'totalValue':
676 $orderField = 'total_paid';
677 break;
678 case 'creationDate':
679 $orderField = 'date_add';
680 break;
681 default:
682 $orderField = null;
683 break;
684 }
685
686 $type = $orderParams[1];
687 if ($type == 'asc' || $type == 'desc') {
688 $orderType = $type;
689 }
690 }
691
692 if ($f_creationDate = Tools::getValue('f_creationDate')) {
693 preg_match('/\[(.*?)\]/s', $f_creationDate, $creationDate);
694 $creationDate = explode('TO', $creationDate[1]);
695 if ((bool)strtotime(trim($creationDate[0])) && (bool)strtotime(trim($creationDate[1]))) {
696 $date_range['from'] = date('"Y-m-d H:i:s"', strtotime(trim($creationDate[0])));
697 $date_range['to'] = date('"Y-m-d H:i:s"', strtotime(trim($creationDate[1])));
698 }
699 }
700
701 if ($f_updateDate = Tools::getValue('f_updateDate')) {
702 preg_match('/\[(.*?)\]/s', $f_updateDate, $updatedDate);
703 $updatedDate = explode('TO', $updatedDate[1]);
704 if ((bool)strtotime(trim($updatedDate[0])) && (bool)strtotime(trim($updatedDate[1]))) {
705 $date_updated['from'] = date('"Y-m-d H:i:s"', strtotime(trim($updatedDate[0])));
706 $date_updated['to'] = date('"Y-m-d H:i:s"', strtotime(trim($updatedDate[1])));
707 }
708 }
709
710 $data_orders = $this->getOrdersWithInformations(
711 $limit,
712 $page,
713 $orderField,
714 $orderType,
715 $date_range,
716 $date_updated,
717 $order_states
718 );
719
720 $ordersFormatVtex = array();
721 $ordersFormatVtex['list'] = array();
722 foreach ($data_orders['orders'] as &$order) {
723 $ordersFormatVtex['list'][] = $this->formatListOrder($order);
724 }
725
726 //if (count($ordersFormatVtex['list'])) {
727 $ordersFormatVtex['facets'] = array();
728 $ordersFormatVtex['paging'] = array(
729 'total' => (int)$data_orders['count'],
730 'pages' => ceil($data_orders['count'] / $limit),
731 'currentPage' => $page,
732 'perPage' => $limit,
733 );
734 $ordersFormatVtex['stats'] = array(
735 'stats' => array(
736 'totalValue' => array(
737 'Count' => (int)$data_orders['count'],
738 'Max' => 0,
739 'Mean' => 0,
740 'Min' => 0,
741 'Missing' => 0,
742 'StdDev' => 0,
743 'Sum' => 0,
744 'SumOfSquares' => 0,
745 'Facets' => array(),
746 ),
747 'totalItems' => array(
748 'Count' => (int)$data_orders['count'],
749 'Max' => 0,
750 'Mean' => 0,
751 'Min' => 0,
752 'Missing' => 0,
753 'StdDev' => 0,
754 'Sum' => 0,
755 'SumOfSquares' => 0,
756 'Facets' => array(),
757 ),
758 ),
759 );
760 //}
761
762 exit(json_encode($ordersFormatVtex));
763 }
764
765
766 public function formatListOrder($order)
767 {
768 $data = array(
769 'orderId' => $order['id_order'],
770 'creationDate' => gmdate("c", strtotime($order['date_add'])),
771 'clientName' => $order['firstname'] . ' ' . $order['lastname'],
772 'totalValue' => round($order['total_paid'], 2),
773 'paymentNames' => $order['payment'],
774 'status' => $order['state_name'],
775 'statusId' => $order['current_state'],
776 'statusDescription' => $order['state_name'],
777 'marketPlaceOrderId' => $order['id_order'],
778 'sequence' => $order['id_order'],
779 'salesChannel' => 1,
780 'affiliateId' => null,
781 'origin' => null,
782 'workflowInErrorState' => null,
783 'workflowInRetry' => null,
784 'lastMessageUnread' => null,
785 'ShippingEstimatedDate' => 'undefined',
786 'orderIsComplete' => ($order['valid'] ? true : false),
787 'listId' => null,
788 'listType' => null,
789 'authorizedDate' => gmdate("c", strtotime($order['date_add'])),
790 'callCenterOperatorName' => 'undefined',
791 'items' => $this->formatProductList($order['id_order']),
792 );
793
794 return $data;
795 }
796
797 public function getOrdersWithInformations(
798 $limit = null,
799 $page = null,
800 $orderField = null,
801 $orderType = null,
802 $date_range = array(),
803 $date_updated = array(),
804 $order_states = array(),
805 Context $context = null
806 ) {
807 $result = array();
808
809 if (!$context) {
810 $context = Context::getContext();
811 }
812
813 if (!$page) {
814 $n = 0;
815 } else {
816 $n = ((int)$page - 1) * (int)$limit;
817 }
818 $where = '';
819
820 if (count($date_range)) {
821 $where .= ' AND o.date_add BETWEEN ' . $date_range['from'] . ' AND ' . $date_range['to'];
822 }
823
824 if (count($date_updated)) {
825 $where .= ' AND o.date_upd BETWEEN ' . $date_updated['from'] . ' AND ' . $date_updated['to'];
826 }
827
828 if (count($order_states)) {
829 $where .= ' AND o.current_state IN (' . implode(',', $order_states) . ') ';
830 }
831
832
833 $sql = 'SELECT *, (
834 SELECT osl.`name`
835 FROM `' . _DB_PREFIX_ . 'order_state_lang` osl
836 WHERE osl.`id_order_state` = o.`current_state`
837 AND osl.`id_lang` = ' . (int)$context->language->id . '
838 LIMIT 1
839 ) AS `state_name`,
840 (
841 SELECT c.`name`
842 FROM `' . _DB_PREFIX_ . 'carrier` c
843 WHERE c.`id_carrier` = o.`id_carrier`
844 LIMIT 1
845 ) AS `carrier_name`,
846 o.`date_add` AS `date_add`, o.`date_upd` AS `date_upd`
847 FROM `' . _DB_PREFIX_ . 'orders` o
848 LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = o.`id_customer`)
849 LEFT JOIN `' . _DB_PREFIX_ . 'address` ad ON (ad.`id_address` = o.`id_address_delivery`)
850 WHERE 1
851 ' . Shop::addSqlRestriction(false, 'o') . '
852 ' . $where . '
853 ORDER BY o.' . ($orderField ? $orderField : 'id_order') . ' ' . ($orderType ? $orderType : 'DESC') . '
854 ' . ((int)$limit ? 'LIMIT ' . (int)$n . ', ' . (int)$limit : '');
855
856 $result['orders'] = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
857
858
859 $sql = 'SELECT count(id_order)
860 FROM `' . _DB_PREFIX_ . 'orders` o
861 WHERE 1
862 ' . Shop::addSqlRestriction(false, 'o') . '
863 ' . $where . '
864 ORDER BY o.' . ($orderField ? $orderField : 'id_order') . ' ' . ($orderType ? $orderType : 'DESC');
865
866 $result['count'] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
867
868 return $result;
869 }
870
871 public function getOrderInformation($id_order, Context $context = null)
872 {
873 if (!$context) {
874 $context = Context::getContext();
875 }
876
877 $limit = false;
878 $sql = 'SELECT *, (
879 SELECT osl.`name`
880 FROM `' . _DB_PREFIX_ . 'order_state_lang` osl
881 WHERE osl.`id_order_state` = o.`current_state`
882 AND osl.`id_lang` = ' . (int)$context->language->id . '
883 LIMIT 1
884 ) AS `state_name`,
885 (
886 SELECT c.`name`
887 FROM `' . _DB_PREFIX_ . 'carrier` c
888 WHERE c.`id_carrier` = o.`id_carrier`
889 LIMIT 1
890 ) AS `carrier_name`,
891 o.`date_add` AS `date_add`, o.`date_upd` AS `date_upd`
892 FROM `' . _DB_PREFIX_ . 'orders` o
893 LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = o.`id_customer`)
894 LEFT JOIN `' . _DB_PREFIX_ . 'address` ad ON (ad.`id_address` = o.`id_address_delivery`)
895 WHERE 1
896 ' . Shop::addSqlRestriction(false, 'o') . ' AND id_order = ' . $id_order . '
897 ORDER BY o.`date_add` DESC
898 ' . ((int)$limit ? 'LIMIT 0, ' . (int)$limit : '');
899 return Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
900 }
901
902 public function formatProductList($id_order, $extend = false, Context $context = null)
903 {
904 if (!$context) {
905 $context = Context::getContext();
906 }
907
908 $products = array();
909
910 foreach (OrderDetail::getList($id_order) as $item) {
911 $data = array(
912 'seller' => null,
913 'quantity' => $item['product_quantity'],
914 'description' => $item['product_name'],
915 'ean' => $item['product_ean13'],
916 'refId' => $item['product_reference'],
917 'id' => (empty($item['product_attribute_id']) ? $item['product_id'] : $item['product_attribute_id']),
918 'productId' => $item['product_id'],
919 'sellingPrice' => round($item['unit_price_tax_incl'], 2),
920 'price' => round($item['total_price_tax_incl'], 2),
921 );
922
923 if ($extend) {
924 $product = new Product($item['product_id'], false, (int)$context->language->id);
925
926 $image = Image::getCover($item['product_id']);
927 $image_result = (isset($image['id_image']))
928 ?
929 $context->link->getImageLink($product->link_rewrite, $image['id_image'])
930 :
931 'not_cover_image';
932 $data_extend = array(
933 'uniqueId' => $item['product_id'],
934 'description' => $item['product_name'],
935 'listPrice' => round($item['original_product_price'], 2),
936 'manualPrice' => null,
937 'priceTags' => array(),
938 'imageUrl' => $image_result,
939 'detailUrl' => $context->link->getProductLink($item['product_id']),
940 'categories' => array_column(Product::getProductCategoriesFull($item['product_id']), 'name'),
941 'components' => array(),
942 'bundleItems' => array(),
943 'params' => array(),
944 'offerings' => array(),
945 'sellerSku' => $item['product_attribute_id'],
946 'priceValidUntil' => null,
947 'commission' => 0,
948 'tax' => $item['tax_rate'],
949 'preSaleDate' => null,
950 'additionalInfo' => array(
951 'brandName' => $product->manufacturer_name,
952 'brandId' => $product->id_manufacturer,
953 'categoriesIds' => implode(',', $product->getCategories()),
954 'productClusterId' => '',
955 'commercialConditionId' => "1",
956 'dimension' => array(
957 'cubicweight' => 1,
958 'height' => 1,
959 'length' => 1,
960 'weight' => 1,
961 'width' => 1
962 ),
963 'offeringInfo' => null,
964 'offeringType' => null,
965 'offeringTypeId' => null,
966 ),
967 'measurementUnit' => "un",
968 'unitMultiplier' => 1,
969 'isGift' => false,
970 'shippingPrice' => round($item['total_shipping_price_tax_incl'], 2),
971 'rewardValue' => 0,
972 'freightCommission' => 0,
973 );
974
975 $data = array_merge($data, $data_extend);
976 }
977
978 $products[] = $data;
979 }
980
981 return $products;
982 }
983
984 public function getLogisticInfo($id_order)
985 {
986 $data = array();
987
988 foreach (OrderDetail::getList($id_order) as $key => $item) {
989 $data[] = array(
990 'itemIndex' => $key,
991 'selectedSla' => "Normal",
992 'lockTTL' => "12d",
993 'price' => round($item['unit_price_tax_incl'], 2),
994 'listPrice' => round($item['original_product_price'], 2),
995 'sellingPrice' => round($item['unit_price_tax_incl'], 2),
996 'deliveryWindow' => null,
997 'deliveryCompany' => "",
998 'shippingEstimate' => "",
999 'shippingEstimateDate' => "",
1000 'slas' => array(
1001 array(
1002 'id' => "Normal",
1003 'name' => "Normal",
1004 'shippingEstimate' => "",
1005 'deliveryWindow' => null,
1006 'price' => round($item['unit_price_tax_incl'], 2),
1007 'deliveryChannel' => "delivery",
1008 'pickupStoreInfo' => array(
1009 'additionalInfo' => null,
1010 'address' => null,
1011 'dockId' => null,
1012 'friendlyName' => null,
1013 'isPickupStore' => false,
1014 ),
1015 ),
1016 ),
1017 'deliveryIds' => array(
1018 array(
1019 'courierId' => "1",
1020 'courierName' => "",
1021 'dockId' => "1",
1022 'quantity' => 1,
1023 'warehouseId' => "1_1",
1024 ),
1025 ),
1026 'deliveryChannel' => 'delivery',
1027 'pickupStoreInfo' => array(
1028 'additionalInfo' => null,
1029 'address' => null,
1030 'dockId' => null,
1031 'friendlyName' => null,
1032 'isPickupStore' => false,
1033 ),
1034 'addressId' => ""
1035 );
1036 }
1037 }
1038
1039 public function getCartRules($id_order)
1040 {
1041 return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
1042 SELECT *
1043 FROM `' . _DB_PREFIX_ . 'order_cart_rule` ocr
1044 LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule` cr ON ocr.id_cart_rule = cr.id_cart_rule
1045 WHERE ocr.`id_order` = ' . (int)$id_order);
1046 }
1047
1048 public static function getDataPayment($order_reference)
1049 {
1050 $payments = Db::getInstance()->executeS("
1051 SELECT *
1052 FROM `" . _DB_PREFIX_ . "order_payment`
1053 WHERE `order_reference` = '" . $order_reference . "'");
1054
1055 $data = array();
1056
1057 foreach ($payments as $value) {
1058 $data[] = array(
1059 'id' => $value['transaction_id'],
1060 'paymentSystem' => "",
1061 'paymentSystemName' => $value['card_brand'],
1062 'value' => $value['amount'],
1063 'installments' => 3,
1064 'referenceValue' => $value['transaction_id'],
1065 'cardHolder' => $value['card_holder'],
1066 'cardNumber' => $value['card_number'],
1067 'firstDigits' => "",
1068 'lastDigits' => "",
1069 'cvv2' => null,
1070 'expireMonth' => ($value['card_expiration'] ? Tools::subst($value['card_expiration'], 2) : null),
1071 'expireYear' => ($value['card_expiration'] ? Tools::subst($value['card_expiration'], -2) : null),
1072 'url' => null,
1073 'giftCardId' => null,
1074 'giftCardName' => null,
1075 'giftCardCaption' => null,
1076 'redemptionCode' => null,
1077 'group' => "",
1078 'tid' => "",
1079 'dueDate' => null,
1080 'connectorResponses' => array(),
1081 );
1082 }
1083
1084 return $data;
1085 }
1086
1087 public function getClients()
1088 {
1089 $customers = $this->getCustomers();
1090 $prepared_data = array();
1091 $langs = Language::getLanguages();
1092
1093 foreach ($customers as $customer) {
1094 $customer['address_data_object'] = $this->getAddressCustomer($customer['id_customer']);
1095 $customer['address_company_object'] = $this->getAddressCompanyCustomer($customer['id_customer']);
1096 $customer['localeDefault'] = (($customer['id_lang'] && isset($langs[$customer['id_lang']])) ?
1097 $langs[$customer['id_lang']]['iso_code'] : null);
1098 $prepared_data[] = $this->formatCustomerDataToVTEX($customer);
1099 }
1100 die(json_encode($prepared_data));
1101 }
1102
1103 public function getCustomers($only_active = false)
1104 {
1105 $where_params = Tools::getValue('_where');
1106 if (!$where_params || strpos($where_params, 'lastInteractionIn') === false
1107 || strpos($where_params, 'createdIn') === false
1108 ) {
1109 die('no "where" parameter missing lastInteractionIn/createdIn on where clausule');
1110 }
1111 $where_params = $this->sanitizeWhereParams($where_params);
1112
1113 $page = 1;
1114 $limit = 1;
1115 if (Tools::getValue('page') && is_numeric(Tools::getValue('page'))) {
1116 $page = (int)Tools::getValue('page');
1117 }
1118 if (Tools::getValue('per_page') && is_numeric(Tools::getValue('per_page'))) {
1119 $limit = (int)Tools::getValue('per_page');
1120 }
1121 if (!$page) {
1122 $n = 0;
1123 } else {
1124 $n = ((int)$page - 1) * (int)$limit;
1125 }
1126
1127 $where_params = str_replace('lastInteractionIn between ', 'date_upd between \'', $where_params);
1128 $where_params = str_replace('createdIn between ', 'date_add between \'', $where_params);
1129 $where_params = str_replace(' AND ', '\' AND \'', $where_params);
1130 $where_params = str_replace(')', '\')', $where_params);
1131 $sql = 'SELECT *
1132 FROM `' . _DB_PREFIX_ . 'customer`
1133 WHERE 1 ' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) .
1134 ($only_active ? ' AND `active` = 1' : '') . '
1135 ' . ($where_params ? ' AND (' . $where_params . ')' : '') . '
1136 ORDER BY `date_add` ASC
1137 ' . ((int)$limit ? 'LIMIT ' . (int)$n . ', ' . (int)$limit : '');
1138
1139 $sql_count = 'SELECT count(*) cuenta
1140 FROM `' . _DB_PREFIX_ . 'customer`
1141 WHERE 1 ' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) .
1142 ($only_active ? ' AND `active` = 1' : '') . '
1143 ' . ($where_params ? ' AND (' . $where_params . ')' : '') . '
1144 ORDER BY `date_add` ASC';
1145
1146 $count = Db::getInstance()->getValue($sql_count);
1147 header('Total-Records: ' . $count);
1148
1149 return Db::getInstance()->executeS($sql);
1150 }
1151
1152 public function getAddressCustomer($id_customer, $active = true)
1153 {
1154 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(
1155 'SELECT *
1156 FROM `' . _DB_PREFIX_ . 'address`
1157 WHERE `id_customer` = ' . (int)$id_customer . ' AND `deleted` = 0' . ($active ? ' AND `active` = 1' : '')
1158 );
1159 return $result;
1160 }
1161
1162 public function getAddressCompanyCustomer($id_customer, $active = true)
1163 {
1164 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(
1165 'SELECT *
1166 FROM `' . _DB_PREFIX_ . 'address`
1167 WHERE `id_customer` = ' . (int)$id_customer . ' '
1168 . "AND company <> '' "
1169 . 'AND `deleted` = 0' . ($active ? ' AND `active` = 1' : '')
1170 );
1171 return $result;
1172 }
1173
1174 public function formatCustomerDataToVTEX($customer)
1175 {
1176 $data = array(
1177 'email' => $customer['email'],
1178 'approved' => $customer['active'],
1179 'attach' => null,
1180 'birthDate' => $customer['birthday'],
1181 'firstName' => $customer['firstname'],
1182 'gender' => $customer['id_gender'],
1183 'isNewsletterOptIn' => $customer['newsletter'],
1184 'lastName' => $customer['lastname'],
1185 'localeDefault' => $customer['localeDefault'],
1186 'nickName' => null,
1187 'tradeName' => null,
1188 'userId' => $customer['id_customer']
1189 );
1190 $data += array(
1191 'phone' => (($customer['address_data_object']) ? $customer['address_data_object']['phone_mobile'] : null),
1192 'homePhone' => (($customer['address_data_object']) ? $customer['address_data_object']['phone'] : null),
1193 'document' => (($customer['address_data_object']) ? $customer['address_data_object']['dni'] : null),
1194 'documentType' => (($customer['address_data_object']) ?
1195 ($customer['address_data_object']['dni'] ? 'dni' : null) : null),
1196 );
1197 $data += array(
1198 'businessPhone' => (($customer['address_company_object']) ?
1199 $customer['address_company_object']['phone'] : null),
1200 'corporateName' => (($customer['address_company_object']) ?
1201 $customer['address_company_object']['company'] : null),
1202 'isCorporate' => (($customer['address_company_object']) ?
1203 ($customer['address_company_object']['company'] ? 1 : null) : null),
1204 );
1205 return $data;
1206 }
1207
1208 public function getStatusList(Context $context = null)
1209 {
1210 if (!$context) {
1211 $context = Context::getContext();
1212 }
1213 $orderStatus = OrderState::getOrderStates((int)$context->language->id);
1214 exit(json_encode($orderStatus));
1215 }
1216
1217 public function sanitizeWhereParams($where)
1218 {
1219 return (str_replace(array("'", '"'), array("''", '""'), $where));
1220 }
1221
1222 public function getFormattedLink($params)
1223 {
1224 $base_url = Tools::getHttpHost(true);
1225 $url_end = '';
1226 if (Configuration::get('ICOMMKT_FRIENDLY_URL', null) == 1) {
1227 $url = $base_url . '/abandomentcart';
1228 $url_end = '/'.$params['action']. '/'.$params['secure_token']. '/'.$params['id_cart']. '?d=0';
1229
1230 } else {
1231 $url = $base_url . '/index.php?fc=module&controller=abandomentcart&module=icommktconnector&d=0&';
1232 foreach ($params as $key => $param) {
1233 $url_end .= $key . '=' . $param;
1234 if (next($params)) {
1235 $url_end .= '&';
1236 }
1237 }
1238 }
1239
1240
1241
1242 $url = $url . $url_end;
1243 return $url;
1244 }
1245
1246 public function getFormattedLinkUser($params)
1247 {
1248 $base_url = Tools::getHttpHost(true);
1249
1250 $url = $base_url . '/index.php?fc=module&controller=sendtoicommkt&module=icommktconnector&';
1251
1252 $url_end = '';
1253 foreach ($params as $key => $param) {
1254 $url_end .= $key . '=' . $param;
1255 if (next($params)) {
1256 $url_end .= '&';
1257 }
1258 }
1259
1260 $url = $url . $url_end;
1261
1262 return $url;
1263 }
1264}