mirror of
https://github.com/retailcrm/prestashop-module.git
synced 2025-03-01 19:03:14 +03:00
V3 major update
* New design * Corporate clients * Online consultant * Job manager (cron replacement) * Improved compatibility with 1.6 * Possibility to toggle inventory & history uploads * Better error logging * Abandoned carts improvements * Drop inactive category branch from ICML generation
This commit is contained in:
parent
8bd474846d
commit
006bd960e3
6
.gitignore
vendored
6
.gitignore
vendored
@ -1 +1,7 @@
|
||||
.idea/
|
||||
retailcrm/views/css/less/*.css
|
||||
retailcrm/views/css/less/*.map
|
||||
retailcrm/views/css/*.css
|
||||
retailcrm/views/css/*.map
|
||||
!retailcrm/views/css/*.min.css
|
||||
retailcrm/config_*.xml
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,3 +1,13 @@
|
||||
## v3.0.2
|
||||
* Подкатегории неактивной категории и товары в них больше не попадают в ICML
|
||||
|
||||
## v3.0.1
|
||||
* Исправлена ошибка, приводившая к приостановке работы системы регулярных задач
|
||||
|
||||
## v3.0.0
|
||||
* Новый интерфейс в модуле
|
||||
* Добавлена возможность подключения онлайн-консультанта
|
||||
|
||||
## v2.5.1
|
||||
* Исправлена ошибка с некорректным значением скидки в заказе по истории
|
||||
|
||||
|
35
README.md
35
README.md
@ -6,12 +6,12 @@
|
||||
Prestashop module
|
||||
=================
|
||||
|
||||
Module allows integrate CMS Prestashop with [retailCRM](http://www.retailcrm.pro)
|
||||
Module allows integrate CMS Prestashop with [retailCRM](https://www.retailcrm.pro)
|
||||
|
||||
#### Features:
|
||||
|
||||
* Export orders to retailCRM & fetch changes back
|
||||
* Export product catalog into [ICML](http://www.retailcrm.pro/docs/Developers/ICML) format
|
||||
* Export product catalog into [ICML](https://help.retailcrm.pro/Developers/ICML) format
|
||||
|
||||
#### Setup
|
||||
|
||||
@ -19,32 +19,7 @@ Module allows integrate CMS Prestashop with [retailCRM](http://www.retailcrm.pro
|
||||
* Fill you api url & api key
|
||||
* Specify directories matching
|
||||
|
||||
#### Setting product catalog export
|
||||
#### Notice
|
||||
|
||||
Add to cron:
|
||||
|
||||
```
|
||||
* */4 * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/icml.php
|
||||
```
|
||||
|
||||
#### Getting changes in orders
|
||||
|
||||
Add to cron:
|
||||
|
||||
```
|
||||
*/7 * * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/sync.php
|
||||
```
|
||||
|
||||
#### Receiving balances from retailCRM
|
||||
|
||||
Add to cron:
|
||||
|
||||
```
|
||||
*/15 * * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/inventories.php
|
||||
```
|
||||
|
||||
#### Single orders archive export to retailCRM
|
||||
|
||||
```
|
||||
/usr/bin/php /path/to/your/site/modules/retailcrm/job/export.php
|
||||
```
|
||||
* This release contains an experimental feature "corporate customers". Use at your own risk.
|
||||
* This release only supports retailCRM API v5.
|
||||
|
54
README.ru.md
54
README.ru.md
@ -1,54 +0,0 @@
|
||||
Prestashop module
|
||||
=================
|
||||
|
||||
Модуль интеграции CMS Prestashop c [retailCRM](http://www.retailcrm.com)
|
||||
|
||||
#### Модуль позволяет:
|
||||
|
||||
* Экспортировать в CRM данные о заказах и клиентах и получать обратно изменения по этим данным
|
||||
* Синхронизировать справочники (способы доставки и оплаты, статусы заказов и т.п.)
|
||||
* Выгружать каталог товаров в формате [ICML](http://retailcrm.ru/docs/Разработчики/ФорматICML) (IntaroCRM Markup Language)
|
||||
|
||||
#### Настройка
|
||||
|
||||
На странице настроек модуля введите API url и API ключ, после этого установите соответствие справочников
|
||||
|
||||
#### Выгрузка каталога
|
||||
|
||||
Добавьте в крон запись вида
|
||||
|
||||
```
|
||||
* */4 * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/icml.php
|
||||
```
|
||||
|
||||
#### Получение изменение из retailCRM
|
||||
|
||||
Добавьте в крон запись вида
|
||||
|
||||
```
|
||||
*/7 * * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/sync.php
|
||||
```
|
||||
|
||||
#### Получение остатков из retailCRM
|
||||
|
||||
Добавьте в крон запись вида
|
||||
|
||||
```
|
||||
*/15 * * * * /usr/bin/php /path/to/your/site/modules/retailcrm/job/inventories.php
|
||||
```
|
||||
|
||||
#### Единоразовая выгрузка архива клиентов и заказов в retailCRM
|
||||
|
||||
```
|
||||
/usr/bin/php /path/to/your/site/modules/retailcrm/job/export.php
|
||||
```
|
||||
|
||||
#### Рекомендации
|
||||
|
||||
Для более полной выгрузки заказов из CRM в магазин рекомендуется заполнять следующие поля:
|
||||
|
||||
1. Покупатель
|
||||
..* Фамилия - если не указано, то в магазин выгрузится в виде прочерка(дефиса).
|
||||
..* E-mail - если не указано, то в магазин выгрузится в виде md5(Имя)@retailcrm.ru
|
||||
2. Доставка
|
||||
|
31
retailcrm/bootstrap.php
Executable file → Normal file
31
retailcrm/bootstrap.php
Executable file → Normal file
@ -1,13 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.0
|
||||
* @link https://retailcrm.ru
|
||||
* The MIT License (MIT)
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2014 Rob Dunham
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -16,8 +11,8 @@
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
@ -26,6 +21,19 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -67,7 +75,10 @@ class RetailcrmAutoloader
|
||||
$filename = $className . self::$fileExt;
|
||||
|
||||
foreach ($fileIterator as $file) {
|
||||
if (Tools::strtolower($file->getFilename()) === Tools::strtolower($filename) && $file->isReadable()) {
|
||||
if (Tools::strtolower($file->getFilename()) === Tools::strtolower($filename)
|
||||
&& $file->isReadable()
|
||||
&& !class_exists($className)
|
||||
) {
|
||||
include_once $file->getPathname();
|
||||
}
|
||||
}
|
||||
|
109
retailcrm/controllers/front/Consultant.php
Normal file
109
retailcrm/controllers/front/Consultant.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
class RetailcrmConsultantModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
/**
|
||||
* Universal render function for 1.6 and 1.7.
|
||||
*
|
||||
* @param string $response
|
||||
*/
|
||||
private function renderData($response)
|
||||
{
|
||||
if (property_exists($this, 'ajax')) {
|
||||
$this->ajax = true;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (Tools::substr(_PS_VERSION_, 0, 3) == '1.6') {
|
||||
echo $response;
|
||||
} else {
|
||||
try {
|
||||
parent::initContent();
|
||||
$this->ajaxRender($response);
|
||||
} catch (\Exception $exception) {
|
||||
// Sometimes ps_shoppingcart throws exception which breaks our controller.
|
||||
// We don't care about ps_shoppingcart here, so, we will fallback to old way.
|
||||
echo $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initContent()
|
||||
{
|
||||
$this->renderData(json_encode($this->getData()));
|
||||
}
|
||||
|
||||
/**
|
||||
* PrestaShop 1.6 compatibility
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds RCCT with site
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
$rcctExtractor = new RetailcrmCachedSettingExtractor();
|
||||
$rcct = $rcctExtractor
|
||||
->setCachedAndConfigKey(RetailCRM::CONSULTANT_RCCT)
|
||||
->getData();
|
||||
|
||||
if (empty($rcct)) {
|
||||
$script = trim(Configuration::get(RetailCRM::CONSULTANT_SCRIPT));
|
||||
|
||||
if (!empty($script)) {
|
||||
$rcctBuilder = new RetailcrmConsultantRcctExtractor();
|
||||
$rcct = $rcctBuilder->setConsultantScript($script)->build()->getDataString();
|
||||
|
||||
if (!empty($rcct)) {
|
||||
Cache::getInstance()->set(RetailCRM::CONSULTANT_RCCT, $rcct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('rcct' => empty($rcct) ? '' : $rcct);
|
||||
}
|
||||
}
|
103
retailcrm/controllers/front/DaemonCollector.php
Normal file
103
retailcrm/controllers/front/DaemonCollector.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
class RetailcrmDaemonCollectorModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
/**
|
||||
* Universal render function for 1.6 and 1.7
|
||||
*
|
||||
* @param string $response
|
||||
*/
|
||||
private function renderData($response)
|
||||
{
|
||||
if (property_exists($this, 'ajax')) {
|
||||
$this->ajax = true;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (Tools::substr(_PS_VERSION_, 0, 3) == '1.6') {
|
||||
echo $response;
|
||||
} else {
|
||||
try {
|
||||
parent::initContent();
|
||||
$this->ajaxRender($response);
|
||||
} catch (\Exception $exception) {
|
||||
// Sometimes ps_shoppingcart throws exception which breaks our controller.
|
||||
// We don't care about ps_shoppingcart here, so, we will fallback to old way.
|
||||
echo $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initContent()
|
||||
{
|
||||
$this->renderData(json_encode($this->getData()));
|
||||
}
|
||||
|
||||
/**
|
||||
* PrestaShop 1.6 compatibility
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns controller data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getData()
|
||||
{
|
||||
$isActive = Configuration::get(RetailCRM::COLLECTOR_ACTIVE);
|
||||
$siteKey = Configuration::get(RetailCRM::COLLECTOR_KEY);
|
||||
$collectorConfigured = $isActive && $siteKey;
|
||||
|
||||
$params = array('siteKey' => !$collectorConfigured ? '' : $siteKey);
|
||||
|
||||
if ($collectorConfigured && !empty($this->context->customer) && $this->context->customer->id) {
|
||||
$params['customerId'] = $this->context->customer->id;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
100
retailcrm/controllers/front/Jobs.php
Normal file
100
retailcrm/controllers/front/Jobs.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
class RetailcrmJobsModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
/**
|
||||
* Universal render function for 1.6 and 1.7
|
||||
*
|
||||
* @param string $response
|
||||
*/
|
||||
private function renderData($response)
|
||||
{
|
||||
if (property_exists($this, 'ajax')) {
|
||||
$this->ajax = true;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (Tools::substr(_PS_VERSION_, 0, 3) == '1.6') {
|
||||
echo $response;
|
||||
} else {
|
||||
try {
|
||||
parent::initContent();
|
||||
$this->ajaxRender($response);
|
||||
} catch (\Exception $exception) {
|
||||
// Sometimes ps_shoppingcart throws exception which breaks our controller.
|
||||
// We don't care about ps_shoppingcart here, so, we will fallback to old way.
|
||||
echo $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initContent()
|
||||
{
|
||||
$this->renderData(json_encode($this->getData()));
|
||||
}
|
||||
|
||||
/**
|
||||
* PrestaShop 1.6 compatibility
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs jobs
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
RetailcrmJobManager::startJobs(
|
||||
array(
|
||||
'RetailcrmAbandonedCartsEvent' => null,
|
||||
'RetailcrmIcmlEvent' => new \DateInterval('PT4H'),
|
||||
'RetailcrmSyncEvent' => new \DateInterval('PT7M'),
|
||||
'RetailcrmInventoriesEvent' => new \DateInterval('PT15M')
|
||||
)
|
||||
);
|
||||
|
||||
return array('success' => true);
|
||||
}
|
||||
}
|
8
retailcrm/controllers/front/index.php
Normal file
8
retailcrm/controllers/front/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
8
retailcrm/controllers/index.php
Normal file
8
retailcrm/controllers/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
9
retailcrm/index.php
Executable file → Normal file
9
retailcrm/index.php
Executable file → Normal file
@ -1 +1,8 @@
|
||||
<?php // Silence is golden
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
||||
|
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.9
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require_once(dirname(__FILE__) . '/../../../init.php');
|
||||
require_once(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
if (empty(Configuration::get('RETAILCRM_API_SYNCHRONIZE_CARTS'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$apiUrl = Configuration::get('RETAILCRM_ADDRESS');
|
||||
$apiKey = Configuration::get('RETAILCRM_API_TOKEN');
|
||||
$apiVersion = Configuration::get('RETAILCRM_API_VERSION');
|
||||
$api = null;
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log', $apiVersion);
|
||||
} else {
|
||||
error_log('abandonedCarts: set api key & url first', 3, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
return;
|
||||
}
|
||||
|
||||
$time = Configuration::get('RETAILCRM_API_SYNCHRONIZED_CART_DELAY');
|
||||
|
||||
if (is_numeric($time) && $time > 0) {
|
||||
$time = intval($time);
|
||||
} else {
|
||||
$time = 0;
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
$sql = 'SELECT c.id_cart, c.date_upd
|
||||
FROM '._DB_PREFIX_.'cart AS c
|
||||
WHERE id_customer != 0
|
||||
AND TIME_TO_SEC(TIMEDIFF(\''.pSQL($now->format('Y-m-d H:i:s')).'\', date_upd)) >= '.$time.'
|
||||
AND c.id_cart NOT IN(SELECT id_cart from '._DB_PREFIX_.'orders);';
|
||||
$rows = Db::getInstance()->executeS($sql);
|
||||
$status = Configuration::get('RETAILCRM_API_SYNCHRONIZED_CART_STATUS');
|
||||
$paymentTypes = array_keys(json_decode(Configuration::get('RETAILCRM_API_PAYMENT'), true));
|
||||
|
||||
if (empty($rows)
|
||||
|| empty($status)
|
||||
|| !$api
|
||||
|| (count($paymentTypes) < 1)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($rows as $cartId) {
|
||||
$cart = new Cart($cartId['id_cart']);
|
||||
$cartExternalId = RetailCRM::getCartOrderExternalId($cart);
|
||||
|
||||
$response = $api->ordersGet($cartExternalId);
|
||||
|
||||
if ($response === false) {
|
||||
$api->customersCreate(RetailCRM::buildCrmCustomer(new Customer($cart->id_customer)));
|
||||
$order = RetailCRM::buildCrmOrderFromCart($cart, $cartExternalId, $paymentTypes[0], $status);
|
||||
|
||||
if (empty($order)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($api->ordersCreate($order) !== false) {
|
||||
$cart->date_upd = date('Y-m-d H:i:s');
|
||||
$cart->save();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($response['order']) && !empty($response['order'])) {
|
||||
$order = RetailCRM::buildCrmOrderFromCart($cart, $response['order']['externalId'], $paymentTypes[0], $status);
|
||||
|
||||
if (empty($order)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($api->ordersEdit($order) !== false) {
|
||||
$cart->date_upd = date('Y-m-d H:i:s');
|
||||
$cart->save();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.0
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require(dirname(__FILE__) . '/../../../init.php');
|
||||
require(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
$apiUrl = Configuration::get('RETAILCRM_ADDRESS');
|
||||
$apiKey = Configuration::get('RETAILCRM_API_TOKEN');
|
||||
$apiVersion = Configuration::get('RETAILCRM_API_VERSION');
|
||||
$statusExport = Configuration::get('RETAILCRM_STATUS_EXPORT');
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log', $apiVersion);
|
||||
} else {
|
||||
error_log('orderHistory: set api key & url first', 3, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
exit();
|
||||
}
|
||||
|
||||
$orders = array();
|
||||
$customers = array();
|
||||
|
||||
$customerRecords = Customer::getCustomers();
|
||||
$orderRecords = Order::getOrdersWithInformations();
|
||||
|
||||
$delivery = json_decode(Configuration::get('RETAILCRM_API_DELIVERY'), true);
|
||||
$payment = json_decode(Configuration::get('RETAILCRM_API_PAYMENT'), true);
|
||||
$status = json_decode(Configuration::get('RETAILCRM_API_STATUS'), true);
|
||||
|
||||
foreach ($customerRecords as $record) {
|
||||
$customers[$record['id_customer']] = RetailCRM::buildCrmCustomer(new Customer($record['id_customer']));
|
||||
}
|
||||
|
||||
unset($customerRecords);
|
||||
|
||||
foreach ($orderRecords as $record) {
|
||||
$order = new Order();
|
||||
|
||||
foreach ($record as $property => $value) {
|
||||
$order->$property = $value;
|
||||
}
|
||||
|
||||
$order->id = $record['id_order'];
|
||||
|
||||
$orders[$record['id_order']] = RetailCRM::buildCrmOrder(
|
||||
$order,
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
unset($orderRecords);
|
||||
|
||||
$customers = array_chunk($customers, 50);
|
||||
|
||||
foreach ($customers as $chunk) {
|
||||
$api->customersUpload($chunk);
|
||||
time_nanosleep(0, 200000000);
|
||||
}
|
||||
|
||||
$orders = array_chunk($orders, 50);
|
||||
|
||||
foreach ($orders as $chunk) {
|
||||
$api->ordersUpload($chunk);
|
||||
time_nanosleep(0, 200000000);
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.0
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require(dirname(__FILE__) . '/../../../init.php');
|
||||
require(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
$job = new RetailcrmCatalog();
|
||||
$data = $job->getData();
|
||||
|
||||
$icml = new RetailcrmIcml(Configuration::get('PS_SHOP_NAME'), _PS_ROOT_DIR_ . '/retailcrm.xml');
|
||||
$icml->generate($data[0], $data[1]);
|
@ -1 +0,0 @@
|
||||
<?php // Silence is golden
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.9
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require(dirname(__FILE__) . '/../../../init.php');
|
||||
require(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
$apiUrl = Configuration::get('RETAILCRM_ADDRESS');
|
||||
$apiKey = Configuration::get('RETAILCRM_API_TOKEN');
|
||||
$apiVersion = Configuration::get('RETAILCRM_API_VERSION');
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
RetailcrmInventories::$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log', $apiVersion);
|
||||
} else {
|
||||
error_log('inventories: set api key & url first', 3, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
exit();
|
||||
}
|
||||
|
||||
RetailcrmInventories::loadStocks();
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.9
|
||||
* @link https://retailcrm.ru
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require_once(dirname(__FILE__) . '/../../../init.php');
|
||||
require_once(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
JobManager::startJobs(
|
||||
array(
|
||||
'abandonedCarts' => null
|
||||
),
|
||||
true
|
||||
);
|
@ -1,167 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.0
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
$shortopts = 'o:';
|
||||
$options = getopt($shortopts);
|
||||
|
||||
if (!isset($options['o'])) {
|
||||
echo ('Parameter -o is missing');
|
||||
exit();
|
||||
}
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require(dirname(__FILE__) . '/../../../init.php');
|
||||
require(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
$apiUrl = Configuration::get('RETAILCRM_ADDRESS');
|
||||
$apiKey = Configuration::get('RETAILCRM_API_TOKEN');
|
||||
$apiVersion = Configuration::get('RETAILCRM_API_VERSION');
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log', $apiVersion);
|
||||
} else {
|
||||
echo('Set api key & url first');
|
||||
exit();
|
||||
}
|
||||
|
||||
$delivery = json_decode(Configuration::get('RETAILCRM_API_DELIVERY'), true);
|
||||
$payment = json_decode(Configuration::get('RETAILCRM_API_PAYMENT'), true);
|
||||
$status = json_decode(Configuration::get('RETAILCRM_API_STATUS'), true);
|
||||
|
||||
$orderInstance = new Order($options['o']);
|
||||
|
||||
$order = array(
|
||||
'externalId' => $orderInstance->id,
|
||||
'createdAt' => $orderInstance->date_add,
|
||||
);
|
||||
|
||||
/**
|
||||
* Add order customer info
|
||||
*
|
||||
*/
|
||||
|
||||
if (!empty($orderInstance->id_customer)) {
|
||||
$orderCustomer = new Customer($orderInstance->id_customer);
|
||||
$customer = array(
|
||||
'externalId' => $orderCustomer->id,
|
||||
'firstName' => $orderCustomer->firstname,
|
||||
'lastname' => $orderCustomer->lastname,
|
||||
'email' => $orderCustomer->email,
|
||||
'createdAt' => $orderCustomer->date_add
|
||||
);
|
||||
|
||||
$response = $api->customersEdit($customer);
|
||||
|
||||
if ($response) {
|
||||
$order['customer']['externalId'] = $orderCustomer->id;
|
||||
$order['firstName'] = $orderCustomer->firstname;
|
||||
$order['lastName'] = $orderCustomer->lastname;
|
||||
$order['email'] = $orderCustomer->email;
|
||||
} else {
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add order status
|
||||
*
|
||||
*/
|
||||
|
||||
if ($orderInstance->current_state == 0) {
|
||||
$order['status'] = 'completed';
|
||||
} else {
|
||||
$order['status'] = array_key_exists($orderInstance->current_state, $status)
|
||||
? $status[$orderInstance->current_state]
|
||||
: 'completed'
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add order address data
|
||||
*
|
||||
*/
|
||||
|
||||
$cart = new Cart($orderInstance->getCartIdStatic($orderInstance->id));
|
||||
$addressCollection = $cart->getAddressCollection();
|
||||
$address = array_shift($addressCollection);
|
||||
|
||||
if ($address instanceof Address) {
|
||||
$phone = is_null($address->phone)
|
||||
? is_null($address->phone_mobile) ? '' : $address->phone_mobile
|
||||
: $address->phone
|
||||
;
|
||||
|
||||
$postcode = $address->postcode;
|
||||
$city = $address->city;
|
||||
$addres_line = sprintf("%s %s", $address->address1, $address->address2);
|
||||
}
|
||||
|
||||
if (!empty($postcode)) {
|
||||
$order['delivery']['address']['index'] = $postcode;
|
||||
}
|
||||
|
||||
if (!empty($city)) {
|
||||
$order['delivery']['address']['city'] = $city;
|
||||
}
|
||||
|
||||
if (!empty($addres_line)) {
|
||||
$order['delivery']['address']['text'] = $addres_line;
|
||||
}
|
||||
|
||||
if (!empty($phone)) {
|
||||
$order['phone'] = $phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add payment & shippment data
|
||||
*/
|
||||
|
||||
if (Module::getInstanceByName('advancedcheckout') === false) {
|
||||
$paymentType = $orderInstance->module;
|
||||
} else {
|
||||
$paymentType = $orderInstance->payment;
|
||||
}
|
||||
|
||||
if (array_key_exists($paymentType, $payment) && !empty($payment[$paymentType])) {
|
||||
$order['paymentType'] = $payment[$paymentType];
|
||||
}
|
||||
|
||||
if (array_key_exists($orderInstance->id_carrier, $delivery) && !empty($delivery[$orderInstance->id_carrier])) {
|
||||
$order['delivery']['code'] = $delivery[$orderInstance->id_carrier];
|
||||
}
|
||||
|
||||
if (isset($orderInstance->total_shipping_tax_incl) && (int) $orderInstance->total_shipping_tax_incl > 0) {
|
||||
$order['delivery']['cost'] = round($orderInstance->total_shipping_tax_incl, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add products
|
||||
*
|
||||
*/
|
||||
|
||||
$products = $orderInstance->getProducts();
|
||||
|
||||
foreach ($products as $product) {
|
||||
$item = array(
|
||||
//'productId' => $product['product_id'],
|
||||
'offer' => array('externalId' => $product['product_id']),
|
||||
'productName' => $product['product_name'],
|
||||
'quantity' => $product['product_quantity'],
|
||||
'initialPrice' => round($product['product_price'], 2),
|
||||
'purchasePrice' => round($product['purchase_supplier_price'], 2)
|
||||
);
|
||||
|
||||
$order['items'][] = $item;
|
||||
}
|
||||
|
||||
$api->ordersEdit($order);
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.0
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require(dirname(__FILE__) . '/../../../init.php');
|
||||
require(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
$apiUrl = Configuration::get('RETAILCRM_ADDRESS');
|
||||
$apiKey = Configuration::get('RETAILCRM_API_TOKEN');
|
||||
$apiVersion = Configuration::get('RETAILCRM_API_VERSION');
|
||||
RetailcrmHistory::$default_lang = (int) Configuration::get('PS_LANG_DEFAULT');
|
||||
RetailcrmHistory::$apiVersion = $apiVersion;
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
RetailcrmHistory::$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log', $apiVersion);
|
||||
} else {
|
||||
error_log('orderHistory: set api key & url first', 3, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
exit();
|
||||
}
|
||||
|
||||
RetailcrmHistory::customersHistory();
|
||||
RetailcrmHistory::ordersHistory();
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP version 5.3
|
||||
*
|
||||
* Class CurlException
|
||||
*
|
||||
* @category RetailCrm
|
||||
* @package RetailCrm
|
||||
* @author RetailCrm <integration@retailcrm.ru>
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||
*/
|
||||
class CurlException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP version 5.3
|
||||
*
|
||||
* Class InvalidJsonException
|
||||
*
|
||||
* @category RetailCrm
|
||||
* @package RetailCrm
|
||||
* @author RetailCrm <integration@retailcrm.ru>
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||
*/
|
||||
class InvalidJsonException extends \DomainException
|
||||
{
|
||||
}
|
@ -1,444 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Retail Driver LCC
|
||||
* @copyright RetailCRM
|
||||
* @license GPL
|
||||
* @version 2.2.11
|
||||
* @link https://retailcrm.ru
|
||||
*
|
||||
*/
|
||||
|
||||
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require_once(dirname(__FILE__) . '/../../../init.php');
|
||||
require_once(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class JobManager
|
||||
*
|
||||
* @author Retail Driver LCC
|
||||
* @license GPL
|
||||
* @link https://retailcrm.ru
|
||||
*/
|
||||
class JobManager
|
||||
{
|
||||
const LAST_RUN_NAME = 'RETAILCRM_LAST_RUN';
|
||||
const IN_PROGRESS_NAME = 'RETAILCRM_JOBS_IN_PROGRESS';
|
||||
|
||||
/**
|
||||
* @var resource $lock
|
||||
*/
|
||||
static $lock;
|
||||
|
||||
/**
|
||||
* Entry point for all jobs.
|
||||
* Jobs must be passed in this format:
|
||||
* JobManager::startJobs(
|
||||
* array(
|
||||
* 'jobName' => DateInterval::createFromDateString('1 hour')
|
||||
* ),
|
||||
* true
|
||||
* );
|
||||
*
|
||||
* File `jobName.php` must exist in retailcrm/job and must contain everything to run job.
|
||||
* Throwed errors will be logged in <prestashop directory>/retailcrm.log
|
||||
* DateInterval must be positive. Pass `null` instead of DateInterval to remove
|
||||
* any delay - in other words, jobs without interval will be executed every time.
|
||||
*
|
||||
* @param array $jobs
|
||||
* @param bool $runOnceInContext
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function startJobs($jobs = array(), $runOnceInContext = false)
|
||||
{
|
||||
$inBackground = static::canExecInBackground();
|
||||
|
||||
if ($inBackground) {
|
||||
$cmdline = sprintf('%s "%s" %b', __FILE__, static::serializeJobs($jobs), $runOnceInContext);
|
||||
static::execPHP($cmdline, true, $runOnceInContext);
|
||||
} else {
|
||||
static::execJobs($jobs, $runOnceInContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run scheduled jobs with request
|
||||
*
|
||||
* @param array $jobs
|
||||
* @param bool $runOnceInContext
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function execJobs($jobs = array(), $runOnceInContext = false)
|
||||
{
|
||||
$current = date_create('now');
|
||||
$lastRuns = static::getLastRuns();
|
||||
|
||||
if (!static::lock()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($jobs as $job => $diff) {
|
||||
try {
|
||||
if (isset($lastRuns[$job]) && $lastRuns[$job] instanceof DateTime) {
|
||||
$shouldRunAt = clone $lastRuns[$job];
|
||||
} else {
|
||||
$shouldRunAt = new DateTime();
|
||||
}
|
||||
|
||||
if ($diff instanceof DateInterval) {
|
||||
$shouldRunAt->add($diff);
|
||||
}
|
||||
|
||||
if (!isset($shouldRunAt) || $shouldRunAt <= $current) {
|
||||
JobManager::runJob($job, $runOnceInContext);
|
||||
$lastRuns[$job] = new DateTime();
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
static::handleError($exception->getFile(), $exception->getMessage());
|
||||
} catch (\Throwable $throwable) {
|
||||
static::handleError($throwable->getFile(), $throwable->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static::setLastRuns($lastRuns);
|
||||
static::unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts jobs last runs from db
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getLastRuns()
|
||||
{
|
||||
$lastRuns = json_decode((string) Configuration::get(self::LAST_RUN_NAME), true);
|
||||
|
||||
if (json_last_error() != JSON_ERROR_NONE) {
|
||||
$lastRuns = [];
|
||||
} else {
|
||||
foreach ($lastRuns as $job => $ran) {
|
||||
$lastRan = DateTime::createFromFormat(DATE_RFC3339, $ran);
|
||||
|
||||
if ($lastRan instanceof DateTime) {
|
||||
$lastRuns[$job] = $lastRan;
|
||||
} else {
|
||||
$lastRuns[$job] = new DateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (array) $lastRuns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates jobs last runs in db
|
||||
*
|
||||
* @param array $lastRuns
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function setLastRuns($lastRuns = [])
|
||||
{
|
||||
$now = new DateTime();
|
||||
|
||||
if (!is_array($lastRuns)) {
|
||||
$lastRuns = [];
|
||||
}
|
||||
|
||||
foreach ($lastRuns as $job => $ran) {
|
||||
if ($ran instanceof DateTime) {
|
||||
$lastRuns[$job] = $ran->format(DATE_RFC3339);
|
||||
} else {
|
||||
$lastRuns[$job] = $now->format(DATE_RFC3339);
|
||||
}
|
||||
}
|
||||
|
||||
Configuration::updateValue(self::LAST_RUN_NAME, (string) json_encode($lastRuns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs job
|
||||
*
|
||||
* @param string $job
|
||||
* @param bool $once
|
||||
*/
|
||||
public static function runJob($job, $once = false)
|
||||
{
|
||||
$jobFile = implode(DIRECTORY_SEPARATOR, array(_PS_ROOT_DIR_, 'modules', 'retailcrm', 'job', $job . '.php'));
|
||||
|
||||
if (!file_exists($jobFile)) {
|
||||
throw new \InvalidArgumentException('Cannot find job');
|
||||
}
|
||||
|
||||
static::execPHP($jobFile, false, $once);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP file
|
||||
*
|
||||
* @param $fileCommandLine
|
||||
* @param bool $fork
|
||||
* @param bool $once
|
||||
*/
|
||||
private static function execPHP($fileCommandLine, $fork = true, $once = false)
|
||||
{
|
||||
if ($fork) {
|
||||
static::execInBackground(sprintf('%s %s', static::getPhpBinary(), $fileCommandLine));
|
||||
} else {
|
||||
static::execHere($fileCommandLine, $once);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes jobs to JSON
|
||||
*
|
||||
* @param $jobs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function serializeJobs($jobs)
|
||||
{
|
||||
foreach ($jobs as $name => $interval) {
|
||||
$jobs[$name] = serialize($interval);
|
||||
}
|
||||
|
||||
return (string) base64_encode(json_encode($jobs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes jobs
|
||||
*
|
||||
* @param $jobsJson
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function deserializeJobs($jobsJson)
|
||||
{
|
||||
$jobs = json_decode(base64_decode($jobsJson), true);
|
||||
|
||||
if (json_last_error() != JSON_ERROR_NONE) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid JSON: %s', json_last_error_msg()));
|
||||
}
|
||||
|
||||
if (!is_array($jobs) || count($jobs) == 0) {
|
||||
throw new \InvalidArgumentException('Empty or invalid data');
|
||||
}
|
||||
|
||||
foreach ($jobs as $name => $interval) {
|
||||
if (!is_string($name) || !is_string($interval)) {
|
||||
throw new \InvalidArgumentException('Invalid job in array');
|
||||
}
|
||||
|
||||
$intervalObj = unserialize($interval);
|
||||
|
||||
if (!($intervalObj instanceof DateInterval)) {
|
||||
throw new \InvalidArgumentException('Invalid job interval in array');
|
||||
}
|
||||
|
||||
$jobs[$name] = $intervalObj;
|
||||
}
|
||||
|
||||
return (array) $jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes error to log and returns 500
|
||||
*
|
||||
* @param $file
|
||||
* @param $msg
|
||||
*/
|
||||
private static function handleError($file, $msg)
|
||||
{
|
||||
error_log(sprintf('%s: %s', $file, $msg), 3, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run process in background without waiting
|
||||
*
|
||||
* @param $cmd
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function execInBackground($cmd) {
|
||||
if (substr(php_uname(), 0, 7) == "Windows"){
|
||||
pclose(popen("start /B ". $cmd, "r"));
|
||||
} else {
|
||||
$outputPos = strpos($cmd, '>');
|
||||
|
||||
if ($outputPos !== false) {
|
||||
$cmd = substr($cmd, 0, $outputPos);
|
||||
}
|
||||
|
||||
$command = $cmd . " > /dev/null &";
|
||||
|
||||
if (function_exists('exec')) {
|
||||
exec($command);
|
||||
} else if (function_exists('shell_exec')) {
|
||||
shell_exec($command);
|
||||
} else if (function_exists('passthru')) {
|
||||
passthru($command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes php script in this context, without hanging up request
|
||||
*
|
||||
* @param string $phpScript
|
||||
* @param bool $once
|
||||
*/
|
||||
private static function execHere($phpScript, $once = false)
|
||||
{
|
||||
ignore_user_abort( true);
|
||||
set_time_limit(static::getTimeLimit());
|
||||
|
||||
if (version_compare(phpversion(), '7.0.16', '>=') &&
|
||||
function_exists('fastcgi_finish_request')
|
||||
) {
|
||||
if (!headers_sent()) {
|
||||
header('Expires: Thu, 19 Nov 1981 08:52:00 GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
}
|
||||
|
||||
fastcgi_finish_request();
|
||||
}
|
||||
|
||||
if ($once) {
|
||||
require_once($phpScript);
|
||||
} else {
|
||||
require($phpScript);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if system support execution in background
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function canExecInBackground()
|
||||
{
|
||||
if (substr(php_uname(), 0, 7) == "Windows"){
|
||||
return function_exists('pclose') && function_exists('popen');
|
||||
} else {
|
||||
return function_exists('exec')
|
||||
|| function_exists('shell_exec')
|
||||
|| function_exists('passthru');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to current PHP binary
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getPhpBinary()
|
||||
{
|
||||
if (defined('PHP_BINARY') && !empty(PHP_BINARY)) {
|
||||
return PHP_BINARY;
|
||||
}
|
||||
|
||||
if (defined('PHP_BINDIR') && !empty(PHP_BINDIR)) {
|
||||
$version = phpversion();
|
||||
$filePath = implode(DIRECTORY_SEPARATOR, array(PHP_BINDIR, 'php' . $version));
|
||||
|
||||
while (strlen($version) != 0 && !file_exists($filePath)) {
|
||||
$dotPos = strrpos($version, '.');
|
||||
|
||||
if ($dotPos !== false) {
|
||||
$version = substr($version, 0, strrpos($version, '.'));
|
||||
} else {
|
||||
$version = '';
|
||||
}
|
||||
|
||||
$filePath = implode(DIRECTORY_SEPARATOR, array(PHP_BINDIR, 'php' . $version));
|
||||
}
|
||||
|
||||
if (file_exists($filePath)) {
|
||||
return $filePath;
|
||||
}
|
||||
}
|
||||
|
||||
return 'php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns script execution time limit
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function getTimeLimit()
|
||||
{
|
||||
return 14400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if lock is present and it's not expired
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isLocked()
|
||||
{
|
||||
$inProcess = (bool) Configuration::get(self::IN_PROGRESS_NAME);
|
||||
$lastRan = date_create_from_format(DATE_RFC3339, (string) Configuration::get(self::LAST_RUN_NAME));
|
||||
$lastRanSeconds = $lastRan instanceof DateTime ? $lastRan->format('U') : time();
|
||||
|
||||
if (($lastRanSeconds + self::getTimeLimit()) < time()) {
|
||||
static::unlock();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $inProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs lock
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function lock()
|
||||
{
|
||||
if (!static::isLocked()) {
|
||||
Configuration::updateValue(self::IN_PROGRESS_NAME, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes lock
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function unlock()
|
||||
{
|
||||
Configuration::updateValue(self::IN_PROGRESS_NAME, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_SAPI == 'cli' && $argc == 3) {
|
||||
try {
|
||||
$jobs = JobManager::deserializeJobs($argv[1]);
|
||||
$runOnce = (bool) $argv[2];
|
||||
} catch (InvalidArgumentException $exception) {
|
||||
printf('Error: %s%s', $exception->getMessage(), PHP_EOL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
JobManager::execJobs($jobs, $runOnce);
|
||||
}
|
109
retailcrm/lib/RetailcrmAbstractDataBuilder.php
Normal file
109
retailcrm/lib/RetailcrmAbstractDataBuilder.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
abstract class RetailcrmAbstractDataBuilder
|
||||
{
|
||||
/**
|
||||
* @var mixed $data Any data type (depends on the builder)
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* RetailcrmAddressBuilder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset builder state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return cleared built data casted to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDataArray()
|
||||
{
|
||||
if (is_array($this->data)) {
|
||||
return RetailcrmTools::clearArray((array) $this->data);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns built data casted to string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDataString()
|
||||
{
|
||||
if (is_string($this->data)) {
|
||||
return (string) $this->data;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return builder data without any type-casting
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
abstract public function build();
|
||||
}
|
299
retailcrm/lib/RetailcrmAddressBuilder.php
Normal file
299
retailcrm/lib/RetailcrmAddressBuilder.php
Normal file
@ -0,0 +1,299 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmAddressBuilder extends RetailcrmAbstractDataBuilder
|
||||
{
|
||||
/**
|
||||
* Mode for regular customer. Default.
|
||||
*/
|
||||
const MODE_CUSTOMER = 0;
|
||||
|
||||
/**
|
||||
* Mode for corporate customer.
|
||||
*/
|
||||
const MODE_CORPORATE_CUSTOMER = 1;
|
||||
|
||||
/**
|
||||
* Mode for order delivery address
|
||||
*/
|
||||
const MODE_ORDER_DELIVERY = 2;
|
||||
|
||||
/**
|
||||
* @var Address|\AddressCore
|
||||
*/
|
||||
private $address;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isMain;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $withExternalId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $externalIdSuffix = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $mode;
|
||||
|
||||
/**
|
||||
* @param Address|\AddressCore $address
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setAddress($address)
|
||||
{
|
||||
$this->address = $address;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isMain
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setIsMain($isMain)
|
||||
{
|
||||
$this->isMain = $isMain;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $mode
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $withExternalId
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setWithExternalId($withExternalId)
|
||||
{
|
||||
$this->withExternalId = $withExternalId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $externalIdSuffix
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setExternalIdSuffix($externalIdSuffix)
|
||||
{
|
||||
$this->externalIdSuffix = $externalIdSuffix;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
*
|
||||
* @return RetailcrmAddressBuilder
|
||||
*/
|
||||
public function setAddressId($addressId)
|
||||
{
|
||||
$this->address = new Address($addressId);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset builder state
|
||||
*
|
||||
* @return \RetailcrmAbstractDataBuilder|void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
|
||||
$this->data = array();
|
||||
$this->address = null;
|
||||
$this->mode = static::MODE_CUSTOMER;
|
||||
$this->isMain = false;
|
||||
$this->withExternalId = false;
|
||||
$this->externalIdSuffix = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build address
|
||||
*
|
||||
* @return $this|\RetailcrmAbstractDataBuilder
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
if (!empty($this->address)) {
|
||||
switch ($this->mode) {
|
||||
case static::MODE_CUSTOMER:
|
||||
$this->buildCustomerAddress();
|
||||
$this->buildCustomerPhones();
|
||||
break;
|
||||
case static::MODE_CORPORATE_CUSTOMER:
|
||||
$this->buildCorporateCustomerAddress();
|
||||
break;
|
||||
case static::MODE_ORDER_DELIVERY:
|
||||
$this->buildOrderAddress();
|
||||
$this->buildOrderPhones();
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Incorrect builder mode");
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns built data. Data for order and for customer should be merged respectively, e.g.
|
||||
* $order = array_merge($order, $builder->getData());
|
||||
* or
|
||||
* $customer = array_merge($customer, $builder->getData());
|
||||
* Data for corporate customers should be used as address array e.g.
|
||||
* $corporateCustomer["addresses"][] = $builder->getData();
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDataArray()
|
||||
{
|
||||
if (!empty($this->address)) {
|
||||
switch ($this->mode) {
|
||||
case static::MODE_CUSTOMER:
|
||||
return $this->data['customer'];
|
||||
case static::MODE_CORPORATE_CUSTOMER:
|
||||
return $this->data['customer']['address'];
|
||||
case static::MODE_ORDER_DELIVERY:
|
||||
return $this->data['order'];
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse generic address data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseAddress()
|
||||
{
|
||||
return array(
|
||||
'index' => $this->address->postcode,
|
||||
'city' => $this->address->city,
|
||||
'countryIso' => Country::getIsoById($this->address->id_country),
|
||||
'text' => sprintf("%s %s", $this->address->address1, $this->address->address2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract customer phones from address
|
||||
*/
|
||||
private function buildCustomerPhones()
|
||||
{
|
||||
if (!empty($this->address->phone_mobile)) {
|
||||
$this->data['customer']['phones'][] = array('number'=> $this->address->phone_mobile);
|
||||
}
|
||||
|
||||
if (!empty($this->address->phone)) {
|
||||
$this->data['customer']['phones'][] = array('number'=> $this->address->phone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract order phone from address
|
||||
*/
|
||||
private function buildOrderPhones()
|
||||
{
|
||||
if (!empty($this->address->phone_mobile)) {
|
||||
$this->data['order']['phone'] = $this->address->phone_mobile;
|
||||
}
|
||||
|
||||
if (!empty($this->address->phone)) {
|
||||
if (empty($this->data['order']['phone'])) {
|
||||
$this->data['order']['phone'] = $this->address->phone;
|
||||
} else {
|
||||
$this->data['order']['additionalPhone'] = $this->address->phone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build regular customer address
|
||||
*/
|
||||
private function buildCustomerAddress()
|
||||
{
|
||||
$this->data['customer']['address'] = $this->parseAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build corporate customer address. Address's `externalId` should be unique in customer.
|
||||
* Attempt to create address with same `externalId` in customer will result in error.
|
||||
*/
|
||||
private function buildCorporateCustomerAddress()
|
||||
{
|
||||
$this->data['customer']['address'] = $this->parseAddress();
|
||||
$this->data['customer']['address']['isMain'] = $this->isMain;
|
||||
|
||||
if ($this->withExternalId) {
|
||||
$this->data['customer']['address']['externalId'] = $this->address->id;
|
||||
|
||||
if (!empty($this->externalIdSuffix)) {
|
||||
$this->data['customer']['address']['externalId'] .= $this->externalIdSuffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build order address
|
||||
*/
|
||||
private function buildOrderAddress()
|
||||
{
|
||||
$this->data['order']['delivery']['address'] = $this->parseAddress();
|
||||
$this->data['order']['countryIso'] = Country::getIsoById($this->address->id_country);
|
||||
unset($this->data['order']['delivery']['address']['countryIso']);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class RetailcrmApiErrors
|
||||
* This is storage for all API exceptions.
|
||||
*/
|
||||
class RetailcrmApiErrors
|
||||
{
|
||||
/** @var array */
|
||||
private static $errors;
|
||||
|
||||
/** @var integer */
|
||||
private static $statusCode;
|
||||
|
||||
/**
|
||||
* ApiErrors constructor. Isn't accessible.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getStatusCode()
|
||||
{
|
||||
return isset(static::$statusCode) ? static::$statusCode : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns static::$errors array, or regenerates it.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getErrors()
|
||||
{
|
||||
static::checkArray();
|
||||
return static::$errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets static::$errors array, or regenerates it.
|
||||
* Returns true if errors is assigned.
|
||||
* Returns false if incorrect data was passed to it.
|
||||
*
|
||||
* @param array $errors
|
||||
* @param integer $statusCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function set($errors, $statusCode)
|
||||
{
|
||||
static::checkArray();
|
||||
|
||||
if (is_array($errors) && is_integer($statusCode)) {
|
||||
static::$errors = $errors;
|
||||
static::$statusCode = $statusCode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerates static::$errors array
|
||||
*/
|
||||
private static function checkArray()
|
||||
{
|
||||
if (!is_array(static::$errors)) {
|
||||
static::$errors = array();
|
||||
}
|
||||
}
|
||||
}
|
132
retailcrm/lib/RetailcrmCachedSettingExtractor.php
Normal file
132
retailcrm/lib/RetailcrmCachedSettingExtractor.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmCachedSettingExtractor extends RetailcrmAbstractDataBuilder
|
||||
{
|
||||
/** @var string */
|
||||
private $cachedKey;
|
||||
|
||||
/** @var string */
|
||||
private $configKey;
|
||||
|
||||
/** @var bool */
|
||||
private $fromCache;
|
||||
|
||||
/**
|
||||
* RetailcrmCachedValueExtractor constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cachedKey
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCachedKey($cachedKey)
|
||||
{
|
||||
$this->cachedKey = $cachedKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $configKey
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfigKey($configKey)
|
||||
{
|
||||
$this->configKey = $configKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCachedAndConfigKey($key)
|
||||
{
|
||||
$this->setCachedKey($key);
|
||||
$this->setConfigKey($key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
/** @var Cache $cache */
|
||||
$cache = Cache::getInstance();
|
||||
$this->fromCache = false;
|
||||
|
||||
if ($cache->exists($this->cachedKey)) {
|
||||
$this->data = $cache->get($this->cachedKey);
|
||||
$this->fromCache = true;
|
||||
}
|
||||
|
||||
if (empty($this->data)) {
|
||||
$this->data = Configuration::get($this->configKey);
|
||||
$this->fromCache = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset inner state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
|
||||
$this->cachedKey = '';
|
||||
$this->configKey = '';
|
||||
$this->fromCache = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFromCache()
|
||||
{
|
||||
return $this->fromCache;
|
||||
}
|
||||
}
|
390
retailcrm/lib/RetailcrmCartUploader.php
Normal file
390
retailcrm/lib/RetailcrmCartUploader.php
Normal file
@ -0,0 +1,390 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmCartUploader
|
||||
{
|
||||
/**
|
||||
* @var \RetailcrmProxy|\RetailcrmApiClientV5
|
||||
*/
|
||||
static $api;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static $cartsIds;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static $paymentTypes;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
static $syncDelay;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static $syncStatus;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
static $now;
|
||||
|
||||
/**
|
||||
* Cast provided sync delay to integer
|
||||
*
|
||||
* @param $time
|
||||
*/
|
||||
public static function setSyncDelay($time)
|
||||
{
|
||||
if (is_numeric($time) && $time > 0) {
|
||||
static::$syncDelay = (int)$time;
|
||||
} else {
|
||||
static::$syncDelay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize inner state
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
static::$api = null;
|
||||
static::$cartsIds = array();
|
||||
static::$paymentTypes = array();
|
||||
static::$syncDelay = 0;
|
||||
static::$syncStatus = '';
|
||||
static::$now = new \DateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* run carts upload
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
if (!static::validateState()) {
|
||||
return;
|
||||
}
|
||||
|
||||
static::loadAbandonedCartsIds();
|
||||
|
||||
foreach (static::$cartsIds as $cartId) {
|
||||
$cart = new Cart($cartId['id_cart']);
|
||||
$cartExternalId = RetailcrmTools::getCartOrderExternalId($cart);
|
||||
$cartLastUpdateDate = null;
|
||||
|
||||
if (static::isGuestCart($cart) || static::isCartTooOld($cart->date_upd) || static::isCartEmpty($cart)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($cart->date_upd)) {
|
||||
$cartLastUpdateDate = \DateTime::createFromFormat('Y-m-d H:i:s', $cart->date_upd);
|
||||
}
|
||||
|
||||
if (!static::isAbandonedCartShouldBeUpdated(
|
||||
static::getAbandonedCartLastSync($cart->id),
|
||||
$cartLastUpdateDate
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$response = static::$api->ordersGet($cartExternalId);
|
||||
|
||||
if (!($response instanceof RetailcrmApiResponse)) {
|
||||
//TODO
|
||||
// Extract address from cart (if exists) and append to customer?
|
||||
// Or maybe this customer will not order anything, so we don't need it's address...
|
||||
static::$api->customersCreate(RetailcrmOrderBuilder::buildCrmCustomer(new Customer($cart->id_customer)));
|
||||
|
||||
$order = static::buildCartOrder($cart, $cartExternalId);
|
||||
|
||||
if (empty($order)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (static::$api->ordersCreate($order) !== false) {
|
||||
$cart->date_upd = date('Y-m-d H:i:s');
|
||||
$cart->save();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($response['order']) && !empty($response['order'])) {
|
||||
$order = static::buildCartOrder($cart, $response['order']['externalId']);
|
||||
|
||||
if (empty($order)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (static::$api->ordersEdit($order) !== false) {
|
||||
static::registerAbandonedCartSync($cart->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if cart belongs to guest.
|
||||
*
|
||||
* @param $cart
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isGuestCart($cart)
|
||||
{
|
||||
/** @var Customer|\CustomerCore $guestCustomer */
|
||||
$guestCustomer = new Customer($cart->id_guest);
|
||||
|
||||
if (!empty($cart->id_guest) && $cart->id_customer == $cart->id_guest && $guestCustomer->is_guest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if cart is too old to update.
|
||||
*
|
||||
* @param string $cartDateUpd It's $cart->date_upd
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isCartTooOld($cartDateUpd)
|
||||
{
|
||||
try {
|
||||
$allowedUpdateInterval = new \DateInterval('P1D');
|
||||
$cartLastUpdate = \DateTime::createFromFormat('Y-m-d H:i:s', $cartDateUpd);
|
||||
|
||||
if ($cartLastUpdate instanceof \DateTime) {
|
||||
$cartLastUpdateDiff = $cartLastUpdate->diff(new \DateTime('now'));
|
||||
|
||||
// Workaround for PHP bug: https://bugs.php.net/bug.php?id=49914
|
||||
ob_start();
|
||||
var_dump($allowedUpdateInterval);
|
||||
var_dump($cartLastUpdateDiff);
|
||||
ob_clean();
|
||||
ob_end_flush();
|
||||
|
||||
if ($cartLastUpdateDiff > $allowedUpdateInterval) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
RetailcrmLogger::writeCaller(__METHOD__, $exception->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if cart is empty or if cart emptiness cannot be checked because something gone wrong.
|
||||
* Errors with checking cart emptiness will be correctly written to log.
|
||||
*
|
||||
* @param Cart|CartCore $cart
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isCartEmpty($cart)
|
||||
{
|
||||
$shouldBeUploaded = true;
|
||||
|
||||
try {
|
||||
$currentCartTotal = $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
|
||||
|
||||
if ($currentCartTotal == 0) {
|
||||
$shouldBeUploaded = false;
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
RetailcrmLogger::writeCaller(
|
||||
__METHOD__,
|
||||
sprintf("Failure while trying to get cart total (cart id=%d)", $cart->id)
|
||||
);
|
||||
RetailcrmLogger::writeCaller(__METHOD__, "Error message and stacktrace will be printed below");
|
||||
RetailcrmLogger::writeCaller(__METHOD__, $exception->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// Don't upload empty cartsIds.
|
||||
if (count($cart->getProducts()) == 0 || !$shouldBeUploaded) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
RetailcrmLogger::writeCaller(
|
||||
__METHOD__,
|
||||
sprintf("Failure while trying to get cart total (cart id=%d)", $cart->id)
|
||||
);
|
||||
RetailcrmLogger::writeCaller(__METHOD__, "Error message and stacktrace will be printed below");
|
||||
RetailcrmLogger::writeCaller(__METHOD__, $exception->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build order for abandoned cart
|
||||
*
|
||||
* @param Cart|\CartCore $cart
|
||||
* @param string $cartExternalId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function buildCartOrder($cart, $cartExternalId)
|
||||
{
|
||||
$order = array();
|
||||
|
||||
try {
|
||||
$order = RetailcrmOrderBuilder::buildCrmOrderFromCart(
|
||||
static::$api,
|
||||
$cart,
|
||||
$cartExternalId,
|
||||
static::$paymentTypes[0],
|
||||
static::$syncStatus
|
||||
);
|
||||
} catch (\Exception $exception) {
|
||||
RetailcrmLogger::writeCaller(
|
||||
'abandonedCarts',
|
||||
$exception->getMessage() . PHP_EOL . $exception->getTraceAsString()
|
||||
);
|
||||
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register abandoned cart sync event
|
||||
*
|
||||
* @param int $cartId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function registerAbandonedCartSync($cartId)
|
||||
{
|
||||
$sql = 'INSERT INTO `' . _DB_PREFIX_ . 'retailcrm_abandonedcarts` (`id_cart`, `last_uploaded`)
|
||||
VALUES (\'' . pSQL($cartId) . '\', \'' . pSQL(date('Y-m-d H:i:s')) . '\')
|
||||
ON DUPLICATE KEY UPDATE `last_uploaded` = \'' . pSQL(date('Y-m-d H:i:s')) . '\';';
|
||||
|
||||
return Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get abandoned cart last sync time
|
||||
*
|
||||
* @param int $cartId
|
||||
*
|
||||
* @return \DateTime|false
|
||||
*/
|
||||
private static function getAbandonedCartLastSync($cartId)
|
||||
{
|
||||
$sql = 'SELECT `last_uploaded` FROM `' . _DB_PREFIX_ . 'retailcrm_abandonedcarts`
|
||||
WHERE `id_cart` = \'' . pSQL((int) $cartId) . '\'';
|
||||
$when = Db::getInstance()->getValue($sql);
|
||||
|
||||
if (empty($when)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \DateTime::createFromFormat('Y-m-d H:i:s', $when);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads abandoned carts ID's from DB.
|
||||
*/
|
||||
private static function loadAbandonedCartsIds()
|
||||
{
|
||||
$sql = 'SELECT c.id_cart, c.date_upd
|
||||
FROM ' . _DB_PREFIX_ . 'cart AS c
|
||||
WHERE id_customer != 0
|
||||
AND TIME_TO_SEC(TIMEDIFF(\'' . pSQL(static::$now->format('Y-m-d H:i:s'))
|
||||
. '\', date_upd)) >= ' . pSQL(static::$syncDelay) . '
|
||||
AND c.id_cart NOT IN(SELECT id_cart from ' . _DB_PREFIX_ . 'orders);';
|
||||
static::$cartsIds = Db::getInstance()->executeS($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if abandoned cart should be uploaded
|
||||
*
|
||||
* @param \DateTime|null $lastUploadDate
|
||||
* @param \DateTime|null $lastUpdatedDate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isAbandonedCartShouldBeUpdated($lastUploadDate, $lastUpdatedDate)
|
||||
{
|
||||
// Workaround for PHP bug: https://bugs.php.net/bug.php?id=49914
|
||||
ob_start();
|
||||
var_dump($lastUploadDate);
|
||||
var_dump($lastUpdatedDate);
|
||||
ob_clean();
|
||||
ob_end_flush();
|
||||
|
||||
if (is_null($lastUploadDate) || is_null($lastUpdatedDate)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $lastUploadDate < $lastUpdatedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if inner state is not correct
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function validateState()
|
||||
{
|
||||
if (empty(static::$syncStatus)
|
||||
|| (count(static::$paymentTypes) < 1)
|
||||
|| is_null(static::$now)
|
||||
|| !static::$api
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
112
retailcrm/lib/RetailcrmCatalog.php
Executable file → Normal file
112
retailcrm/lib/RetailcrmCatalog.php
Executable file → Normal file
@ -1,5 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmCatalog
|
||||
{
|
||||
public $default_lang;
|
||||
@ -15,6 +50,8 @@ class RetailcrmCatalog
|
||||
|
||||
public function getData()
|
||||
{
|
||||
$version = substr(_PS_VERSION_, 0, 3);
|
||||
$versionSplit = explode('.', $version);
|
||||
$id_lang = (int) Configuration::get('PS_LANG_DEFAULT');
|
||||
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
|
||||
$shop_url = (Configuration::get('PS_SSL_ENABLED') ? _PS_BASE_URL_SSL_ : _PS_BASE_URL_);
|
||||
@ -22,6 +59,8 @@ class RetailcrmCatalog
|
||||
|
||||
$items = array();
|
||||
$categories = array();
|
||||
$inactiveCategories = array();
|
||||
$categoriesIds = array();
|
||||
|
||||
if ($currency->iso_code == 'RUB') {
|
||||
$currency->iso_code = 'RUR';
|
||||
@ -32,8 +71,17 @@ class RetailcrmCatalog
|
||||
$types = Category::getCategories($id_lang, true, false);
|
||||
|
||||
foreach ($types as $category) {
|
||||
if (!self::isCategoryActive(new Category($category['id_category']))) {
|
||||
if (!in_array($category['id_category'], $inactiveCategories)) {
|
||||
$inactiveCategories[] = $category['id_category'];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$picture = $link->getCatImageLink($category['link_rewrite'], $category['id_category'], 'category_default');
|
||||
|
||||
$categoriesIds[] = $category['id_category'];
|
||||
$categories[] = array(
|
||||
'id' => $category['id_category'],
|
||||
'parentId' => $category['id_parent'],
|
||||
@ -45,22 +93,32 @@ class RetailcrmCatalog
|
||||
$products = Product::getProducts($id_lang, 0, 0, 'name', 'asc');
|
||||
|
||||
foreach ($products AS $product) {
|
||||
$homeCategory = Configuration::get('PS_HOME_CATEGORY');
|
||||
$category = $product['id_category_default'];
|
||||
|
||||
if ($category == Configuration::get('PS_HOME_CATEGORY')) {
|
||||
$temp_categories = Product::getProductCategories($product['id_product']);
|
||||
|
||||
foreach ($temp_categories AS $category) {
|
||||
if ($category != Configuration::get('PS_HOME_CATEGORY'))
|
||||
break;
|
||||
}
|
||||
|
||||
if ($category == Configuration::get('PS_HOME_CATEGORY')) {
|
||||
continue;
|
||||
}
|
||||
if (!in_array($category, $categoriesIds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$version = substr(_PS_VERSION_, 0, 3);
|
||||
$currentProductCategories = Product::getProductCategories($product['id_product']);
|
||||
$categoriesLeft = array_filter(
|
||||
$currentProductCategories,
|
||||
function ($val) use ($inactiveCategories, $categoriesIds, $homeCategory) {
|
||||
if ($val == $homeCategory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($val, $inactiveCategories)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($val, $categoriesIds);
|
||||
}
|
||||
);
|
||||
|
||||
if (empty($categoriesLeft)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($version == "1.3") {
|
||||
$available_for_order = $product['active'] && $product['quantity'];
|
||||
@ -229,4 +287,32 @@ class RetailcrmCatalog
|
||||
|
||||
return array($categories, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Category|\CategoryCore $category
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isCategoryActive($category)
|
||||
{
|
||||
if ($category->id == Configuration::get('PS_HOME_CATEGORY')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$category->active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($category->id_parent)) {
|
||||
$parent = new Category($category->id_parent);
|
||||
|
||||
if (!$parent->active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::isCategoryActive($parent);
|
||||
}
|
||||
|
||||
return $category->active;
|
||||
}
|
||||
}
|
||||
|
105
retailcrm/lib/RetailcrmConsultantRcctExtractor.php
Normal file
105
retailcrm/lib/RetailcrmConsultantRcctExtractor.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmConsultantRcctExtractor extends RetailcrmAbstractDataBuilder
|
||||
{
|
||||
/** @var string */
|
||||
const EXTRACT_REGEX = '/.*rcct(\s+)?\=(\s+)?[\'\"](?P<token>[\w\d]+)[\'\"]/m';
|
||||
|
||||
/** @var string */
|
||||
private $consultantScript;
|
||||
|
||||
/**
|
||||
* @param string $consultantScript
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConsultantScript($consultantScript)
|
||||
{
|
||||
$this->consultantScript = $consultantScript;
|
||||
$this->data = '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset inner state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
|
||||
$this->consultantScript = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
preg_match_all(
|
||||
static::EXTRACT_REGEX,
|
||||
$this->consultantScript,
|
||||
$this->data,
|
||||
PREG_SET_ORDER,
|
||||
0
|
||||
);
|
||||
|
||||
$this->data = reset($this->data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string because token should be returned as string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDataString()
|
||||
{
|
||||
if (!empty($this->data) && is_array($this->data) && isset($this->data['token'])) {
|
||||
return $this->data['token'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
class RetailcrmDaemonCollector
|
||||
{
|
||||
private $customer, $siteKey, $js;
|
||||
|
||||
private $template = <<<EOT
|
||||
<script type="text/javascript">
|
||||
(function(_,r,e,t,a,i,l){_['retailCRMObject']=a;_[a]=_[a]||function(){(_[a].q=_[a].q||[]).push(arguments)};_[a].l=1*new Date();l=r.getElementsByTagName(e)[0];i=r.createElement(e);i.async=!0;i.src=t;l.parentNode.insertBefore(i,l)})(window,document,'script','https://collector.retailcrm.pro/w.js','_rc');
|
||||
{{ code }}
|
||||
_rc('send', 'pageView');
|
||||
</script>
|
||||
EOT;
|
||||
|
||||
public function __construct($customer, $siteKey)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
$this->siteKey = $siteKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJs()
|
||||
{
|
||||
return $this->js;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function buildScript()
|
||||
{
|
||||
$params = array();
|
||||
|
||||
if ($this->customer->id) {
|
||||
$params['customerId'] = $this->customer->id;
|
||||
}
|
||||
|
||||
$this->js = preg_replace(
|
||||
'/{{ code }}/',
|
||||
sprintf(
|
||||
"\t_rc('create', '%s', %s);\n",
|
||||
$this->siteKey,
|
||||
json_encode((object) $params)
|
||||
),
|
||||
$this->template
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
752
retailcrm/lib/RetailcrmHistory.php
Executable file → Normal file
752
retailcrm/lib/RetailcrmHistory.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
138
retailcrm/lib/RetailcrmHistoryHelper.php
Executable file → Normal file
138
retailcrm/lib/RetailcrmHistoryHelper.php
Executable file → Normal file
@ -1,5 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmHistoryHelper {
|
||||
public static function assemblyOrder($orderHistory)
|
||||
{
|
||||
@ -12,11 +47,14 @@ class RetailcrmHistoryHelper {
|
||||
$orders = array();
|
||||
foreach ($orderHistory as $change) {
|
||||
$change['order'] = self::removeEmpty($change['order']);
|
||||
|
||||
if (isset($change['order']['items']) && $change['order']['items']) {
|
||||
$items = array();
|
||||
|
||||
foreach($change['order']['items'] as $item) {
|
||||
$items[$item['id']] = $item;
|
||||
}
|
||||
|
||||
$change['order']['items'] = $items;
|
||||
}
|
||||
|
||||
@ -114,6 +152,8 @@ class RetailcrmHistoryHelper {
|
||||
|
||||
public static function assemblyCustomer($customerHistory)
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
if (file_exists(_PS_ROOT_DIR_ . '/modules/retailcrm/objects.xml')) {
|
||||
$objects = simplexml_load_file(_PS_ROOT_DIR_ . '/modules/retailcrm/objects.xml');
|
||||
|
||||
@ -125,9 +165,22 @@ class RetailcrmHistoryHelper {
|
||||
}
|
||||
|
||||
$customers = array();
|
||||
|
||||
foreach ($customerHistory as $change) {
|
||||
$change['customer'] = self::removeEmpty($change['customer']);
|
||||
|
||||
if (isset($change['deleted'])
|
||||
&& $change['deleted']
|
||||
&& isset($customers[$change['customer']['id']])
|
||||
) {
|
||||
$customers[$change['customer']['id']]['deleted'] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($change['field'] == 'id') {
|
||||
$customers[$change['customer']['id']] = $change['customer'];
|
||||
}
|
||||
|
||||
if (isset($customers[$change['customer']['id']])) {
|
||||
$customers[$change['customer']['id']] = array_merge($customers[$change['customer']['id']], $change['customer']);
|
||||
} else {
|
||||
@ -139,14 +192,95 @@ class RetailcrmHistoryHelper {
|
||||
) {
|
||||
$customers[$change['customer']['id']][$fields['customer'][$change['field']]] = self::newValue($change['newValue']);
|
||||
}
|
||||
|
||||
// email_marketing_unsubscribed_at old value will be null and new value will be datetime in
|
||||
// `Y-m-d H:i:s` format if customer was marked as unsubscribed in retailCRM
|
||||
if (isset($change['customer']['id']) &&
|
||||
$change['field'] == 'email_marketing_unsubscribed_at'
|
||||
) {
|
||||
if ($change['oldValue'] == null && is_string(self::newValue($change['newValue']))) {
|
||||
$customers[$change['customer']['id']]['subscribed'] = false;
|
||||
} elseif (is_string($change['oldValue']) && self::newValue($change['newValue']) == null) {
|
||||
$customers[$change['customer']['id']]['subscribed'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $customers;
|
||||
}
|
||||
|
||||
public static function assemblyCorporateCustomer($customerHistory)
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
if (file_exists(_PS_ROOT_DIR_ . '/modules/retailcrm/objects.xml')) {
|
||||
$objects = simplexml_load_file(_PS_ROOT_DIR_ . '/modules/retailcrm/objects.xml');
|
||||
|
||||
foreach($objects->fields->field as $object) {
|
||||
if (in_array($object["group"], array('customerCorporate', 'customerAddress'))) {
|
||||
$fields[(string)$object["group"]][(string)$object["id"]] = (string)$object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$customersCorporate = array();
|
||||
foreach ($customerHistory as $change) {
|
||||
$change['customer'] = self::removeEmpty($change['customer']);
|
||||
|
||||
if (isset($change['deleted'])
|
||||
&& $change['deleted']
|
||||
&& isset($customersCorporate[$change['customer']['id']])
|
||||
) {
|
||||
$customersCorporate[$change['customer']['id']]['deleted'] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($customersCorporate[$change['customer']['id']])) {
|
||||
if (isset($customersCorporate[$change['customer']['id']]['deleted'])
|
||||
&& $customersCorporate[$change['customer']['id']]['deleted']
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$customersCorporate[$change['customer']['id']] = array_merge($customersCorporate[$change['customer']['id']], $change['customer']);
|
||||
} else {
|
||||
$customersCorporate[$change['customer']['id']] = $change['customer'];
|
||||
}
|
||||
|
||||
if (isset($fields['customerCorporate'][$change['field']])
|
||||
&& $fields['customerCorporate'][$change['field']]
|
||||
) {
|
||||
$customersCorporate[$change['customer']['id']][$fields['customerCorporate'][$change['field']]] = self::newValue($change['newValue']);
|
||||
}
|
||||
|
||||
if (isset($fields['customerAddress'][$change['field']])
|
||||
&& $fields['customerAddress'][$change['field']]
|
||||
) {
|
||||
if (empty($customersCorporate[$change['customer']['id']]['address'])) {
|
||||
$customersCorporate[$change['customer']['id']]['address'] = array();
|
||||
}
|
||||
|
||||
$customersCorporate[$change['customer']['id']]['address'][$fields['customerAddress'][$change['field']]] = self::newValue($change['newValue']);
|
||||
}
|
||||
|
||||
if ($change['field'] == 'address') {
|
||||
$customersCorporate[$change['customer']['id']]['address'] = array_merge($change['address'], self::newValue($change['newValue']));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($customersCorporate as $id => &$customer) {
|
||||
if (empty($customer['id']) && !empty($id)) {
|
||||
$customer['id'] = $id;
|
||||
$customer['deleted'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $customersCorporate;
|
||||
}
|
||||
|
||||
public static function newValue($value)
|
||||
{
|
||||
if(isset($value['code'])) {
|
||||
if (isset($value['code'])) {
|
||||
return $value['code'];
|
||||
} else {
|
||||
return $value;
|
||||
|
37
retailcrm/lib/RetailcrmIcml.php
Executable file → Normal file
37
retailcrm/lib/RetailcrmIcml.php
Executable file → Normal file
@ -1,5 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmIcml
|
||||
{
|
||||
protected $shop;
|
||||
|
40
retailcrm/lib/RetailcrmInventories.php
Executable file → Normal file
40
retailcrm/lib/RetailcrmInventories.php
Executable file → Normal file
@ -1,7 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmInventories
|
||||
{
|
||||
/**
|
||||
* @var \RetailcrmProxy|\RetailcrmApiClientV5
|
||||
*/
|
||||
public static $api;
|
||||
|
||||
/**
|
||||
|
472
retailcrm/lib/RetailcrmJobManager.php
Normal file
472
retailcrm/lib/RetailcrmJobManager.php
Normal file
@ -0,0 +1,472 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require_once(dirname(__FILE__) . '/../../../init.php');
|
||||
require_once(dirname(__FILE__) . '/../bootstrap.php');
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class RetailcrmJobManager
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @license GPL
|
||||
* @link https://retailcrm.ru
|
||||
*/
|
||||
class RetailcrmJobManager
|
||||
{
|
||||
const LAST_RUN_NAME = 'RETAILCRM_LAST_RUN';
|
||||
const IN_PROGRESS_NAME = 'RETAILCRM_JOBS_IN_PROGRESS';
|
||||
|
||||
/**
|
||||
* Entry point for all jobs.
|
||||
* Jobs must be passed in this format:
|
||||
* RetailcrmJobManager::startJobs(
|
||||
* array(
|
||||
* 'jobName' => DateInterval::createFromDateString('1 hour')
|
||||
* ),
|
||||
* true
|
||||
* );
|
||||
*
|
||||
* File `jobName.php` must exist in retailcrm/job and must contain everything to run job.
|
||||
* Throwed errors will be logged in <prestashop directory>/retailcrm.log
|
||||
* DateInterval must be positive. Pass `null` instead of DateInterval to remove
|
||||
* any delay - in other words, jobs without interval will be executed every time.
|
||||
*
|
||||
* @param array $jobs Jobs list
|
||||
* @param bool $runOnceInContext Use require_once instead of require
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function startJobs(
|
||||
$jobs = array(),
|
||||
$runOnceInContext = true
|
||||
) {
|
||||
RetailcrmLogger::writeDebug(__METHOD__,'starting JobManager');
|
||||
static::execJobs($jobs, $runOnceInContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run scheduled jobs with request
|
||||
*
|
||||
* @param array $jobs
|
||||
* @param bool $runOnceInContext
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function execJobs($jobs = array(), $runOnceInContext = false)
|
||||
{
|
||||
$current = date_create('now');
|
||||
$lastRuns = array();
|
||||
|
||||
try {
|
||||
$lastRuns = static::getLastRuns();
|
||||
} catch (Exception $exception) {
|
||||
static::handleError(
|
||||
$exception->getFile(),
|
||||
$exception->getMessage(),
|
||||
$exception->getTraceAsString(),
|
||||
'',
|
||||
$jobs
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Trying to acquire lock...');
|
||||
|
||||
if (!static::lock()) {
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Cannot acquire lock');
|
||||
die;
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeDebug(
|
||||
__METHOD__,
|
||||
sprintf('Current time: %s', $current->format(DATE_RFC3339))
|
||||
);
|
||||
|
||||
foreach ($lastRuns as $name => $diff) {
|
||||
if (!array_key_exists($name, $jobs)) {
|
||||
unset($lastRuns[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($jobs as $job => $diff) {
|
||||
try {
|
||||
if (isset($lastRuns[$job]) && $lastRuns[$job] instanceof DateTime) {
|
||||
$shouldRunAt = clone $lastRuns[$job];
|
||||
|
||||
if ($diff instanceof DateInterval) {
|
||||
$shouldRunAt->add($diff);
|
||||
}
|
||||
} else {
|
||||
$shouldRunAt = \DateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00');
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeDebug(__METHOD__, sprintf(
|
||||
'Checking %s, interval %s, shouldRunAt: %s: %s',
|
||||
$job,
|
||||
is_null($diff) ? 'NULL' : $diff->format('%R%Y-%m-%d %H:%i:%s:%F'),
|
||||
isset($shouldRunAt) && $shouldRunAt instanceof \DateTime
|
||||
? $shouldRunAt->format(DATE_RFC3339)
|
||||
: 'undefined',
|
||||
(isset($shouldRunAt) && $shouldRunAt <= $current) ? 'true' : 'false'
|
||||
));
|
||||
|
||||
if (isset($shouldRunAt) && $shouldRunAt <= $current) {
|
||||
RetailcrmLogger::writeDebug(__METHOD__, sprintf('Executing job %s', $job));
|
||||
RetailcrmJobManager::runJob($job, $runOnceInContext);
|
||||
$lastRuns[$job] = new \DateTime('now');
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
static::handleError(
|
||||
$exception->getFile(),
|
||||
$exception->getMessage(),
|
||||
$exception->getTraceAsString(),
|
||||
$job
|
||||
);
|
||||
} catch (\Throwable $throwable) {
|
||||
static::handleError(
|
||||
$throwable->getFile(),
|
||||
$throwable->getMessage(),
|
||||
$throwable->getTraceAsString(),
|
||||
$job
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
static::setLastRuns($lastRuns);
|
||||
} catch (Exception $exception) {
|
||||
static::handleError(
|
||||
$exception->getFile(),
|
||||
$exception->getMessage(),
|
||||
$exception->getTraceAsString(),
|
||||
'',
|
||||
$jobs
|
||||
);
|
||||
}
|
||||
|
||||
static::unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts jobs last runs from db
|
||||
*
|
||||
* @return array<string, \DateTime>
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getLastRuns()
|
||||
{
|
||||
$lastRuns = json_decode((string)Configuration::get(self::LAST_RUN_NAME), true);
|
||||
|
||||
if (json_last_error() != JSON_ERROR_NONE) {
|
||||
$lastRuns = array();
|
||||
} else {
|
||||
foreach ($lastRuns as $job => $ran) {
|
||||
$lastRan = DateTime::createFromFormat(DATE_RFC3339, $ran);
|
||||
|
||||
if ($lastRan instanceof DateTime) {
|
||||
$lastRuns[$job] = $lastRan;
|
||||
} else {
|
||||
$lastRuns[$job] = new DateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (array)$lastRuns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates jobs last runs in db
|
||||
*
|
||||
* @param array $lastRuns
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function setLastRuns($lastRuns = array())
|
||||
{
|
||||
$now = new DateTime();
|
||||
|
||||
if (!is_array($lastRuns)) {
|
||||
$lastRuns = array();
|
||||
}
|
||||
|
||||
foreach ($lastRuns as $job => $ran) {
|
||||
if ($ran instanceof DateTime) {
|
||||
$lastRuns[$job] = $ran->format(DATE_RFC3339);
|
||||
} else {
|
||||
$lastRuns[$job] = $now->format(DATE_RFC3339);
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeDebug(
|
||||
__METHOD__,
|
||||
sprintf('Saving last run for %s as %s', $job, $lastRuns[$job])
|
||||
);
|
||||
}
|
||||
|
||||
Configuration::updateValue(self::LAST_RUN_NAME, (string)json_encode($lastRuns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs job
|
||||
*
|
||||
* @param string $job
|
||||
* @param bool $once
|
||||
*
|
||||
* @throws \RetailcrmJobManagerException
|
||||
*/
|
||||
public static function runJob($job, $once = false)
|
||||
{
|
||||
$jobFile = implode(
|
||||
DIRECTORY_SEPARATOR,
|
||||
array(_PS_ROOT_DIR_, 'modules', 'retailcrm', 'lib', 'events', self::escapeJobName($job) . '.php')
|
||||
);
|
||||
|
||||
if (!file_exists($jobFile)) {
|
||||
throw new \RetailcrmJobManagerException('Cannot find job', $job);
|
||||
}
|
||||
|
||||
static::execPHP($jobFile, $once);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP file
|
||||
*
|
||||
* @param string $fileCommandLine
|
||||
* @param bool $once
|
||||
*
|
||||
* @throws \RetailcrmJobManagerException
|
||||
*/
|
||||
private static function execPHP($fileCommandLine, $once = false)
|
||||
{
|
||||
$error = null;
|
||||
|
||||
try {
|
||||
static::execHere($fileCommandLine, $once);
|
||||
} catch (\Exception $exception) {
|
||||
throw new RetailcrmJobManagerException($exception->getMessage(), $fileCommandLine);
|
||||
} catch (\Throwable $exception) {
|
||||
throw new RetailcrmJobManagerException($exception->getMessage(), $fileCommandLine);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes jobs to JSON
|
||||
*
|
||||
* @param $jobs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function serializeJobs($jobs)
|
||||
{
|
||||
foreach ($jobs as $name => $interval) {
|
||||
$jobs[$name] = serialize($interval);
|
||||
}
|
||||
|
||||
return (string)base64_encode(json_encode($jobs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes error to log and returns 500
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $msg
|
||||
* @param string $trace
|
||||
* @param string $currentJob
|
||||
* @param array $jobs
|
||||
*/
|
||||
private static function handleError($file, $msg, $trace, $currentJob = '', $jobs = array())
|
||||
{
|
||||
$data = array();
|
||||
|
||||
if (!empty($currentJob)) {
|
||||
$data[] = 'current job: ' . $currentJob;
|
||||
}
|
||||
|
||||
if (count($jobs) > 0) {
|
||||
$data[] = 'jobs list: ' . self::serializeJobs($jobs);
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeNoCaller(sprintf('%s: %s (%s)', $file, $msg, implode(', ', $data)));
|
||||
RetailcrmLogger::writeNoCaller($trace);
|
||||
RetailcrmTools::http_response_code(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes php script in this context, without hanging up request
|
||||
*
|
||||
* @param string $phpScript
|
||||
* @param bool $once
|
||||
*/
|
||||
private static function execHere($phpScript, $once = false)
|
||||
{
|
||||
ignore_user_abort(true);
|
||||
set_time_limit(static::getTimeLimit());
|
||||
|
||||
if (version_compare(phpversion(), '7.0.16', '>=') &&
|
||||
function_exists('fastcgi_finish_request')
|
||||
) {
|
||||
if (!headers_sent()) {
|
||||
header('Expires: Thu, 19 Nov 1981 08:52:00 GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
}
|
||||
|
||||
fastcgi_finish_request();
|
||||
}
|
||||
|
||||
if ($once) {
|
||||
require_once($phpScript);
|
||||
} else {
|
||||
require($phpScript);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns script execution time limit
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function getTimeLimit()
|
||||
{
|
||||
return 14400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes disallowed symbols from job name. Only latin characters, numbers and underscore allowed.
|
||||
*
|
||||
* @param string $job
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function escapeJobName($job)
|
||||
{
|
||||
return (string) preg_replace('/[^[a-zA-Z0-9_]]*/m', '', $job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns when JobManager was executed
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getLastRun()
|
||||
{
|
||||
$lastRuns = array_values(static::getLastRuns());
|
||||
|
||||
if (empty($lastRuns)) {
|
||||
return \DateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00');
|
||||
}
|
||||
|
||||
usort(
|
||||
$lastRuns,
|
||||
function ($first, $second) {
|
||||
if ($first < $second) {
|
||||
return 1;
|
||||
} else if ($first > $second) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return $lastRuns[count($lastRuns) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if lock is present and it's not expired
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function isLocked()
|
||||
{
|
||||
$inProcess = (bool)Configuration::get(self::IN_PROGRESS_NAME);
|
||||
$lastRan = static::getLastRun();
|
||||
$lastRanSeconds = $lastRan->format('U');
|
||||
|
||||
if (($lastRanSeconds + self::getTimeLimit()) < time()) {
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Removing lock because time limit exceeded.');
|
||||
static::unlock();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $inProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs lock
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function lock()
|
||||
{
|
||||
if (!static::isLocked()) {
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Acquiring lock...');
|
||||
Configuration::updateValue(self::IN_PROGRESS_NAME, true);
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Lock acquired.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes lock
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function unlock()
|
||||
{
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Removing lock...');
|
||||
Configuration::updateValue(self::IN_PROGRESS_NAME, false);
|
||||
RetailcrmLogger::writeDebug(__METHOD__, 'Lock removed.');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
118
retailcrm/lib/RetailcrmLogger.php
Normal file
118
retailcrm/lib/RetailcrmLogger.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class RetailcrmLogger
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @license GPL
|
||||
* @link https://retailcrm.ru
|
||||
*/
|
||||
class RetailcrmLogger
|
||||
{
|
||||
/**
|
||||
* Write entry to log
|
||||
*
|
||||
* @param string $caller
|
||||
* @param string $message
|
||||
*/
|
||||
public static function writeCaller($caller, $message)
|
||||
{
|
||||
error_log(
|
||||
sprintf(
|
||||
'[%s] @ [%s] %s' . PHP_EOL,
|
||||
date(DATE_RFC3339),
|
||||
$caller,
|
||||
$message
|
||||
),
|
||||
3,
|
||||
static::getErrorLog()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write entry to log without caller name
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public static function writeNoCaller($message)
|
||||
{
|
||||
error_log(
|
||||
sprintf(
|
||||
'[%s] %s' . PHP_EOL,
|
||||
date(DATE_RFC3339),
|
||||
$message
|
||||
),
|
||||
3,
|
||||
static::getErrorLog()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write debug log record
|
||||
*
|
||||
* @param string $caller
|
||||
* @param mixed $message
|
||||
*/
|
||||
public static function writeDebug($caller, $message)
|
||||
{
|
||||
if (RetailcrmTools::isDebug()) {
|
||||
static::writeNoCaller(sprintf(
|
||||
'(DEBUG) <%s> %s',
|
||||
$caller,
|
||||
print_r($message, true)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error log path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getErrorLog()
|
||||
{
|
||||
if (!defined('_PS_ROOT_DIR_')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return _PS_ROOT_DIR_ . '/retailcrm.log';
|
||||
}
|
||||
}
|
1213
retailcrm/lib/RetailcrmOrderBuilder.php
Normal file
1213
retailcrm/lib/RetailcrmOrderBuilder.php
Normal file
File diff suppressed because it is too large
Load Diff
42
retailcrm/lib/RetailcrmPrestashopLoader.php
Normal file
42
retailcrm/lib/RetailcrmPrestashopLoader.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../../config/config.inc.php');
|
||||
require_once(dirname(__FILE__) . '/../../../init.php');
|
||||
require_once(dirname(__FILE__) . '/../bootstrap.php');
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class RequestProxy
|
||||
* @package RetailCrm\Component
|
||||
*/
|
||||
class RetailcrmProxy
|
||||
{
|
||||
private $api;
|
||||
private $log;
|
||||
|
||||
public function __construct($url, $key, $log, $version = '4')
|
||||
{
|
||||
switch ($version) {
|
||||
case '5':
|
||||
$this->api = new RetailcrmApiClientV5($url, $key);
|
||||
break;
|
||||
case '4':
|
||||
$this->api = new RetailcrmApiClientV4($url, $key);
|
||||
break;
|
||||
case '3':
|
||||
$this->api = new RetailcrmApiClientV3($url, $key);
|
||||
break;
|
||||
}
|
||||
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
$date = date('Y-m-d H:i:s');
|
||||
try {
|
||||
$response = call_user_func_array(array($this->api, $method), $arguments);
|
||||
|
||||
if (!$response->isSuccessful()) {
|
||||
error_log("[$date] @ [$method] " . $response->getErrorMsg() . "\n", 3, $this->log);
|
||||
if (isset($response['errors'])) {
|
||||
RetailcrmApiErrors::set($response['errors'], $response->getStatusCode());
|
||||
$error = implode("\n", $response['errors']);
|
||||
error_log($error . "\n", 3, $this->log);
|
||||
}
|
||||
$response = false;
|
||||
}
|
||||
|
||||
return $response;
|
||||
} catch (CurlException $e) {
|
||||
error_log("[$date] @ [$method] " . $e->getMessage() . "\n", 3, $this->log);
|
||||
return false;
|
||||
} catch (InvalidJsonException $e) {
|
||||
error_log("[$date] @ [$method] " . $e->getMessage() . "\n", 3, $this->log);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
58
retailcrm/lib/RetailcrmReferences.php
Executable file → Normal file
58
retailcrm/lib/RetailcrmReferences.php
Executable file → Normal file
@ -1,5 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmReferences
|
||||
{
|
||||
public $default_lang;
|
||||
@ -33,6 +68,7 @@ class RetailcrmReferences
|
||||
'type' => 'select',
|
||||
'label' => $carrier['name'],
|
||||
'name' => 'RETAILCRM_API_DELIVERY[' . $carrier['id_carrier'] . ']',
|
||||
'subname' => $carrier['id_carrier'],
|
||||
'required' => false,
|
||||
'options' => array(
|
||||
'query' => $apiDeliveryTypes,
|
||||
@ -60,6 +96,7 @@ class RetailcrmReferences
|
||||
'type' => 'select',
|
||||
'label' => $state['name'],
|
||||
'name' => "RETAILCRM_API_STATUS[$key]",
|
||||
'subname' => $key,
|
||||
'required' => false,
|
||||
'options' => array(
|
||||
'query' => $apiStatuses,
|
||||
@ -86,6 +123,7 @@ class RetailcrmReferences
|
||||
'type' => 'select',
|
||||
'label' => $payment['name'],
|
||||
'name' => 'RETAILCRM_API_PAYMENT[' . $payment['code'] . ']',
|
||||
'subname' => $payment['code'],
|
||||
'required' => false,
|
||||
'options' => array(
|
||||
'query' => $apiPaymentTypes,
|
||||
@ -165,27 +203,31 @@ class RetailcrmReferences
|
||||
|
||||
public function getSystemPaymentModules($active = true)
|
||||
{
|
||||
$shop_id = Context::getContext()->shop->id;
|
||||
$shop_id = (int) Context::getContext()->shop->id;
|
||||
|
||||
/* Get all modules then select only payment ones */
|
||||
$modules = Module::getModulesOnDisk(true);
|
||||
/**
|
||||
* Get all modules then select only payment ones
|
||||
*/
|
||||
$modules = RetailCRM::getCachedCmsModulesList();
|
||||
|
||||
foreach ($modules as $module) {
|
||||
if ($module->tab == 'payments_gateways') {
|
||||
if (!empty($module->parent_class) && $module->parent_class == 'PaymentModule') {
|
||||
if ($module->id) {
|
||||
$module_id = (int) $module->id;
|
||||
|
||||
if (!get_class($module) == 'SimpleXMLElement')
|
||||
$module->country = array();
|
||||
$countries = DB::getInstance()->executeS('SELECT id_country FROM ' . _DB_PREFIX_ . 'module_country WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id);
|
||||
$countries = DB::getInstance()->executeS('SELECT id_country FROM ' . _DB_PREFIX_ . 'module_country WHERE id_module = ' . pSQL($module_id) . ' AND `id_shop`=' . pSQL($shop_id));
|
||||
foreach ($countries as $country)
|
||||
$module->country[] = $country['id_country'];
|
||||
if (!get_class($module) == 'SimpleXMLElement')
|
||||
$module->currency = array();
|
||||
$currencies = DB::getInstance()->executeS('SELECT id_currency FROM ' . _DB_PREFIX_ . 'module_currency WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id);
|
||||
$currencies = DB::getInstance()->executeS('SELECT id_currency FROM ' . _DB_PREFIX_ . 'module_currency WHERE id_module = ' . pSQL($module_id) . ' AND `id_shop`=' . pSQL($shop_id));
|
||||
foreach ($currencies as $currency)
|
||||
$module->currency[] = $currency['id_currency'];
|
||||
if (!get_class($module) == 'SimpleXMLElement')
|
||||
$module->group = array();
|
||||
$groups = DB::getInstance()->executeS('SELECT id_group FROM ' . _DB_PREFIX_ . 'module_group WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id);
|
||||
$groups = DB::getInstance()->executeS('SELECT id_group FROM ' . _DB_PREFIX_ . 'module_group WHERE id_module = ' . pSQL($module_id) . ' AND `id_shop`=' . pSQL($shop_id));
|
||||
foreach ($groups as $group)
|
||||
$module->group[] = $group['id_group'];
|
||||
} else {
|
||||
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Service
|
||||
{
|
||||
public static function getDate($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
$result = file_get_contents($file);
|
||||
} else {
|
||||
$result = date('Y-m-d H:i:s', strtotime('-1 days', strtotime(date('Y-m-d H:i:s'))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function explodeFIO($string)
|
||||
{
|
||||
$result = array();
|
||||
$parse = (!$string) ? false : explode(" ", $string, 3);
|
||||
|
||||
switch (count($parse)) {
|
||||
case 1:
|
||||
$result['firstName'] = $parse[0];
|
||||
break;
|
||||
case 2:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
break;
|
||||
case 3:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
$result['patronymic'] = $parse[2];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
463
retailcrm/lib/RetailcrmTools.php
Normal file
463
retailcrm/lib/RetailcrmTools.php
Normal file
@ -0,0 +1,463 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmTools
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
static $currentStatusCode;
|
||||
|
||||
/**
|
||||
* Returns true if corporate customers are enabled in settings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCorporateEnabled()
|
||||
{
|
||||
return (bool)Configuration::get(RetailCRM::ENABLE_CORPORATE_CLIENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if customer is corporate
|
||||
*
|
||||
* @param Customer $customer
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCustomerCorporate(Customer $customer)
|
||||
{
|
||||
$addresses = $customer->getAddresses((int)Configuration::get('PS_LANG_DEFAULT'));
|
||||
|
||||
foreach ($addresses as $address) {
|
||||
if (($address instanceof Address && !empty($address->company))
|
||||
|| (is_array($address) && !empty($address['company']))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if order is corporate
|
||||
*
|
||||
* @param Order $order
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isOrderCorporate(Order $order)
|
||||
{
|
||||
if (empty($order->id_address_invoice)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$address = new Address($order->id_address_invoice);
|
||||
|
||||
return $address instanceof Address && !empty($address->company);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'true' if provided date string is valid
|
||||
*
|
||||
* @param $date
|
||||
* @param string $format
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function verifyDate($date, $format = "Y-m-d")
|
||||
{
|
||||
return $date !== "0000-00-00" && (bool)date_create_from_format($format, $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a string to id
|
||||
*
|
||||
* @param string $ids string with id
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public static function partitionId($ids)
|
||||
{
|
||||
$ids = explode(',', $ids);
|
||||
|
||||
$ranges = array();
|
||||
|
||||
foreach ($ids as $idx => $uid) {
|
||||
if (strpos($uid, '-')) {
|
||||
$range = explode('-', $uid);
|
||||
$ranges = array_merge($ranges, range($range[0], $range[1]));
|
||||
unset($ids[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
$ids = implode(',', array_merge($ids, $ranges));
|
||||
$ids = explode(',', $ids);
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts CMS address to CRM address
|
||||
*
|
||||
* @param $address
|
||||
* @param array $customer
|
||||
* @param array $order
|
||||
* @deprecated Replaced with RetailcrmAddressBuilder
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function addressParse($address, &$customer = array(), &$order = array())
|
||||
{
|
||||
if (!isset($customer)) {
|
||||
$customer = array();
|
||||
}
|
||||
|
||||
if (!isset($order)) {
|
||||
$order = array();
|
||||
}
|
||||
|
||||
if ($address instanceof Address) {
|
||||
$postcode = $address->postcode;
|
||||
$city = $address->city;
|
||||
$addres_line = sprintf("%s %s", $address->address1, $address->address2);
|
||||
$countryIso = Country::getIsoById($address->id_country);
|
||||
$vat = $address->vat_number;
|
||||
}
|
||||
|
||||
if (!empty($postcode)) {
|
||||
$customer['address']['index'] = $postcode;
|
||||
$order['delivery']['address']['index'] = $postcode;
|
||||
}
|
||||
|
||||
if (!empty($city)) {
|
||||
$customer['address']['city'] = $city;
|
||||
$order['delivery']['address']['city'] = $city;
|
||||
}
|
||||
|
||||
if (!empty($addres_line)) {
|
||||
$customer['address']['text'] = $addres_line;
|
||||
$order['delivery']['address']['text'] = $addres_line;
|
||||
}
|
||||
|
||||
if (!empty($countryIso)) {
|
||||
$order['countryIso'] = $countryIso;
|
||||
$customer['address']['countryIso'] = $countryIso;
|
||||
}
|
||||
|
||||
$phones = static::getPhone($address, $customer, $order);
|
||||
$order = array_merge($order, $phones['order']);
|
||||
$customer = array_merge($customer, $phones['customer']);
|
||||
|
||||
return array(
|
||||
'order' => RetailcrmTools::clearArray($order),
|
||||
'customer' => RetailcrmTools::clearArray($customer),
|
||||
'vat' => isset($vat) && !empty($vat) ? $vat : ''
|
||||
);
|
||||
}
|
||||
|
||||
public static function getPhone($address, &$customer = array(), &$order = array())
|
||||
{
|
||||
if (!isset($customer)) {
|
||||
$customer = array();
|
||||
}
|
||||
|
||||
if (!isset($order)) {
|
||||
$order = array();
|
||||
}
|
||||
|
||||
if (!empty($address->phone_mobile)) {
|
||||
$order['phone'] = $address->phone_mobile;
|
||||
$customer['phones'][] = array('number'=> $address->phone_mobile);
|
||||
}
|
||||
|
||||
if (!empty($address->phone)) {
|
||||
$order['additionalPhone'] = $address->phone;
|
||||
$customer['phones'][] = array('number'=> $address->phone);
|
||||
}
|
||||
|
||||
if (!isset($order['phone']) && !empty($order['additionalPhone'])) {
|
||||
$order['phone'] = $order['additionalPhone'];
|
||||
unset($order['additionalPhone']);
|
||||
}
|
||||
|
||||
$phonesArray = array('customer' => $customer, 'order' => $order);
|
||||
|
||||
return $phonesArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate crm address
|
||||
*
|
||||
* @param $address
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateCrmAddress($address)
|
||||
{
|
||||
if (preg_match("/https:\/\/(.*).retailcrm.(pro|ru|es)/", $address) === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getDate($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
$result = file_get_contents($file);
|
||||
} else {
|
||||
$result = date('Y-m-d H:i:s', strtotime('-1 days', strtotime(date('Y-m-d H:i:s'))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function explodeFIO($string)
|
||||
{
|
||||
$result = array();
|
||||
$parse = (!$string) ? false : explode(" ", $string, 3);
|
||||
|
||||
switch (count($parse)) {
|
||||
case 1:
|
||||
$result['firstName'] = $parse[0];
|
||||
break;
|
||||
case 2:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
break;
|
||||
case 3:
|
||||
$result['firstName'] = $parse[1];
|
||||
$result['lastName'] = $parse[0];
|
||||
$result['patronymic'] = $parse[2];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns externalId for order
|
||||
*
|
||||
* @param Cart $cart
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCartOrderExternalId(Cart $cart)
|
||||
{
|
||||
return sprintf('pscart_%d', $cart->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset empty fields
|
||||
*
|
||||
* @param array $arr input array
|
||||
* @param callable|null $filterFunc
|
||||
*
|
||||
* @return array
|
||||
* @todo Don't filter out false & all methods MUST NOT use false as blank value.
|
||||
*/
|
||||
public static function clearArray(array $arr, $filterFunc = null)
|
||||
{
|
||||
if (!is_array($arr)) {
|
||||
return $arr;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($arr as $index => $node) {
|
||||
$result[$index] = (is_array($node))
|
||||
? self::clearArray($node)
|
||||
: $node;
|
||||
|
||||
if ($result[$index] == ''
|
||||
|| $result[$index] === null
|
||||
|| (is_array($result[$index]) && count($result[$index]) < 1)
|
||||
) {
|
||||
unset($result[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_callable($filterFunc)) {
|
||||
return array_filter($result, $filterFunc);
|
||||
}
|
||||
|
||||
return array_filter($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if PrestaShop in debug mode or _RCRM_MODE_DEV_ const defined to true.
|
||||
* Add define('_RCRM_MODE_DEV_', true); to enable extended logging (dev mode) ONLY for retailCRM module.
|
||||
* In developer mode module will log every JobManager run and every request and response from retailCRM API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDebug()
|
||||
{
|
||||
return (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_ == true)
|
||||
|| (defined('_RCRM_MODE_DEV_') && _RCRM_MODE_DEV_ == true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates placeholder email
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function createPlaceholderEmail($name)
|
||||
{
|
||||
return substr(md5($name), 0, 15) . '@example.com';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns API client proxy if connection is configured.
|
||||
* Returns null if connection is not configured.
|
||||
*
|
||||
* @return \RetailcrmProxy|\RetailcrmApiClientV5|null
|
||||
*/
|
||||
public static function getApiClient()
|
||||
{
|
||||
$apiUrl = Configuration::get(RetailCRM::API_URL);
|
||||
$apiKey = Configuration::get(RetailCRM::API_KEY);
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
return new RetailcrmProxy($apiUrl, $apiKey, RetailCRM::getErrorLog());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new address to customer, preserves old phone numbers.
|
||||
*
|
||||
* @param array $customer
|
||||
* @param array $address
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function mergeCustomerAddress($customer, $address)
|
||||
{
|
||||
$customerPhones = isset($customer['phones']) ? $customer['phones'] : array();
|
||||
$addressPhones = isset($address['phones']) ? $address['phones'] : array();
|
||||
$squashedCustomerPhones = array_filter(array_map(function ($val) {
|
||||
return isset($val['number']) ? $val['number'] : null;
|
||||
}, $customerPhones));
|
||||
|
||||
foreach ($addressPhones as $newPhone) {
|
||||
if (empty($newPhone['number'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($newPhone['number'], $squashedCustomerPhones)) {
|
||||
$customerPhones[] = $newPhone;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($customer, $address, array('phones' => $customerPhones));
|
||||
}
|
||||
|
||||
/**
|
||||
* http_response_code polyfill
|
||||
*
|
||||
* @param null $code
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public static function http_response_code($code = null)
|
||||
{
|
||||
if (function_exists('http_response_code')) {
|
||||
$code = http_response_code($code);
|
||||
} else {
|
||||
if ($code !== NULL) {
|
||||
switch ($code) {
|
||||
case 100: $text = 'Continue'; break;
|
||||
case 101: $text = 'Switching Protocols'; break;
|
||||
case 200: $text = 'OK'; break;
|
||||
case 201: $text = 'Created'; break;
|
||||
case 202: $text = 'Accepted'; break;
|
||||
case 203: $text = 'Non-Authoritative Information'; break;
|
||||
case 204: $text = 'No Content'; break;
|
||||
case 205: $text = 'Reset Content'; break;
|
||||
case 206: $text = 'Partial Content'; break;
|
||||
case 300: $text = 'Multiple Choices'; break;
|
||||
case 301: $text = 'Moved Permanently'; break;
|
||||
case 302: $text = 'Moved Temporarily'; break;
|
||||
case 303: $text = 'See Other'; break;
|
||||
case 304: $text = 'Not Modified'; break;
|
||||
case 305: $text = 'Use Proxy'; break;
|
||||
case 400: $text = 'Bad Request'; break;
|
||||
case 401: $text = 'Unauthorized'; break;
|
||||
case 402: $text = 'Payment Required'; break;
|
||||
case 403: $text = 'Forbidden'; break;
|
||||
case 404: $text = 'Not Found'; break;
|
||||
case 405: $text = 'Method Not Allowed'; break;
|
||||
case 406: $text = 'Not Acceptable'; break;
|
||||
case 407: $text = 'Proxy Authentication Required'; break;
|
||||
case 408: $text = 'Request Time-out'; break;
|
||||
case 409: $text = 'Conflict'; break;
|
||||
case 410: $text = 'Gone'; break;
|
||||
case 411: $text = 'Length Required'; break;
|
||||
case 412: $text = 'Precondition Failed'; break;
|
||||
case 413: $text = 'Request Entity Too Large'; break;
|
||||
case 414: $text = 'Request-URI Too Large'; break;
|
||||
case 415: $text = 'Unsupported Media Type'; break;
|
||||
case 500: $text = 'Internal Server Error'; break;
|
||||
case 501: $text = 'Not Implemented'; break;
|
||||
case 502: $text = 'Bad Gateway'; break;
|
||||
case 503: $text = 'Service Unavailable'; break;
|
||||
case 504: $text = 'Gateway Time-out'; break;
|
||||
case 505: $text = 'HTTP Version not supported'; break;
|
||||
default:
|
||||
exit('Unknown http status code "' . htmlentities($code) . '"');
|
||||
break;
|
||||
}
|
||||
|
||||
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
|
||||
|
||||
header($protocol . ' ' . $code . ' ' . $text);
|
||||
} else {
|
||||
$code = !empty(static::$currentStatusCode) ? static::$currentStatusCode : 200;
|
||||
}
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
40
retailcrm/lib/api/CurlException.php
Normal file
40
retailcrm/lib/api/CurlException.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class CurlException extends \RuntimeException
|
||||
{
|
||||
}
|
40
retailcrm/lib/api/InvalidJsonException.php
Normal file
40
retailcrm/lib/api/InvalidJsonException.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class InvalidJsonException extends \DomainException
|
||||
{
|
||||
}
|
871
retailcrm/lib/RetailcrmApiClientV5.php → retailcrm/lib/api/RetailcrmApiClientV5.php
Executable file → Normal file
871
retailcrm/lib/RetailcrmApiClientV5.php → retailcrm/lib/api/RetailcrmApiClientV5.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
108
retailcrm/lib/api/RetailcrmApiErrors.php
Normal file
108
retailcrm/lib/api/RetailcrmApiErrors.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmApiErrors
|
||||
{
|
||||
/** @var array */
|
||||
private static $errors;
|
||||
|
||||
/** @var integer */
|
||||
private static $statusCode;
|
||||
|
||||
/**
|
||||
* ApiErrors constructor. Isn't accessible.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getStatusCode()
|
||||
{
|
||||
return isset(static::$statusCode) ? static::$statusCode : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns static::$errors array, or regenerates it.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getErrors()
|
||||
{
|
||||
static::checkArray();
|
||||
return static::$errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets static::$errors array, or regenerates it.
|
||||
* Returns true if errors is assigned.
|
||||
* Returns false if incorrect data was passed to it.
|
||||
*
|
||||
* @param array $errors
|
||||
* @param integer $statusCode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function set($errors, $statusCode)
|
||||
{
|
||||
static::checkArray();
|
||||
|
||||
if (is_array($errors) && is_integer($statusCode)) {
|
||||
static::$errors = $errors;
|
||||
static::$statusCode = $statusCode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerates static::$errors array
|
||||
*/
|
||||
private static function checkArray()
|
||||
{
|
||||
if (!is_array(static::$errors)) {
|
||||
static::$errors = array();
|
||||
}
|
||||
}
|
||||
}
|
218
retailcrm/lib/api/RetailcrmApiPaginatedRequest.php
Normal file
218
retailcrm/lib/api/RetailcrmApiPaginatedRequest.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmApiPaginatedRequest
|
||||
{
|
||||
/**
|
||||
* @var \RetailcrmProxy|\RetailcrmApiClientV5
|
||||
*/
|
||||
private $api;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $params;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dataKey;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $limit;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* RetailcrmApiPaginatedRequest constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets retailCRM api client to request
|
||||
*
|
||||
* @param \RetailcrmApiClientV5|\RetailcrmProxy $api
|
||||
*
|
||||
* @return RetailcrmApiPaginatedRequest
|
||||
*/
|
||||
public function setApi($api)
|
||||
{
|
||||
$this->api = $api;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets API client method to request
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @return RetailcrmApiPaginatedRequest
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets method params for API client (leave `{{page}}` instead of page and `{{limit}}` instead of limit)
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return RetailcrmApiPaginatedRequest
|
||||
*/
|
||||
public function setParams($params)
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets dataKey (key with data in response)
|
||||
*
|
||||
* @param string $dataKey
|
||||
*
|
||||
* @return RetailcrmApiPaginatedRequest
|
||||
*/
|
||||
public function setDataKey($dataKey)
|
||||
{
|
||||
$this->dataKey = $dataKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets record limit per request
|
||||
*
|
||||
* @param int $limit
|
||||
*
|
||||
* @return RetailcrmApiPaginatedRequest
|
||||
*/
|
||||
public function setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes request
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$this->data = array();
|
||||
$response = true;
|
||||
$page = 1;
|
||||
|
||||
do {
|
||||
$response = call_user_func_array(
|
||||
array($this->api, $this->method),
|
||||
$this->buildParams($this->params, $page)
|
||||
);
|
||||
|
||||
if ($response instanceof RetailcrmApiResponse && $response->offsetExists($this->dataKey)) {
|
||||
$this->data = array_merge($response[$this->dataKey]);
|
||||
$page = $response['pagination']['currentPage'] + 1;
|
||||
}
|
||||
|
||||
time_nanosleep(0, 300000000);
|
||||
} while ($response && (isset($response['pagination'])
|
||||
&& $response['pagination']['currentPage'] < $response['pagination']['totalPageCount']));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset paginated request
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->method = '';
|
||||
$this->limit = 100;
|
||||
$this->data = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* buildParams
|
||||
*
|
||||
* @param array $placeholderParams
|
||||
* @param int $currentPage
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function buildParams($placeholderParams, $currentPage)
|
||||
{
|
||||
foreach ($placeholderParams as $key => $param) {
|
||||
if ($param == '{{page}}') {
|
||||
$placeholderParams[$key] = $currentPage;
|
||||
}
|
||||
|
||||
if ($param == '{{limit}}') {
|
||||
$placeholderParams[$key] = $this->limit;
|
||||
}
|
||||
}
|
||||
|
||||
return $placeholderParams;
|
||||
}
|
||||
}
|
51
retailcrm/lib/RetailcrmApiResponse.php → retailcrm/lib/api/RetailcrmApiResponse.php
Executable file → Normal file
51
retailcrm/lib/RetailcrmApiResponse.php → retailcrm/lib/api/RetailcrmApiResponse.php
Executable file → Normal file
@ -1,14 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP version 5.3
|
||||
* MIT License
|
||||
*
|
||||
* Response from retailCRM API
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* @category RetailCrm
|
||||
* @package RetailCrm
|
||||
* @author RetailCrm <integration@retailcrm.ru>
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmApiResponse implements \ArrayAccess
|
||||
{
|
||||
@ -18,6 +43,9 @@ class RetailcrmApiResponse implements \ArrayAccess
|
||||
// response assoc array
|
||||
protected $response;
|
||||
|
||||
// raw response
|
||||
protected $rawResponse;
|
||||
|
||||
/**
|
||||
* ApiResponse constructor.
|
||||
*
|
||||
@ -29,6 +57,7 @@ class RetailcrmApiResponse implements \ArrayAccess
|
||||
public function __construct($statusCode, $responseBody = null)
|
||||
{
|
||||
$this->statusCode = (int) $statusCode;
|
||||
$this->rawResponse = $responseBody;
|
||||
|
||||
if (!empty($responseBody)) {
|
||||
$response = json_decode($responseBody, true);
|
||||
@ -44,6 +73,14 @@ class RetailcrmApiResponse implements \ArrayAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getRawResponse()
|
||||
{
|
||||
return $this->rawResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTTP response status code
|
||||
*
|
61
retailcrm/lib/RetailcrmHttpClient.php → retailcrm/lib/api/RetailcrmHttpClient.php
Executable file → Normal file
61
retailcrm/lib/RetailcrmHttpClient.php → retailcrm/lib/api/RetailcrmHttpClient.php
Executable file → Normal file
@ -1,14 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP version 5.3
|
||||
* MIT License
|
||||
*
|
||||
* HTTP client
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* @category RetailCrm
|
||||
* @package RetailCrm
|
||||
* @author RetailCrm <integration@retailcrm.ru>
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmHttpClient
|
||||
{
|
||||
@ -38,6 +63,16 @@ class RetailcrmHttpClient
|
||||
$this->defaultParameters = $defaultParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make HTTP request
|
||||
*
|
||||
@ -51,7 +86,7 @@ class RetailcrmHttpClient
|
||||
* @throws CurlException
|
||||
* @throws InvalidJsonException
|
||||
*
|
||||
* @return ApiResponse
|
||||
* @return RetailcrmApiResponse
|
||||
*/
|
||||
public function makeRequest(
|
||||
$path,
|
||||
@ -104,6 +139,16 @@ class RetailcrmHttpClient
|
||||
throw new CurlException($error, $errno);
|
||||
}
|
||||
|
||||
RetailcrmLogger::writeDebug(
|
||||
sprintf(
|
||||
'%s `%s`, status: %d',
|
||||
$method,
|
||||
$url,
|
||||
(int) $statusCode
|
||||
),
|
||||
self::METHOD_POST == $method ? ' POST fields: `' . print_r($parameters, true) . '`' : ''
|
||||
);
|
||||
|
||||
return new RetailcrmApiResponse($statusCode, $responseBody);
|
||||
}
|
||||
}
|
111
retailcrm/lib/api/RetailcrmProxy.php
Normal file
111
retailcrm/lib/api/RetailcrmProxy.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmProxy
|
||||
{
|
||||
private $api;
|
||||
private $log;
|
||||
|
||||
public function __construct($url, $key, $log)
|
||||
{
|
||||
$this->api = new RetailcrmApiClientV5($url, $key);
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces error array into string
|
||||
*
|
||||
* @param $errors
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
private static function reduceErrors($errors)
|
||||
{
|
||||
$reduced = '';
|
||||
|
||||
if (is_array($errors)) {
|
||||
foreach ($errors as $key => $error) {
|
||||
$reduced .= sprintf('%s => %s\n', $key, $error);
|
||||
}
|
||||
}
|
||||
|
||||
return $reduced;
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
$date = date('Y-m-d H:i:s');
|
||||
try {
|
||||
RetailcrmLogger::writeDebug($method, print_r($arguments, true));
|
||||
$response = call_user_func_array(array($this->api, $method), $arguments);
|
||||
|
||||
if (!($response instanceof RetailcrmApiResponse)) {
|
||||
RetailcrmLogger::writeDebug($method, $response);
|
||||
return $response;
|
||||
}
|
||||
|
||||
if (!$response->isSuccessful()) {
|
||||
RetailcrmLogger::writeCaller($method, $response->getErrorMsg());
|
||||
|
||||
if (isset($response['errors'])) {
|
||||
RetailcrmApiErrors::set($response['errors'], $response->getStatusCode());
|
||||
$error = static::reduceErrors($response['errors']);
|
||||
RetailcrmLogger::writeNoCaller($error);
|
||||
}
|
||||
|
||||
$response = false;
|
||||
} else {
|
||||
// Don't print long lists in debug logs (errors while calling this will be easy to detect anyway)
|
||||
if (in_array($method, array('statusesList', 'paymentTypesList', 'deliveryTypesList'))) {
|
||||
RetailcrmLogger::writeDebug($method, '[request was successful, but response is omitted]');
|
||||
} else {
|
||||
RetailcrmLogger::writeDebug($method, $response->getRawResponse());
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
} catch (CurlException $e) {
|
||||
RetailcrmLogger::writeCaller(get_class($this->api).'::'.$method, $e->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
|
||||
return false;
|
||||
} catch (InvalidJsonException $e) {
|
||||
RetailcrmLogger::writeCaller(get_class($this->api).'::'.$method, $e->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
8
retailcrm/lib/api/index.php
Normal file
8
retailcrm/lib/api/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
70
retailcrm/lib/events/RetailcrmAbandonedCartsEvent.php
Normal file
70
retailcrm/lib/events/RetailcrmAbandonedCartsEvent.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmAbandonedCartsEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$syncCartsActive = Configuration::get(RetailCRM::SYNC_CARTS_ACTIVE);
|
||||
if (empty($syncCartsActive)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$api = RetailcrmTools::getApiClient();
|
||||
|
||||
if (empty($api)) {
|
||||
RetailcrmLogger::writeCaller('abandonedCarts', 'set api key & url first');
|
||||
return;
|
||||
}
|
||||
|
||||
RetailcrmCartUploader::init();
|
||||
RetailcrmCartUploader::$api = $api;
|
||||
RetailcrmCartUploader::$paymentTypes = array_keys(json_decode(Configuration::get(RetailCRM::PAYMENT), true));
|
||||
RetailcrmCartUploader::$syncStatus = Configuration::get(RetailCRM::SYNC_CARTS_STATUS);
|
||||
RetailcrmCartUploader::setSyncDelay(Configuration::get(RetailCRM::SYNC_CARTS_DELAY));
|
||||
RetailcrmCartUploader::run();
|
||||
}
|
||||
}
|
||||
|
||||
$event = new RetailcrmAbandonedCartsEvent();
|
||||
$event->execute();
|
47
retailcrm/lib/events/RetailcrmEventInterface.php
Normal file
47
retailcrm/lib/events/RetailcrmEventInterface.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
interface RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* Execute event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function execute();
|
||||
}
|
108
retailcrm/lib/events/RetailcrmExportEvent.php
Normal file
108
retailcrm/lib/events/RetailcrmExportEvent.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmExportEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$api = RetailcrmTools::getApiClient();
|
||||
|
||||
if (empty($api)) {
|
||||
RetailcrmLogger::writeCaller('orderHistory', 'set api key & url first');
|
||||
exit();
|
||||
}
|
||||
|
||||
$orders = array();
|
||||
$orderRecords = Order::getOrdersWithInformations();
|
||||
$orderBuilder = new RetailcrmOrderBuilder();
|
||||
$orderBuilder->defaultLangFromConfiguration()->setApi($api);
|
||||
|
||||
foreach ($orderRecords as $record) {
|
||||
$order = new Order($record['id_order']);
|
||||
|
||||
$orderCart = new Cart($order->id_cart);
|
||||
$orderCustomer = new Customer($order->id_customer);
|
||||
|
||||
if (!empty($orderCustomer->id)) {
|
||||
$orderBuilder->setCmsCustomer($orderCustomer);
|
||||
} else {
|
||||
//TODO
|
||||
// Caused crash before because of empty RetailcrmOrderBuilder::cmsCustomer.
|
||||
// Current version *shouldn't* do this, but I suggest more tests for guest customers.
|
||||
$orderBuilder->setCmsCustomer(null);
|
||||
}
|
||||
|
||||
if (!empty($orderCart->id)) {
|
||||
$orderBuilder->setCmsCart($orderCart);
|
||||
} else {
|
||||
$orderBuilder->setCmsCart(null);
|
||||
}
|
||||
|
||||
$orderBuilder->setCmsOrder($order);
|
||||
|
||||
try {
|
||||
$orders[] = $orderBuilder->buildOrderWithPreparedCustomer();
|
||||
} catch (\InvalidArgumentException $exception) {
|
||||
RetailcrmLogger::writeCaller('export', $exception->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
|
||||
|
||||
if (PHP_SAPI == 'cli') {
|
||||
echo $exception->getMessage() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
time_nanosleep(0, 500000000);
|
||||
}
|
||||
|
||||
unset($orderRecords);
|
||||
|
||||
$orders = array_chunk($orders, 50);
|
||||
|
||||
foreach ($orders as $chunk) {
|
||||
$api->ordersUpload($chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$event = new RetailcrmExportEvent();
|
||||
$event->execute();
|
57
retailcrm/lib/events/RetailcrmIcmlEvent.php
Normal file
57
retailcrm/lib/events/RetailcrmIcmlEvent.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmIcmlEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$job = new RetailcrmCatalog();
|
||||
$data = $job->getData();
|
||||
|
||||
$icml = new RetailcrmIcml(Configuration::get('PS_SHOP_NAME'), _PS_ROOT_DIR_ . '/retailcrm.xml');
|
||||
$icml->generate($data[0], $data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$event = new RetailcrmIcmlEvent();
|
||||
$event->execute();
|
70
retailcrm/lib/events/RetailcrmInventoriesEvent.php
Normal file
70
retailcrm/lib/events/RetailcrmInventoriesEvent.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmInventoriesEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$apiUrl = Configuration::get(RetailCRM::API_URL);
|
||||
$apiKey = Configuration::get(RetailCRM::API_KEY);
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
RetailcrmInventories::$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
} else {
|
||||
RetailcrmLogger::writeCaller('inventories', 'set api key & url first');
|
||||
exit();
|
||||
}
|
||||
|
||||
RetailcrmInventories::loadStocks();
|
||||
}
|
||||
}
|
||||
|
||||
if (Configuration::get(RetailCRM::ENABLE_BALANCES_RECEIVING)) {
|
||||
$event = new RetailcrmInventoriesEvent();
|
||||
$event->execute();
|
||||
} else {
|
||||
RetailcrmLogger::writeDebug(
|
||||
'RetailcrmInventoriesEvent',
|
||||
'Balances receiving is not enabled, skipping...'
|
||||
);
|
||||
}
|
202
retailcrm/lib/events/RetailcrmMissingEvent.php
Normal file
202
retailcrm/lib/events/RetailcrmMissingEvent.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmMissingEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$shortopts = 'o:';
|
||||
$options = getopt($shortopts);
|
||||
|
||||
if (!isset($options['o'])) {
|
||||
echo ('Parameter -o is missing');
|
||||
exit();
|
||||
}
|
||||
|
||||
$apiUrl = Configuration::get(RetailCRM::API_URL);
|
||||
$apiKey = Configuration::get(RetailCRM::API_KEY);
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
} else {
|
||||
echo('Set api key & url first');
|
||||
exit();
|
||||
}
|
||||
|
||||
$delivery = json_decode(Configuration::get(RetailCRM::DELIVERY), true);
|
||||
$payment = json_decode(Configuration::get(RetailCRM::PAYMENT), true);
|
||||
$status = json_decode(Configuration::get(RetailCRM::STATUS), true);
|
||||
|
||||
$orderInstance = new Order($options['o']);
|
||||
|
||||
$order = array(
|
||||
'externalId' => $orderInstance->id,
|
||||
'createdAt' => $orderInstance->date_add,
|
||||
);
|
||||
|
||||
/**
|
||||
* Add order customer info
|
||||
*
|
||||
*/
|
||||
|
||||
if (!empty($orderInstance->id_customer)) {
|
||||
$orderCustomer = new Customer($orderInstance->id_customer);
|
||||
$customer = array(
|
||||
'externalId' => $orderCustomer->id,
|
||||
'firstName' => $orderCustomer->firstname,
|
||||
'lastname' => $orderCustomer->lastname,
|
||||
'email' => $orderCustomer->email,
|
||||
'createdAt' => $orderCustomer->date_add
|
||||
);
|
||||
|
||||
$response = $api->customersEdit($customer);
|
||||
|
||||
if ($response) {
|
||||
$order['customer']['externalId'] = $orderCustomer->id;
|
||||
$order['firstName'] = $orderCustomer->firstname;
|
||||
$order['lastName'] = $orderCustomer->lastname;
|
||||
$order['email'] = $orderCustomer->email;
|
||||
} else {
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add order status
|
||||
*
|
||||
*/
|
||||
|
||||
if ($orderInstance->current_state == 0) {
|
||||
$order['status'] = 'completed';
|
||||
} else {
|
||||
$order['status'] = array_key_exists($orderInstance->current_state, $status)
|
||||
? $status[$orderInstance->current_state]
|
||||
: 'completed'
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add order address data
|
||||
*
|
||||
*/
|
||||
|
||||
$cart = new Cart($orderInstance->getCartIdStatic($orderInstance->id));
|
||||
$addressCollection = $cart->getAddressCollection();
|
||||
$address = array_shift($addressCollection);
|
||||
|
||||
if ($address instanceof Address) {
|
||||
$phone = is_null($address->phone)
|
||||
? is_null($address->phone_mobile) ? '' : $address->phone_mobile
|
||||
: $address->phone
|
||||
;
|
||||
|
||||
$postcode = $address->postcode;
|
||||
$city = $address->city;
|
||||
$addres_line = sprintf("%s %s", $address->address1, $address->address2);
|
||||
}
|
||||
|
||||
if (!empty($postcode)) {
|
||||
$order['delivery']['address']['index'] = $postcode;
|
||||
}
|
||||
|
||||
if (!empty($city)) {
|
||||
$order['delivery']['address']['city'] = $city;
|
||||
}
|
||||
|
||||
if (!empty($addres_line)) {
|
||||
$order['delivery']['address']['text'] = $addres_line;
|
||||
}
|
||||
|
||||
if (!empty($phone)) {
|
||||
$order['phone'] = $phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add payment & shippment data
|
||||
*/
|
||||
|
||||
if (Module::getInstanceByName('advancedcheckout') === false) {
|
||||
$paymentType = $orderInstance->module;
|
||||
} else {
|
||||
$paymentType = $orderInstance->payment;
|
||||
}
|
||||
|
||||
if (array_key_exists($paymentType, $payment) && !empty($payment[$paymentType])) {
|
||||
$order['paymentType'] = $payment[$paymentType];
|
||||
}
|
||||
|
||||
if (array_key_exists($orderInstance->id_carrier, $delivery) && !empty($delivery[$orderInstance->id_carrier])) {
|
||||
$order['delivery']['code'] = $delivery[$orderInstance->id_carrier];
|
||||
}
|
||||
|
||||
if (isset($orderInstance->total_shipping_tax_incl) && (int) $orderInstance->total_shipping_tax_incl > 0) {
|
||||
$order['delivery']['cost'] = round($orderInstance->total_shipping_tax_incl, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add products
|
||||
*
|
||||
*/
|
||||
|
||||
$products = $orderInstance->getProducts();
|
||||
|
||||
foreach ($products as $product) {
|
||||
$item = array(
|
||||
//'productId' => $product['product_id'],
|
||||
'offer' => array('externalId' => $product['product_id']),
|
||||
'productName' => $product['product_name'],
|
||||
'quantity' => $product['product_quantity'],
|
||||
'initialPrice' => round($product['product_price'], 2),
|
||||
'purchasePrice' => round($product['purchase_supplier_price'], 2)
|
||||
);
|
||||
|
||||
$order['items'][] = $item;
|
||||
}
|
||||
|
||||
$api->ordersEdit($order);
|
||||
}
|
||||
}
|
||||
|
||||
$event = new RetailcrmMissingEvent();
|
||||
$event->execute();
|
73
retailcrm/lib/events/RetailcrmSyncEvent.php
Normal file
73
retailcrm/lib/events/RetailcrmSyncEvent.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../RetailcrmPrestashopLoader.php');
|
||||
|
||||
class RetailcrmSyncEvent implements RetailcrmEventInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$apiUrl = Configuration::get(RetailCRM::API_URL);
|
||||
$apiKey = Configuration::get(RetailCRM::API_KEY);
|
||||
RetailcrmHistory::$default_lang = (int) Configuration::get('PS_LANG_DEFAULT');
|
||||
|
||||
if (!empty($apiUrl) && !empty($apiKey)) {
|
||||
RetailcrmHistory::$api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log');
|
||||
} else {
|
||||
RetailcrmLogger::writeCaller('orderHistory', 'set api key & url first');
|
||||
exit();
|
||||
}
|
||||
|
||||
RetailcrmHistory::customersHistory();
|
||||
RetailcrmHistory::ordersHistory();
|
||||
}
|
||||
}
|
||||
|
||||
if (Configuration::get(RetailCRM::ENABLE_HISTORY_UPLOADS)) {
|
||||
$event = new RetailcrmSyncEvent();
|
||||
$event->execute();
|
||||
} else {
|
||||
RetailcrmLogger::writeDebug(
|
||||
'RetailcrmSyncEvent',
|
||||
'History uploads is not enabled, skipping...'
|
||||
);
|
||||
}
|
||||
|
8
retailcrm/lib/events/index.php
Normal file
8
retailcrm/lib/events/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
84
retailcrm/lib/exceptions/RetailcrmJobManagerException.php
Normal file
84
retailcrm/lib/exceptions/RetailcrmJobManagerException.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
class RetailcrmJobManagerException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var string $job
|
||||
*/
|
||||
private $job;
|
||||
|
||||
/**
|
||||
* @var array $jobs
|
||||
*/
|
||||
private $jobs;
|
||||
|
||||
/**
|
||||
* RetailcrmJobManagerException constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $job
|
||||
* @param array $jobs
|
||||
* @param int $code
|
||||
* @param \Exception|null $previous
|
||||
*
|
||||
*/
|
||||
public function __construct($message = "", $job = "", $jobs = array(), $code = 0, \Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
$this->job = $job;
|
||||
$this->jobs = $jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJob()
|
||||
{
|
||||
return $this->job;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJobs()
|
||||
{
|
||||
return $this->jobs;
|
||||
}
|
||||
}
|
8
retailcrm/lib/exceptions/index.php
Normal file
8
retailcrm/lib/exceptions/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
9
retailcrm/lib/index.php
Executable file → Normal file
9
retailcrm/lib/index.php
Executable file → Normal file
@ -1 +1,8 @@
|
||||
<?php // Silence is golden
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
||||
|
202
retailcrm/lib/templates/RetailcrmAbstractTemplate.php
Normal file
202
retailcrm/lib/templates/RetailcrmAbstractTemplate.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
abstract class RetailcrmAbstractTemplate
|
||||
{
|
||||
/** @var Module|\RetailCRM */
|
||||
protected $module;
|
||||
protected $smarty;
|
||||
protected $assets;
|
||||
|
||||
/** @var string */
|
||||
protected $template;
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/** @var array */
|
||||
private $errors;
|
||||
|
||||
/** @var array */
|
||||
private $warnings;
|
||||
|
||||
/** @var array */
|
||||
private $informations;
|
||||
|
||||
/** @var array */
|
||||
private $confirmations;
|
||||
|
||||
/** @var Context $context */
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* RetailcrmAbstractTemplate constructor.
|
||||
*
|
||||
* @param Module $module
|
||||
* @param $smarty
|
||||
* @param $assets
|
||||
*/
|
||||
public function __construct(Module $module, $smarty, $assets)
|
||||
{
|
||||
$this->module = $module;
|
||||
$this->smarty = $smarty;
|
||||
$this->assets = $assets;
|
||||
$this->errors = array();
|
||||
$this->warnings = array();
|
||||
$this->informations = array();
|
||||
$this->confirmations = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ISO code of current employee language or default language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCurrentLanguageISO()
|
||||
{
|
||||
$langId = 0;
|
||||
|
||||
global $cookie;
|
||||
|
||||
if (!empty($this->context) && !empty($this->context->employee)) {
|
||||
$langId = (int) $this->context->employee->id_lang;
|
||||
} elseif ($cookie instanceof Cookie) {
|
||||
$langId = (int) $cookie->id_lang;
|
||||
} else {
|
||||
$langId = (int) Configuration::get('PS_LANG_DEFAULT');
|
||||
}
|
||||
|
||||
return (string) Language::getIsoById($langId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function render($file)
|
||||
{
|
||||
$this->buildParams();
|
||||
$this->setTemplate();
|
||||
|
||||
if (null === $this->template) {
|
||||
throw new \RuntimeException("Template not be blank");
|
||||
}
|
||||
|
||||
$this->smarty->assign(\array_merge($this->data, array(
|
||||
'moduleErrors' => $this->errors,
|
||||
'moduleWarnings' => $this->warnings,
|
||||
'moduleConfirmations' => $this->confirmations,
|
||||
'moduleInfos' => $this->informations,
|
||||
)));
|
||||
|
||||
return $this->module->display($file, "views/templates/admin/$this->template");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $messages
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setErrors($messages)
|
||||
{
|
||||
if (!empty($messages)) {
|
||||
$this->errors = $messages;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $messages
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setWarnings($messages)
|
||||
{
|
||||
if (!empty($messages)) {
|
||||
$this->warnings = $messages;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $messages
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setInformations($messages)
|
||||
{
|
||||
if (!empty($messages)) {
|
||||
$this->informations = $messages;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $messages
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfirmations($messages)
|
||||
{
|
||||
if (!empty($messages)) {
|
||||
$this->confirmations = $messages;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setContext($context)
|
||||
{
|
||||
if (!empty($context)) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract protected function buildParams();
|
||||
abstract protected function setTemplate();
|
||||
}
|
77
retailcrm/lib/templates/RetailcrmBaseTemplate.php
Normal file
77
retailcrm/lib/templates/RetailcrmBaseTemplate.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmBaseTemplate extends RetailcrmAbstractTemplate
|
||||
{
|
||||
protected function buildParams()
|
||||
{
|
||||
switch ($this->getCurrentLanguageISO()) {
|
||||
case 'ru':
|
||||
$promoVideoUrl = 'VEatkEGJfGw';
|
||||
$registerUrl = 'https://retailcrm.ru/signup?utm_source=prestashop&utm_medium=modul&utm_campaign=button-in-modul';
|
||||
$supportEmail = 'support@retailcrm.ru';
|
||||
break;
|
||||
case 'es':
|
||||
$promoVideoUrl = 'LdJFoqOkLj8';
|
||||
$registerUrl = 'https://retailcrm.es/signup?utm_source=prestashop&utm_medium=modul&utm_campaign=button-in-modul';
|
||||
$supportEmail = 'support@retailcrm.es';
|
||||
break;
|
||||
default:
|
||||
$promoVideoUrl = 'wLjtULfZvOw';
|
||||
$registerUrl = 'https://retailcrm.pro/signup?utm_source=prestashop&utm_medium=modul&utm_campaign=button-in-modul';
|
||||
$supportEmail = 'support@retailcrm.pro';
|
||||
break;
|
||||
}
|
||||
|
||||
$this->data = array(
|
||||
'assets' => $this->assets,
|
||||
'apiUrl' => RetailCRM::API_URL,
|
||||
'apiKey' => RetailCRM::API_KEY,
|
||||
'promoVideoUrl' => $promoVideoUrl,
|
||||
'registerUrl' => $registerUrl,
|
||||
'supportEmail' => $supportEmail
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set template data
|
||||
*/
|
||||
protected function setTemplate()
|
||||
{
|
||||
$this->template = "index.tpl";
|
||||
}
|
||||
}
|
102
retailcrm/lib/templates/RetailcrmSettingsTemplate.php
Normal file
102
retailcrm/lib/templates/RetailcrmSettingsTemplate.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmSettingsTemplate extends RetailcrmAbstractTemplate
|
||||
{
|
||||
protected $settings;
|
||||
protected $settingsNames;
|
||||
|
||||
/**
|
||||
* RetailcrmSettingsTemplate constructor.
|
||||
*
|
||||
* @param \Module $module
|
||||
* @param $smarty
|
||||
* @param $assets
|
||||
* @param $settings
|
||||
* @param $settingsNames
|
||||
*/
|
||||
public function __construct(Module $module, $smarty, $assets, $settings, $settingsNames)
|
||||
{
|
||||
parent::__construct($module, $smarty, $assets);
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->settingsNames = $settingsNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build params for template
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getParams()
|
||||
{
|
||||
$params = array();
|
||||
|
||||
if ($this->module->api) {
|
||||
$params['statusesDefaultExport'] = $this->module->reference->getStatuseDefaultExport();
|
||||
$params['deliveryTypes'] = $this->module->reference->getDeliveryTypes();
|
||||
$params['orderStatuses'] = $this->module->reference->getStatuses();
|
||||
$params['paymentTypes'] = $this->module->reference->getPaymentTypes();
|
||||
$params['methodsForDefault'] = $this->module->reference->getPaymentAndDeliveryForDefault(
|
||||
array($this->module->translate('Delivery method'), $this->module->translate('Payment type'))
|
||||
);
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
protected function buildParams()
|
||||
{
|
||||
$this->data = array_merge(
|
||||
array(
|
||||
'assets' => $this->assets,
|
||||
'cartsDelays' => $this->module->getSynchronizedCartsTimeSelect(),
|
||||
),
|
||||
$this->getParams(),
|
||||
$this->settingsNames,
|
||||
$this->settings
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set template data
|
||||
*/
|
||||
protected function setTemplate()
|
||||
{
|
||||
$this->template = "settings.tpl";
|
||||
}
|
||||
}
|
70
retailcrm/lib/templates/RetailcrmTemplateFactory.php
Normal file
70
retailcrm/lib/templates/RetailcrmTemplateFactory.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
class RetailcrmTemplateFactory
|
||||
{
|
||||
private $assets;
|
||||
private $smarty;
|
||||
|
||||
/**
|
||||
* RetailcrmTemplateFactory constructor.
|
||||
*
|
||||
* @param $smarty
|
||||
* @param $assets
|
||||
*/
|
||||
public function __construct($smarty, $assets)
|
||||
{
|
||||
$this->smarty = $smarty;
|
||||
$this->assets = $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Module $module
|
||||
*
|
||||
* @return RetailcrmAbstractTemplate
|
||||
*/
|
||||
public function createTemplate(Module $module)
|
||||
{
|
||||
$settings = RetailCRM::getSettings();
|
||||
|
||||
if (empty($settings['url']) && empty($settings['apiKey'])) {
|
||||
return new RetailcrmBaseTemplate($module, $this->smarty, $this->assets);
|
||||
} else {
|
||||
return new RetailcrmSettingsTemplate($module, $this->smarty, $this->assets, $settings, RetailCRM::getSettingsNames());
|
||||
}
|
||||
}
|
||||
}
|
8
retailcrm/lib/templates/index.php
Normal file
8
retailcrm/lib/templates/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
0
retailcrm/logo.gif
Executable file → Normal file
0
retailcrm/logo.gif
Executable file → Normal file
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 306 B |
0
retailcrm/logo.png
Executable file → Normal file
0
retailcrm/logo.png
Executable file → Normal file
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
14
retailcrm/objects.xml
Executable file → Normal file
14
retailcrm/objects.xml
Executable file → Normal file
@ -15,6 +15,20 @@
|
||||
<field id="personal_discount" group="customer">personalDiscount</field>
|
||||
<field id="discount_card_number" group="customer">discountCardNumber</field>
|
||||
|
||||
<field id="id" group="customerCorporate">id</field>
|
||||
<field id="external_id" group="customerCorporate">externalId</field>
|
||||
<field id="nick_name" group="customerCorporate">nickName</field>
|
||||
<field id="vip" group="customerCorporate">vip</field>
|
||||
<field id="bad" group="customerCorporate">bad</field>
|
||||
<field id="custom_fields" group="customerCorporate">customFields</field>
|
||||
<field id="personal_discount" group="customerCorporate">personalDiscount</field>
|
||||
<field id="discount_card_number" group="customerCorporate">discountCardNumber</field>
|
||||
<field id="manager" group="customerCorporate">manager</field>
|
||||
<field id="address" group="customerCorporate">address</field>
|
||||
<field id="main_contact" group="customerCorporate">mainCustomerContact</field>
|
||||
<field id="company.contragent.i_n_n" group="customerCorporate">companyInn</field>
|
||||
<field id="main_company" group="customerCorporate">company</field>
|
||||
|
||||
<field id="address.index" group="customerAddress">index</field>
|
||||
<field id="address.country" group="customerAddress">country</field>
|
||||
<field id="address.region" group="customerAddress">region</field>
|
||||
|
1
retailcrm/public/css/.gitignore
vendored
1
retailcrm/public/css/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.min.css
|
@ -1,29 +0,0 @@
|
||||
#retailcrm-loading-fade {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
opacity: .5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
|
||||
#retailcrm-loader {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 10px solid white;
|
||||
animation: retailcrm-loader 2s linear infinite;
|
||||
border-top: 10px solid #0c0c0c;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@keyframes retailcrm-loader {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
1
retailcrm/public/js/.gitignore
vendored
1
retailcrm/public/js/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.min.js
|
@ -1,6 +0,0 @@
|
||||
(function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/modules/retailcrm/job/jobs.php', true);
|
||||
xhr.timeout = 0;
|
||||
xhr.send(null);
|
||||
})();
|
@ -1,66 +0,0 @@
|
||||
$(function(){
|
||||
function RetailcrmUploadForm() {
|
||||
this.form = $('input[value="retailcrm_upload_form"]').parent().get(0);
|
||||
|
||||
if (typeof this.form === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.input = $(this.form).find('input[name="RETAILCRM_UPLOAD_ORDERS_ID"]').get(0);
|
||||
this.submitButton = $(this.form).find('button[type="submit"]').get(0);
|
||||
this.messageContainer = document.querySelector('#content > div.bootstrap + div.bootstrap');
|
||||
this.submitAction = this.submitAction.bind(this);
|
||||
this.partitionId = this.partitionId.bind(this);
|
||||
this.setLoading = this.setLoading.bind(this);
|
||||
|
||||
$(this.submitButton).click(this.submitAction);
|
||||
}
|
||||
|
||||
RetailcrmUploadForm.prototype.submitAction = function (event) {
|
||||
event.preventDefault();
|
||||
let ids = this.partitionId($(this.input).val().toString().replace(/\s+/g, ''));
|
||||
|
||||
if (ids.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setLoading(true);
|
||||
$(this.form).submit();
|
||||
}
|
||||
|
||||
RetailcrmUploadForm.prototype.setLoading = function (loading) {
|
||||
let indicator = $('div#retailcrm-loading-fade');
|
||||
|
||||
if (indicator.length === 0) {
|
||||
$('body').append(`
|
||||
<div id="retailcrm-loading-fade">
|
||||
<div id="retailcrm-loader"></div>
|
||||
</div>
|
||||
`.trim());
|
||||
}
|
||||
|
||||
indicator.css('visibility', (loading ? 'visible' : 'hidden'));
|
||||
}
|
||||
|
||||
RetailcrmUploadForm.prototype.partitionId = function (idList) {
|
||||
if (idList === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
let itemsList = idList.split(',');
|
||||
let ids = itemsList.filter(item => item.toString().indexOf('-') === -1);
|
||||
let ranges = itemsList.filter(item => item.toString().indexOf('-') !== -1);
|
||||
let resultRanges = [];
|
||||
|
||||
ranges.forEach(item => {
|
||||
let rangeData = item.split('-');
|
||||
|
||||
resultRanges = [...resultRanges, ...[...Array(+rangeData[1] + 1)
|
||||
.keys()].slice(+rangeData[0], +rangeData[1] + 1)];
|
||||
});
|
||||
|
||||
return [...ids, ...resultRanges].map(item => +item).sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
new RetailcrmUploadForm();
|
||||
});
|
2073
retailcrm/retailcrm.php
Executable file → Normal file
2073
retailcrm/retailcrm.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
213
retailcrm/translations/es.php
Executable file → Normal file
213
retailcrm/translations/es.php
Executable file → Normal file
@ -2,71 +2,17 @@
|
||||
|
||||
global $_MODULE;
|
||||
$_MODULE = array();
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7d1d9327371097419bdf83ffa671d2f2'] = 'Versión de la API';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_463dc31aa1a0b6e871b1a9fed8e9860a'] = 'retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_30de6237576b9a24f6fc599c22a35a4b'] = 'El módulo de integración con retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b0edd77b179acca4cb3572c4393db254'] = 'retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4aa0e53499eeb8383a6330c96b9ed7c3'] = 'Módulo de integración para retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_876f23178c29dc2552c0b48bf23cd9bd'] = '¿Está seguro de que desea eliminar el módulo?';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6bd461d1fc51b3294c6513cecc24758d'] = 'Los pedidos han sido cargados con éxito';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9a7fc06b4b2359f1f26f75fbbe27a3e8'] = 'No todos los pedidos se han cargado con existo';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9b2d9f66d0112f3aae7dbdbd4e22a43'] = 'La dirección del CRM es incorrecta o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_942010ef43f3fec28741f62a0d9ff29c'] = 'La clave CRM es incorrecta o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_fba05687b61bc936d1a9a92371ba8bcf'] = '¡Atención! La zona horaria de CRM debe coincidir con la zona horaria de la tienda, la configuración de la zona horaria de CRM se puede establecer en:';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_5effd5157947e8ba4a08883f198b2e31'] = 'La dirección del CRM no es válida o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_576300f5b6faeb746bb6d034d98e7afd'] = 'La clave de API no es válida o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c888438d14855d7d96a2724ee9c306bd'] = 'Los ajustes están actualizados';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_51af428aa0dcceb5230acb267ecb91c5'] = 'La configuración de la conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4cbd5dbeeef7392e50358b1bc00dd592'] = 'URL CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7f775042e08eddee6bbfd8fbe0add4a3'] = 'La clave API';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a13367a8e2a3f3bf4f3409079e3fdf87'] = 'Active';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f75d8fa5c89351544d372cf90528ccf2'] = 'Clave de la página web';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_065ab3a28ca4f16f55f103adc7d0226f'] = 'Los métodos del envío';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_33af8066d3c83110d4bd897f687cedd2'] = 'Los estados de pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bab959acc06bb03897b294fbb892be6b'] = 'Los métodos de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6310f29293c902c64db619c29179d99a'] = 'Los método de envío';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4dbcb38bbbff5d4a402f2575c57a35e6'] = 'El tipo de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dd7bf230fde8d4836917806aff6a6b27'] = 'Dirección';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_630f6dc397fe74e52d5189e2c80f282b'] = 'Volver a la lista';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_5c1cf6cfec2dad86c8ca5286a0294516'] = 'Nombre';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c695cfe527a6fcd680114851b86b7555'] = 'Apellido';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f9dd946cc89c1f3b41a0edbe0f36931d'] = 'Teléfono';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_61a649a33f2869e5e35fbb7aff3a80d9'] = 'Email';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_2664f03ac6b8bb9eee4287720e407db3'] = 'Dirección';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6ddc09dc456001d9854e9fe670374eb2'] = 'País';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_69aede266809f89b89fe70681f6a129f'] = 'Provincia/Región/República';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_859214628431995197c0558f7b5f8ffc'] = 'Ciudad';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4348f938bbddd8475e967ccb47ecb234'] = 'Código Postal';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_78fce82336bbbdca7f6da7564b8f9325'] = 'Calle';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_71a6834884666147c0334f0c40bc7295'] = 'Casa/Edificio';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f88a77e3d68d251c3dc4008c327b5a0c'] = 'Piso';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d977f846d110fcb7f71c6f97330c9d10'] = 'Número del piso y la letra';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_56c1e354d36beb85b0d881c5b2e24cbe'] = 'Planta';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4d34f53389ed7f28ca91fc31ea360a66'] = 'Bloque';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_49354b452ec305136a56fe7731834156'] = 'Casa/Edificio';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_04176f095283bc729f1e3926967e7034'] = 'Nombre';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dff4bf10409100d989495c6d5486035e'] = 'Apellido';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1c76cbfe21c6f44c1d1e59d54f3e4420'] = 'Empresa';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1aadcc03a9dbba84a3c5a5cbfde8a162'] = 'NIF';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_93d03fe37ab3c6abc2a19dd8e41543bd'] = 'Línea de dirección 1';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_22fcffe02ab9eda5b769387122f2ddce'] = 'Línea de dirección 2';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_8bcdc441379cbf584638b0589a3f9adb'] = 'Código Postal';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_57d056ed0984166336b7879c2af3657f'] = 'Ciudad';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bcc254b55c4a1babdf1dcb82c207506b'] = 'Teléfono';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f0e1fc6f97d36cb80f29196e2662ffde'] = 'Teléfono móvil';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7a1920d61156abc05a60135aefe8bc67'] = 'Por defecto';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_cc18dd262eff97c4dd4b56f750896adb'] = 'Estado predeterminado';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a33b96f0ce0f1227132f1cb3cf1c9e88'] = 'Estado del pedido al exportar por lotes';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1bd340aeb42a5ee0318784c2cffed8a9'] = 'La versión seleccionada de la API no está disponible';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c2784d9473fed62ae67fe8597011166a'] = 'Exportación manual de los pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Identificador del pedido';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_91412465ea9169dfd901dd5e7c96dd99'] = 'Exportar';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6bd461d1fc51b3294c6513cecc24758d'] = 'Los pedidos han sido cargados con éxito';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_3518f7b8d79f91da4c91772b4c46db94'] = 'No se han podido cargar algunos pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9a7fc06b4b2359f1f26f75fbbe27a3e8'] = 'No todos los pedidos se han cargado con existo';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_917afe348e09163269225a89a825e634'] = 'Sincronización de carritos de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Crear pedidos para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_35b5a9139a54caeb925556ceb2c38086'] = 'Estado del pedido para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9c4e8fe56eabcc4c7913ebb2f8eb388'] = 'Estado del pedido para carritos abandonados no debe ser utilizado en otros ajustes';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a0d135501a738c3c98de385dc28cda61'] = 'Cargar carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a52213fa61ecf700d1a6091d9769c9a8'] = 'Los tipos de entrega no deben repetirse en la matriz de entrega';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f08acd4b354f4d5f4e531ca1972e4504'] = 'Los tipos de pago no deben repetirse en la matriz de pagos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_fd83e0ccb3e6312a62f888dd496dd0a5'] = 'Instantáneamente';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6c70ac5cc9fe8dff4f3bfe765dfe8798'] = 'Tras 1 minuto';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_be76333ef50b23b6337d263fc87fe11a'] = 'Tras 5 minutos';
|
||||
@ -74,4 +20,149 @@ $_MODULE['<{retailcrm}prestashop>retailcrm_6e74495fad332de9a8207b5416de3cce'] =
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d5bb7c2cb1565fb1568924b01847b330'] = 'Tras 15 minutos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9d3095e54f694bb41ef4a3e62ed90e7a'] = 'Tras 30 minutos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dfb403fd86851c7d9f97706dff5a2327'] = 'Tras 45 minutos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4b5e6470d5d85448fcd89c828352d25e'] = 'Tras 1 hora';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4b5e6470d5d85448fcd89c828352d25e'] = 'Tras 1 hora';
|
||||
$_MODULE['<{retailcrm}prestashop>index_acbcb05077815fe6e9a7620b1d952462'] = 'retailCRM es un servicio para tiendas online, el cual ayuda a dejar de perder pedidos y así mejorar las ganancias de tu comercio online en todas las etapas del embudo de ventas. ';
|
||||
$_MODULE['<{retailcrm}prestashop>index_09fe407e2337c1120980a2b4ee72ac6e'] = 'Tengo una cuenta en retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e81c4e4f2b7b93b481e13a8553c2ae1b'] = 'o';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7a0a77aaf1bdd053fca69fa882c87df0'] = 'Obtenga retailCRM gratis';
|
||||
$_MODULE['<{retailcrm}prestashop>index_061b368c43f85d3fe2c7ccc842883a40'] = 'Configuración de la conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>index_86ee1fa7924a67e54ac66e11c214e674'] = 'URL de retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_656a6828d7ef1bb791e42087c4b5ee6e'] = 'Accesos API retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
|
||||
$_MODULE['<{retailcrm}prestashop>index_b5a7adde1af5c87d7fd797b6245c2a39'] = 'Descripción';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9aa698f602b1e5694855cee73a683488'] = 'Contactos';
|
||||
$_MODULE['<{retailcrm}prestashop>index_764fa884e3fba8a3f40422aa1eadde23'] = 'Deja de perder pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>index_070f41773a46ce08231e11316603a099'] = 'Livechat es una forma activa de incitar al diálogo que inmediatamente te ayuda a recibir más pedidos en la tienda online.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_87ef6941837db5b2370eb2c04a2f9e73'] = 'Chatbot, Facebook Messenger y WhatsApp en una misma ventana, te ayudan a no perder leads “frescos” que están a punto de hacer su pedido.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_0e307da9d0c9ee16b47ef71c39f236a3'] = 'Emails de bienvenida te ayudarán a motivar a los clientes a realizar su primer pedido.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e83c1eb5df794bf22e69eb893e80fdd6'] = 'Motivar a concretar la compra';
|
||||
$_MODULE['<{retailcrm}prestashop>index_456329795d41ba012fc4fb3ed063d1fe'] = 'Upsells es la mejor opción para mejorar el ticket medio de manera automática.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4ab044d4168a44dbe50ecc01181e81ad'] = 'La gestión de carritos abandonados incrementa la cantidad de pedidos completados en la tienda online.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_0f93ca5bf76e978aa9162e7fc53897ea'] = 'Gestiona los pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3efd2720a5c93a8fe785084d925024ce'] = 'Con ayuda del CRM podrás recibir pedidos, distribuirlos entre tus empleados, controlar los estados y cerrarlos.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_8823fb21e79cd316df376e80bb635329'] = 'Las notificaciones sobre el cambio de estado de cada pedido te ayuda a mantener a los clientes informados sobre sus pedidos.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2280ad04ce9fc872f86e839265f170a2'] = 'SalesApp es una aplicación para puntos de venta, la cual te ayudará a mejorar las ventas offline y a crear una base de clientes en un mismo sistema.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9f1ddb1081aee21a39383a5be24e6c78'] = 'La integración con el catálogo permite controlar el stock de tus productos, los precios y sus movimientos.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_94d467d04e7d7b0c92df78f3de00fb20'] = 'Retén a tus actuales clientes';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7f5875d2c134ba80d0ae9a5b51b2a805'] = 'CDP (Customer Data Platform) agrupa toda la información de tus clientes desde distintos canales y crea un perfil 360° de cada uno de ellos.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2708fc15917156fafb712217dcebdab5'] = 'La segmentación de la base de clientes te ayuda a hacer la comunicación con tus clientes más relevante y precisa.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d2d8dd2103f64290845f5635ce185270'] = 'Las campañas de mailing, SMS, WhatsApp y Facebook Messenger incrementarán la frecuencia de compra de tus clientes actuales.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_b0e12648f812bedb79fe86c8f66cec8a'] = 'La regla “Productos de consumo regular” te ayuda a recordarle a tus clientes para que vuelvan a hacer la compra antes de que se les agoten sus productos.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_02f67e7fb237e6fa9eb746fa0f721e96'] = 'Reanima a clientes inactivos';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d5eb65bf655de38d7ac070bfdc328a74'] = 'Con ayuda de retargeting en el CRM podrás iniciar campañas utilizando los segmentos de tu base de clientes.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9f8f75ffd4d9e4f326576dfdc5570739'] = 'Las visitas con abandono te permiten registrar los productos que el cliente estaba viendo, así podrás proponerle completar su pedido.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_f78799eda5746aebce16dfbc6c824b71'] = 'Las campañas para reactivar clientes te ayudarán a recuperar a aquellos que se habían perdido y así lograr que vuelvan a tu tienda online.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3b863a2b271ee8ebcceb0e79c51711b7'] = 'retailCRM mejorará la efectividad de todos tus canales de marketing';
|
||||
$_MODULE['<{retailcrm}prestashop>index_17b39a0118f63cf041abfb9d92d12414'] = 'LiveChat';
|
||||
$_MODULE['<{retailcrm}prestashop>index_ce8ae9da5b7cd6c3df2929543a9af92d'] = 'Email';
|
||||
$_MODULE['<{retailcrm}prestashop>index_31f803c0e3b881bf2fc62b248c8aaace'] = 'Facebook Messenger';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4cecb21b44628b17c436739bf6301af2'] = 'SMS';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2ca3885b024c5983c60a69c6af0ecd28'] = 'Retargeting';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9d4f613c288a9cf21d59cc45f1d3dc2c'] = '¿Hay un trial del módulo?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4427ea757e4bf7ccea501cef064fdeaa'] = 'El módulo cuenta con una versión trial de 14 días en los cuales podrás trabajar con ayuda del módulo de retailCRM.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3b15dabe24b3ea13a55b08ca7abf1a94'] = '¿Qué es un usuario?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e4ed8cbeb5e181f15ad0192772ef76dd'] = 'Un usuario es la persona que trabajará con el módulo de retailCRM es como el representante de tu negocio o tu web. Cada usuario puede crear un perfil personal y tener su propio acceso al panel de la herramienta.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_65991f2dd292e02d64d248906dfe0f40'] = '¿En qué idiomas está disponible el módulo?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_fa224ef4c21784276945b35acdfe5605'] = 'El módulo de retailCRM está disponible en los siguientes idiomas:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_cb5480c32e71778852b08ae1e8712775'] = 'Español';
|
||||
$_MODULE['<{retailcrm}prestashop>index_78463a384a5aa4fad5fa73e2f506ecfc'] = 'Inglés';
|
||||
$_MODULE['<{retailcrm}prestashop>index_deba6920e70615401385fe1fb5a379ec'] = 'Ruso';
|
||||
$_MODULE['<{retailcrm}prestashop>index_59064b34ae482528c8dbeb1b0214ee12'] = '¿Cuánto tiempo dura el trial?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_26a6451f37fce97782d596fe7373e834'] = 'El tiempo de duración de la versión trial del módulo de retailCRM es de 14 días.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d8ff508a2fce371d8c36bd2bedbaecf6'] = '¿Se paga por usuario o se paga por cuenta?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_5e2c0f6429d1304965531a63cf35dfd7'] = 'El pago se realiza por usuario, si se agrega a otro usuario dentro del sistema de retailCRM se realizaría el pago por dos usuarios. Cada usuario tiene derecho a una cuenta (web-chat y redes sociales). En caso de que un usuario necesite trabajar con más de una cuenta, es necesario ponerse en contacto con el equipo de retailCRM.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_a833bd40df33cff491112eb9316fb050'] = '¿Cómo puedo realizar el pago?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4889fefd090fe608a9b5403d02e2e97f'] = 'Los métodos para realizar el pago son:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_95428f32e5c696cf71baccb776bc5c15'] = 'Transferencia bancaria';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e7f9e382dc50889098cbe56f2554c77b'] = 'Tarjeta bancaria';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7088f1d1d9c91d8b75e9882ffd78540c'] = 'Datos de contacto';
|
||||
$_MODULE['<{retailcrm}prestashop>index_50f158e2507321f1a5b6f8fb9e350818'] = 'Escríbenos en caso de preguntas o dudas';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c2cc7082a89c1ad6631a2f66af5f00c0'] = 'Conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_6bcde6286f8d1b76063ee52104a240cf'] = 'Carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_065ab3a28ca4f16f55f103adc7d0226f'] = 'Los métodos del envío';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_33af8066d3c83110d4bd897f687cedd2'] = 'Los estados de pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_bab959acc06bb03897b294fbb892be6b'] = 'Los métodos de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7a1920d61156abc05a60135aefe8bc67'] = 'Por defecto';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_20cacc01d0de8bc6e9c9846f477e886b'] = 'Subir pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_71098155ccc0a0d6e0b501fbee37e7a9'] = 'LiveChat';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_061b368c43f85d3fe2c7ccc842883a40'] = 'La configuración de la conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_86ee1fa7924a67e54ac66e11c214e674'] = 'retailCRM URL';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_656a6828d7ef1bb791e42087c4b5ee6e'] = 'API key';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_f8d7c52aa84f358caedb96fda86809da'] = 'Permitir el soporte a clientes corporativos';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4d3d769b812b6faa6b76e1a8abaece2d'] = 'Active';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_f75d8fa5c89351544d372cf90528ccf2'] = 'Clave de la página web';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_917afe348e09163269225a89a825e634'] = 'Sincronización de carritos de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Crear pedidos para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_35b5a9139a54caeb925556ceb2c38086'] = 'Estado del pedido para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_9b9cf9f8778f69b4c6cf37e66f886be8'] = 'Elige el estado';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_a0d135501a738c3c98de385dc28cda61'] = 'Cargar carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_27096e1243f98e1b3300f57ff1c76456'] = 'Elige la demora';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_5b385947acf10ac0c5521161ce96aaa7'] = 'Elige la entrega';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7dcc1208fa03381346955c6732d9ea85'] = 'Elige el tipo';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Identificador del pedido';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_91412465ea9169dfd901dd5e7c96dd99'] = 'Exportar';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4f18e3f1c9941a6ec5a38bc716c521b4'] = 'Código que necesita insertar en la web';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c888438d14855d7d96a2724ee9c306bd'] = 'Los ajustes están actualizados';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_51af428aa0dcceb5230acb267ecb91c5'] = 'La configuración de la conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7d1d9327371097419bdf83ffa671d2f2'] = 'Versión de la API';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4cbd5dbeeef7392e50358b1bc00dd592'] = 'URL CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7f775042e08eddee6bbfd8fbe0add4a3'] = 'La clave API';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a13367a8e2a3f3bf4f3409079e3fdf87'] = 'Active';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f75d8fa5c89351544d372cf90528ccf2'] = 'Clave de la página web';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_917afe348e09163269225a89a825e634'] = 'Sincronización de carritos de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Crear pedidos para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_35b5a9139a54caeb925556ceb2c38086'] = 'Estado del pedido para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a0d135501a738c3c98de385dc28cda61'] = 'Cargar carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_065ab3a28ca4f16f55f103adc7d0226f'] = 'Los métodos del envío';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_33af8066d3c83110d4bd897f687cedd2'] = 'Los estados de pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bab959acc06bb03897b294fbb892be6b'] = 'Los métodos de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7a1920d61156abc05a60135aefe8bc67'] = 'Por defecto';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6310f29293c902c64db619c29179d99a'] = 'Los método de envío';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4dbcb38bbbff5d4a402f2575c57a35e6'] = 'El tipo de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_cc18dd262eff97c4dd4b56f750896adb'] = 'Estado predeterminado';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a33b96f0ce0f1227132f1cb3cf1c9e88'] = 'Estado del pedido al exportar por lotes';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_630f6dc397fe74e52d5189e2c80f282b'] = 'Volver a la lista';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c2784d9473fed62ae67fe8597011166a'] = 'Exportación manual de los pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Identificador del pedido';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_91412465ea9169dfd901dd5e7c96dd99'] = 'Exportar';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9b2d9f66d0112f3aae7dbdbd4e22a43'] = 'La dirección del CRM es incorrecta o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_942010ef43f3fec28741f62a0d9ff29c'] = 'La clave CRM es incorrecta o está vacía';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1bd340aeb42a5ee0318784c2cffed8a9'] = 'La versión seleccionada de la API no está disponible';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9c4e8fe56eabcc4c7913ebb2f8eb388'] = 'Estado del pedido para carritos abandonados no debe ser utilizado en otros ajustes';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c2cc7082a89c1ad6631a2f66af5f00c0'] = 'Conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_6bcde6286f8d1b76063ee52104a240cf'] = 'Carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_065ab3a28ca4f16f55f103adc7d0226f'] = 'Los métodos del envío';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_33af8066d3c83110d4bd897f687cedd2'] = 'Los estados de pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_bab959acc06bb03897b294fbb892be6b'] = 'Los métodos de pago';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7a1920d61156abc05a60135aefe8bc67'] = 'Por defecto';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_061b368c43f85d3fe2c7ccc842883a40'] = 'La configuración de la conexión';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_86ee1fa7924a67e54ac66e11c214e674'] = 'retailCRM URL';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_656a6828d7ef1bb791e42087c4b5ee6e'] = 'API key';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4d3d769b812b6faa6b76e1a8abaece2d'] = 'Active';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_f75d8fa5c89351544d372cf90528ccf2'] = 'Clave de la página web';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_917afe348e09163269225a89a825e634'] = 'Sincronización de carritos de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Crear pedidos para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_35b5a9139a54caeb925556ceb2c38086'] = 'Estado del pedido para carritos abandonados de compradores';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_a0d135501a738c3c98de385dc28cda61'] = 'Cargar carritos abandonados';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Identificador del pedido';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_91412465ea9169dfd901dd5e7c96dd99'] = 'Exportar';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4aa0e53499eeb8383a6330c96b9ed7c3'] = 'Módulo de integración para retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_20cacc01d0de8bc6e9c9846f477e886b'] = 'Subir pedidos';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_71098155ccc0a0d6e0b501fbee37e7a9'] = 'LiveChat';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_9b9cf9f8778f69b4c6cf37e66f886be8'] = 'Elige el estado';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_27096e1243f98e1b3300f57ff1c76456'] = 'Elige la demora';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_5b385947acf10ac0c5521161ce96aaa7'] = 'Elige la entrega';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7dcc1208fa03381346955c6732d9ea85'] = 'Elige el tipo';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4f18e3f1c9941a6ec5a38bc716c521b4'] = 'Código que necesita insertar en la web';
|
||||
$_MODULE['<{retailcrm}prestashop>index_84cff42a89e3866f0ed4f2979d340895'] = 'Solución para convertir más oportunidades de venta a través del chat web y Facebook Messenger, disponible 24/7, incluso cuando no estás en línea.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_50f158e2507321f1a5b6f8fb9e350818'] = 'Escríbenos en caso de preguntas o dudas';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_39e90036af004a005ccbccbe9a9c19c2'] = 'Los estados de orden no deben repetirse en la matriz de estados';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_8ffa3281a35a0d80fef2cac0fa680523'] = 'Habilitar la carga del historial';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_80e47b10a89a3f22e0def96577ee8b25'] = 'Recibir las existencias del retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7d320ac32b103449d18b51f47e7b1329'] = 'Activar solo si está habilitada la opción \"Clientes corporativos\" en retailCRM';
|
||||
|
0
retailcrm/translations/index.php
Executable file → Normal file
0
retailcrm/translations/index.php
Executable file → Normal file
170
retailcrm/translations/ru.php
Executable file → Normal file
170
retailcrm/translations/ru.php
Executable file → Normal file
@ -2,71 +2,17 @@
|
||||
|
||||
global $_MODULE;
|
||||
$_MODULE = array();
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7d1d9327371097419bdf83ffa671d2f2'] = 'Версия API';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_463dc31aa1a0b6e871b1a9fed8e9860a'] = 'RetailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_30de6237576b9a24f6fc599c22a35a4b'] = 'Модуль интеграции с RetailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b0edd77b179acca4cb3572c4393db254'] = 'retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4aa0e53499eeb8383a6330c96b9ed7c3'] = 'Интеграционный модуль для retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_876f23178c29dc2552c0b48bf23cd9bd'] = 'Вы уверены, что хотите удалить модуль?';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6bd461d1fc51b3294c6513cecc24758d'] = 'Все заказы успешно загружены';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9a7fc06b4b2359f1f26f75fbbe27a3e8'] = 'Не все заказы загружены успешно';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9b2d9f66d0112f3aae7dbdbd4e22a43'] = 'Некорректный или пустой адрес CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_942010ef43f3fec28741f62a0d9ff29c'] = 'Некорректный или пустой ключ CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_fba05687b61bc936d1a9a92371ba8bcf'] = 'Внимание! Часовой пояс в CRM должен совпадать с часовым поясом в магазине, настроки часового пояса CRM можно задать по адресу:';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_5effd5157947e8ba4a08883f198b2e31'] = 'Неверный или пустой адрес CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_576300f5b6faeb746bb6d034d98e7afd'] = 'Неверный или пустой API ключ';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c888438d14855d7d96a2724ee9c306bd'] = 'Настройки обновлены';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_51af428aa0dcceb5230acb267ecb91c5'] = 'Настройка соединения';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4cbd5dbeeef7392e50358b1bc00dd592'] = 'URL адрес CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7f775042e08eddee6bbfd8fbe0add4a3'] = 'API ключ';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a13367a8e2a3f3bf4f3409079e3fdf87'] = 'Активировать';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f75d8fa5c89351544d372cf90528ccf2'] = 'Ключ сайта';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c9cc8cce247e49bae79f15173ce97354'] = 'Сохранить';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_065ab3a28ca4f16f55f103adc7d0226f'] = 'Способы доставки';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_33af8066d3c83110d4bd897f687cedd2'] = 'Статусы заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bab959acc06bb03897b294fbb892be6b'] = 'Способы оплаты';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6310f29293c902c64db619c29179d99a'] = 'Способ доставки';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4dbcb38bbbff5d4a402f2575c57a35e6'] = 'Тип оплаты';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dd7bf230fde8d4836917806aff6a6b27'] = 'Адрес';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_630f6dc397fe74e52d5189e2c80f282b'] = 'Вернуться к списку';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_5c1cf6cfec2dad86c8ca5286a0294516'] = 'Имя';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c695cfe527a6fcd680114851b86b7555'] = 'Фамилия';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f9dd946cc89c1f3b41a0edbe0f36931d'] = 'Телефон';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_61a649a33f2869e5e35fbb7aff3a80d9'] = 'Email';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_2664f03ac6b8bb9eee4287720e407db3'] = 'Адрес';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6ddc09dc456001d9854e9fe670374eb2'] = 'Страна';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_69aede266809f89b89fe70681f6a129f'] = 'Область/Край/Республика';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_859214628431995197c0558f7b5f8ffc'] = 'Город';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4348f938bbddd8475e967ccb47ecb234'] = 'Почтовый индекс';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_78fce82336bbbdca7f6da7564b8f9325'] = 'Улица';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_71a6834884666147c0334f0c40bc7295'] = 'Дом/Строение';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f88a77e3d68d251c3dc4008c327b5a0c'] = 'Квартира';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d977f846d110fcb7f71c6f97330c9d10'] = 'Код домофона';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_56c1e354d36beb85b0d881c5b2e24cbe'] = 'Этаж';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4d34f53389ed7f28ca91fc31ea360a66'] = 'Корпус';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_49354b452ec305136a56fe7731834156'] = 'Дом/Строение';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_04176f095283bc729f1e3926967e7034'] = 'Имя';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dff4bf10409100d989495c6d5486035e'] = 'Фамилия';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1c76cbfe21c6f44c1d1e59d54f3e4420'] = 'Компания';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1aadcc03a9dbba84a3c5a5cbfde8a162'] = 'ИНН';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_93d03fe37ab3c6abc2a19dd8e41543bd'] = 'Адрес строка 1';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_22fcffe02ab9eda5b769387122f2ddce'] = 'Адрес строка 2';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_8bcdc441379cbf584638b0589a3f9adb'] = 'Почтовый индекс';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_57d056ed0984166336b7879c2af3657f'] = 'Город';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bcc254b55c4a1babdf1dcb82c207506b'] = 'Телефон';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f0e1fc6f97d36cb80f29196e2662ffde'] = 'Мобильный телефон';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7a1920d61156abc05a60135aefe8bc67'] = 'По умолчанию';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_cc18dd262eff97c4dd4b56f750896adb'] = 'Статус по умолчанию';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a33b96f0ce0f1227132f1cb3cf1c9e88'] = 'Статус заказа при пакетной выгрузке ';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1bd340aeb42a5ee0318784c2cffed8a9'] = 'Выбранная версия API недоступна';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c2784d9473fed62ae67fe8597011166a'] = 'Ручная выгрузка заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Идентификаторы заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_91412465ea9169dfd901dd5e7c96dd99'] = 'Выгрузить';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6bd461d1fc51b3294c6513cecc24758d'] = 'Все заказы успешно загружены';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_3518f7b8d79f91da4c91772b4c46db94'] = 'Некоторые заказы не удалось загрузить';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9a7fc06b4b2359f1f26f75fbbe27a3e8'] = 'Не все заказы загружены успешно';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_917afe348e09163269225a89a825e634'] = 'Синхронизация корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Создавать заказы для брошенных корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_35b5a9139a54caeb925556ceb2c38086'] = 'Статус заказа для брошенных корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9c4e8fe56eabcc4c7913ebb2f8eb388'] = 'Статус заказа для брошенных корзин не должен использоваться в других настройках';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a0d135501a738c3c98de385dc28cda61'] = 'Выгружать брошенные корзины';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a52213fa61ecf700d1a6091d9769c9a8'] = 'Типы доставок не должны повторяться в матрице соответствий типов доставок';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_f08acd4b354f4d5f4e531ca1972e4504'] = 'Способы оплат не должны повторяться в матрице соответствий способов оплат';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_fd83e0ccb3e6312a62f888dd496dd0a5'] = 'Мгновенно';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6c70ac5cc9fe8dff4f3bfe765dfe8798'] = 'Через 1 минуту';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_be76333ef50b23b6337d263fc87fe11a'] = 'Через 5 минут';
|
||||
@ -74,4 +20,106 @@ $_MODULE['<{retailcrm}prestashop>retailcrm_6e74495fad332de9a8207b5416de3cce'] =
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_d5bb7c2cb1565fb1568924b01847b330'] = 'Через 15 минут';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_9d3095e54f694bb41ef4a3e62ed90e7a'] = 'Через 30 минут';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_dfb403fd86851c7d9f97706dff5a2327'] = 'Через 45 минут';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4b5e6470d5d85448fcd89c828352d25e'] = 'Через 1 час';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4b5e6470d5d85448fcd89c828352d25e'] = 'Через 1 час';
|
||||
$_MODULE['<{retailcrm}prestashop>index_acbcb05077815fe6e9a7620b1d952462'] = 'retailCRM — сервис для интернет магазинов, который поможет перестать терять заказы и увеличить доход на всех этапах воронки.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_09fe407e2337c1120980a2b4ee72ac6e'] = 'У меня уже есть аккаунт retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e81c4e4f2b7b93b481e13a8553c2ae1b'] = 'или';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7a0a77aaf1bdd053fca69fa882c87df0'] = 'Получить retailCRM бесплатно';
|
||||
$_MODULE['<{retailcrm}prestashop>index_061b368c43f85d3fe2c7ccc842883a40'] = 'Настройка соединения';
|
||||
$_MODULE['<{retailcrm}prestashop>index_86ee1fa7924a67e54ac66e11c214e674'] = 'URL адрес retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_656a6828d7ef1bb791e42087c4b5ee6e'] = 'API ключ retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_c9cc8cce247e49bae79f15173ce97354'] = 'Сохранить';
|
||||
$_MODULE['<{retailcrm}prestashop>index_b5a7adde1af5c87d7fd797b6245c2a39'] = 'Описание';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9aa698f602b1e5694855cee73a683488'] = 'Контакты';
|
||||
$_MODULE['<{retailcrm}prestashop>index_764fa884e3fba8a3f40422aa1eadde23'] = 'Перестаньте терять лиды:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_070f41773a46ce08231e11316603a099'] = 'LiveChat с активным вовлечением, поможет получить больше заказов с сайта';
|
||||
$_MODULE['<{retailcrm}prestashop>index_87ef6941837db5b2370eb2c04a2f9e73'] = 'Чат-боты и единый Inbox для Facebook Messengers и WhatsApp помогут перестать терять горячих лидов, готовых вот-вот купить';
|
||||
$_MODULE['<{retailcrm}prestashop>index_0e307da9d0c9ee16b47ef71c39f236a3'] = 'Welcome-цепочки прогреют ваши лиды и подтолкнут их к первой покупке.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e83c1eb5df794bf22e69eb893e80fdd6'] = 'Доводите заказы до оплаты:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_456329795d41ba012fc4fb3ed063d1fe'] = 'Допродажи увеличат средний чек ваших заказов в автоматическом режиме';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4ab044d4168a44dbe50ecc01181e81ad'] = 'Сценарий Брошенная корзина повысит количество оплаченных заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>index_0f93ca5bf76e978aa9162e7fc53897ea'] = 'Управляйте выполнением заказа:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3efd2720a5c93a8fe785084d925024ce'] = 'CRM-система поможет получать заказы, распределять их между сотрудниками, управлять их статусами и выполнять их';
|
||||
$_MODULE['<{retailcrm}prestashop>index_8823fb21e79cd316df376e80bb635329'] = 'Уведомления о статусе заказа помогут автоматически информировать клиента о том, что происходит с его заказом';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2280ad04ce9fc872f86e839265f170a2'] = 'SalesApp — приложение для розничных точек, которое поможет повысить продажи в офлайне и собрать клиенсткую базу в единой системе';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9f1ddb1081aee21a39383a5be24e6c78'] = 'Интеграция с каталогом поможет учитывать остатки, цены и местонахождение товаров';
|
||||
$_MODULE['<{retailcrm}prestashop>index_94d467d04e7d7b0c92df78f3de00fb20'] = 'Удерживайте ваших текущих клиентов:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7f5875d2c134ba80d0ae9a5b51b2a805'] = 'CDP объединит данные ваших клиентов из разных источников и построит профиль 360°';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2708fc15917156fafb712217dcebdab5'] = 'Сегменты помогут разделить вашу базу на небольшие группы, чтобы сделать ваши коммуникации релевантнее';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d2d8dd2103f64290845f5635ce185270'] = 'Рассылки в Email, SMS, WhatsApp и Facebook Messenger увеличат частоту покупок вашей клиентской базы';
|
||||
$_MODULE['<{retailcrm}prestashop>index_b0e12648f812bedb79fe86c8f66cec8a'] = 'Сценарий \"Товары расходники\" поможет автоматически напоминать о необходимости пополнить запасы';
|
||||
$_MODULE['<{retailcrm}prestashop>index_02f67e7fb237e6fa9eb746fa0f721e96'] = 'Возвращайте ушедших клиентов:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d5eb65bf655de38d7ac070bfdc328a74'] = 'CRM-ремаркетинг поможет запускать рекламу, используя сегменты из retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9f8f75ffd4d9e4f326576dfdc5570739'] = 'Брошенный просмотр сохранит товары, которые клиент смотрел на сайте и предложит оплатить их';
|
||||
$_MODULE['<{retailcrm}prestashop>index_f78799eda5746aebce16dfbc6c824b71'] = 'Реактивационные кампании будут возвращать потерянных клиентов обратно в ваш магазин';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3b863a2b271ee8ebcceb0e79c51711b7'] = 'retailCRM повысит эффективность всех ваших маркетинговых каналов:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_17b39a0118f63cf041abfb9d92d12414'] = 'LiveChat';
|
||||
$_MODULE['<{retailcrm}prestashop>index_ce8ae9da5b7cd6c3df2929543a9af92d'] = 'Email';
|
||||
$_MODULE['<{retailcrm}prestashop>index_31f803c0e3b881bf2fc62b248c8aaace'] = 'Facebook Messenger';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4cecb21b44628b17c436739bf6301af2'] = 'SMS';
|
||||
$_MODULE['<{retailcrm}prestashop>index_2ca3885b024c5983c60a69c6af0ecd28'] = 'Ретаргетинг';
|
||||
$_MODULE['<{retailcrm}prestashop>index_9d4f613c288a9cf21d59cc45f1d3dc2c'] = 'Существует ли ознакомительный период?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4427ea757e4bf7ccea501cef064fdeaa'] = 'Да. Существует 14-дневный ознакомительный период в рамках которого Вы можете ознакомиться с возможностями retailCRM.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_3b15dabe24b3ea13a55b08ca7abf1a94'] = 'Кто такой пользователь?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e4ed8cbeb5e181f15ad0192772ef76dd'] = 'Пользователь - это сотрудник, который имеет доступ к retailCRM в качестве представителя Вашего бизнеса или в качестве пользователя Вашего веб-сайта. Каждый пользователь имеет свой доступ к аккаунту retailCRM.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_65991f2dd292e02d64d248906dfe0f40'] = 'Какие языки доступны в модуле?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_fa224ef4c21784276945b35acdfe5605'] = 'Модуль retailCRM переведён на следующие языки:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_cb5480c32e71778852b08ae1e8712775'] = 'Испанский';
|
||||
$_MODULE['<{retailcrm}prestashop>index_78463a384a5aa4fad5fa73e2f506ecfc'] = 'Английский';
|
||||
$_MODULE['<{retailcrm}prestashop>index_deba6920e70615401385fe1fb5a379ec'] = 'Русский';
|
||||
$_MODULE['<{retailcrm}prestashop>index_59064b34ae482528c8dbeb1b0214ee12'] = 'Как долго длится ознакомительный режим?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_26a6451f37fce97782d596fe7373e834'] = 'Длительность пробного режима составляет 14 дней';
|
||||
$_MODULE['<{retailcrm}prestashop>index_d8ff508a2fce371d8c36bd2bedbaecf6'] = 'Оплата производится за пользователя или за аккаунт?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_5e2c0f6429d1304965531a63cf35dfd7'] = 'Оплата осуществляется за каждого пользователя. Если в систему будет добавлен новый пользователь за него так же будет взыматься оплата. Каждый пользователь имеет доступ к функциям онлайн-чата и социальных сетей. Если Вам нужен дополнительный аккаунт обратитесь к команде retailCRM.';
|
||||
$_MODULE['<{retailcrm}prestashop>index_a833bd40df33cff491112eb9316fb050'] = 'Как я могу оплатить?';
|
||||
$_MODULE['<{retailcrm}prestashop>index_4889fefd090fe608a9b5403d02e2e97f'] = 'Оплатить можно следующими способами:';
|
||||
$_MODULE['<{retailcrm}prestashop>index_95428f32e5c696cf71baccb776bc5c15'] = 'Банковским переводом';
|
||||
$_MODULE['<{retailcrm}prestashop>index_e7f9e382dc50889098cbe56f2554c77b'] = 'Кредитной картой';
|
||||
$_MODULE['<{retailcrm}prestashop>index_7088f1d1d9c91d8b75e9882ffd78540c'] = 'Наши контакты';
|
||||
$_MODULE['<{retailcrm}prestashop>index_50f158e2507321f1a5b6f8fb9e350818'] = 'Пишите нам если у Вас есть вопросы';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c2cc7082a89c1ad6631a2f66af5f00c0'] = 'Соединение';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_52a13123e134b8b72b6299bc14a36aad'] = 'Daemon Collector';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_6bcde6286f8d1b76063ee52104a240cf'] = 'Брошенные корзины';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_065ab3a28ca4f16f55f103adc7d0226f'] = 'Способы доставки';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_33af8066d3c83110d4bd897f687cedd2'] = 'Статусы заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_bab959acc06bb03897b294fbb892be6b'] = 'Способы оплаты';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7a1920d61156abc05a60135aefe8bc67'] = 'По умолчанию';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_20cacc01d0de8bc6e9c9846f477e886b'] = 'Выгрузка заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_71098155ccc0a0d6e0b501fbee37e7a9'] = 'Онлайн-консультант';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_061b368c43f85d3fe2c7ccc842883a40'] = 'Настройка соединения';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_86ee1fa7924a67e54ac66e11c214e674'] = 'retailCRM URL';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_656a6828d7ef1bb791e42087c4b5ee6e'] = 'API-ключ';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_f8d7c52aa84f358caedb96fda86809da'] = 'Включить поддержку корпоративных клиентов';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4d3d769b812b6faa6b76e1a8abaece2d'] = 'Активно';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_f75d8fa5c89351544d372cf90528ccf2'] = 'Ключ сайта';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_917afe348e09163269225a89a825e634'] = 'Синхронизация корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_d8e002d770b6f98af7b7ae9a0e5acfe9'] = 'Создавать заказы для брошенных корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_35b5a9139a54caeb925556ceb2c38086'] = 'Статус заказа для брошенных корзин покупателей';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_9b9cf9f8778f69b4c6cf37e66f886be8'] = 'Выберите статус';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_a0d135501a738c3c98de385dc28cda61'] = 'Выгружать брошенные корзины';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_27096e1243f98e1b3300f57ff1c76456'] = 'Выберите задержку';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_5b385947acf10ac0c5521161ce96aaa7'] = 'Выберите доставку';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7dcc1208fa03381346955c6732d9ea85'] = 'Выберите тип';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_acfa058ec9e6e4745eddc0cae3f0f881'] = 'ID заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_91412465ea9169dfd901dd5e7c96dd99'] = 'Выгрузить';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_c9cc8cce247e49bae79f15173ce97354'] = 'Сохранить';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_4f18e3f1c9941a6ec5a38bc716c521b4'] = 'Код для вставки на сайт';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_065ab3a28ca4f16f55f103adc7d0226f'] = 'Способы доставки';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_33af8066d3c83110d4bd897f687cedd2'] = 'Статусы заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_bab959acc06bb03897b294fbb892be6b'] = 'Способы оплаты';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_7a1920d61156abc05a60135aefe8bc67'] = 'По умолчанию';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_6310f29293c902c64db619c29179d99a'] = 'Способ доставки';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_4dbcb38bbbff5d4a402f2575c57a35e6'] = 'Тип оплаты';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_cc18dd262eff97c4dd4b56f750896adb'] = 'Статус по умолчанию';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_a33b96f0ce0f1227132f1cb3cf1c9e88'] = 'Статус заказа при пакетной выгрузке ';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_630f6dc397fe74e52d5189e2c80f282b'] = 'Вернуться к списку';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_c2784d9473fed62ae67fe8597011166a'] = 'Ручная выгрузка заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Идентификаторы заказов';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_91412465ea9169dfd901dd5e7c96dd99'] = 'Выгрузить';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_b9b2d9f66d0112f3aae7dbdbd4e22a43'] = 'Некорректный или пустой адрес CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_942010ef43f3fec28741f62a0d9ff29c'] = 'Некорректный или пустой ключ CRM';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_1bd340aeb42a5ee0318784c2cffed8a9'] = 'Выбранная версия API недоступна';
|
||||
$_MODULE['<{retailcrm}prestashop>retailcrm_39e90036af004a005ccbccbe9a9c19c2'] = 'Статусы заказов не должны повторяться в матрице соответствий статусов';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_8ffa3281a35a0d80fef2cac0fa680523'] = 'Включить выгрузку истории';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_80e47b10a89a3f22e0def96577ee8b25'] = 'Получать остатки из retailCRM';
|
||||
$_MODULE['<{retailcrm}prestashop>settings_7d320ac32b103449d18b51f47e7b1329'] = 'Активировать только при включенной опции \"Корпоративные клиенты\" в retailCRM';
|
||||
|
8
retailcrm/upgrade/index.php
Normal file
8
retailcrm/upgrade/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
87
retailcrm/upgrade/upgrade-3.0.1.php
Normal file
87
retailcrm/upgrade/upgrade-3.0.1.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade module to version 3.0.1
|
||||
*
|
||||
* @param \RetailCRM $module
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function upgrade_module_3_0_1($module)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
$apiVersion = 'RETAILCRM_API_VERSION';
|
||||
$lastRun = 'RETAILCRM_LAST_RUN';
|
||||
$syncCarts = 'RETAILCRM_API_SYNCHRONIZED_CART_DELAY';
|
||||
|
||||
// Suppress warning. DB creation below shouldn't be changed in next versions.
|
||||
if ('retailcrm' != $module->name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// API v4 is deprecated, so API version flag is removed for now.
|
||||
if (Configuration::hasKey($apiVersion)) {
|
||||
$result = Configuration::deleteByName($apiVersion);
|
||||
}
|
||||
|
||||
// Fixes consequences of old fixed bug in JobManager
|
||||
if (Configuration::hasKey($lastRun)) {
|
||||
$result = $result && Configuration::deleteByName($lastRun);
|
||||
}
|
||||
|
||||
// Immediate cart synchronization is not safe anymore (causes data inconsistency)
|
||||
if (Configuration::hasKey($syncCarts) && Configuration::get($syncCarts) == "0") {
|
||||
$result = $result && Configuration::set($syncCarts, "900");
|
||||
}
|
||||
|
||||
return $result && Db::getInstance()->execute(
|
||||
'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'retailcrm_abandonedcarts` (
|
||||
`id_cart` INT UNSIGNED UNIQUE NOT NULL,
|
||||
`last_uploaded` DATETIME,
|
||||
FOREIGN KEY (id_cart) REFERENCES '._DB_PREFIX_.'cart (id_cart)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
) DEFAULT CHARSET=utf8;'
|
||||
);
|
||||
}
|
57
retailcrm/upgrade/upgrade-3.0.2.php
Normal file
57
retailcrm/upgrade/upgrade-3.0.2.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
|
||||
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
|
||||
* @license https://opensource.org/licenses/MIT The MIT License
|
||||
*
|
||||
* Don't forget to prefix your containers with your own identifier
|
||||
* to avoid any conflicts with others containers.
|
||||
*/
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade module to version 3.0.2
|
||||
*
|
||||
* @param \RetailCRM $module
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function upgrade_module_3_0_2($module)
|
||||
{
|
||||
if ('retailcrm' != $module->name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $module->registerHook('actionCarrierUpdate');
|
||||
}
|
1
retailcrm/views/css/fonts.min.css
vendored
Normal file
1
retailcrm/views/css/fonts.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
@font-face{font-family:'OpenSans';src:url('../fonts/OpenSans/opensans-regular.eot');src:url('../fonts/OpenSans/opensans-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/OpenSans/opensans-regular.woff2') format('woff2'),url('../fonts/OpenSans/opensans-regular.woff') format('woff'),url('../fonts/OpenSans/opensans-regular.ttf') format('truetype'),url('../fonts/OpenSans/opensans-regular.svg#open_sansregular') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'OpenSans';src:url('../fonts/OpenSansBold/opensans-bold.eot');src:url('../fonts/OpenSansBold/opensans-bold.eot?#iefix') format('embedded-opentype'),url('../fonts/OpenSansBold/opensans-bold.woff2') format('woff2'),url('../fonts/OpenSansBold/opensans-bold.woff') format('woff'),url('../fonts/OpenSansBold/opensans-bold.ttf') format('truetype'),url('../fonts/OpenSansBold/opensans-bold.svg#open_sansbold') format('svg');font-weight:600;font-style:normal}
|
8
retailcrm/views/css/index.php
Normal file
8
retailcrm/views/css/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
23
retailcrm/views/css/less/fonts.less
Normal file
23
retailcrm/views/css/less/fonts.less
Normal file
@ -0,0 +1,23 @@
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('../fonts/OpenSans/opensans-regular.eot');
|
||||
src: url('../fonts/OpenSans/opensans-regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans/opensans-regular.woff2') format('woff2'),
|
||||
url('../fonts/OpenSans/opensans-regular.woff') format('woff'),
|
||||
url('../fonts/OpenSans/opensans-regular.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans/opensans-regular.svg#open_sansregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('../fonts/OpenSansBold/opensans-bold.eot');
|
||||
src: url('../fonts/OpenSansBold/opensans-bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSansBold/opensans-bold.woff2') format('woff2'),
|
||||
url('../fonts/OpenSansBold/opensans-bold.woff') format('woff'),
|
||||
url('../fonts/OpenSansBold/opensans-bold.ttf') format('truetype'),
|
||||
url('../fonts/OpenSansBold/opensans-bold.svg#open_sansbold') format('svg');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
8
retailcrm/views/css/less/index.php
Normal file
8
retailcrm/views/css/less/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
29
retailcrm/views/css/less/retailcrm-upload.less
Normal file
29
retailcrm/views/css/less/retailcrm-upload.less
Normal file
@ -0,0 +1,29 @@
|
||||
#retailcrm-loading-fade {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
opacity: .5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
|
||||
#retailcrm-loader {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 10px solid white;
|
||||
animation: retailcrm-loader 2s linear infinite;
|
||||
border-top: 10px solid #0c0c0c;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@keyframes retailcrm-loader {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
557
retailcrm/views/css/less/styles.less
Normal file
557
retailcrm/views/css/less/styles.less
Normal file
@ -0,0 +1,557 @@
|
||||
@import "fonts.less";
|
||||
|
||||
@red: #ef5e67;
|
||||
@redHover: #ff4c4c;
|
||||
@redActive: darken(@redHover, 10%);
|
||||
@gray: #7A7A7A;
|
||||
@grayBg: #EAEBEC;
|
||||
@grayBtn: rgba(122, 122, 122, 0.1);
|
||||
@grayBtnHover: rgba(122, 122, 122, 0.15);
|
||||
@grayBtnActive: fadein(@grayBtnHover, 10%);
|
||||
@darkGray: #363A41;
|
||||
@lightYellow: #fcf3b5;
|
||||
@shadowGray: #fdd0d0;
|
||||
@bord: #DFDFDF;
|
||||
@green: #33D16B;
|
||||
@greenHover: #22CA5D;
|
||||
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.retail {
|
||||
&-wrap {
|
||||
font-family: OpenSans, Arial, sans-serif;
|
||||
padding: 0 15px;
|
||||
height: 100%;
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
&-container {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 950px;
|
||||
}
|
||||
&-title {
|
||||
margin: 60px 0 0;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
line-height: 38px;
|
||||
|
||||
&_content {
|
||||
text-align: left;
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
&-txt {
|
||||
color: @gray;
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
}
|
||||
&-descript {
|
||||
margin-top: 45px;
|
||||
text-align: center;
|
||||
}
|
||||
&-tab {
|
||||
&__enabled {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&__disabled {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
&-video {
|
||||
margin: 57px auto 0;
|
||||
max-width: 442px;
|
||||
position: relative;
|
||||
|
||||
&-trigger {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& iframe {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&__btn {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
cursor: pointer;
|
||||
opacity: .4;
|
||||
transition: .25s ease;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-btns {
|
||||
margin: 56px auto 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
max-width: 815px;
|
||||
transition: .05s ease;
|
||||
|
||||
&__separate {
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: @gray;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&_hide {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
&-form {
|
||||
&__spacer {
|
||||
|
||||
}
|
||||
|
||||
margin-top: 60px;
|
||||
|
||||
&__title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
&__label {
|
||||
width: 100% !important;
|
||||
text-align: left !important;
|
||||
margin: 15px 12px;
|
||||
font-size: 15px;
|
||||
}
|
||||
&__row {
|
||||
margin-top: 15px;
|
||||
|
||||
&_submit {
|
||||
margin-top: 23px;
|
||||
}
|
||||
}
|
||||
&__message-warning {
|
||||
padding: 13px 18px;
|
||||
margin: 1px 13px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid @lightYellow;
|
||||
font-size: 1rem;
|
||||
box-shadow: 0px 0px 6px 0px @shadowGray;
|
||||
}
|
||||
&__checkbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 4px 12px;
|
||||
|
||||
input[type=checkbox] {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
label {
|
||||
width: auto;
|
||||
margin-left: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
&__area {
|
||||
display: inline-block !important;
|
||||
vertical-align: top;
|
||||
width: 430px !important;
|
||||
height: 60px !important;
|
||||
border: 1px solid @grayBtnHover !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 58px !important;
|
||||
padding: 0 28px !important;
|
||||
line-height: normal;
|
||||
color: @gray !important;
|
||||
font-size: 16px !important;
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
color: @darkGray;
|
||||
|
||||
&::-webkit-input-placeholder {color: @darkGray;}
|
||||
&::-moz-placeholder {color: @darkGray;}
|
||||
&:-moz-placeholder {color: @darkGray;}
|
||||
&:-ms-input-placeholder {color: @darkGray;}
|
||||
}
|
||||
|
||||
&_txt {
|
||||
padding: 20px 28px !important;
|
||||
line-height: 24px !important;
|
||||
height: 487px !important;
|
||||
border-radius: 20px !important;
|
||||
resize: none !important;
|
||||
font-family: OpenSans, Arial, sans-serif !important;
|
||||
}
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
&:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&_main {
|
||||
margin-top: 34px;
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
|
||||
.retail-form__area {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-tabs {
|
||||
margin-top: 60px;
|
||||
|
||||
&__btn {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 19px 30px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: @gray;
|
||||
text-align: center;
|
||||
min-width: 152px;
|
||||
text-decoration: none !important;
|
||||
position: relative;
|
||||
transition: .25s ease;
|
||||
|
||||
&:hover {
|
||||
color: @darkGray;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
background: @red;
|
||||
transition: .25s ease;
|
||||
}
|
||||
|
||||
&_active {
|
||||
color: @darkGray;
|
||||
|
||||
&::after {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
&__head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid @bord;
|
||||
}
|
||||
&__body {
|
||||
padding-top: 18px;
|
||||
p {
|
||||
margin-top: 23px;
|
||||
margin-bottom: 0;
|
||||
color: @gray;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
&__item {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
&__item {
|
||||
padding-left: 2px;
|
||||
position: relative;
|
||||
color: @gray;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
|
||||
&::before {
|
||||
content: "-";
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
color: @gray;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-tile {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__col {
|
||||
width: 48%;
|
||||
padding-right: 35px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 52%;
|
||||
}
|
||||
&_contacts {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
&__row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
&:nth-last-child(1) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
&__item {
|
||||
margin-top: 34px;
|
||||
|
||||
&:nth-child(1) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
&__title {
|
||||
color: @darkGray;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
&__descript {
|
||||
color: @gray;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
&__link {
|
||||
color: @red;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
transition: .25s ease;
|
||||
|
||||
&:hover {
|
||||
color: @redHover;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-popup {
|
||||
position: absolute;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
background: white;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
transform: translate3d(0, -1000%, 0) scale(.1);
|
||||
transition: 0.25s ease;
|
||||
|
||||
&__close {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: -30px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
|
||||
&::before, &::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
height: 30px;
|
||||
width: 2px;
|
||||
background: white;
|
||||
}
|
||||
&::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
&::after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
transform: translate3d(0, 0, 0) scale(1);
|
||||
}
|
||||
&-wrap {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&-column {
|
||||
display: flex;
|
||||
max-width: 1389px;
|
||||
height: 100%;
|
||||
|
||||
&__aside {
|
||||
width: 253px;
|
||||
background: @grayBg;min-height: 300px;
|
||||
}
|
||||
&__content {
|
||||
flex: 1 0 auto;
|
||||
padding: 0 58px;
|
||||
min-height: 300px;
|
||||
|
||||
}
|
||||
}
|
||||
&-menu {
|
||||
padding: 8px 20px 8px 15px;
|
||||
|
||||
&__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background: @grayBtn !important;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
color: @darkGray !important;
|
||||
text-decoration: none !important;
|
||||
padding: 0 30px;
|
||||
margin-top: 20px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
transition: .25s ease;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: @grayBtnHover !important;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&_active {
|
||||
color: white !important;
|
||||
background: @red !important;
|
||||
|
||||
&:hover {
|
||||
background: @redHover !important;
|
||||
}
|
||||
}
|
||||
&_big {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-full-height {
|
||||
& {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
background: @grayBtn;
|
||||
border-radius: 58px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
padding: 0 30px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
color: @red;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
transition: .25s ease;
|
||||
|
||||
&:hover {
|
||||
background: @grayBtnHover;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: @grayBtnActive;
|
||||
}
|
||||
|
||||
&_max {
|
||||
min-width: 356px;
|
||||
}
|
||||
&_invert {
|
||||
background: @red;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background: @redHover;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: @redActive;
|
||||
}
|
||||
}
|
||||
&_whatsapp {
|
||||
background: @green;
|
||||
color: white;
|
||||
padding: 0 62px;
|
||||
|
||||
&:hover {
|
||||
background: @greenHover;
|
||||
}
|
||||
}
|
||||
&_submit {
|
||||
min-width: 218px;
|
||||
}
|
||||
}
|
||||
.toggle-box {
|
||||
display: none;
|
||||
}
|
||||
}
|
52
retailcrm/views/css/less/sumoselect-custom.less
Normal file
52
retailcrm/views/css/less/sumoselect-custom.less
Normal file
@ -0,0 +1,52 @@
|
||||
@fontSize: 16px;
|
||||
@selectHeight: 60px;
|
||||
@borderRadius: 58px;
|
||||
@optionsBorderRadius: 10px;
|
||||
@innerPadding: 28px;
|
||||
@textColor: #7a7a7a;
|
||||
@border: 1px solid rgba(122,122,122,0.15);
|
||||
|
||||
.SumoSelect {
|
||||
width: 100%;
|
||||
|
||||
&.open > .optWrapper {
|
||||
top: @selectHeight !important;
|
||||
}
|
||||
|
||||
& > .optWrapper {
|
||||
border-radius: @optionsBorderRadius;
|
||||
|
||||
& > .options {
|
||||
li label {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
li.opt {
|
||||
float: left !important;
|
||||
width: 100% !important;
|
||||
font-size: @fontSize;
|
||||
font-weight: normal !important;
|
||||
|
||||
label {
|
||||
width: 100% !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .CaptionCont {
|
||||
border: @border !important;
|
||||
box-shadow: none!important;
|
||||
border-radius: @borderRadius;
|
||||
line-height: normal;
|
||||
padding: 0 @innerPadding !important;
|
||||
color: @textColor !important;
|
||||
font-size: @fontSize !important;
|
||||
height: @selectHeight;
|
||||
|
||||
& > span {
|
||||
line-height: @selectHeight;
|
||||
}
|
||||
}
|
||||
}
|
1
retailcrm/views/css/retailcrm-upload.min.css
vendored
Normal file
1
retailcrm/views/css/retailcrm-upload.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
#retailcrm-loading-fade{display:flex;flex-direction:row;align-items:center;justify-content:center;background:#000;position:fixed;left:0;right:0;bottom:0;top:0;z-index:9999;opacity:.5;filter:alpha(opacity=50)}#retailcrm-loader{width:50px;height:50px;border:10px solid white;animation:retailcrm-loader 2s linear infinite;border-top:10px solid #0c0c0c;border-radius:50%}@keyframes retailcrm-loader{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
1
retailcrm/views/css/styles.min.css
vendored
Normal file
1
retailcrm/views/css/styles.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
retailcrm/views/css/sumoselect-custom.min.css
vendored
Normal file
1
retailcrm/views/css/sumoselect-custom.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.SumoSelect{width:100%}.SumoSelect.open>.optWrapper{top:60px!important}.SumoSelect>.optWrapper{border-radius:10px}.SumoSelect>.optWrapper>.options li label{font-weight:normal!important}.SumoSelect>.optWrapper>.options li.opt{float:left!important;width:100%!important;font-size:16px;font-weight:normal!important}.SumoSelect>.optWrapper>.options li.opt label{width:100%!important;text-align:left!important}.SumoSelect>.CaptionCont{border:1px solid rgba(122,122,122,0.15)!important;box-shadow:none!important;border-radius:58px;line-height:normal;padding:0 28px!important;color:#7a7a7a!important;font-size:16px!important;height:60px}.SumoSelect>.CaptionCont>span{line-height:60px}
|
8
retailcrm/views/css/vendor/index.php
vendored
Normal file
8
retailcrm/views/css/vendor/index.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
1
retailcrm/views/css/vendor/sumoselect.min.css
vendored
Normal file
1
retailcrm/views/css/vendor/sumoselect.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
8
retailcrm/views/fonts/OpenSans/index.php
Normal file
8
retailcrm/views/fonts/OpenSans/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
BIN
retailcrm/views/fonts/OpenSans/opensans-regular.eot
Normal file
BIN
retailcrm/views/fonts/OpenSans/opensans-regular.eot
Normal file
Binary file not shown.
7651
retailcrm/views/fonts/OpenSans/opensans-regular.svg
Normal file
7651
retailcrm/views/fonts/OpenSans/opensans-regular.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 409 KiB |
BIN
retailcrm/views/fonts/OpenSans/opensans-regular.ttf
Normal file
BIN
retailcrm/views/fonts/OpenSans/opensans-regular.ttf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user