mirror of
https://github.com/retailcrm/prestashop-module.git
synced 2025-03-01 19:03:14 +03:00
Added export functionality on the module settings page
This commit is contained in:
parent
9e9c13bb66
commit
ad9ce38131
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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';
|
||||
|
@ -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'] = 'Последний запуск';
|
||||
|
45
retailcrm/views/css/less/retailcrm-export.less
Normal file
45
retailcrm/views/css/less/retailcrm-export.less
Normal 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;
|
||||
}
|
||||
}
|
1
retailcrm/views/css/retailcrm-export.min.css
vendored
Normal file
1
retailcrm/views/css/retailcrm-export.min.css
vendored
Normal 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}
|
612
retailcrm/views/css/styles.min.css
vendored
612
retailcrm/views/css/styles.min.css
vendored
File diff suppressed because one or more lines are too long
143
retailcrm/views/js/retailcrm-export.js
Normal file
143
retailcrm/views/js/retailcrm-export.js
Normal 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;
|
||||
});
|
37
retailcrm/views/js/retailcrm-export.min.js
vendored
Normal file
37
retailcrm/views/js/retailcrm-export.min.js
vendored
Normal 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});
|
@ -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);
|
||||
|
38
retailcrm/views/js/retailcrm.min.js
vendored
38
retailcrm/views/js/retailcrm.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user