Added export functionality on the module settings page

This commit is contained in:
max-baranikov 2021-04-29 16:40:42 +03:00 committed by GitHub
parent 9e9c13bb66
commit ad9ce38131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 574 additions and 724 deletions

View File

@ -38,6 +38,35 @@
*/
class RetailcrmExport
{
const RETAILCRM_EXPORT_ORDERS_STEP_SIZE_CLI = 5000;
const RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_CLI = 5000;
const RETAILCRM_EXPORT_ORDERS_STEP_SIZE_WEB = 50;
const RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_WEB = 300;
/**
* @var \RetailcrmProxy|\RetailcrmApiClientV5
*/
static $api;
/**
* @var integer
*/
static $ordersOffset;
/**
* @var integer
*/
static $customersOffset;
/**
* Initialize inner state
*/
public static function init()
{
static::$api = null;
static::$ordersOffset = self::RETAILCRM_EXPORT_ORDERS_STEP_SIZE_CLI;
static::$customersOffset = self::RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_CLI;
}
/**
* Get total count of orders for context shop
@ -66,19 +95,23 @@ class RetailcrmExport
public static function getOrdersIds($start = 0, $count = null)
{
if (is_null($count)) {
$count = static::getOrdersCount();
$to = static::getOrdersCount();
$count = $to - $start;
} else {
$to = $start + $count;
}
if ($count > 0) {
$loadSize = 5000;
$predefinedSql = 'SELECT o.`id_order`
FROM `' . _DB_PREFIX_ . 'orders` o
WHERE 1
' . Shop::addSqlRestriction(false, 'o') . '
ORDER BY o.`id_order` ASC';
while ($start <= $count) {
$offset = ($start + $loadSize > $count) ? $count - $start : $loadSize;
while ($start < $to) {
$offset = ($start + static::$ordersOffset > $to) ? $to - $start : static::$ordersOffset;
if ($offset <= 0)
break;
$sql = $predefinedSql . '
LIMIT ' . (int)$start . ', ' . (int)$offset;
@ -98,16 +131,82 @@ class RetailcrmExport
}
/**
* Get total count of customers without orders for context shop
* @param int $from
* @param int|null $count
*/
public static function exportOrders($from = 0, $count = null)
{
if (!static::validateState()) {
return;
}
$orders = array();
$orderRecords = static::getOrdersIds($from, $count);
$orderBuilder = new RetailcrmOrderBuilder();
$orderBuilder->defaultLangFromConfiguration()->setApi(static::$api);
foreach ($orderRecords as $record) {
$orderBuilder->reset();
$order = new Order($record['id_order']);
$orderCart = new Cart($order->id_cart);
$orderCustomer = new Customer($order->id_customer);
$orderBuilder->setCmsOrder($order);
if (!empty($orderCart->id)) {
$orderBuilder->setCmsCart($orderCart);
} else {
$orderBuilder->setCmsCart(null);
}
if (!empty($orderCustomer->id)) {
$orderBuilder->setCmsCustomer($orderCustomer);
} else {
//TODO
// Caused crash before because of empty RetailcrmOrderBuilder::cmsCustomer.
// Current version *shouldn't* do this, but I suggest more tests for guest customers.
$orderBuilder->setCmsCustomer(null);
}
try {
$orders[] = $orderBuilder->buildOrderWithPreparedCustomer();
} catch (\InvalidArgumentException $exception) {
RetailcrmLogger::writeCaller('export', sprintf('Error while building %s: %s', $record['id_order'], $exception->getMessage()));
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
RetailcrmLogger::output($exception->getMessage());
}
time_nanosleep(0, 250000000);
if (count($orders) == 50) {
static::$api->ordersUpload($orders);
$orders = array();
}
}
if (count($orders)) {
static::$api->ordersUpload($orders);
}
}
/**
* Get total count of customers for context shop
* @param bool $withOrders If set to <b>true</b>, then return total count of customers.
* If set to <b>false</b>, then return count of customers without orders
*
* @return int
*/
public static function getCustomersCount()
public static function getCustomersCount($withOrders = true)
{
$sql = 'SELECT count(c.id_customer)
FROM `' . _DB_PREFIX_ . 'customer` c
WHERE 1
' . Shop::addSqlRestriction(false, 'c') . '
' . Shop::addSqlRestriction(false, 'c');
if (!$withOrders) {
$sql .= '
AND c.id_customer not in (
select o.id_customer
from `' . _DB_PREFIX_ . 'orders` o
@ -115,6 +214,7 @@ class RetailcrmExport
' . Shop::addSqlRestriction(false, 'o') . '
group by o.id_customer
)';
}
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
@ -124,23 +224,27 @@ class RetailcrmExport
*
* @param int $start Sets the LIMIT start parameter for sql query
* @param null $count Sets the count of customers to get from database
* @param bool $withAddressId If set to <b>true</b>, then also return address id in <i>`id_address`</i>
* @param bool $withOrders If set to <b>true</b>, then return all customers ids.
* If set to <b>false</b>, then return ids only of customers without orders
* @param bool $returnAddressId If set to <b>true</b>, then also return address id in <i>`id_address`</i>
*
* @return Generator
* @throws PrestaShopDatabaseException
*/
public static function getCustomersIds($start = 0, $count = null, $withAddressId = true)
public static function getCustomersIds($start = 0, $count = null, $withOrders = true, $returnAddressId = true)
{
if (is_null($count)) {
$count = static::getCustomersCount();
$to = static::getCustomersCount($withOrders);
$count = $to - $start;
} else {
$to = $start + $count;
}
if ($count > 0) {
$loadSize = 500;
$predefinedSql = 'SELECT c.`id_customer`
' . ($withAddressId ? ', a.`id_address`' : '') . '
' . ($returnAddressId ? ', a.`id_address`' : '') . '
FROM `' . _DB_PREFIX_ . 'customer` c
' . ($withAddressId ? '
' . ($returnAddressId ? '
LEFT JOIN
(
SELECT
@ -167,19 +271,22 @@ class RetailcrmExport
a.`id_customer` = c.`id_customer`
' : '') . '
WHERE 1
' . Shop::addSqlRestriction(false, 'c') . '
' . Shop::addSqlRestriction(false, 'c') .
($withOrders ? '' : '
AND c.`id_customer` not in (
select o.`id_customer`
from `' . _DB_PREFIX_ . 'orders` o
WHERE 1
' . Shop::addSqlRestriction(false, 'o') . '
group by o.`id_customer`
)
)') . '
ORDER BY c.`id_customer` ASC';
while ($start <= $count) {
$offset = ($start + $loadSize > $count) ? $count - $start : $loadSize;
while ($start < $to) {
$offset = ($start + static::$customersOffset > $to) ? $to - $start : static::$customersOffset;
if ($offset <= 0)
break;
$sql = $predefinedSql . '
LIMIT ' . (int)$start . ', ' . (int)$offset;
@ -198,4 +305,74 @@ class RetailcrmExport
}
}
/**
* @param int $from
* @param int|null $count
*/
public static function exportCustomers($from = 0, $count = null)
{
if (!static::validateState()) {
return;
}
$customers = array();
$customersRecords = RetailcrmExport::getCustomersIds($from, $count, false);
foreach ($customersRecords as $record) {
$customerId = $record['id_customer'];
$addressId = $record['id_address'];
$cmsCustomer = new Customer($customerId);
if (Validate::isLoadedObject($cmsCustomer)) {
if ($addressId) {
$cmsAddress = new Address($addressId);
$addressBuilder = new RetailcrmAddressBuilder();
$address = $addressBuilder
->setAddress($cmsAddress)
->build()
->getDataArray();
} else {
$address = array();
}
try {
$customers[] = RetailcrmOrderBuilder::buildCrmCustomer($cmsCustomer, $address);
} catch (\Exception $exception) {
RetailcrmLogger::writeCaller('export', sprintf('Error while building %s: %s', $customerId, $exception->getMessage()));
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
RetailcrmLogger::output($exception->getMessage());
}
if (count($customers) == 50) {
static::$api->customersUpload($customers);
$customers = array();
time_nanosleep(0, 250000000);
}
}
}
if (count($customers)) {
static::$api->customersUpload($customers);
}
}
/**
* Returns false if inner state is not correct
*
* @return bool
*/
private static function validateState()
{
if (!static::$api ||
!static::$ordersOffset ||
!static::$customersOffset
) {
return false;
}
return true;
}
}

View File

@ -64,98 +64,10 @@ class RetailcrmExportEvent extends RetailcrmAbstractEvent implements RetailcrmEv
continue;
}
$orders = array();
$orderRecords = RetailcrmExport::getOrdersIds();
$orderBuilder = new RetailcrmOrderBuilder();
$orderBuilder->defaultLangFromConfiguration()->setApi($api);
foreach ($orderRecords as $record) {
$orderBuilder->reset();
$order = new Order($record['id_order']);
$orderCart = new Cart($order->id_cart);
$orderCustomer = new Customer($order->id_customer);
$orderBuilder->setCmsOrder($order);
if (!empty($orderCart->id)) {
$orderBuilder->setCmsCart($orderCart);
} else {
$orderBuilder->setCmsCart(null);
}
if (!empty($orderCustomer->id)) {
$orderBuilder->setCmsCustomer($orderCustomer);
} else {
//TODO
// Caused crash before because of empty RetailcrmOrderBuilder::cmsCustomer.
// Current version *shouldn't* do this, but I suggest more tests for guest customers.
$orderBuilder->setCmsCustomer(null);
}
try {
$orders[] = $orderBuilder->buildOrderWithPreparedCustomer();
} catch (\InvalidArgumentException $exception) {
RetailcrmLogger::writeCaller('export', sprintf('Error while building %s: %s', $record['id_order'], $exception->getMessage()));
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
RetailcrmLogger::output($exception->getMessage());
}
time_nanosleep(0, 250000000);
if (count($orders) == 50) {
$api->ordersUpload($orders);
$orders = array();
}
}
if (count($orders)) {
$api->ordersUpload($orders);
}
$customers = array();
$customersRecords = RetailcrmExport::getCustomersIds();
foreach ($customersRecords as $record) {
$customerId = $record['id_customer'];
$addressId = $record['id_address'];
$cmsCustomer = new Customer($customerId);
if (Validate::isLoadedObject($cmsCustomer)) {
if ($addressId) {
$cmsAddress = new Address($addressId);
$addressBuilder = new RetailcrmAddressBuilder();
$address = $addressBuilder
->setAddress($cmsAddress)
->build()
->getDataArray();
} else {
$address = array();
}
try {
$customers[] = RetailcrmOrderBuilder::buildCrmCustomer($cmsCustomer, $address);
} catch (\Exception $exception) {
RetailcrmLogger::writeCaller('export', sprintf('Error while building %s: %s', $customerId, $exception->getMessage()));
RetailcrmLogger::writeNoCaller($exception->getTraceAsString());
RetailcrmLogger::output($exception->getMessage());
}
if (count($customers) == 50) {
$api->customersUpload($customers);
$customers = array();
time_nanosleep(0, 250000000);
}
}
}
if (count($customers)) {
$api->customersUpload($customers);
}
RetailcrmExport::init();
RetailcrmExport::$api = $api;
RetailcrmExport::exportOrders();
RetailcrmExport::exportCustomers();
}
return true;

View File

@ -74,6 +74,11 @@ class RetailcrmSettingsTemplate extends RetailcrmAbstractTemplate
$params['methodsForDefault'] = $this->module->reference->getPaymentAndDeliveryForDefault(
array($this->module->translate('Delivery method'), $this->module->translate('Payment type'))
);
$params['ordersCount'] = RetailcrmExport::getOrdersCount();
$params['customersCount'] = RetailcrmExport::getCustomersCount();
$params['exportCustomersCount'] = RetailcrmExport::getCustomersCount(false);
$params['exportOrdersStepSize'] = RetailcrmExport::RETAILCRM_EXPORT_ORDERS_STEP_SIZE_WEB;
$params['exportCustomersStepSize'] = RetailcrmExport::RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_WEB;
}
return $params;

View File

@ -63,6 +63,8 @@ class RetailCRM extends Module
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';
const EXPORT_ORDERS = 'RETAILCRM_EXPORT_ORDERS_STEP';
const EXPORT_CUSTOMERS = 'RETAILCRM_EXPORT_CUSTOMERS_STEP';
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';
@ -261,9 +263,15 @@ class RetailCRM extends Module
if (Tools::isSubmit('submit' . $this->name)) {
$ordersIds = (string)(Tools::getValue(static::UPLOAD_ORDERS));
$exportOrders = (int)(Tools::getValue(static::EXPORT_ORDERS));
$exportCustomers = (int)(Tools::getValue(static::EXPORT_CUSTOMERS));
if (!empty($ordersIds)) {
$output .= $this->uploadOrders(RetailcrmTools::partitionId($ordersIds));
} elseif (!empty($exportOrders)) {
return $this->export($exportOrders);
} elseif (!empty($exportCustomers)) {
return $this->export($exportCustomers, 'customer');
} else {
$output .= $this->saveSettings();
}
@ -357,6 +365,45 @@ class RetailCRM extends Module
}
}
/**
* @param int $step
* @param string $entity
* @return bool
*/
public function export($step, $entity = 'order')
{
$step--;
if ($step < 0)
return false;
$api = RetailcrmTools::getApiClient();
if (empty($api)) {
RetailcrmLogger::writeCaller(__METHOD__, 'Set API key & URL first');
return false;
}
RetailcrmExport::init();
RetailcrmExport::$api = $api;
if ($entity === 'order') {
$stepSize = RetailcrmExport::RETAILCRM_EXPORT_ORDERS_STEP_SIZE_WEB;
RetailcrmExport::$ordersOffset = $stepSize;
RetailcrmExport::exportOrders($step * $stepSize, $stepSize);
// todo maybe save current step to database
} elseif ($entity === 'customer') {
$stepSize = RetailcrmExport::RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE_WEB;
RetailcrmExport::$customersOffset = $stepSize;
RetailcrmExport::exportCustomers($step * $stepSize, $stepSize);
// todo maybe save current step to database
}
return true;
}
public function hookActionCustomerAccountAdd($params)
{
if ($this->api) {

View File

@ -47,10 +47,17 @@ $_MODULE['<{retailcrm}prestashop>settings_27096e1243f98e1b3300f57ff1c76456'] = '
$_MODULE['<{retailcrm}prestashop>settings_5b385947acf10ac0c5521161ce96aaa7'] = 'Elige la entrega';
$_MODULE['<{retailcrm}prestashop>settings_7dcc1208fa03381346955c6732d9ea85'] = 'Elige el tipo';
$_MODULE['<{retailcrm}prestashop>settings_acfa058ec9e6e4745eddc0cae3f0f881'] = 'Identificador del pedido';
$_MODULE['<{retailcrm}prestashop>settings_91412465ea9169dfd901dd5e7c96dd99'] = 'Exportar';
$_MODULE['<{retailcrm}prestashop>settings_91412465ea9169dfd901dd5e7c96dd99'] = 'Subir';
$_MODULE['<{retailcrm}prestashop>settings_4d3d769b812b6faa6b76e1a8abaece2d'] = 'Active';
$_MODULE['<{retailcrm}prestashop>settings_f75d8fa5c89351544d372cf90528ccf2'] = 'Clave de la página web';
$_MODULE['<{retailcrm}prestashop>settings_c9cc8cce247e49bae79f15173ce97354'] = 'Guardar';
$_MODULE['<{retailcrm}prestashop>settings_30a8be02b0e6e45988617eca94301966'] = 'Ingrese los ID de los pedidos para cargar en RetailCRM, divididos por una coma. También puede especificar rangos, como "1-10". Se permite subir hasta 10 pedidos a la vez.';
$_MODULE['<{retailcrm}prestashop>settings_f4af7f6987dfee28741ce77ff2d09d46'] = 'Exportar pedidos y clientes';
$_MODULE['<{retailcrm}prestashop>settings_06d94a1c5dfe9d54ef201d2217ca477c'] = 'Puede exportar todos los pedidos y clientes de CMS a RetailCRM presionando el botón "Exportar". Este proceso puede llevar mucho tiempo y es necesario que mantenga la pestaña abierta hasta que termine.';
$_MODULE['<{retailcrm}prestashop>settings_7442e29d7d53e549b78d93c46b8cdcfc'] = 'Pedidos';
$_MODULE['<{retailcrm}prestashop>settings_e6d0e1c8fc6a4fcf47869df87e04cd88'] = 'Clientes';
$_MODULE['<{retailcrm}prestashop>settings_f8f36c02fa6f370808135c66cfc788aa'] = 'Clientes sin pedidos';
$_MODULE['<{retailcrm}prestashop>settings_0095a9fa74d1713e43e370a7d7846224'] = 'Exportar';
$_MODULE['<{retailcrm}prestashop>settings_4f18e3f1c9941a6ec5a38bc716c521b4'] = 'Código que necesita insertar en la web';
$_MODULE['<{retailcrm}prestashop>settings_9082f68bc90113d8950e4ed7fe8fa0a4'] = 'Administrador de tareas';
$_MODULE['<{retailcrm}prestashop>settings_9194de58ce560c095f02cefc1c1c61e6'] = 'Nombre de la tarea';

View File

@ -52,6 +52,13 @@ $_MODULE['<{retailcrm}prestashop>settings_4d3d769b812b6faa6b76e1a8abaece2d'] = '
$_MODULE['<{retailcrm}prestashop>settings_f75d8fa5c89351544d372cf90528ccf2'] = 'Ключ сайта';
$_MODULE['<{retailcrm}prestashop>settings_c9cc8cce247e49bae79f15173ce97354'] = 'Сохранить';
$_MODULE['<{retailcrm}prestashop>settings_4f18e3f1c9941a6ec5a38bc716c521b4'] = 'Код для вставки на сайт';
$_MODULE['<{retailcrm}prestashop>settings_30a8be02b0e6e45988617eca94301966'] = 'Введите идентификаторы заказов для загрузки в RetailCRM, разделив их запятыми. Вы также можете указать диапазоны, например "1-10". Одновременно можно загружать до 10 заказов.';
$_MODULE['<{retailcrm}prestashop>settings_f4af7f6987dfee28741ce77ff2d09d46'] = 'Экспортировать заказы и клиентов';
$_MODULE['<{retailcrm}prestashop>settings_06d94a1c5dfe9d54ef201d2217ca477c'] = 'Вы можете экспортировать все заказы и клиентов из CMS в RetailCRM, нажав кнопку «Экспорт». Этот процесс может занять много времени, и до его завершения необходимо держать вкладку открытой.';
$_MODULE['<{retailcrm}prestashop>settings_7442e29d7d53e549b78d93c46b8cdcfc'] = 'Заказы';
$_MODULE['<{retailcrm}prestashop>settings_e6d0e1c8fc6a4fcf47869df87e04cd88'] = 'Клиенты';
$_MODULE['<{retailcrm}prestashop>settings_f8f36c02fa6f370808135c66cfc788aa'] = 'Клиенты без заказов';
$_MODULE['<{retailcrm}prestashop>settings_0095a9fa74d1713e43e370a7d7846224'] = 'Экспортировать';
$_MODULE['<{retailcrm}prestashop>settings_9082f68bc90113d8950e4ed7fe8fa0a4'] = 'Менеджер задач';
$_MODULE['<{retailcrm}prestashop>settings_9194de58ce560c095f02cefc1c1c61e6'] = 'Имя задачи';
$_MODULE['<{retailcrm}prestashop>settings_05a3a24340b7b9cc8d4e08f0ef4f4dd9'] = 'Последний запуск';

View File

@ -0,0 +1,45 @@
.retail {
&-circle {
float: left;
width: 50%;
text-align: center;
padding: 20px;
margin: 20px 0;
&__title {
font-size: 18px;
margin-bottom: 20px;
}
input&__content {
width: 120px;
height: 120px;
border-radius: 120px;
text-align: center;
font-size: 20px;
line-height: 60px;
}
}
&-progress {
border-radius: 60px;
border: 1px solid rgba(122, 122, 122, 0.15);
width: 100%;
height: 60px;
overflow: hidden;
transition: height 0.25s ease;
&__loader {
width: 0;
border-radius: 60px;
background: #0068FF;
color: white;
text-align: center;
padding: 0 30px;
font-size: 18px;
font-weight: 600;
transition: width 0.4s ease-in;
line-height: 60px;
}
}
&-hidden {
visibility: hidden;
height: 0!important;
}
}

View File

@ -0,0 +1 @@
.retail-circle{float:left;width:50%;text-align:center;padding:20px;margin:20px 0}.retail-circle__title{font-size:18px;margin-bottom:20px}input.retail-circle__content{width:120px;height:120px;border-radius:120px;text-align:center;font-size:20px;line-height:60px}.retail-progress{border-radius:60px;border:1px solid rgba(122,122,122,0.15);width:100%;height:60px;overflow:hidden;transition:height .25s ease}.retail-progress__loader{width:0;border-radius:60px;background:#0068FF;color:white;text-align:center;padding:0 30px;font-size:18px;font-weight:600;transition:width .4s ease-in;line-height:60px}.retail-hidden{visibility:hidden;height:0!important}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,143 @@
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
$(function () {
function RetailcrmExportForm() {
this.form = $('input[name=RETAILCRM_EXPORT_ORDERS_COUNT]').closest('form').get(0);
if (typeof this.form === 'undefined') {
return 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());
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);
}
RetailcrmExportForm.prototype.submitAction = function (event) {
event.preventDefault();
this.initializeProgressBar();
this.exportAction();
};
RetailcrmExportForm.prototype.exportAction = function () {
let data = {};
if (this.ordersStep * this.ordersStepSize < this.ordersCount) {
this.ordersStep++;
data = {
submitretailcrm: 1,
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
}
} else {
return this.exportDone();
}
}
let _this = this;
$.ajax({
url: this.form.action,
method: this.form.method,
timeout: 0,
data: data
})
.done(function (response) {
_this.updateProgressBar();
_this.exportAction();
})
};
RetailcrmExportForm.prototype.initializeProgressBar = function () {
$(this.submitButton).addClass('retail-hidden');
$(this.progressBar)
.removeClass('retail-hidden')
.append($('<div/>', {class: 'retail-progress__loader', text: '0%'}))
window.addEventListener('beforeunload', this.confirmLeave);
};
RetailcrmExportForm.prototype.updateProgressBar = function () {
let processedOrders = this.ordersStep * this.ordersStepSize;
if (processedOrders > this.ordersCount)
processedOrders = this.ordersCount;
let processedCustomers = this.customersStep * this.customersStepSize;
if (processedCustomers > this.customersCount)
processedCustomers = this.customersCount;
const processed = processedOrders + processedCustomers;
const total = this.ordersCount + this.customersCount;
const percents = Math.round(100 * processed / total);
$(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);
};
RetailcrmExportForm.prototype.confirmLeave = function (event) {
event.preventDefault();
e.returnValue = 'Export process has been started';
}
RetailcrmExportForm.prototype.exportDone = function () {
window.removeEventListener('beforeunload', this.confirmLeave);
alert('Export is done')
}
window.RetailcrmExportForm = RetailcrmExportForm;
});

View File

@ -0,0 +1,37 @@
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
$(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<this.ordersCount)this.ordersStep++,t={submitretailcrm:1,RETAILCRM_EXPORT_ORDERS_STEP:this.ordersStep};else{if(!(this.customersStep*this.customersStepSize<this.customersCount))return this.exportDone();this.customersStep++,t={submitretailcrm:1,RETAILCRM_EXPORT_CUSTOMERS_STEP:this.customersStep}}let e=this;$.ajax({url:this.form.action,method:this.form.method,timeout:0,data:t}).done(function(t){e.updateProgressBar(),e.exportAction()})},t.prototype.initializeProgressBar=function(){$(this.submitButton).addClass("retail-hidden"),$(this.progressBar).removeClass("retail-hidden").append($("<div/>",{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});

View File

@ -43,6 +43,7 @@ $(function(){
this.player.init();
this.tabs.init();
this.uploadForm.init(this.settingsTabs.init());
this.exportForm.init()
this.popup.init();
this.toggleBox();
this.trimConsultant();
@ -233,6 +234,13 @@ $(function(){
}
}
},
exportForm: {
init: function () {
if (!(typeof RetailcrmExportForm === 'undefined')) {
new RetailcrmExportForm();
}
}
},
tabs: {
init: function () {
$('.retail-tabs__btn').on('click', this.swithTab);

File diff suppressed because one or more lines are too long

View File

@ -40,6 +40,7 @@
<link rel="stylesheet" href="{$assets|escape:'htmlall':'UTF-8'}/css/vendor/sumoselect.min.css">
<link rel="stylesheet" href="{$assets|escape:'htmlall':'UTF-8'}/css/sumoselect-custom.min.css">
<link rel="stylesheet" href="{$assets|escape:'htmlall':'UTF-8'}/css/retailcrm-upload.min.css">
<link rel="stylesheet" href="{$assets|escape:'htmlall':'UTF-8'}/css/retailcrm-export.min.css">
<link rel="stylesheet" href="{$assets|escape:'htmlall':'UTF-8'}/css/styles.min.css">
<title>RetailCRM</title>
<div class="retail retail-wrap hidden">
@ -180,11 +181,44 @@
</div>
<div id="rcrm_tab_orders_upload">
<div class="retail-form__title">{l s='Upload orders' mod='retailcrm'}</div>
<div class="retail-form__label">{l s='Enter order IDs to upload to RetailCRM, divided by a comma. You can also specify ranges, like "1-10". It\'s allowed to upload to 10 orders at a time.' mod='retailcrm'}</div>
<div class="retail-form__row">
<input type="text" name="{$uploadOrders|escape:'htmlall':'UTF-8'}" value="" class="retail-form__area" placeholder="{l s='Orders IDs' mod='retailcrm'}">
<input type="text" name="{$uploadOrders|escape:'htmlall':'UTF-8'}" value=""
class="retail-form__area" placeholder="{l s='Orders IDs' mod='retailcrm'}">
</div>
<div class="retail-form__row retail-form__row_submit">
<button id="upload-orders-submit" class="btn btn_invert btn_submit" style="outline: none;">{l s='Upload' mod='retailcrm'}</button>
<button id="upload-orders-submit" class="btn btn_invert btn_submit"
style="outline: none;">{l s='Upload' mod='retailcrm'}</button>
</div>
<div class="retail-form__title"
style="margin-top: 40px;">{l s='Export orders & customers' mod='retailcrm'}</div>
<div class="retail-form__label">{l s='You can export all the orders and customers from CMS to RetailCRM by pressing "Export" button. This process can take a long time, and it\'s required that you keep the tab opened until it\'s done.' mod='retailcrm'}</div>
<div class="retail-form__row">
<div class="retail-circle">
<div class="retail-circle__title">{l s='Orders' mod='retailcrm'}</div>
<input type="text" name="RETAILCRM_EXPORT_ORDERS_COUNT" readonly="readonly"
class="retail-circle__content" value="{$ordersCount}"/>
<input type="hidden" name="RETAILCRM_EXPORT_ORDERS_STEP_SIZE"
value="{$exportOrdersStepSize}"/>
</div>
<div class="retail-circle">
<div class="retail-circle__title">
{l s='Customers' mod='retailcrm'}
</div>
<input type="text" readonly="readonly"
title="{l s='Customers without orders' mod='retailcrm'}: {$exportCustomersCount}"
class="retail-circle__content" value="{$customersCount}"/>
<input type="hidden" name="RETAILCRM_EXPORT_CUSTOMERS_COUNT"
value="{$exportCustomersCount}"/>
<input type="hidden" name="RETAILCRM_EXPORT_CUSTOMERS_STEP_SIZE"
value="{$exportCustomersStepSize}"/>
</div>
</div>
<div class="retail-form__row retail-form__row_submit"
style="text-align: center; height: 60px; margin-bottom: 20px; clear:both;">
<button id="export-orders-submit" class="btn btn_invert btn_submit"
style="outline: none;">{l s='Export' mod='retailcrm'}</button>
<div id="export-orders-progress" class="retail-progress retail-hidden"></div>
</div>
</div>
<div id="rcrm_tab_daemon_collector">
@ -286,4 +320,5 @@
<script src="{$assets|escape:'htmlall':'UTF-8'}/js/vendor/jquery.sumoselect.min.js"></script>
<script src="{$assets|escape:'htmlall':'UTF-8'}/js/retailcrm-tabs.min.js"></script>
<script src="{$assets|escape:'htmlall':'UTF-8'}/js/retailcrm-upload.min.js"></script>
<script src="{$assets|escape:'htmlall':'UTF-8'}/js/retailcrm-export.min.js"></script>
<script src="{$assets|escape:'htmlall':'UTF-8'}/js/retailcrm.min.js"></script>