From 6cdb1f48a0fe46ca5e1f18bca4d377c9ef458abd Mon Sep 17 00:00:00 2001 From: max-baranikov Date: Fri, 28 May 2021 14:32:43 +0300 Subject: [PATCH] Move logs to var, split it by days, add task to remove old logs --- retailcrm/lib/RetailcrmCli.php | 3 +- retailcrm/lib/RetailcrmHistory.php | 3 + retailcrm/lib/RetailcrmJobManager.php | 13 +- retailcrm/lib/RetailcrmJsonResponse.php | 91 +++++++++ retailcrm/lib/RetailcrmLogger.php | 59 +++++- retailcrm/lib/RetailcrmTools.php | 11 +- .../lib/events/RetailcrmClearLogsEvent.php | 66 +++++++ retailcrm/lib/events/RetailcrmExportEvent.php | 4 + .../templates/RetailcrmSettingsTemplate.php | 4 + retailcrm/retailcrm.php | 87 ++++++++- retailcrm/translations/es.php | 10 + retailcrm/translations/ru.php | 10 + retailcrm/views/css/less/styles.less | 3 + retailcrm/views/css/styles.min.css | 2 +- retailcrm/views/js/retailcrm-export.js | 25 +-- retailcrm/views/js/retailcrm-export.min.js | 2 +- retailcrm/views/js/retailcrm.js | 2 +- retailcrm/views/js/retailcrm.min.js | 2 +- retailcrm/views/templates/admin/settings.tpl | 176 +++++++++++++----- 19 files changed, 494 insertions(+), 79 deletions(-) create mode 100644 retailcrm/lib/RetailcrmJsonResponse.php create mode 100644 retailcrm/lib/events/RetailcrmClearLogsEvent.php diff --git a/retailcrm/lib/RetailcrmCli.php b/retailcrm/lib/RetailcrmCli.php index 3480638..3802c42 100644 --- a/retailcrm/lib/RetailcrmCli.php +++ b/retailcrm/lib/RetailcrmCli.php @@ -374,8 +374,9 @@ class RetailcrmCli 'RetailcrmIcmlEvent', 'RetailcrmSyncEvent', 'RetailcrmInventoriesEvent', + 'RetailcrmExportEvent', 'RetailcrmUpdateSinceIdEvent', - 'RetailcrmExportEvent' + 'RetailcrmClearLogsEvent' ); } } diff --git a/retailcrm/lib/RetailcrmHistory.php b/retailcrm/lib/RetailcrmHistory.php index 91cdbac..37f184a 100644 --- a/retailcrm/lib/RetailcrmHistory.php +++ b/retailcrm/lib/RetailcrmHistory.php @@ -724,6 +724,9 @@ class RetailcrmHistory } $orderToUpdate = new Order((int)$order['externalId']); + if(!Validate::isLoadedObject($orderToUpdate)) { + continue; + } self::handleCustomerDataChange($orderToUpdate, $order); /* diff --git a/retailcrm/lib/RetailcrmJobManager.php b/retailcrm/lib/RetailcrmJobManager.php index a5ee468..9976424 100644 --- a/retailcrm/lib/RetailcrmJobManager.php +++ b/retailcrm/lib/RetailcrmJobManager.php @@ -191,11 +191,6 @@ class RetailcrmJobManager sprintf('Executed job %s, result: %s', $job, $result ? 'true' : 'false') ); $lastRuns[$job] = new \DateTime('now'); - $lastRunsDetails[$job] = [ - 'success' => true, - 'lastRun' => new \DateTime('now'), - 'error' => null, - ]; break; } @@ -241,6 +236,12 @@ class RetailcrmJobManager } if (isset($result) && $result) { + $lastRunsDetails[$job] = [ + 'success' => true, + 'lastRun' => new \DateTime('now'), + 'error' => null, + ]; + self::clearCurrentJob($job); } @@ -325,7 +326,7 @@ class RetailcrmJobManager * @return array * @throws \Exception */ - private static function getLastRunDetails() + public static function getLastRunDetails() { $lastRuns = json_decode((string)Configuration::getGlobalValue(self::LAST_RUN_DETAIL_NAME), true); diff --git a/retailcrm/lib/RetailcrmJsonResponse.php b/retailcrm/lib/RetailcrmJsonResponse.php new file mode 100644 index 0000000..0758435 --- /dev/null +++ b/retailcrm/lib/RetailcrmJsonResponse.php @@ -0,0 +1,91 @@ + + * @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 + * @license GPL + * @link https://retailcrm.ru + */ +class RetailcrmJsonResponse +{ + private static function jsonResponse($response) + { + header('Content-Type: application/json'); + + $result = json_encode($response); + + echo $result; + return $result; + } + + public static function invalidResponse($msg, $status = 404) + { + http_response_code($status); + + return self::jsonResponse([ + 'success' => false, + 'errorMsg' => $msg + ]); + } + + public static function successfullResponse($data = null, $key = null) + { + $response = [ + 'success' => true, + ]; + + if (!is_null($data)) { + if (is_array($key)) { + foreach ($key as $i => $value) { + if (isset($data[$i])) + $response[$value] = $data[$i]; + } + } elseif (is_string($key)) { + $response[$key] = $data; + } else { + $response['response'] = $data; + } + } + + return self::jsonResponse($response); + } +} \ No newline at end of file diff --git a/retailcrm/lib/RetailcrmLogger.php b/retailcrm/lib/RetailcrmLogger.php index edcb41b..86bd45e 100644 --- a/retailcrm/lib/RetailcrmLogger.php +++ b/retailcrm/lib/RetailcrmLogger.php @@ -176,7 +176,12 @@ class RetailcrmLogger return ''; } - return _PS_ROOT_DIR_ . '/retailcrm_' . self::getLogFilePrefix() . '.log'; + return self::getLogDir() . '/retailcrm_' . self::getLogFilePrefix() . '_' . date('Y_m_d') . '.log'; + } + + public static function getLogDir() + { + return _PS_ROOT_DIR_ . '/var/logs'; } /** @@ -196,4 +201,56 @@ class RetailcrmLogger return 'web'; } + + /** + * Removes module log files from var/logs which is older than 30 days + */ + public static function clearObsoleteLogs() + { + $logDir = self::getLogDir(); + $handle = opendir($logDir); + while (($file = readdir($handle)) !== false) { + if (false !== self::checkFileName($file)) { + $path = "$logDir/$file"; + if (filemtime($path) < strtotime('-30 days')) { + unlink($path); + } + } + } + } + + public static function getLogFilesInfo() + { + $fileNames = []; + $logDir = self::getLogDir(); + + $handle = opendir($logDir); + while (false !== $file = readdir($handle)) { + if (false !== self::checkFileName($file)) { + $path = "$logDir/$file"; + $fileNames[] = [ + 'name' => $file, + 'path' => $path, + 'size' => number_format(filesize($path), 0, '.', ' ') . ' bytes', + 'modified' => date('Y-m-d H:i:s', filemtime($path)), + ]; + } + } + closedir($handle); + + return $fileNames; + } + + public static function checkFileName($file) + { + $logDir = self::getLogDir(); + if (preg_match('/^retailcrm[a-zA-Z0-9-_]+.log$/', $file)) { + $path = "$logDir/$file"; + if (is_file($path)) { + return $path; + } + } + + return false; + } } \ No newline at end of file diff --git a/retailcrm/lib/RetailcrmTools.php b/retailcrm/lib/RetailcrmTools.php index 2953a7f..cf75f8a 100644 --- a/retailcrm/lib/RetailcrmTools.php +++ b/retailcrm/lib/RetailcrmTools.php @@ -410,16 +410,14 @@ class RetailcrmTools } /** - * 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. + * Returns true if debug mode is checked in advance settings page * 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); + return '1' === Configuration::get(RetailCRM::ENABLE_DEBUG_MODE); } /** @@ -633,10 +631,11 @@ class RetailcrmTools public static function startJobManager() { RetailcrmJobManager::startJobs(array( - 'RetailcrmAbandonedCartsEvent' => new \DateInterval('PT1M'), + 'RetailcrmClearLogsEvent' => new \DateInterval('P1D'), 'RetailcrmIcmlEvent' => new \DateInterval('PT4H'), + 'RetailcrmInventoriesEvent' => new \DateInterval('PT15M'), 'RetailcrmSyncEvent' => new \DateInterval('PT7M'), - 'RetailcrmInventoriesEvent' => new \DateInterval('PT15M') + 'RetailcrmAbandonedCartsEvent' => new \DateInterval('PT1M') )); } diff --git a/retailcrm/lib/events/RetailcrmClearLogsEvent.php b/retailcrm/lib/events/RetailcrmClearLogsEvent.php new file mode 100644 index 0000000..f3b8936 --- /dev/null +++ b/retailcrm/lib/events/RetailcrmClearLogsEvent.php @@ -0,0 +1,66 @@ + + * @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 RetailcrmClearLogsEvent extends RetailcrmAbstractEvent implements RetailcrmEventInterface +{ + /** + * @inheritDoc + */ + public function execute() + { + if ($this->isRunning()) { + return false; + } + + $this->setRunning(); + + RetailcrmLogger::clearObsoleteLogs(); + + return true; + } + + /** + * @inheritDoc + */ + public function getName() + { + return 'RetailcrmClearLogsEvent'; + } +} diff --git a/retailcrm/lib/events/RetailcrmExportEvent.php b/retailcrm/lib/events/RetailcrmExportEvent.php index 7d2b540..df0ab32 100644 --- a/retailcrm/lib/events/RetailcrmExportEvent.php +++ b/retailcrm/lib/events/RetailcrmExportEvent.php @@ -68,6 +68,10 @@ class RetailcrmExportEvent extends RetailcrmAbstractEvent implements RetailcrmEv RetailcrmExport::$api = $api; RetailcrmExport::exportOrders(); RetailcrmExport::exportCustomers(); + + RetailcrmHistory::$api = $api; + RetailcrmHistory::updateSinceId('customers'); + RetailcrmHistory::updateSinceId('orders'); } return true; diff --git a/retailcrm/lib/templates/RetailcrmSettingsTemplate.php b/retailcrm/lib/templates/RetailcrmSettingsTemplate.php index 168e6ad..cc4f02f 100644 --- a/retailcrm/lib/templates/RetailcrmSettingsTemplate.php +++ b/retailcrm/lib/templates/RetailcrmSettingsTemplate.php @@ -79,6 +79,10 @@ class RetailcrmSettingsTemplate extends RetailcrmAbstractTemplate $params['exportCustomersCount'] = RetailcrmExport::getCustomersCount(false); $params['exportOrdersStepSize'] = RetailcrmExport::RETAILCRM_EXPORT_ORDERS_STEP_SIZE_WEB; $params['exportCustomersStepSize'] = RetailcrmExport::RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_WEB; + $params['lastRunDetails'] = RetailcrmJobManager::getLastRunDetails(); + $params['currentJob'] = Configuration::get(RetailcrmJobManager::CURRENT_TASK); + $params['currentJobCli'] = Configuration::get(RetailcrmCli::CURRENT_TASK_CLI); + $params['retailcrmLogsInfo'] = RetailcrmLogger::getLogFilesInfo(); } return $params; diff --git a/retailcrm/retailcrm.php b/retailcrm/retailcrm.php index a964e1f..40a8fc4 100644 --- a/retailcrm/retailcrm.php +++ b/retailcrm/retailcrm.php @@ -65,10 +65,14 @@ class RetailCRM extends Module const UPLOAD_ORDERS = 'RETAILCRM_UPLOAD_ORDERS_ID'; 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_DEBUG_MODE = 'RETAILCRM_ENABLE_DEBUG_MODE'; const LATEST_API_VERSION = '5'; const CONSULTANT_SCRIPT = 'RETAILCRM_CONSULTANT_SCRIPT'; @@ -78,7 +82,8 @@ class RetailCRM extends Module 'RetailcrmAbandonedCartsEvent' => 'Abandoned Carts', 'RetailcrmIcmlEvent' => 'Icml generation', 'RetailcrmSyncEvent' => 'History synchronization', - 'RetailcrmInventoriesEvent' => 'Inventories uploads' + 'RetailcrmInventoriesEvent' => 'Inventories uploads', + 'RetailcrmClearLogsEvent' => 'Clearing logs' ]; /** @@ -226,6 +231,7 @@ class RetailCRM extends Module Configuration::deleteByName(static::ENABLE_CORPORATE_CLIENTS) && Configuration::deleteByName(static::ENABLE_HISTORY_UPLOADS) && Configuration::deleteByName(static::ENABLE_BALANCES_RECEIVING) && + Configuration::deleteByName(static::ENABLE_DEBUG_MODE) && Configuration::deleteByName('RETAILCRM_LAST_SYNC') && Configuration::deleteByName('RETAILCRM_LAST_ORDERS_SYNC') && Configuration::deleteByName('RETAILCRM_LAST_CUSTOMERS_SYNC') && @@ -265,6 +271,9 @@ class RetailCRM extends Module $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)); + $logNames = (string)(Tools::getValue(static::DOWNLOAD_LOGS_NAME)); + $downloadLogs = (bool)(Tools::getValue(static::DOWNLOAD_LOGS)); if (!empty($ordersIds)) { $output .= $this->uploadOrders(RetailcrmTools::partitionId($ordersIds)); @@ -272,6 +281,10 @@ class RetailCRM extends Module return $this->export($exportOrders); } elseif (!empty($exportCustomers)) { return $this->export($exportCustomers, 'customer'); + } elseif ($updateSinceId) { + return $this->updateSinceId(); + } elseif ($downloadLogs) { + return $this->downloadLogs($logNames); } else { $output .= $this->saveSettings(); } @@ -372,16 +385,18 @@ class RetailCRM extends Module */ public function export($step, $entity = 'order') { + if (!Tools::getValue('ajax')) + return RetailcrmJsonResponse::invalidResponse('This method allow only in ajax mode'); + $step--; if ($step < 0) - return false; + return RetailcrmJsonResponse::invalidResponse('Invalid request data'); $api = RetailcrmTools::getApiClient(); if (empty($api)) { RetailcrmLogger::writeCaller(__METHOD__, 'Set API key & URL first'); - - return false; + return RetailcrmJsonResponse::invalidResponse('Set API key & URL first'); } RetailcrmExport::init(); @@ -401,6 +416,65 @@ class RetailCRM extends Module // todo maybe save current step to database } + return RetailcrmJsonResponse::successfullResponse(); + } + + public function updateSinceId() + { + if (!Tools::getValue('ajax')) + return RetailcrmJsonResponse::invalidResponse('This method allow only in ajax mode'); + + $api = RetailcrmTools::getApiClient(); + + if (empty($api)) { + RetailcrmLogger::writeCaller(__METHOD__, 'Set API key & URL first'); + return RetailcrmJsonResponse::invalidResponse('Set API key & URL first'); + } + + RetailcrmHistory::$api = $api; + RetailcrmHistory::updateSinceId('customers'); + RetailcrmHistory::updateSinceId('orders'); + + return RetailcrmJsonResponse::successfullResponse(); + } + + public function downloadLogs($name = '') + { + if (!Tools::getValue('ajax')) + return false; + + 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; } @@ -811,6 +885,7 @@ class RetailCRM extends Module 'enableCorporate' => (Tools::getValue(static::ENABLE_CORPORATE_CLIENTS) !== false), 'enableHistoryUploads' => (Tools::getValue(static::ENABLE_HISTORY_UPLOADS) !== false), 'enableBalancesReceiving' => (Tools::getValue(static::ENABLE_BALANCES_RECEIVING) !== false), + 'debugMode' => (Tools::getValue(static::ENABLE_DEBUG_MODE) !== false), 'collectorActive' => (Tools::getValue(static::COLLECTOR_ACTIVE) !== false), 'collectorKey' => (string)(Tools::getValue(static::COLLECTOR_KEY)), 'clientId' => Configuration::get(static::CLIENT_ID), @@ -838,6 +913,7 @@ class RetailCRM extends Module 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']); $this->apiUrl = $settings['url']; $this->apiKey = $settings['apiKey']; @@ -1093,7 +1169,6 @@ class RetailCRM extends Module 'deliveryDefault' => json_decode(Configuration::get(static::DELIVERY_DEFAULT), true), 'paymentDefault' => json_decode(Configuration::get(static::PAYMENT_DEFAULT), true), 'statusExport' => (string)(Configuration::get(static::STATUS_EXPORT)), - 'lastRunDetails' => json_decode(Configuration::get(RetailcrmJobManager::LAST_RUN_DETAIL_NAME), true), 'collectorActive' => (Configuration::get(static::COLLECTOR_ACTIVE)), 'collectorKey' => (string)(Configuration::get(static::COLLECTOR_KEY)), 'clientId' => Configuration::get(static::CLIENT_ID), @@ -1104,6 +1179,7 @@ class RetailCRM extends Module 'enableCorporate' => (bool)(Configuration::get(static::ENABLE_CORPORATE_CLIENTS)), 'enableHistoryUploads' => (bool)(Configuration::get(static::ENABLE_HISTORY_UPLOADS)), 'enableBalancesReceiving' => (bool)(Configuration::get(static::ENABLE_BALANCES_RECEIVING)), + 'debugMode' => (bool)(Configuration::get(static::ENABLE_DEBUG_MODE)), ); } @@ -1134,6 +1210,7 @@ class RetailCRM extends Module 'enableCorporateName' => static::ENABLE_CORPORATE_CLIENTS, 'enableHistoryUploadsName' => static::ENABLE_HISTORY_UPLOADS, 'enableBalancesReceivingName' => static::ENABLE_BALANCES_RECEIVING, + 'debugModeName' => static::ENABLE_DEBUG_MODE, 'jobsNames' => static::JOBS_NAMES ); } diff --git a/retailcrm/translations/es.php b/retailcrm/translations/es.php index a9c13eb..f904b3f 100644 --- a/retailcrm/translations/es.php +++ b/retailcrm/translations/es.php @@ -69,6 +69,16 @@ $_MODULE['<{retailcrm}prestashop>settings_54e85d70ea67acdcc86963b14d6223a8'] = ' $_MODULE['<{retailcrm}prestashop>settings_5ae96cfe7ea77a401db8e0d5dbab333c'] = 'Generación Icml'; $_MODULE['<{retailcrm}prestashop>settings_9abdd7d7fa90b7aa19e8ca8fb9f04ee4'] = 'Sincronización de historia'; $_MODULE['<{retailcrm}prestashop>settings_e1d641ca2884dbd4398e9252c0ab511e'] = 'Cargas de inventarios'; +$_MODULE['<{retailcrm}prestashop>settings_540c49e6e05ff1d08a23d23f34f70d80'] = 'Borrado de registros'; +$_MODULE['<{retailcrm}prestashop>settings_9b6545e4cea9b4ad4979d41bb9170e2b'] = 'Avanzado'; +$_MODULE['<{retailcrm}prestashop>settings_ec3028a12402ab7f43962a6f3a667b6e'] = 'Modo de depuración'; +$_MODULE['<{retailcrm}prestashop>settings_b2d37ae1cedf42ff874289b721860af2'] = 'Registros'; +$_MODULE['<{retailcrm}prestashop>settings_34082694d21dbdcfc31e6e32d9fb2b9f'] = 'Nombre del archivo'; +$_MODULE['<{retailcrm}prestashop>settings_a4b7f1864cfdb47cd05b54eb10337506'] = 'Fecha de modificación'; +$_MODULE['<{retailcrm}prestashop>settings_6f6cb72d544962fa333e2e34ce64f719'] = 'Tamaño'; +$_MODULE['<{retailcrm}prestashop>settings_06df33001c1d7187fdd81ea1f5b277aa'] = 'Comportamiento'; +$_MODULE['<{retailcrm}prestashop>settings_801ab24683a4a8c433c6eb40c48bcd9d'] = 'Descargar'; +$_MODULE['<{retailcrm}prestashop>settings_61b0ada67b7f40bf3d40dcc88ae4f3e6'] = 'Descargar todo'; $_MODULE['<{retailcrm}prestashop>index_f545947db05aa489f59babf06c319d06'] = '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_96f5fae5347f2f1cf560e71a30420fec'] = 'Tengo una cuenta en RetailCRM'; $_MODULE['<{retailcrm}prestashop>index_e81c4e4f2b7b93b481e13a8553c2ae1b'] = 'o'; diff --git a/retailcrm/translations/ru.php b/retailcrm/translations/ru.php index 1ea2893..b9061ec 100644 --- a/retailcrm/translations/ru.php +++ b/retailcrm/translations/ru.php @@ -69,6 +69,16 @@ $_MODULE['<{retailcrm}prestashop>settings_54e85d70ea67acdcc86963b14d6223a8'] = ' $_MODULE['<{retailcrm}prestashop>settings_5ae96cfe7ea77a401db8e0d5dbab333c'] = 'Генерация Icml'; $_MODULE['<{retailcrm}prestashop>settings_9abdd7d7fa90b7aa19e8ca8fb9f04ee4'] = 'Синхронизация истории'; $_MODULE['<{retailcrm}prestashop>settings_e1d641ca2884dbd4398e9252c0ab511e'] = 'Выгрузка остатков'; +$_MODULE['<{retailcrm}prestashop>settings_540c49e6e05ff1d08a23d23f34f70d80'] = 'Очистка лог-файлов'; +$_MODULE['<{retailcrm}prestashop>settings_9b6545e4cea9b4ad4979d41bb9170e2b'] = 'Дополнительно'; +$_MODULE['<{retailcrm}prestashop>settings_ec3028a12402ab7f43962a6f3a667b6e'] = 'Режим отладки'; +$_MODULE['<{retailcrm}prestashop>settings_b2d37ae1cedf42ff874289b721860af2'] = 'Лог-файлы'; +$_MODULE['<{retailcrm}prestashop>settings_34082694d21dbdcfc31e6e32d9fb2b9f'] = 'Имя файла'; +$_MODULE['<{retailcrm}prestashop>settings_a4b7f1864cfdb47cd05b54eb10337506'] = 'Дата изменения'; +$_MODULE['<{retailcrm}prestashop>settings_6f6cb72d544962fa333e2e34ce64f719'] = 'Размер'; +$_MODULE['<{retailcrm}prestashop>settings_06df33001c1d7187fdd81ea1f5b277aa'] = 'Действия'; +$_MODULE['<{retailcrm}prestashop>settings_801ab24683a4a8c433c6eb40c48bcd9d'] = 'Скачать'; +$_MODULE['<{retailcrm}prestashop>settings_61b0ada67b7f40bf3d40dcc88ae4f3e6'] = 'Скачать все'; $_MODULE['<{retailcrm}prestashop>index_f545947db05aa489f59babf06c319d06'] = 'RetailCRM — сервис для интернет магазинов, который поможет перестать терять заказы и увеличить доход на всех этапах воронки.'; $_MODULE['<{retailcrm}prestashop>index_96f5fae5347f2f1cf560e71a30420fec'] = 'У меня уже есть аккаунт RetailCRM'; $_MODULE['<{retailcrm}prestashop>index_e81c4e4f2b7b93b481e13a8553c2ae1b'] = 'или'; diff --git a/retailcrm/views/css/less/styles.less b/retailcrm/views/css/less/styles.less index 777372e..b3a748c 100644 --- a/retailcrm/views/css/less/styles.less +++ b/retailcrm/views/css/less/styles.less @@ -488,6 +488,9 @@ body, html { &_big { font-size: 18px; } + &_hidden { + display: none; + } } } &-full-height { diff --git a/retailcrm/views/css/styles.min.css b/retailcrm/views/css/styles.min.css index 4820beb..672daef 100644 --- a/retailcrm/views/css/styles.min.css +++ b/retailcrm/views/css/styles.min.css @@ -1 +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}body,html{margin:0;padding:0;height:100%}.hidden{visibility:hidden}.retail-wrap{font-family:OpenSans,Arial,sans-serif;padding:0 15px;height:100%}.retail-wrap *,.retail-wrap *::before,.retail-wrap *::after{box-sizing:border-box}.retail-container{margin:0 auto;width:100%;max-width:950px}.retail-title{margin:60px 0 0;font-weight:400;text-align:center;font-size:28px;line-height:38px}.retail-title_content{text-align:left;margin-top:40px}.retail-txt{color:#7A7A7A;font-size:18px;line-height:26px}.retail-descript{margin-top:45px;text-align:center}.retail-tab__enabled{display:block}.retail-tab__disabled{display:none !important}.retail-video{margin:57px auto 0;max-width:442px;position:relative}.retail-video-trigger{position:absolute;top:0;bottom:0;right:0;left:0;width:100%;height:100%;cursor:pointer}.retail-video iframe{pointer-events:none}.retail-video__btn{position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;width:100px;height:100px;cursor:pointer;opacity:.4;transition:.25s ease}.retail-video__btn svg{width:100%}.retail-video__btn:hover{opacity:.6}.retail-btns{margin:56px auto 0;display:flex;justify-content:space-between;max-width:815px;transition:.05s ease}.retail-btns__separate{padding:0 20px;display:flex;align-items:center;color:#7A7A7A;font-size:16px}.retail-btns_hide{opacity:0}.retail-form{margin-top:60px}.retail-form__title{font-size:16px;font-weight:600;line-height:24px;margin-bottom:22px}.retail-form__label{width:100% !important;text-align:left !important;margin:15px 12px;font-size:15px}.retail-form__row{margin-top:15px}.retail-form__row_submit{margin-top:23px}.retail-form__message-warning{padding:13px 18px;margin:1px 13px;border-radius:8px;border:1px solid #fcf3b5;font-size:1rem;box-shadow:0 0 6px 0 #fdd0d0}.retail-form__checkbox{display:flex;flex-direction:row;align-items:center;padding:4px 12px}.retail-form__checkbox input[type=checkbox]{width:24px;height:24px}.retail-form__checkbox label{width:auto;margin-left:8px;font-size:16px}.retail-form__area{display:inline-block !important;vertical-align:top;width:430px !important;height:60px !important;border:1px solid rgba(122,122,122,0.15) !important;box-shadow:none !important;border-radius:58px !important;padding:0 28px !important;line-height:normal;color:#7A7A7A !important;font-size:16px !important;appearance:none}.retail-form__area:focus{color:#363A41}.retail-form__area:focus::-webkit-input-placeholder{color:#363A41}.retail-form__area:focus::-moz-placeholder{color:#363A41}.retail-form__area:focus:-moz-placeholder{color:#363A41}.retail-form__area:focus:-ms-input-placeholder{color:#363A41}.retail-form__area_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}.retail-form input:focus,.retail-form textarea:focus{outline:none !important}.retail-form_main{margin-top:34px;max-width:900px;width:100%}.retail-form_main .retail-form__area{width:100% !important}.retail-tabs{margin-top:60px}.retail-tabs__btn{display:inline-block;vertical-align:top;padding:19px 30px;font-size:16px;font-weight:600;line-height:22px;color:#7A7A7A;text-align:center;min-width:152px;text-decoration:none !important;position:relative;transition:.25s ease}.retail-tabs__btn:hover{color:#363A41}.retail-tabs__btn::after{content:"";height:3px;width:100%;position:absolute;bottom:-1px;left:0;right:0;opacity:0;visibility:hidden;background:#0068FF;transition:.25s ease}.retail-tabs__btn_active{color:#363A41}.retail-tabs__btn_active::after{opacity:1;visibility:visible}.retail-tabs__head{display:flex;justify-content:space-between;border-bottom:1px solid #DFDFDF}.retail-tabs__body{padding-top:18px}.retail-tabs__body p{margin-top:23px;margin-bottom:0;color:#7A7A7A;font-size:16px;line-height:24px}.retail-tabs__item{display:none}.retail-list{margin:0;padding:0;list-style:none}.retail-list__item{padding-left:2px;position:relative;color:#7A7A7A;font-size:16px;line-height:24px}.retail-list__item::before{content:"-";display:inline-block;vertical-align:top;color:#7A7A7A;font-size:16px;line-height:24px;margin-right:3px}.retail-tile{display:flex;flex-wrap:wrap}.retail-tile__col{width:48%;padding-right:35px}.retail-tile__col:nth-child(1){width:52%}.retail-tile__col_contacts{padding-right:0}.retail-tile__row{display:flex;justify-content:center;margin-bottom:30px}.retail-tile__row:nth-last-child(1){margin-bottom:0}.retail-tile__item{margin-top:34px}.retail-tile__item:nth-child(1){margin-top:20px}.retail-tile__title{color:#363A41;font-size:16px;font-weight:600;line-height:24px}.retail-tile__descript{color:#7A7A7A;font-size:16px;line-height:24px;margin-top:10px}.retail-tile__link{color:#0068FF;font-size:16px;font-weight:600;line-height:24px;transition:.25s ease}.retail-tile__link:hover{color:#005add}.retail-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:.25s ease}.retail-popup__close{position:absolute;top:-30px;right:-30px;width:30px;height:30px;cursor:pointer}.retail-popup__close::before,.retail-popup__close::after{content:"";position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;height:30px;width:2px;background:white}.retail-popup__close::before{transform:rotate(45deg)}.retail-popup__close::after{transform:rotate(-45deg)}.retail-popup.open{transform:translate3d(0, 0, 0) scale(1)}.retail-popup-wrap{position:fixed;left:0;right:0;top:0;bottom:0;background:rgba(0,0,0,0.6);z-index:1000;display:none}.retail-column{display:flex;max-width:1389px;height:100%}.retail-column__aside{width:253px;background:#EAEBEC;min-height:300px}.retail-column__content{flex:1 0 auto;padding:0 58px;min-height:300px}.retail-menu{padding:8px 20px 8px 15px}.retail-menu__btn{display:inline-flex;align-items:center;justify-content:center;vertical-align:top;width:100%;height:60px;background:rgba(122,122,122,0.1) !important;font-weight:bold;font-size:16px;color:#363A41 !important;text-decoration:none !important;padding:0 30px;margin-top:20px;border-radius:5px;text-align:center;transition:.25s ease}.retail-menu__btn span{display:block}.retail-menu__btn:hover{background:rgba(122,122,122,0.15) !important}.retail-menu__btn:nth-child(1){margin-top:0}.retail-menu__btn_active{color:white !important;background:#0068FF !important}.retail-menu__btn_active:hover{background:#005add !important}.retail-menu__btn_big{font-size:18px}.retail-full-height{height:100%}.retail .btn{display:inline-block;vertical-align:top;background:rgba(122,122,122,0.1);border-radius:58px;height:60px;line-height:60px;padding:0 30px;font-size:18px;font-weight:600;text-align:center;color:#0068FF;text-decoration:none;cursor:pointer;appearance:none;border:none;box-shadow:none;transition:.25s ease}.retail .btn:hover{background:rgba(122,122,122,0.15)}.retail .btn:active{background:rgba(122,122,122,0.25)}.retail .btn_max{min-width:356px}.retail .btn_invert{background:#0068FF;color:white}.retail .btn_invert:hover{background:#005add}.retail .btn_invert:active{background:#0045aa}.retail .btn_whatsapp{background:#33D16B;color:white;padding:0 62px}.retail .btn_whatsapp:hover{background:#22CA5D}.retail .btn_submit{min-width:218px}.retail .toggle-box{display:none}.retail-table{width:100%;border:none;border-radius:20px}.retail-table thead th{background:rgba(122,122,122,0.15);font-size:16px}.retail-table tbody tr td{border-bottom:1px solid #ccc}.retail-table td,.retail-table th{color:#333;font-size:14px;line-height:60px;padding:4px 4px 4px 6px;max-width:300px;vertical-align:middle}.retail-table-no-wrap{white-space:nowrap}.retail-table-center{text-align:center}.retail-table-sort__btn,.retail-table-sort__switch{cursor:pointer}.retail-table-sort__btn:hover,.retail-table-sort__switch:hover{color:#005add}.retail-table-sort__btn{float:left;clear:both;line-height:15px;font-size:20px;padding-left:10px;padding-right:10px;opacity:0;transition:opacity .2s ease-out}.retail-table-sort__btn-wrap{position:absolute}.retail-table-sort__asc{padding-top:15px;padding-bottom:0}.retail-table-sort__desc{padding-top:0;padding-bottom:15px}.retail-table-sort thead th:hover .retail-table-sort__btn,.retail-table-sort thead td:hover .retail-table-sort__btn{opacity:1}.retail-collapsible__input{display:none}label.retail-collapsible__title{cursor:pointer;font-weight:normal;text-align:center;padding:0;position:relative;line-height:1;width:100%}label.retail-collapsible__title:before{content:'\25B6';opacity:0;transition:opacity .2s ease-out}label.retail-collapsible__title:hover:before{opacity:1}.retail-collapsible__content{text-align:left;font-size:12px;line-height:1.5;background:#fff;border:1px solid rgba(122,122,122,0.15);position:absolute;top:20px;left:0;padding:18px;margin:0;border-radius:20px;overflow:hidden;max-height:0;transition-duration:.2s;transition-timing-function:ease-out;transition-property:max-height,visibility;visibility:hidden}.retail-collapsible__input:checked+.retail-collapsible__title .retail-collapsible__content{max-height:100vh;visibility:visible}.retail-error-msg,.retail-error-msg:after,.retail-error-msg:before{color:#dd2e44} \ No newline at end of file +@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}body,html{margin:0;padding:0;height:100%}.hidden{visibility:hidden}.retail-wrap{font-family:OpenSans,Arial,sans-serif;padding:0 15px;height:100%}.retail-wrap *,.retail-wrap *::before,.retail-wrap *::after{box-sizing:border-box}.retail-container{margin:0 auto;width:100%;max-width:950px}.retail-title{margin:60px 0 0;font-weight:400;text-align:center;font-size:28px;line-height:38px}.retail-title_content{text-align:left;margin-top:40px}.retail-txt{color:#7A7A7A;font-size:18px;line-height:26px}.retail-descript{margin-top:45px;text-align:center}.retail-tab__enabled{display:block}.retail-tab__disabled{display:none !important}.retail-video{margin:57px auto 0;max-width:442px;position:relative}.retail-video-trigger{position:absolute;top:0;bottom:0;right:0;left:0;width:100%;height:100%;cursor:pointer}.retail-video iframe{pointer-events:none}.retail-video__btn{position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;width:100px;height:100px;cursor:pointer;opacity:.4;transition:.25s ease}.retail-video__btn svg{width:100%}.retail-video__btn:hover{opacity:.6}.retail-btns{margin:56px auto 0;display:flex;justify-content:space-between;max-width:815px;transition:.05s ease}.retail-btns__separate{padding:0 20px;display:flex;align-items:center;color:#7A7A7A;font-size:16px}.retail-btns_hide{opacity:0}.retail-form{margin-top:60px}.retail-form__title{font-size:16px;font-weight:600;line-height:24px;margin-bottom:22px}.retail-form__label{width:100% !important;text-align:left !important;margin:15px 12px;font-size:15px}.retail-form__row{margin-top:15px}.retail-form__row_submit{margin-top:23px}.retail-form__message-warning{padding:13px 18px;margin:1px 13px;border-radius:8px;border:1px solid #fcf3b5;font-size:1rem;box-shadow:0 0 6px 0 #fdd0d0}.retail-form__checkbox{display:flex;flex-direction:row;align-items:center;padding:4px 12px}.retail-form__checkbox input[type=checkbox]{width:24px;height:24px}.retail-form__checkbox label{width:auto;margin-left:8px;font-size:16px}.retail-form__area{display:inline-block !important;vertical-align:top;width:430px !important;height:60px !important;border:1px solid rgba(122,122,122,0.15) !important;box-shadow:none !important;border-radius:58px !important;padding:0 28px !important;line-height:normal;color:#7A7A7A !important;font-size:16px !important;appearance:none}.retail-form__area:focus{color:#363A41}.retail-form__area:focus::-webkit-input-placeholder{color:#363A41}.retail-form__area:focus::-moz-placeholder{color:#363A41}.retail-form__area:focus:-moz-placeholder{color:#363A41}.retail-form__area:focus:-ms-input-placeholder{color:#363A41}.retail-form__area_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}.retail-form input:focus,.retail-form textarea:focus{outline:none !important}.retail-form_main{margin-top:34px;max-width:900px;width:100%}.retail-form_main .retail-form__area{width:100% !important}.retail-tabs{margin-top:60px}.retail-tabs__btn{display:inline-block;vertical-align:top;padding:19px 30px;font-size:16px;font-weight:600;line-height:22px;color:#7A7A7A;text-align:center;min-width:152px;text-decoration:none !important;position:relative;transition:.25s ease}.retail-tabs__btn:hover{color:#363A41}.retail-tabs__btn::after{content:"";height:3px;width:100%;position:absolute;bottom:-1px;left:0;right:0;opacity:0;visibility:hidden;background:#0068FF;transition:.25s ease}.retail-tabs__btn_active{color:#363A41}.retail-tabs__btn_active::after{opacity:1;visibility:visible}.retail-tabs__head{display:flex;justify-content:space-between;border-bottom:1px solid #DFDFDF}.retail-tabs__body{padding-top:18px}.retail-tabs__body p{margin-top:23px;margin-bottom:0;color:#7A7A7A;font-size:16px;line-height:24px}.retail-tabs__item{display:none}.retail-list{margin:0;padding:0;list-style:none}.retail-list__item{padding-left:2px;position:relative;color:#7A7A7A;font-size:16px;line-height:24px}.retail-list__item::before{content:"-";display:inline-block;vertical-align:top;color:#7A7A7A;font-size:16px;line-height:24px;margin-right:3px}.retail-tile{display:flex;flex-wrap:wrap}.retail-tile__col{width:48%;padding-right:35px}.retail-tile__col:nth-child(1){width:52%}.retail-tile__col_contacts{padding-right:0}.retail-tile__row{display:flex;justify-content:center;margin-bottom:30px}.retail-tile__row:nth-last-child(1){margin-bottom:0}.retail-tile__item{margin-top:34px}.retail-tile__item:nth-child(1){margin-top:20px}.retail-tile__title{color:#363A41;font-size:16px;font-weight:600;line-height:24px}.retail-tile__descript{color:#7A7A7A;font-size:16px;line-height:24px;margin-top:10px}.retail-tile__link{color:#0068FF;font-size:16px;font-weight:600;line-height:24px;transition:.25s ease}.retail-tile__link:hover{color:#005add}.retail-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:.25s ease}.retail-popup__close{position:absolute;top:-30px;right:-30px;width:30px;height:30px;cursor:pointer}.retail-popup__close::before,.retail-popup__close::after{content:"";position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;height:30px;width:2px;background:white}.retail-popup__close::before{transform:rotate(45deg)}.retail-popup__close::after{transform:rotate(-45deg)}.retail-popup.open{transform:translate3d(0, 0, 0) scale(1)}.retail-popup-wrap{position:fixed;left:0;right:0;top:0;bottom:0;background:rgba(0,0,0,0.6);z-index:1000;display:none}.retail-column{display:flex;max-width:1389px;height:100%}.retail-column__aside{width:253px;background:#EAEBEC;min-height:300px}.retail-column__content{flex:1 0 auto;padding:0 58px;min-height:300px}.retail-menu{padding:8px 20px 8px 15px}.retail-menu__btn{display:inline-flex;align-items:center;justify-content:center;vertical-align:top;width:100%;height:60px;background:rgba(122,122,122,0.1) !important;font-weight:bold;font-size:16px;color:#363A41 !important;text-decoration:none !important;padding:0 30px;margin-top:20px;border-radius:5px;text-align:center;transition:.25s ease}.retail-menu__btn span{display:block}.retail-menu__btn:hover{background:rgba(122,122,122,0.15) !important}.retail-menu__btn:nth-child(1){margin-top:0}.retail-menu__btn_active{color:white !important;background:#0068FF !important}.retail-menu__btn_active:hover{background:#005add !important}.retail-menu__btn_big{font-size:18px}.retail-menu__btn_hidden{display:none}.retail-full-height{height:100%}.retail .btn{display:inline-block;vertical-align:top;background:rgba(122,122,122,0.1);border-radius:58px;height:60px;line-height:60px;padding:0 30px;font-size:18px;font-weight:600;text-align:center;color:#0068FF;text-decoration:none;cursor:pointer;appearance:none;border:none;box-shadow:none;transition:.25s ease}.retail .btn:hover{background:rgba(122,122,122,0.15)}.retail .btn:active{background:rgba(122,122,122,0.25)}.retail .btn_max{min-width:356px}.retail .btn_invert{background:#0068FF;color:white}.retail .btn_invert:hover{background:#005add}.retail .btn_invert:active{background:#0045aa}.retail .btn_whatsapp{background:#33D16B;color:white;padding:0 62px}.retail .btn_whatsapp:hover{background:#22CA5D}.retail .btn_submit{min-width:218px}.retail .toggle-box{display:none}.retail-table{width:100%;border:none;border-radius:20px}.retail-table thead th{background:rgba(122,122,122,0.15);font-size:16px}.retail-table tbody tr td{border-bottom:1px solid #ccc}.retail-table td,.retail-table th{color:#333;font-size:14px;line-height:60px;padding:4px 4px 4px 6px;max-width:300px;vertical-align:middle}.retail-table-no-wrap{white-space:nowrap}.retail-table-center{text-align:center}.retail-table-sort__btn,.retail-table-sort__switch{cursor:pointer}.retail-table-sort__btn:hover,.retail-table-sort__switch:hover{color:#005add}.retail-table-sort__btn{float:left;clear:both;line-height:15px;font-size:20px;padding-left:10px;padding-right:10px;opacity:0;transition:opacity .2s ease-out}.retail-table-sort__btn-wrap{position:absolute}.retail-table-sort__asc{padding-top:15px;padding-bottom:0}.retail-table-sort__desc{padding-top:0;padding-bottom:15px}.retail-table-sort thead th:hover .retail-table-sort__btn,.retail-table-sort thead td:hover .retail-table-sort__btn{opacity:1}.retail-collapsible__input{display:none}label.retail-collapsible__title{cursor:pointer;font-weight:normal;text-align:center;padding:0;position:relative;line-height:1;width:100%}label.retail-collapsible__title:before{content:'\25B6';opacity:0;transition:opacity .2s ease-out}label.retail-collapsible__title:hover:before{opacity:1}.retail-collapsible__content{text-align:left;font-size:12px;line-height:1.5;background:#fff;border:1px solid rgba(122,122,122,0.15);position:absolute;top:20px;left:0;padding:18px;margin:0;border-radius:20px;overflow:hidden;max-height:0;transition-duration:.2s;transition-timing-function:ease-out;transition-property:max-height,visibility;visibility:hidden}.retail-collapsible__input:checked+.retail-collapsible__title .retail-collapsible__content{max-height:100vh;visibility:visible}.retail-error-msg,.retail-error-msg:after,.retail-error-msg:before{color:#dd2e44} \ No newline at end of file diff --git a/retailcrm/views/js/retailcrm-export.js b/retailcrm/views/js/retailcrm-export.js index f7d0da3..96afeee 100644 --- a/retailcrm/views/js/retailcrm-export.js +++ b/retailcrm/views/js/retailcrm-export.js @@ -42,6 +42,7 @@ $(function () { return false; } + this.isDone = false; this.ordersCount = parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_COUNT"]').val()); this.customersCount = parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_CUSTOMERS_COUNT"]').val()); this.ordersStepSize = parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_STEP_SIZE"]').val()); @@ -69,22 +70,20 @@ $(function () { }; RetailcrmExportForm.prototype.exportAction = function () { - let data = {}; + let data = { + submitretailcrm: 1, + ajax: 1 + }; if (this.ordersStep * this.ordersStepSize < this.ordersCount) { this.ordersStep++; - data = { - submitretailcrm: 1, - RETAILCRM_EXPORT_ORDERS_STEP: this.ordersStep - } + data.RETAILCRM_EXPORT_ORDERS_STEP = this.ordersStep; } else { if (this.customersStep * this.customersStepSize < this.customersCount) { this.customersStep++; - data = { - submitretailcrm: 1, - RETAILCRM_EXPORT_CUSTOMERS_STEP: this.customersStep - } + data.RETAILCRM_EXPORT_CUSTOMERS_STEP = this.customersStep; } else { - return this.exportDone(); + data.RETAILCRM_UPDATE_SINCE_ID = 1; + this.isDone = true; } } @@ -97,6 +96,10 @@ $(function () { data: data }) .done(function (response) { + if(_this.isDone) { + return _this.exportDone(); + } + _this.updateProgressBar(); _this.exportAction(); }) @@ -126,7 +129,7 @@ $(function () { $(this.progressBar).find('.retail-progress__loader').text(percents + '%'); $(this.progressBar).find('.retail-progress__loader').css('width', percents + '%'); - $(this.progressBar).find('.retail-progress__loader').attr('alt', processed + '/' + total); + $(this.progressBar).find('.retail-progress__loader').attr('title', processed + '/' + total); }; RetailcrmExportForm.prototype.confirmLeave = function (event) { diff --git a/retailcrm/views/js/retailcrm-export.min.js b/retailcrm/views/js/retailcrm-export.min.js index 54c4d06..392af74 100644 --- a/retailcrm/views/js/retailcrm-export.min.js +++ b/retailcrm/views/js/retailcrm-export.min.js @@ -34,4 +34,4 @@ * Don't forget to prefix your containers with your own identifier * to avoid any conflicts with others containers. */ -$(function(){function t(){if(this.form=$("input[name=RETAILCRM_EXPORT_ORDERS_COUNT]").closest("form").get(0),void 0===this.form)return!1;this.ordersCount=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_COUNT"]').val()),this.customersCount=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_CUSTOMERS_COUNT"]').val()),this.ordersStepSize=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_STEP_SIZE"]').val()),this.customersStepSize=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE"]').val()),this.ordersStep=0,this.customersStep=0,this.submitButton=$(this.form).find('button[id="export-orders-submit"]').get(0),this.progressBar=$(this.form).find('div[id="export-orders-progress"]').get(0),this.submitAction=this.submitAction.bind(this),this.exportAction=this.exportAction.bind(this),this.exportDone=this.exportDone.bind(this),this.initializeProgressBar=this.initializeProgressBar.bind(this),this.updateProgressBar=this.updateProgressBar.bind(this),$(this.submitButton).click(this.submitAction)}t.prototype.submitAction=function(t){t.preventDefault(),this.initializeProgressBar(),this.exportAction()},t.prototype.exportAction=function(){let t={};if(this.ordersStep*this.ordersStepSize",{class:"retail-progress__loader",text:"0%"})),window.addEventListener("beforeunload",this.confirmLeave)},t.prototype.updateProgressBar=function(){let t=this.ordersStep*this.ordersStepSize;t>this.ordersCount&&(t=this.ordersCount);let e=this.customersStep*this.customersStepSize;e>this.customersCount&&(e=this.customersCount);var s=t+e,i=this.ordersCount+this.customersCount,r=Math.round(100*s/i);$(this.progressBar).find(".retail-progress__loader").text(r+"%"),$(this.progressBar).find(".retail-progress__loader").css("width",r+"%"),$(this.progressBar).find(".retail-progress__loader").attr("alt",s+"/"+i)},t.prototype.confirmLeave=function(t){t.preventDefault(),e.returnValue="Export process has been started"},t.prototype.exportDone=function(){window.removeEventListener("beforeunload",this.confirmLeave),alert("Export is done")},window.RetailcrmExportForm=t}); \ No newline at end of file +$(function(){function t(){if(this.form=$("input[name=RETAILCRM_EXPORT_ORDERS_COUNT]").closest("form").get(0),void 0===this.form)return!1;this.isDone=!1,this.ordersCount=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_COUNT"]').val()),this.customersCount=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_CUSTOMERS_COUNT"]').val()),this.ordersStepSize=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_ORDERS_STEP_SIZE"]').val()),this.customersStepSize=parseInt($(this.form).find('input[name="RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE"]').val()),this.ordersStep=0,this.customersStep=0,this.submitButton=$(this.form).find('button[id="export-orders-submit"]').get(0),this.progressBar=$(this.form).find('div[id="export-orders-progress"]').get(0),this.submitAction=this.submitAction.bind(this),this.exportAction=this.exportAction.bind(this),this.exportDone=this.exportDone.bind(this),this.initializeProgressBar=this.initializeProgressBar.bind(this),this.updateProgressBar=this.updateProgressBar.bind(this),$(this.submitButton).click(this.submitAction)}t.prototype.submitAction=function(t){t.preventDefault(),this.initializeProgressBar(),this.exportAction()},t.prototype.exportAction=function(){let t={submitretailcrm:1,ajax:1};this.ordersStep*this.ordersStepSize",{class:"retail-progress__loader",text:"0%"})),window.addEventListener("beforeunload",this.confirmLeave)},t.prototype.updateProgressBar=function(){let t=this.ordersStep*this.ordersStepSize;t>this.ordersCount&&(t=this.ordersCount);let s=this.customersStep*this.customersStepSize;s>this.customersCount&&(s=this.customersCount);var e=t+s,i=this.ordersCount+this.customersCount,r=Math.round(100*e/i);$(this.progressBar).find(".retail-progress__loader").text(r+"%"),$(this.progressBar).find(".retail-progress__loader").css("width",r+"%"),$(this.progressBar).find(".retail-progress__loader").attr("title",e+"/"+i)},t.prototype.confirmLeave=function(t){t.preventDefault(),e.returnValue="Export process has been started"},t.prototype.exportDone=function(){window.removeEventListener("beforeunload",this.confirmLeave),alert("Export is done")},window.RetailcrmExportForm=t}); \ No newline at end of file diff --git a/retailcrm/views/js/retailcrm.js b/retailcrm/views/js/retailcrm.js index 640f7d1..fd2d02a 100644 --- a/retailcrm/views/js/retailcrm.js +++ b/retailcrm/views/js/retailcrm.js @@ -219,7 +219,7 @@ $(function(){ 'rcrm_tab_order_statuses': selectsUpdate, 'rcrm_tab_payment_types': selectsUpdate, 'rcrm_tab_consultant': mainSubmitHide, - 'rcrm_tab_job_manager': mainSubmitHide, + 'rcrm_tab_advanced': mainSubmitHide, 'rcrm_tab_orders_upload': mainSubmitHide }); tabs.initializeTabs(); diff --git a/retailcrm/views/js/retailcrm.min.js b/retailcrm/views/js/retailcrm.min.js index 3fedc14..492aaff 100644 --- a/retailcrm/views/js/retailcrm.min.js +++ b/retailcrm/views/js/retailcrm.min.js @@ -34,4 +34,4 @@ * Don't forget to prefix your containers with your own identifier * to avoid any conflicts with others containers. */ -$(function(){var a={init:function(){this.selects.init(),this.tableSort.init(),this.player.init(),this.tabs.init(),this.uploadForm.init(this.settingsTabs.init()),this.exportForm.init(),this.popup.init(),this.toggleBox(),this.trimConsultant(),this.showSettings()},selects:{init:function(){var t=this;try{$(".jq-select").SumoSelect(),$("li.opt").each((t,e)=>{if(0===$(e).find("label").html().length){let t=$(e).closest("ul").closest("div").parent().find("select");$(e).find("label").html(t.attr("placeholder")),$(e).addClass("disabled")}}),t.update(),$(document).on("change",".jq-select",function(){t.update()})}catch(t){console.warn("Cannot initialize select: "+t.message)}},update:function(){var n={};let t=$(".retail-tab__enabled").find("select:not(#RETAILCRM_API_DELIVERY_DEFAULT, #RETAILCRM_API_PAYMENT_DEFAULT)");t.each((t,e)=>{var i=$(e).val();i&&i.length&&(n[t]=$('option[value="'+$(e).val()+'"]',$(e)).index())});let s=Object.values(n);t.each((i,a)=>{$("option",a).each((t,e)=>{-1===$.inArray(t,s)||void 0!==n[i]&&n[i]==t?a.sumo.enableItem(t):a.sumo.disableItem(t)})})}},tableSort:{init:function(){var n=this;$(".retail-table-sort").each((t,a)=>{$(a).find(".retail-table-sort__switch").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i)})}),$(a).find(".retail-table-sort__asc").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i,"asc")})}),$(a).find(".retail-table-sort__desc").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i,"desc")})}),$(a).find(".retail-table-sort__initial").click()})},sort:function(t,e,i=void 0){let a,n,s,o,r,l,c,d=0;for(n=!0,c=i||"asc";n;){for(n=!1,a=t.rows,s=1;sr.innerHTML.toLowerCase()){l=!0;break}}else if("desc"===c&&o.innerHTML.toLowerCase(){if(0===$(e).find("label").html().length){let t=$(e).closest("ul").closest("div").parent().find("select");$(e).find("label").html(t.attr("placeholder")),$(e).addClass("disabled")}}),t.update(),$(document).on("change",".jq-select",function(){t.update()})}catch(t){console.warn("Cannot initialize select: "+t.message)}},update:function(){var n={};let t=$(".retail-tab__enabled").find("select:not(#RETAILCRM_API_DELIVERY_DEFAULT, #RETAILCRM_API_PAYMENT_DEFAULT)");t.each((t,e)=>{var i=$(e).val();i&&i.length&&(n[t]=$('option[value="'+$(e).val()+'"]',$(e)).index())});let s=Object.values(n);t.each((i,a)=>{$("option",a).each((t,e)=>{-1===$.inArray(t,s)||void 0!==n[i]&&n[i]==t?a.sumo.enableItem(t):a.sumo.disableItem(t)})})}},tableSort:{init:function(){var n=this;$(".retail-table-sort").each((t,a)=>{$(a).find(".retail-table-sort__switch").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i)})}),$(a).find(".retail-table-sort__asc").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i,"asc")})}),$(a).find(".retail-table-sort__desc").each((t,e)=>{const i=$(e).closest("th,td").index();$(e).click(t=>{t.preventDefault(),n.sort(a,i,"desc")})}),$(a).find(".retail-table-sort__initial").click()})},sort:function(t,e,i=void 0){let a,n,s,o,r,l,c,d=0;for(n=!0,c=i||"asc";n;){for(n=!1,a=t.rows,s=1;sr.innerHTML.toLowerCase()){l=!0;break}}else if("desc"===c&&o.innerHTML.toLowerCase(){l s='Abandoned carts' mod='retailcrm'} {l s='Daemon Collector' mod='retailcrm'} {l s='Online consultant' mod='retailcrm'} - {l s='Job Manager' mod='retailcrm'} + {l s='Advanced' mod='retailcrm'}

RetailCRM

-
+
{l s='Connection Settings' mod='retailcrm'}
@@ -238,11 +238,15 @@
-
- + +
{l s='Online consultant' mod='retailcrm'}
-
@@ -251,10 +255,27 @@
-
-
{l s='Job Manager' mod='retailcrm'}
- - + +
+
{l s='Advanced' mod='retailcrm'}
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ @@ -269,47 +290,112 @@ - - - {foreach from=$lastRunDetails key=key item=item} - - - - + {foreach from=$lastRunDetails key=key item=item} + + - + + + + + {/foreach} + +
{l s='Job name' mod='retailcrm'} {l s='Comment' mod='retailcrm'}
- {if isset($jobsNames[$key]) } - {l s=$jobsNames[$key] mod='retailcrm'} - {else} - {$key} - {/if} - {if isset($item['lastRun'])}{$item['lastRun']|date_format:'Y-m-d H:i:s'}{/if} - {if isset($item['success'])} - {if $item['success'] === true} - - ✔ - + +
+ {if isset($jobsNames[$key]) } + {l s=$jobsNames[$key] mod='retailcrm'} {else} - - ❌ - + {$key} {/if} - {/if} - - {if isset($item['error']['message'])} - - - {/if} + {if isset($item['lastRun'])}{$item['lastRun']|date_format:'Y-m-d H:i:s'}{/if} + {if $key === $currentJob || $key === $currentJobCli} + + {else} + {if isset($item['success'])} + {if $item['success'] === true} + + {else} + + {/if} + {/if} + {/if} + + {if isset($item['error']['message'])} + + + {/if} +
+
+ +
+ + + + + + + + + + + + {foreach from=$retailcrmLogsInfo key=key item=logItem} + + + + + + + {/foreach} + + + - {/foreach} - -
{l s='File name' mod='retailcrm'} +
+ + +
+ {l s='Modified date' mod='retailcrm'} +
+
+ + +
+ {l s='Size' mod='retailcrm'} +
{l s='Actions' mod='retailcrm'}
{$logItem.name}{$logItem.modified}{$logItem.size} +
+ + + + +
+
+
+ + + +
+ + + +
+ +