1595 lines
57 KiB
PHP
Raw Normal View History

2014-04-30 03:51:52 +04:00
<?php
2017-09-01 10:14:13 +02:00
/**
* MIT License
2017-09-01 10:14:13 +02:00
*
* 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.
2017-09-01 10:14:13 +02:00
*/
if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
date_default_timezone_set(@date_default_timezone_get());
2015-07-21 15:21:12 +03:00
}
if (!defined('_PS_VERSION_')) {
exit;
2014-04-30 03:51:52 +04:00
}
2021-11-03 16:19:39 +07:00
require_once __DIR__ . '/bootstrap.php';
class RetailCRM extends Module
{
const API_URL = 'RETAILCRM_ADDRESS';
const API_KEY = 'RETAILCRM_API_TOKEN';
const DELIVERY = 'RETAILCRM_API_DELIVERY';
const STATUS = 'RETAILCRM_API_STATUS';
const OUT_OF_STOCK_STATUS = 'RETAILCRM_API_OUT_OF_STOCK_STATUS';
const PAYMENT = 'RETAILCRM_API_PAYMENT';
const DELIVERY_DEFAULT = 'RETAILCRM_API_DELIVERY_DEFAULT';
const PAYMENT_DEFAULT = 'RETAILCRM_API_PAYMENT_DEFAULT';
const STATUS_EXPORT = 'RETAILCRM_STATUS_EXPORT';
const CLIENT_ID = 'RETAILCRM_CLIENT_ID';
const COLLECTOR_ACTIVE = 'RETAILCRM_DAEMON_COLLECTOR_ACTIVE';
const COLLECTOR_KEY = 'RETAILCRM_DAEMON_COLLECTOR_KEY';
const SYNC_CARTS_ACTIVE = 'RETAILCRM_API_SYNCHRONIZE_CARTS';
const SYNC_CARTS_STATUS = 'RETAILCRM_API_SYNCHRONIZED_CART_STATUS';
const SYNC_CARTS_DELAY = 'RETAILCRM_API_SYNCHRONIZED_CART_DELAY';
const UPLOAD_ORDERS = 'RETAILCRM_UPLOAD_ORDERS_ID';
2021-07-27 13:25:44 +03:00
const RUN_JOB = 'RETAILCRM_RUN_JOB';
const EXPORT_ORDERS = 'RETAILCRM_EXPORT_ORDERS_STEP';
const EXPORT_CUSTOMERS = 'RETAILCRM_EXPORT_CUSTOMERS_STEP';
const UPDATE_SINCE_ID = 'RETAILCRM_UPDATE_SINCE_ID';
const DOWNLOAD_LOGS_NAME = 'RETAILCRM_DOWNLOAD_LOGS_NAME';
const DOWNLOAD_LOGS = 'RETAILCRM_DOWNLOAD_LOGS';
const MODULE_LIST_CACHE_CHECKSUM = 'RETAILCRM_MODULE_LIST_CACHE_CHECKSUM';
const ENABLE_CORPORATE_CLIENTS = 'RETAILCRM_ENABLE_CORPORATE_CLIENTS';
const ENABLE_HISTORY_UPLOADS = 'RETAILCRM_ENABLE_HISTORY_UPLOADS';
const ENABLE_BALANCES_RECEIVING = 'RETAILCRM_ENABLE_BALANCES_RECEIVING';
const ENABLE_ORDER_NUMBER_SENDING = 'RETAILCRM_ENABLE_ORDER_NUMBER_SENDING';
const ENABLE_ORDER_NUMBER_RECEIVING = 'RETAILCRM_ENABLE_ORDER_NUMBER_RECEIVING';
const ENABLE_DEBUG_MODE = 'RETAILCRM_ENABLE_DEBUG_MODE';
const LATEST_API_VERSION = '5';
const CONSULTANT_SCRIPT = 'RETAILCRM_CONSULTANT_SCRIPT';
const CONSULTANT_RCCT = 'RETAILCRM_CONSULTANT_RCCT';
const ENABLE_WEB_JOBS = 'RETAILCRM_ENABLE_WEB_JOBS';
const RESET_JOBS = 'RETAILCRM_RESET_JOBS';
const JOBS_NAMES = [
'RetailcrmAbandonedCartsEvent' => 'Abandoned Carts',
'RetailcrmIcmlEvent' => 'Icml generation',
2021-07-27 13:25:44 +03:00
'RetailcrmIcmlUpdateUrlEvent' => 'Icml update URL',
'RetailcrmSyncEvent' => 'History synchronization',
'RetailcrmInventoriesEvent' => 'Inventories uploads',
2021-11-03 16:19:39 +07:00
'RetailcrmClearLogsEvent' => 'Clearing logs',
];
const TABS_TO_VALIDATE = [
'delivery' => self::DELIVERY,
'statuses' => self::STATUS,
'payment' => self::PAYMENT,
'deliveryDefault' => self::DELIVERY_DEFAULT,
'paymentDefault' => self::PAYMENT_DEFAULT,
];
/**
2021-11-03 16:19:39 +07:00
* @var array
*/
private $templateErrors;
/**
2021-11-03 16:19:39 +07:00
* @var array
*/
private $templateWarnings;
/**
2021-11-03 16:19:39 +07:00
* @var array
*/
private $templateConfirms;
/**
2021-11-03 16:19:39 +07:00
* @var array
*/
private $templateInfos;
/** @var bool|\RetailcrmApiClientV5 */
2018-05-28 17:09:31 +03:00
public $api = false;
2018-05-29 13:15:18 +03:00
public $default_lang;
public $default_currency;
public $default_country;
public $apiUrl;
public $apiKey;
public $psVersion;
public $log;
public $confirmUninstall;
/**
* @var \RetailcrmReferences
*/
2018-05-29 13:15:18 +03:00
public $reference;
public $assetsBase;
private static $moduleListCache;
2018-05-28 17:09:31 +03:00
private $use_new_hooks = true;
2017-09-01 10:14:13 +02:00
public function __construct()
{
$this->name = 'retailcrm';
$this->tab = 'export';
2021-09-21 11:43:35 +03:00
$this->version = '3.3.4';
$this->author = 'DIGITAL RETAIL TECHNOLOGIES SL';
2021-07-09 11:57:12 +03:00
$this->displayName = $this->l('Simla.com');
$this->description = $this->l('Integration module for Simla.com');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
$this->default_lang = (int) Configuration::get('PS_LANG_DEFAULT');
$this->default_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT');
$this->default_country = (int) Configuration::get('PS_COUNTRY_DEFAULT');
$this->apiUrl = Configuration::get(static::API_URL);
$this->apiKey = Configuration::get(static::API_KEY);
2021-11-03 16:19:39 +07:00
$this->ps_versions_compliancy = ['min' => '1.6.1.0', 'max' => _PS_VERSION_];
2017-09-01 10:14:13 +02:00
$this->psVersion = Tools::substr(_PS_VERSION_, 0, 3);
$this->log = RetailcrmLogger::getLogFile();
$this->module_key = 'dff3095326546f5fe8995d9e86288491';
$this->assetsBase =
Tools::getShopDomainSsl(true, true) .
__PS_BASE_URI__ .
'modules/' .
$this->name .
'/views';
2021-11-03 16:19:39 +07:00
if ('1.6' == $this->psVersion) {
$this->bootstrap = true;
$this->use_new_hooks = false;
}
if ($this->apiUrl && $this->apiKey) {
$this->api = new RetailcrmProxy($this->apiUrl, $this->apiKey, $this->log);
$this->reference = new RetailcrmReferences($this->api);
}
parent::__construct();
}
2017-09-01 10:14:13 +02:00
public function install()
{
2020-12-27 14:48:36 +03:00
if (Shop::isFeatureActive()) {
Shop::setContext(Shop::CONTEXT_ALL);
}
2021-11-03 16:19:39 +07:00
return
parent::install()
&& $this->registerHook('newOrder')
&& $this->registerHook('actionOrderStatusPostUpdate')
&& $this->registerHook('actionPaymentConfirmation')
&& $this->registerHook('actionCustomerAccountAdd')
&& $this->registerHook('actionOrderEdited')
&& $this->registerHook('actionCarrierUpdate')
&& $this->registerHook('header')
&& ($this->use_new_hooks ? $this->registerHook('actionCustomerAccountUpdate') : true)
&& ($this->use_new_hooks ? $this->registerHook('actionValidateCustomerAddressForm') : true)
&& $this->installDB()
;
}
2019-01-18 17:04:32 +03:00
public function hookHeader()
{
if (!empty($this->context) && !empty($this->context->controller)) {
$this->context->controller->addJS($this->assetsBase . '/js/retailcrm-compat.min.js');
$this->context->controller->addJS($this->assetsBase . '/js/retailcrm-jobs.min.js');
$this->context->controller->addJS($this->assetsBase . '/js/retailcrm-collector.min.js');
$this->context->controller->addJS($this->assetsBase . '/js/retailcrm-consultant.min.js');
2019-01-18 17:04:32 +03:00
}
}
2017-09-01 10:14:13 +02:00
public function uninstall()
{
$apiUrl = Configuration::get(static::API_URL);
$apiKey = Configuration::get(static::API_KEY);
if (!empty($apiUrl) && !empty($apiKey)) {
$api = new RetailcrmProxy(
$apiUrl,
$apiKey,
RetailcrmLogger::getLogFile()
);
$clientId = Configuration::get(static::CLIENT_ID);
$this->integrationModule($api, $clientId, false);
}
2021-11-03 16:19:39 +07:00
return parent::uninstall()
&& Configuration::deleteByName(static::API_URL)
&& Configuration::deleteByName(static::API_KEY)
&& Configuration::deleteByName(static::DELIVERY)
&& Configuration::deleteByName(static::STATUS)
&& Configuration::deleteByName(static::OUT_OF_STOCK_STATUS)
&& Configuration::deleteByName(static::PAYMENT)
&& Configuration::deleteByName(static::DELIVERY_DEFAULT)
&& Configuration::deleteByName(static::PAYMENT_DEFAULT)
&& Configuration::deleteByName(static::STATUS_EXPORT)
&& Configuration::deleteByName(static::CLIENT_ID)
&& Configuration::deleteByName(static::COLLECTOR_ACTIVE)
&& Configuration::deleteByName(static::COLLECTOR_KEY)
&& Configuration::deleteByName(static::SYNC_CARTS_ACTIVE)
&& Configuration::deleteByName(static::SYNC_CARTS_STATUS)
&& Configuration::deleteByName(static::SYNC_CARTS_DELAY)
&& Configuration::deleteByName(static::UPLOAD_ORDERS)
&& Configuration::deleteByName(static::MODULE_LIST_CACHE_CHECKSUM)
&& Configuration::deleteByName(static::ENABLE_CORPORATE_CLIENTS)
&& Configuration::deleteByName(static::ENABLE_HISTORY_UPLOADS)
&& Configuration::deleteByName(static::ENABLE_BALANCES_RECEIVING)
&& Configuration::deleteByName(static::ENABLE_ORDER_NUMBER_SENDING)
&& Configuration::deleteByName(static::ENABLE_ORDER_NUMBER_RECEIVING)
&& Configuration::deleteByName(static::ENABLE_DEBUG_MODE)
&& Configuration::deleteByName(static::ENABLE_WEB_JOBS)
&& Configuration::deleteByName('RETAILCRM_LAST_SYNC')
&& Configuration::deleteByName('RETAILCRM_LAST_ORDERS_SYNC')
&& Configuration::deleteByName('RETAILCRM_LAST_CUSTOMERS_SYNC')
&& Configuration::deleteByName(RetailcrmJobManager::LAST_RUN_NAME)
&& Configuration::deleteByName(RetailcrmJobManager::LAST_RUN_DETAIL_NAME)
&& Configuration::deleteByName(RetailcrmCatalogHelper::ICML_INFO_NAME)
&& Configuration::deleteByName(RetailcrmJobManager::IN_PROGRESS_NAME)
&& Configuration::deleteByName(RetailcrmJobManager::CURRENT_TASK)
&& Configuration::deleteByName(RetailcrmCli::CURRENT_TASK_CLI)
&& $this->uninstallDB();
}
public function installDB()
{
return Db::getInstance()->execute(
2021-11-03 16:19:39 +07:00
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'retailcrm_abandonedcarts` (
`id_cart` INT UNSIGNED UNIQUE NOT NULL,
`last_uploaded` DATETIME,
2021-11-03 16:19:39 +07:00
FOREIGN KEY (id_cart) REFERENCES ' . _DB_PREFIX_ . 'cart (id_cart)
ON DELETE CASCADE
ON UPDATE CASCADE
) DEFAULT CHARSET=utf8;'
);
}
public function uninstallDB()
{
2021-11-03 16:19:39 +07:00
return Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'retailcrm_abandonedcarts`;');
}
public function getContent()
{
$output = null;
$address = Configuration::get(static::API_URL);
$token = Configuration::get(static::API_KEY);
if (Tools::isSubmit('submit' . $this->name)) {
2021-07-27 13:25:44 +03:00
// todo all those vars & ifs to one $command var and check in switch
2021-11-03 16:19:39 +07:00
$jobName = (string) (Tools::getValue(static::RUN_JOB));
$ordersIds = (string) (Tools::getValue(static::UPLOAD_ORDERS));
$exportOrders = (int) (Tools::getValue(static::EXPORT_ORDERS));
$exportCustomers = (int) (Tools::getValue(static::EXPORT_CUSTOMERS));
$updateSinceId = (bool) (Tools::getValue(static::UPDATE_SINCE_ID));
$downloadLogs = (bool) (Tools::getValue(static::DOWNLOAD_LOGS));
$resetJobs = (bool) (Tools::getValue(static::RESET_JOBS));
2019-05-28 11:37:29 +03:00
if (!empty($ordersIds)) {
$output .= $this->uploadOrders(RetailcrmTools::partitionId($ordersIds));
2021-07-27 13:25:44 +03:00
} elseif (!empty($jobName)) {
$this->runJobMultistore($jobName);
} elseif (!empty($exportOrders)) {
return $this->export($exportOrders);
} elseif (!empty($exportCustomers)) {
return $this->export($exportCustomers, 'customer');
} elseif ($updateSinceId) {
2021-05-29 18:37:46 +03:00
return $this->updateSinceId();
} elseif ($downloadLogs) {
return $this->downloadLogs();
} elseif ($resetJobs) {
return $this->resetJobs();
2019-05-28 11:37:29 +03:00
} else {
$output .= $this->saveSettings();
}
}
if ($address && $token) {
$this->api = new RetailcrmProxy($address, $token, $this->log);
$this->reference = new RetailcrmReferences($this->api);
}
$templateFactory = new RetailcrmTemplateFactory($this->context->smarty, $this->assetsBase);
return $templateFactory
->createTemplate($this)
->setContext($this->context)
->setErrors($this->getErrorMessages())
->setWarnings($this->getWarningMessage())
->setInformations($this->getInformationMessages())
->setConfirmations($this->getConfirmationMessages())
2021-11-03 16:19:39 +07:00
->render(__FILE__)
;
2019-05-28 11:37:29 +03:00
}
public function uploadOrders($orderIds)
{
2021-11-03 16:19:39 +07:00
if (10 < count($orderIds)) {
return $this->displayError($this->l("Can't upload more than 10 orders per request"));
2019-05-28 11:37:29 +03:00
}
2021-11-03 16:19:39 +07:00
if (1 > count($orderIds)) {
return $this->displayError($this->l('At least one order ID should be specified'));
2019-05-28 11:37:29 +03:00
}
2021-10-20 12:18:08 +03:00
if (!($this->api instanceof RetailcrmProxy)) {
$apiUrl = Configuration::get(static::API_URL);
$apiKey = Configuration::get(static::API_KEY);
if (!empty($apiUrl) && !empty($apiKey)) {
$this->api = new RetailcrmProxy($apiUrl, $apiKey, _PS_ROOT_DIR_ . '/retailcrm.log');
2021-10-20 12:18:08 +03:00
} else {
return $this->displayError($this->l("Can't upload orders - set API key and API URL first!"));
2019-05-28 11:37:29 +03:00
}
}
$result = '';
2021-10-20 12:18:08 +03:00
$isSuccessful = true;
2021-11-03 16:19:39 +07:00
$skippedOrders = [];
2021-10-20 12:18:08 +03:00
RetailcrmExport::$api = $this->api;
2019-05-28 11:37:29 +03:00
foreach ($orderIds as $orderId) {
2021-10-20 12:18:08 +03:00
$response = false;
try {
$response = RetailcrmExport::exportOrder($orderId);
2021-10-20 12:18:08 +03:00
} catch (PrestaShopObjectNotFoundExceptionCore $e) {
$skippedOrders[] = $orderId;
} catch (Exception $e) {
$this->displayError($e->getMessage());
RetailcrmLogger::writeCaller(__METHOD__, $e->getTraceAsString());
2019-05-28 11:37:29 +03:00
}
2021-10-20 12:18:08 +03:00
$isSuccessful = $isSuccessful ? $response : false;
time_nanosleep(0, 50000000);
2019-05-28 11:37:29 +03:00
}
if ($isSuccessful && empty($skippedOrders)) {
2019-05-28 11:37:29 +03:00
return $this->displayConfirmation($this->l('All orders were uploaded successfully'));
} else {
$result .= $this->displayWarning($this->l('Not all orders were uploaded successfully'));
2019-05-28 11:37:29 +03:00
if ($errors = RetailcrmApiErrors::getErrors()) {
foreach ($errors as $error) {
$result .= $this->displayError($error);
}
}
if (!empty($skippedOrders)) {
$result .= $this->displayWarning(sprintf(
$this->l('Orders skipped due to non-existence: %s', 'retailcrm'),
implode(', ', $skippedOrders)
));
2019-05-28 11:37:29 +03:00
}
return $result;
}
}
2021-07-27 13:25:44 +03:00
/**
* @param string $jobName
2021-11-03 16:19:39 +07:00
*
2021-07-27 13:25:44 +03:00
* @return string
*/
public function runJob($jobName)
{
$jobNameFront = (empty(static::JOBS_NAMES[$jobName]) ? $jobName : static::JOBS_NAMES[$jobName]);
try {
if (RetailcrmJobManager::execManualJob($jobName)) {
return $this->displayConfirmation(sprintf(
'%s %s',
$this->l($jobNameFront),
$this->l('was completed successfully')
));
} else {
return $this->displayError(sprintf(
'%s %s',
$this->l($jobNameFront),
$this->l('was not executed')
));
}
} catch (Exception $e) {
return $this->displayError(sprintf(
'%s %s: %s',
$this->l($jobNameFront),
$this->l('was completed with errors'),
$e->getMessage()
));
}
}
public function runJobMultistore($jobName)
{
2021-11-03 16:19:39 +07:00
RetailcrmContextSwitcher::runInContext([$this, 'runJob'], [$jobName]);
2021-07-27 13:25:44 +03:00
}
/**
* @param int $step
* @param string $entity
2021-11-03 16:19:39 +07:00
*
* @return bool
*/
public function export($step, $entity = 'order')
{
2021-05-29 18:37:46 +03:00
if (!Tools::getValue('ajax')) {
return RetailcrmJsonResponse::invalidResponse('This method allow only in ajax mode');
2021-05-29 18:37:46 +03:00
}
2021-11-03 16:19:39 +07:00
--$step;
if (0 > $step) {
return RetailcrmJsonResponse::invalidResponse('Invalid request data');
2021-05-29 18:37:46 +03:00
}
$api = RetailcrmTools::getApiClient();
if (empty($api)) {
return RetailcrmJsonResponse::invalidResponse('Set API key & URL first');
}
RetailcrmExport::init();
RetailcrmExport::$api = $api;
2021-11-03 16:19:39 +07:00
if ('order' === $entity) {
$stepSize = RetailcrmExport::RETAILCRM_EXPORT_ORDERS_STEP_SIZE_WEB;
RetailcrmExport::$ordersOffset = $stepSize;
RetailcrmExport::exportOrders($step * $stepSize, $stepSize);
2021-11-03 16:19:39 +07:00
// todo maybe save current step to database
} elseif ('customer' === $entity) {
$stepSize = RetailcrmExport::RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_WEB;
RetailcrmExport::$customersOffset = $stepSize;
RetailcrmExport::exportCustomers($step * $stepSize, $stepSize);
// todo maybe save current step to database
}
return RetailcrmJsonResponse::successfullResponse();
}
public function updateSinceId()
{
2021-05-29 18:37:46 +03:00
if (!Tools::getValue('ajax')) {
return RetailcrmJsonResponse::invalidResponse('This method allow only in ajax mode');
2021-05-29 18:37:46 +03:00
}
$api = RetailcrmTools::getApiClient();
if (empty($api)) {
return RetailcrmJsonResponse::invalidResponse('Set API key & URL first');
}
RetailcrmHistory::$api = $api;
RetailcrmHistory::updateSinceId('customers');
RetailcrmHistory::updateSinceId('orders');
return RetailcrmJsonResponse::successfullResponse();
}
public function downloadLogs()
{
2021-05-29 18:37:46 +03:00
if (!Tools::getValue('ajax')) {
return false;
2021-05-29 18:37:46 +03:00
}
2021-11-03 16:19:39 +07:00
$name = (string) (Tools::getValue(static::DOWNLOAD_LOGS_NAME));
if (!empty($name)) {
if (false === ($filePath = RetailcrmLogger::checkFileName($name))) {
return false;
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
} else {
$zipname = _PS_DOWNLOAD_DIR_ . '/retailcrm_logs_' . date('Y-m-d H-i-s') . '.zip';
$zipFile = new ZipArchive();
$zipFile->open($zipname, ZIPARCHIVE::CREATE);
foreach (RetailcrmLogger::getLogFilesInfo() as $logFile) {
$zipFile->addFile($logFile['path'], $logFile['name']);
}
$zipFile->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=' . basename($zipname));
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname);
}
return true;
}
/**
* Resets JobManager and cli internal lock
*/
public function resetJobs()
{
2021-11-03 16:19:39 +07:00
$errors = [];
try {
if (!RetailcrmJobManager::reset()) {
$errors[] = 'Job manager internal state was NOT cleared.';
}
if (!RetailcrmCli::clearCurrentJob(null)) {
$errors[] = 'CLI job was NOT cleared';
}
if (!empty($errors)) {
return RetailcrmJsonResponse::invalidResponse(implode(' ', $errors));
}
return RetailcrmJsonResponse::successfullResponse();
} catch (\Exception $exception) {
return RetailcrmJsonResponse::invalidResponse($exception->getMessage());
}
}
public function hookActionCustomerAccountAdd($params)
{
if ($this->api) {
$customer = $params['newCustomer'];
$customerSend = RetailcrmOrderBuilder::buildCrmCustomer($customer);
$this->api->customersCreate($customerSend);
return true;
}
return false;
}
// this hook added in 1.7
public function hookActionCustomerAccountUpdate($params)
{
if ($this->api) {
/** @var Customer|CustomerCore|null $customer */
$customer = isset($params['customer']) ? $params['customer'] : null;
if (empty($customer)) {
return false;
}
/** @var Cart|CartCore|null $cart */
$cart = isset($params['cart']) ? $params['cart'] : null;
/** @var array $customerSend */
$customerSend = RetailcrmOrderBuilder::buildCrmCustomer($customer);
/** @var \RetailcrmAddressBuilder $addressBuilder */
$addressBuilder = new RetailcrmAddressBuilder();
/** @var Address|\AddressCore|array $address */
2021-11-03 16:19:39 +07:00
$address = [];
if (isset($customerSend['externalId'])) {
$customerData = $this->api->customersGet($customerSend['externalId']);
// Necessary part if we don't want to overwrite other phone numbers.
if ($customerData instanceof RetailcrmApiResponse
&& $customerData->isSuccessful()
&& $customerData->offsetExists('customer')
) {
$customerSend['phones'] = $customerData['customer']['phones'];
}
// Workaround: PrestaShop will return OLD address data, before editing.
// In order to circumvent this we are using post data to fill new address object.
if (Tools::getIsset('submitAddress')
&& Tools::getIsset('id_customer')
&& Tools::getIsset('id_address')
) {
$address = new Address(Tools::getValue('id_address'));
foreach (array_keys(Address::$definition['fields']) as $field) {
if (property_exists($address, $field) && Tools::getIsset($field)) {
$address->$field = Tools::getValue($field);
}
}
} else {
$addresses = $customer->getAddresses($this->default_lang);
$address = array_shift($addresses);
}
if (!empty($address)) {
$addressBuilder->setMode(RetailcrmAddressBuilder::MODE_CUSTOMER);
if (is_object($address)) {
$addressBuilder->setAddress($address);
} else {
$addressBuilder->setAddressId($address['id_address']);
}
$addressBuilder->build();
} elseif (!empty($cart)) {
$addressBuilder
->setMode(RetailcrmAddressBuilder::MODE_ORDER_DELIVERY)
->setAddressId($cart->id_address_invoice)
2021-11-03 16:19:39 +07:00
->build()
;
}
$customerSend = RetailcrmTools::mergeCustomerAddress($customerSend, $addressBuilder->getDataArray());
$this->api->customersEdit($customerSend);
return true;
}
}
return false;
}
// this hook added in 1.7
public function hookActionValidateCustomerAddressForm($params)
{
$customer = new Customer($params['cart']->id_customer);
2021-11-03 16:19:39 +07:00
$customerAddress = ['customer' => $customer, 'cart' => $params['cart']];
return $this->hookActionCustomerAccountUpdate($customerAddress);
}
public function hookNewOrder($params)
{
return $this->hookActionOrderStatusPostUpdate($params);
}
public function hookActionPaymentConfirmation($params)
{
return $this->hookActionOrderStatusPostUpdate($params);
}
2019-05-28 11:37:29 +03:00
/**
* This will ensure that our delivery mapping will not lose associations with edited deliveries.
* PrestaShop doesn't actually edit delivery - it will hide it via `delete` flag in DB and create new one.
* That's why we need to intercept this here and update delivery ID in mapping if necessary.
2019-05-28 11:37:29 +03:00
*
* @param array $params
2019-05-28 11:37:29 +03:00
*/
public function hookActionCarrierUpdate($params)
{
if (!array_key_exists('id_carrier', $params) || !array_key_exists('carrier', $params)) {
return;
2019-05-28 11:37:29 +03:00
}
/** @var Carrier|\CarrierCore $newCarrier */
$newCarrier = $params['carrier'];
$oldCarrierId = $params['id_carrier'];
2019-05-28 11:37:29 +03:00
if (!($newCarrier instanceof Carrier) && !($newCarrier instanceof CarrierCore)) {
return;
2019-05-28 11:37:29 +03:00
}
$delivery = json_decode(Configuration::get(RetailCRM::DELIVERY), true);
$deliveryDefault = json_decode(Configuration::get(static::DELIVERY_DEFAULT), true);
2019-05-28 11:37:29 +03:00
if ($oldCarrierId == $deliveryDefault) {
Configuration::updateValue(static::DELIVERY_DEFAULT, json_encode($newCarrier->id));
2019-05-28 11:37:29 +03:00
}
if (is_array($delivery) && array_key_exists($oldCarrierId, $delivery)) {
$delivery[$newCarrier->id] = $delivery[$oldCarrierId];
unset($delivery[$oldCarrierId]);
Configuration::updateValue(static::DELIVERY, json_encode($delivery));
2019-05-28 11:37:29 +03:00
}
}
2019-05-28 11:37:29 +03:00
public function hookActionOrderEdited($params)
{
2021-10-20 12:18:08 +03:00
if (!$this->api) {
return false;
}
2019-05-28 11:37:29 +03:00
2021-10-20 12:18:08 +03:00
try {
RetailcrmExport::$api = $this->api;
2019-05-28 11:37:29 +03:00
2021-10-20 12:18:08 +03:00
return RetailcrmExport::exportOrder($params['order']->id);
} catch (Exception $e) {
RetailcrmLogger::writeCaller(__METHOD__, $e->getMessage());
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
2019-05-28 11:37:29 +03:00
}
return false;
}
2019-05-28 11:37:29 +03:00
public function hookActionOrderStatusPostUpdate($params)
{
2021-10-20 12:18:08 +03:00
if (!$this->api) {
return false;
}
$status = json_decode(Configuration::get(static::STATUS), true);
if (isset($params['orderStatus'])) {
try {
2021-10-20 12:18:08 +03:00
RetailcrmExport::$api = $this->api;
return RetailcrmExport::exportOrder($params['order']->id);
2021-10-20 12:18:08 +03:00
} catch (Exception $e) {
RetailcrmLogger::writeCaller(__METHOD__, $e->getMessage());
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
}
2021-10-20 12:18:08 +03:00
return false;
} elseif (isset($params['newOrderStatus'])) {
$statusCode = $params['newOrderStatus']->id;
2019-05-28 11:37:29 +03:00
if (array_key_exists($statusCode, $status) && !empty($status[$statusCode])) {
$orderStatus = $status[$statusCode];
}
if (isset($orderStatus)) {
$this->api->ordersEdit(
2021-11-03 16:19:39 +07:00
[
'externalId' => $params['id_order'],
2021-11-03 16:19:39 +07:00
'status' => $orderStatus,
]
);
return true;
}
2019-05-28 11:37:29 +03:00
}
return false;
}
2019-05-28 11:37:29 +03:00
public function hookActionPaymentCCAdd($params)
{
2021-10-12 14:35:29 +03:00
$payments = array_filter(json_decode(Configuration::get(static::PAYMENT), true));
$paymentType = false;
$externalId = false;
2021-10-12 14:35:29 +03:00
foreach ($this->reference->getSystemPaymentModules() as $paymentCMS) {
if (
$paymentCMS['name'] === $params['paymentCC']->payment_method
&& array_key_exists($paymentCMS['code'], $payments)
&& !empty($payments[$paymentCMS['code']])
) {
$paymentType = $payments[$paymentCMS['code']];
break;
}
}
2021-10-12 14:35:29 +03:00
if (!$paymentType || empty($params['cart']) || empty((int) $params['cart']->id)) {
return false;
2021-04-05 18:00:04 +03:00
}
$response = $this->api->ordersGet(RetailcrmTools::getCartOrderExternalId($params['cart']));
2019-05-28 11:37:29 +03:00
2021-11-03 16:19:39 +07:00
if (false !== $response && isset($response['order'])) {
$externalId = RetailcrmTools::getCartOrderExternalId($params['cart']);
} else {
if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) {
2021-10-12 14:35:29 +03:00
$id_order = (int) Order::getIdByCartId((int) $params['cart']->id);
} else {
2021-10-12 14:35:29 +03:00
$id_order = (int) Order::getOrderByCartId((int) $params['cart']->id);
}
2021-11-03 16:19:39 +07:00
if (0 < $id_order) {
2021-10-12 14:35:29 +03:00
// do not update payment if the order in Cart and OrderPayment aren't the same
if ($params['paymentCC']->order_reference) {
$order = Order::getByReference($params['paymentCC']->order_reference)->getFirst();
if (!$order || $order->id !== $id_order) {
return false;
}
}
$response = $this->api->ordersGet($id_order);
2021-11-03 16:19:39 +07:00
if (false !== $response && isset($response['order'])) {
$externalId = $id_order;
}
}
}
2021-11-03 16:19:39 +07:00
if (false === $externalId) {
2021-10-12 14:35:29 +03:00
return false;
}
2019-05-28 11:37:29 +03:00
2021-11-03 16:19:39 +07:00
$status = (0 < round($params['paymentCC']->amount, 2) ? 'paid' : null);
2021-10-12 14:35:29 +03:00
$orderCRM = $response['order'];
if ($orderCRM && $orderCRM['payments']) {
foreach ($orderCRM['payments'] as $orderPayment) {
if ($orderPayment['type'] === $paymentType) {
$updatePayment = $orderPayment;
$updatePayment['amount'] = $params['paymentCC']->amount;
$updatePayment['paidAt'] = $params['paymentCC']->date_add;
$updatePayment['status'] = $status;
2019-05-28 11:37:29 +03:00
}
}
2021-10-12 14:35:29 +03:00
}
2019-05-28 11:37:29 +03:00
2021-10-12 14:35:29 +03:00
if (isset($updatePayment)) {
$this->api->ordersPaymentEdit($updatePayment, 'id');
} else {
2021-11-03 16:19:39 +07:00
$createPayment = [
2021-10-12 14:35:29 +03:00
'externalId' => $params['paymentCC']->id,
2021-11-03 16:19:39 +07:00
'amount' => $params['paymentCC']->amount,
'paidAt' => $params['paymentCC']->date_add,
'type' => $paymentType,
'status' => $status,
'order' => [
2021-10-12 14:35:29 +03:00
'externalId' => $externalId,
2021-11-03 16:19:39 +07:00
],
];
2021-10-12 14:35:29 +03:00
$this->api->ordersPaymentCreate($createPayment);
2019-05-28 11:37:29 +03:00
}
return true;
2019-05-28 11:37:29 +03:00
}
/**
* Save settings handler
2019-05-28 11:37:29 +03:00
*
* @return string
2019-05-28 11:37:29 +03:00
*/
private function saveSettings()
2019-05-28 11:37:29 +03:00
{
$output = '';
$url = (string) Tools::getValue(static::API_URL);
$apiKey = (string) Tools::getValue(static::API_KEY);
$consultantCode = (string) Tools::getValue(static::CONSULTANT_SCRIPT);
if (!empty($url) && !empty($apiKey)) {
2021-11-03 16:19:39 +07:00
$settings = [
'url' => rtrim($url, '/'),
'apiKey' => $apiKey,
'address' => (string) (Tools::getValue(static::API_URL)),
'delivery' => json_encode(Tools::getValue(static::DELIVERY)),
'status' => json_encode(Tools::getValue(static::STATUS)),
'outOfStockStatus' => json_encode(Tools::getValue(static::OUT_OF_STOCK_STATUS)),
'payment' => json_encode(Tools::getValue(static::PAYMENT)),
'deliveryDefault' => json_encode(Tools::getValue(static::DELIVERY_DEFAULT)),
'paymentDefault' => json_encode(Tools::getValue(static::PAYMENT_DEFAULT)),
'statusExport' => (string) (Tools::getValue(static::STATUS_EXPORT)),
2021-11-03 16:19:39 +07:00
'enableCorporate' => (false !== Tools::getValue(static::ENABLE_CORPORATE_CLIENTS)),
'enableHistoryUploads' => (false !== Tools::getValue(static::ENABLE_HISTORY_UPLOADS)),
'enableBalancesReceiving' => (false !== Tools::getValue(static::ENABLE_BALANCES_RECEIVING)),
'enableOrderNumberSending' => (false !== Tools::getValue(static::ENABLE_ORDER_NUMBER_SENDING)),
'enableOrderNumberReceiving' => (false !== Tools::getValue(static::ENABLE_ORDER_NUMBER_RECEIVING)),
'debugMode' => (false !== Tools::getValue(static::ENABLE_DEBUG_MODE)),
'webJobs' => (false !== Tools::getValue(static::ENABLE_WEB_JOBS, true) ? '1' : '0'),
'collectorActive' => (false !== Tools::getValue(static::COLLECTOR_ACTIVE)),
'collectorKey' => (string) (Tools::getValue(static::COLLECTOR_KEY)),
'clientId' => Configuration::get(static::CLIENT_ID),
2021-11-03 16:19:39 +07:00
'synchronizeCartsActive' => (false !== Tools::getValue(static::SYNC_CARTS_ACTIVE)),
'synchronizedCartStatus' => (string) (Tools::getValue(static::SYNC_CARTS_STATUS)),
2021-11-03 16:19:39 +07:00
'synchronizedCartDelay' => (string) (Tools::getValue(static::SYNC_CARTS_DELAY)),
];
$output .= $this->validateForm($settings, $output);
2021-11-03 16:19:39 +07:00
if ('' === $output) {
Configuration::updateValue(static::API_URL, $settings['url']);
Configuration::updateValue(static::API_KEY, $settings['apiKey']);
Configuration::updateValue(static::DELIVERY, $settings['delivery']);
Configuration::updateValue(static::STATUS, $settings['status']);
Configuration::updateValue(static::OUT_OF_STOCK_STATUS, $settings['outOfStockStatus']);
Configuration::updateValue(static::PAYMENT, $settings['payment']);
Configuration::updateValue(static::DELIVERY_DEFAULT, $settings['deliveryDefault']);
Configuration::updateValue(static::PAYMENT_DEFAULT, $settings['paymentDefault']);
Configuration::updateValue(static::STATUS_EXPORT, $settings['statusExport']);
Configuration::updateValue(static::ENABLE_CORPORATE_CLIENTS, $settings['enableCorporate']);
Configuration::updateValue(static::ENABLE_HISTORY_UPLOADS, $settings['enableHistoryUploads']);
Configuration::updateValue(static::ENABLE_BALANCES_RECEIVING, $settings['enableBalancesReceiving']);
Configuration::updateValue(static::ENABLE_ORDER_NUMBER_SENDING, $settings['enableOrderNumberSending']);
Configuration::updateValue(
static::ENABLE_ORDER_NUMBER_RECEIVING,
$settings['enableOrderNumberReceiving']
);
Configuration::updateValue(static::COLLECTOR_ACTIVE, $settings['collectorActive']);
Configuration::updateValue(static::COLLECTOR_KEY, $settings['collectorKey']);
Configuration::updateValue(static::SYNC_CARTS_ACTIVE, $settings['synchronizeCartsActive']);
Configuration::updateValue(static::SYNC_CARTS_STATUS, $settings['synchronizedCartStatus']);
Configuration::updateValue(static::SYNC_CARTS_DELAY, $settings['synchronizedCartDelay']);
Configuration::updateValue(static::ENABLE_DEBUG_MODE, $settings['debugMode']);
Configuration::updateValue(static::ENABLE_WEB_JOBS, $settings['webJobs']);
$this->apiUrl = $settings['url'];
$this->apiKey = $settings['apiKey'];
$this->api = new RetailcrmProxy($this->apiUrl, $this->apiKey, $this->log);
$this->reference = new RetailcrmReferences($this->api);
2021-11-03 16:19:39 +07:00
if (0 == $this->isRegisteredInHook('actionPaymentCCAdd')) {
$this->registerHook('actionPaymentCCAdd');
}
}
}
if (!empty($consultantCode)) {
$extractor = new RetailcrmConsultantRcctExtractor();
$rcct = $extractor->setConsultantScript($consultantCode)->build()->getDataString();
if (!empty($rcct)) {
Configuration::updateValue(static::CONSULTANT_SCRIPT, $consultantCode, true);
Configuration::updateValue(static::CONSULTANT_RCCT, $rcct);
Cache::getInstance()->set(static::CONSULTANT_RCCT, $rcct);
} else {
Configuration::deleteByName(static::CONSULTANT_SCRIPT);
Configuration::deleteByName(static::CONSULTANT_RCCT);
Cache::getInstance()->delete(static::CONSULTANT_RCCT);
}
}
return $output;
}
/**
* Activate/deactivate module in marketplace retailCRM
*
* @param \RetailcrmProxy $apiClient
* @param string $clientId
2021-11-03 16:19:39 +07:00
* @param bool $active
*
2021-11-03 16:19:39 +07:00
* @return bool
*/
private function integrationModule($apiClient, $clientId, $active = true)
2019-05-28 11:37:29 +03:00
{
$scheme = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$logo = 'https://s3.eu-central-1.amazonaws.com/retailcrm-billing/images/5b845ce986911-prestashop2.svg';
$integrationCode = 'prestashop';
$name = 'PrestaShop';
$accountUrl = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
2021-11-03 16:19:39 +07:00
$configuration = [
'clientId' => $clientId,
'code' => $integrationCode . '-' . $clientId,
'integrationCode' => $integrationCode,
'active' => $active,
'name' => $name,
'logo' => $logo,
2021-11-03 16:19:39 +07:00
'accountUrl' => $accountUrl,
];
$response = $apiClient->integrationModulesEdit($configuration);
2019-05-28 11:37:29 +03:00
if (!$response) {
return false;
}
2018-05-28 17:09:31 +03:00
if ($response->isSuccessful()) {
return true;
}
return false;
}
/**
* Returns true if provided connection supports API v5
*
* @param $settings
*
* @return bool
*/
private function validateApiVersion($settings)
{
/** @var \RetailcrmProxy|\RetailcrmApiClientV5 $api */
$api = new RetailcrmProxy(
$settings['url'],
$settings['apiKey'],
$this->log
);
2018-10-30 17:07:14 +03:00
$response = $api->apiVersions();
2018-10-30 17:07:14 +03:00
2021-11-03 16:19:39 +07:00
if (false !== $response && isset($response['versions']) && !empty($response['versions'])) {
foreach ($response['versions'] as $version) {
if ($version == static::LATEST_API_VERSION
|| Tools::substr($version, 0, 1) == static::LATEST_API_VERSION
) {
return true;
}
}
}
2018-05-28 17:09:31 +03:00
return false;
}
/**
* Workaround to pass translate method into another classes
*
* @param $text
*
* @return mixed
*/
public function translate($text)
{
return $this->l($text);
}
/**
* Cart status must be present and must be unique to cartsIds only
*
* @param string $statuses
* @param string $statusExport
* @param string $cartStatus
*
* @return bool
*/
private function validateCartStatus($statuses, $statusExport, $cartStatus)
{
2021-11-03 16:19:39 +07:00
if ('' != $cartStatus && ($cartStatus == $statusExport || stripos($statuses, $cartStatus))) {
return false;
2018-05-28 17:09:31 +03:00
}
return true;
}
/**
* Returns false if mapping is not valid in one-to-one relation
*
* @param string $statuses
*
* @return bool
*/
private function validateMappingOneToOne($statuses)
2017-09-01 10:14:13 +02:00
{
$data = json_decode($statuses, true);
2021-11-03 16:19:39 +07:00
if (JSON_ERROR_NONE != json_last_error() || !is_array($data)) {
return true;
}
2018-01-12 14:05:04 +03:00
$statusesList = array_filter(array_values($data));
2018-09-03 16:22:56 +03:00
if (count($statusesList) != count(array_unique($statusesList))) {
return false;
}
2018-01-12 14:05:04 +03:00
return true;
}
public function validateStoredSettings()
{
2021-11-03 16:19:39 +07:00
$output = [];
$checkApiMethods = [
'delivery' => 'getApiDeliveryTypes',
'statuses' => 'getApiStatuses',
'payment' => 'getApiPaymentTypes',
2021-11-03 16:19:39 +07:00
];
foreach (self::TABS_TO_VALIDATE as $tabName => $settingName) {
$storedValues = Tools::getIsset($settingName)
? Tools::getValue($settingName)
: json_decode(Configuration::get($settingName), true);
2021-11-03 16:19:39 +07:00
if (false !== $storedValues && null !== $storedValues) {
if (!$this->validateMappingSelected($storedValues)) {
$output[] = $tabName;
} else {
if (array_key_exists($tabName, $checkApiMethods)) {
2021-11-03 16:19:39 +07:00
$crmValues = call_user_func([$this->reference, $checkApiMethods[$tabName]]);
$crmCodes = array_column($crmValues, 'id_option');
if (!empty(array_diff($storedValues, $crmCodes))) {
$output[] = $tabName;
2021-11-03 16:19:39 +07:00
}
}
}
}
}
2021-07-27 13:25:44 +03:00
if (!$this->validateCatalogMultistore()) {
$output[] = 'catalog';
}
return $output;
}
private function validateMappingSelected($values)
{
if (is_array($values)) {
foreach ($values as $item) {
if (empty($item)) {
return false;
}
}
} else {
if (empty($values)) {
return false;
}
}
2021-07-16 13:22:49 +03:00
return true;
}
2021-07-27 13:25:44 +03:00
/**
* Catalog info validator
*
* @return bool
*/
public function validateCatalog()
{
$icmlInfo = RetailcrmCatalogHelper::getIcmlFileInfo();
if (!$icmlInfo || !isset($icmlInfo['lastGenerated'])) {
$urlConfiguredAt = RetailcrmTools::getConfigurationCreatedAtByName(self::API_KEY);
2021-11-03 16:19:39 +07:00
if ($urlConfiguredAt instanceof DateTimeImmutable) {
$now = new DateTimeImmutable();
2021-07-27 13:25:44 +03:00
/** @var DateInterval $diff */
$diff = $urlConfiguredAt->diff($now);
if (($diff->days * 24 + $diff->h) > 4) {
return false;
}
}
2021-11-03 16:19:39 +07:00
} elseif ($icmlInfo['isOutdated'] || !$icmlInfo['isUrlActual']) {
2021-07-27 13:25:44 +03:00
return false;
}
return true;
}
/**
* Catalog info validator for multistore
*
* @return bool
*/
private function validateCatalogMultistore()
{
2021-11-03 16:19:39 +07:00
$results = RetailcrmContextSwitcher::runInContext([$this, 'validateCatalog']);
2021-07-27 13:25:44 +03:00
$results = array_filter($results, function ($item) {
return !$item;
});
return empty($results);
}
/**
* Settings form validator
*
* @param $settings
* @param $output
*
* @return string
*/
private function validateForm($settings, $output)
{
if (!RetailcrmTools::validateCrmAddress($settings['url']) || !Validate::isGenericName($settings['url'])) {
$output .= $this->displayError($this->l('Invalid or empty crm address'));
2021-11-03 16:19:39 +07:00
} elseif (!$settings['apiKey'] || '' == $settings['apiKey']) {
$output .= $this->displayError($this->l('Invalid or empty crm api token'));
} elseif (!$this->validateApiVersion($settings)) {
$output .= $this->displayError($this->l('The selected version of the API is unavailable'));
} elseif (!$this->validateCartStatus(
$settings['status'],
$settings['statusExport'],
$settings['synchronizedCartStatus']
)) {
$output .= $this->displayError(
$this->l('Order status for abandoned carts should not be used in other settings')
);
} elseif (!$this->validateMappingOneToOne($settings['status'])) {
$output .= $this->displayError(
$this->l('Order statuses should not repeat in statuses matrix')
);
} elseif (!$this->validateMappingOneToOne($settings['delivery'])) {
$output .= $this->displayError(
$this->l('Delivery types should not repeat in delivery matrix')
);
} elseif (!$this->validateMappingOneToOne($settings['payment'])) {
$output .= $this->displayError(
$this->l('Payment types should not repeat in payment matrix')
);
}
$errorTabs = $this->validateStoredSettings();
if (in_array('delivery', $errorTabs)) {
$this->displayWarning($this->l('Select values for all delivery types'));
}
if (in_array('statuses', $errorTabs)) {
$this->displayWarning($this->l('Select values for all order statuses'));
}
if (in_array('payment', $errorTabs)) {
$this->displayWarning($this->l('Select values for all payment types'));
}
if (in_array('deliveryDefault', $errorTabs) || in_array('paymentDefault', $errorTabs)) {
$this->displayWarning($this->l('Select values for all default parameters'));
}
return $output;
}
/**
* Loads data from modules list cache
*
* @return array|mixed
*/
private static function requireModulesCache()
2018-10-24 16:15:28 +03:00
{
if (file_exists(static::getModulesCache())) {
2021-11-03 16:19:39 +07:00
return require_once static::getModulesCache();
}
return false;
}
/**
* Returns path to modules list cache
*
* @return string
*/
private static function getModulesCache()
{
if (defined('_PS_CACHE_DIR_')) {
return _PS_CACHE_DIR_ . '/retailcrm_modules_cache.php';
2018-10-24 16:15:28 +03:00
}
if (!defined('_PS_ROOT_DIR_')) {
return '';
2018-10-24 16:15:28 +03:00
}
$cacheDir = _PS_ROOT_DIR_ . '/cache';
2018-10-24 16:15:28 +03:00
2021-11-03 16:19:39 +07:00
if (false !== realpath($cacheDir) && is_dir($cacheDir)) {
return $cacheDir . '/retailcrm_modules_cache.php';
2018-10-24 16:15:28 +03:00
}
return _PS_ROOT_DIR_ . '/retailcrm_modules_cache.php';
}
2018-10-24 16:15:28 +03:00
/**
* Returns all module settings
*
* @return array
*/
public static function getSettings()
{
$syncCartsDelay = (string) (Configuration::get(static::SYNC_CARTS_DELAY));
// Use 15 minutes as default interval but don't change immediate interval to it if user already made decision
2021-11-03 16:19:39 +07:00
if (empty($syncCartsDelay) && '0' !== $syncCartsDelay) {
$syncCartsDelay = '900';
}
2021-11-03 16:19:39 +07:00
return [
'url' => (string) (Configuration::get(static::API_URL)),
'apiKey' => (string) (Configuration::get(static::API_KEY)),
'delivery' => json_decode(Configuration::get(static::DELIVERY), true),
'status' => json_decode(Configuration::get(static::STATUS), true),
'outOfStockStatus' => json_decode(Configuration::get(static::OUT_OF_STOCK_STATUS), true),
'payment' => json_decode(Configuration::get(static::PAYMENT), true),
'deliveryDefault' => json_decode(Configuration::get(static::DELIVERY_DEFAULT), true),
'paymentDefault' => json_decode(Configuration::get(static::PAYMENT_DEFAULT), true),
2021-11-03 16:19:39 +07:00
'statusExport' => (string) (Configuration::get(static::STATUS_EXPORT)),
'collectorActive' => (Configuration::get(static::COLLECTOR_ACTIVE)),
2021-11-03 16:19:39 +07:00
'collectorKey' => (string) (Configuration::get(static::COLLECTOR_KEY)),
'clientId' => Configuration::get(static::CLIENT_ID),
'synchronizeCartsActive' => (Configuration::get(static::SYNC_CARTS_ACTIVE)),
2021-11-03 16:19:39 +07:00
'synchronizedCartStatus' => (string) (Configuration::get(static::SYNC_CARTS_STATUS)),
'synchronizedCartDelay' => $syncCartsDelay,
2021-11-03 16:19:39 +07:00
'consultantScript' => (string) (Configuration::get(static::CONSULTANT_SCRIPT)),
'enableCorporate' => (bool) (Configuration::get(static::ENABLE_CORPORATE_CLIENTS)),
'enableHistoryUploads' => (bool) (Configuration::get(static::ENABLE_HISTORY_UPLOADS)),
'enableBalancesReceiving' => (bool) (Configuration::get(static::ENABLE_BALANCES_RECEIVING)),
'enableOrderNumberSending' => (bool) (Configuration::get(static::ENABLE_ORDER_NUMBER_SENDING)),
'enableOrderNumberReceiving' => (bool) (Configuration::get(static::ENABLE_ORDER_NUMBER_RECEIVING)),
'debugMode' => RetailcrmTools::isDebug(),
2021-11-03 16:19:39 +07:00
'webJobs' => RetailcrmTools::isWebJobsEnabled(),
];
}
2018-10-24 16:15:28 +03:00
/**
* Returns all settings names in DB
*
* @return array
*/
public static function getSettingsNames()
{
2021-11-03 16:19:39 +07:00
return [
'urlName' => static::API_URL,
'apiKeyName' => static::API_KEY,
'deliveryName' => static::DELIVERY,
'statusName' => static::STATUS,
'outOfStockStatusName' => static::OUT_OF_STOCK_STATUS,
'paymentName' => static::PAYMENT,
'deliveryDefaultName' => static::DELIVERY_DEFAULT,
'paymentDefaultName' => static::PAYMENT_DEFAULT,
'statusExportName' => static::STATUS_EXPORT,
'collectorActiveName' => static::COLLECTOR_ACTIVE,
'collectorKeyName' => static::COLLECTOR_KEY,
'clientIdName' => static::CLIENT_ID,
'synchronizeCartsActiveName' => static::SYNC_CARTS_ACTIVE,
'synchronizedCartStatusName' => static::SYNC_CARTS_STATUS,
'synchronizedCartDelayName' => static::SYNC_CARTS_DELAY,
'uploadOrders' => static::UPLOAD_ORDERS,
2021-07-27 13:25:44 +03:00
'runJobName' => static::RUN_JOB,
'consultantScriptName' => static::CONSULTANT_SCRIPT,
'enableCorporateName' => static::ENABLE_CORPORATE_CLIENTS,
'enableHistoryUploadsName' => static::ENABLE_HISTORY_UPLOADS,
'enableBalancesReceivingName' => static::ENABLE_BALANCES_RECEIVING,
'enableOrderNumberSendingName' => static::ENABLE_ORDER_NUMBER_SENDING,
'enableOrderNumberReceivingName' => static::ENABLE_ORDER_NUMBER_RECEIVING,
'debugModeName' => static::ENABLE_DEBUG_MODE,
'webJobsName' => static::ENABLE_WEB_JOBS,
2021-11-03 16:19:39 +07:00
'jobsNames' => static::JOBS_NAMES,
];
2018-10-24 16:15:28 +03:00
}
/**
* Returns modules list, caches result. Recreates cache when needed.
* Activity indicator in cache will be rewrited by current state.
*
* @return array
*/
public static function getCachedCmsModulesList()
2018-10-24 16:15:28 +03:00
{
$storedHash = (string) Configuration::get(static::MODULE_LIST_CACHE_CHECKSUM);
$calculatedHash = md5(implode('#', Module::getModulesDirOnDisk(true)));
if ($storedHash != $calculatedHash) {
2021-11-03 16:19:39 +07:00
$serializedModules = [];
static::$moduleListCache = Module::getModulesOnDisk(true);
foreach (static::$moduleListCache as $module) {
$serializedModules[] = json_encode($module);
}
2018-10-24 16:15:28 +03:00
Configuration::updateValue(static::MODULE_LIST_CACHE_CHECKSUM, $calculatedHash);
static::writeModulesCache($serializedModules);
2018-10-24 16:15:28 +03:00
return static::$moduleListCache;
} else {
try {
if (is_array(static::$moduleListCache)) {
return static::$moduleListCache;
}
2018-10-24 16:15:28 +03:00
$modulesList = static::requireModulesCache();
2018-10-24 16:15:28 +03:00
2021-11-03 16:19:39 +07:00
if (false === $modulesList) {
Configuration::updateValue(static::MODULE_LIST_CACHE_CHECKSUM, 'not exist');
2018-10-24 16:15:28 +03:00
return static::getCachedCmsModulesList();
}
2021-11-03 16:19:39 +07:00
static::$moduleListCache = [];
2018-09-03 16:22:56 +03:00
foreach ($modulesList as $serializedModule) {
$deserialized = json_decode($serializedModule);
2018-05-28 17:09:31 +03:00
if ($deserialized instanceof stdClass
&& property_exists($deserialized, 'name')
&& property_exists($deserialized, 'active')
) {
$deserialized->active = Module::isEnabled($deserialized->name);
static::$moduleListCache[] = $deserialized;
}
}
2018-05-28 17:09:31 +03:00
static::$moduleListCache = array_filter(static::$moduleListCache);
unset($modulesList);
return static::$moduleListCache;
} catch (Exception $exception) {
RetailcrmLogger::writeCaller(__METHOD__, $exception->getMessage());
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
Configuration::updateValue(static::MODULE_LIST_CACHE_CHECKSUM, 'exception');
return static::getCachedCmsModulesList();
}
}
}
/**
* Writes module list to cache file.
*
* @param $data
*/
private static function writeModulesCache($data)
{
$file = fopen(static::getModulesCache(), 'w+');
2021-11-03 16:19:39 +07:00
if (false !== $file) {
fwrite($file, '<?php' . PHP_EOL);
fwrite($file, '// Autogenerated module list cache for retailCRM' . PHP_EOL);
fwrite($file, '// Delete this file if you cannot see some payment types in module' . PHP_EOL);
fwrite($file, 'return ' . var_export($data, true) . ';' . PHP_EOL);
fflush($file);
fclose($file);
}
}
2018-05-28 17:09:31 +03:00
/**
* Synchronized cartsIds time choice
*
* @return array
*/
public function getSynchronizedCartsTimeSelect()
{
2021-11-03 16:19:39 +07:00
return [
[
'id_option' => '900',
2021-11-03 16:19:39 +07:00
'name' => $this->l('After 15 minutes'),
],
[
'id_option' => '1800',
2021-11-03 16:19:39 +07:00
'name' => $this->l('After 30 minutes'),
],
[
'id_option' => '2700',
2021-11-03 16:19:39 +07:00
'name' => $this->l('After 45 minute'),
],
[
'id_option' => '3600',
2021-11-03 16:19:39 +07:00
'name' => $this->l('After 1 hour'),
],
];
}
2018-05-28 17:09:31 +03:00
/**
* Initializes arrays of messages
*/
private function initializeTemplateMessages()
{
2021-11-03 16:19:39 +07:00
if (null === $this->templateErrors) {
$this->templateErrors = [];
}
2021-11-03 16:19:39 +07:00
if (null === $this->templateWarnings) {
$this->templateWarnings = [];
}
2018-05-28 17:09:31 +03:00
2021-11-03 16:19:39 +07:00
if (null === $this->templateConfirms) {
$this->templateConfirms = [];
}
2018-05-28 17:09:31 +03:00
2021-11-03 16:19:39 +07:00
if (null === $this->templateErrors) {
$this->templateInfos = [];
}
}
/**
* Returns error messages
*
* @return array
*/
protected function getErrorMessages()
2017-09-01 10:14:13 +02:00
{
if (empty($this->templateErrors)) {
2021-11-03 16:19:39 +07:00
return [];
2017-09-01 10:14:13 +02:00
}
return $this->templateErrors;
}
/**
* Returns warning messages
*
* @return array
*/
protected function getWarningMessage()
2017-09-01 10:14:13 +02:00
{
if (empty($this->templateWarnings)) {
2021-11-03 16:19:39 +07:00
return [];
2017-09-01 10:14:13 +02:00
}
return $this->templateWarnings;
}
/**
* Returns information messages
*
* @return array
*/
protected function getInformationMessages()
{
if (empty($this->templateInfos)) {
2021-11-03 16:19:39 +07:00
return [];
}
return $this->templateInfos;
}
/**
* Returns confirmation messages
*
* @return array
*/
protected function getConfirmationMessages()
2017-09-01 10:14:13 +02:00
{
if (empty($this->templateConfirms)) {
2021-11-03 16:19:39 +07:00
return [];
}
return $this->templateConfirms;
}
/**
* Replacement for default error message helper
*
* @param string|array $message
*
* @return string
*/
public function displayError($message)
{
$this->initializeTemplateMessages();
$this->templateErrors[] = $message;
return ' ';
}
/**
* Replacement for default warning message helper
*
* @param string|array $message
*
* @return string
*/
public function displayWarning($message)
{
$this->initializeTemplateMessages();
$this->templateWarnings[] = $message;
return ' ';
}
/**
* Replacement for default warning message helper
*
* @param string|array $message
*
* @return string
*/
public function displayConfirmation($message)
{
$this->initializeTemplateMessages();
$this->templateConfirms[] = $message;
return ' ';
}
/**
* Replacement for default warning message helper
*
* @param string|array $message
*
* @return string
*/
public function displayInformation($message)
{
$this->initializeTemplateMessages();
$this->templateInfos[] = $message;
return ' ';
}
}