diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a63b23d..bbf400e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2025-09-26 v6.7.5 +- Добавлена опция обновления участий программы лояльности + ## 2025-08-29 v6.7.4 - Обновлен тип данных у стоимости доставки diff --git a/intaro.retailcrm/classes/general/user/RetailCrmUser.php b/intaro.retailcrm/classes/general/user/RetailCrmUser.php index dc454941..28581211 100644 --- a/intaro.retailcrm/classes/general/user/RetailCrmUser.php +++ b/intaro.retailcrm/classes/general/user/RetailCrmUser.php @@ -12,6 +12,8 @@ IncludeModuleLangFile(__FILE__); use Bitrix\Main\UserTable; +use Retailcrm\ApiClient; +use Throwable; /** * Class RetailCrmUser @@ -207,7 +209,7 @@ public static function fixDateCustomer(): void COption::SetOptionString(RetailcrmConstants::MODULE_ID, RetailcrmConstants::OPTION_FIX_DATE_CUSTOMER, 'Y'); $startId = COption::GetOptionInt(RetailcrmConstants::MODULE_ID, RetailcrmConstants::OPTION_FIX_DATE_CUSTOMER_LAST_ID, 0); - $api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); + $api = new ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); $optionsSitesList = RetailcrmConfigProvider::getSitesList(); $limit = 50; $offset = 0; @@ -221,7 +223,7 @@ public static function fixDateCustomer(): void 'limit' => $limit, 'offset' => $offset, ]); - } catch (\Throwable $exception) { + } catch (Throwable $exception) { Logger::getInstance()->write($exception->getMessage(), 'fixDateCustomers'); break; @@ -234,14 +236,10 @@ public static function fixDateCustomer(): void } foreach ($users as $user) { - $site = null; - - if ($optionsSitesList) { - if (isset($user['LID']) && array_key_exists($user['LID'], $optionsSitesList) && $optionsSitesList[$user['LID']] !== null) { - $site = $optionsSitesList[$user['LID']]; - } else { - continue; - } + $site = RetailcrmConfigProvider::getUserSite($user, $optionsSitesList); + + if ($optionsSitesList && $site === null) { + continue; } $customer['externalId'] = $user['ID']; @@ -251,7 +249,7 @@ public static function fixDateCustomer(): void $customer['createdAt'] = $date->format('Y-m-d H:i:s'); RCrmActions::apiMethod($api, 'customersEdit', __METHOD__, $customer, $site); - } catch (\Throwable $exception) { + } catch (Throwable $exception) { Logger::getInstance()->write($exception->getMessage(), 'fixDateCustomers'); continue; } @@ -264,4 +262,102 @@ public static function fixDateCustomer(): void $offset += $limit; } } + + public static function updateLoyaltyAccountIds(): bool + { + $api = new ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); + $offset = 0; + $limit = 50; + $optionsSitesList = RetailcrmConfigProvider::getSitesList(); + $status = true; + + while (true) { + try { + $usersResult = UserTable::getList([ + 'select' => ['ID', 'UF_REG_IN_PL_INTARO', 'LID', 'UF_LP_ID_INTARO'], + 'filter' => ['=UF_REG_IN_PL_INTARO' => true], + 'order' => ['ID'], + 'limit' => $limit, + 'offset' => $offset + ]); + } catch (Throwable $exception) { + Logger::getInstance()->write($exception->getMessage(), 'loyaltyIdsUpdate'); + + $status = false; + + break; + } + + $users = $usersResult->fetchAll(); + + if ($users === []) { + break; + } + + $offset += $limit; + + foreach ($users as $user) { + $site = RetailcrmConfigProvider::getUserSite($user, $optionsSitesList); + + if ($optionsSitesList && $site === null) { + continue; + } + + $filter['customerExternalId'] = $user['ID']; + + try { + $actualLoyalty = null; + $crmAccounts = RCrmActions::apiMethod($api, 'getLoyaltyAccounts', __METHOD__, $filter, $site); + + foreach ($crmAccounts['loyaltyAccounts'] as $crmAccount) { + $loyalty = $crmAccounts = RCrmActions::apiMethod( + $api, + 'getLoyaltyLoyalty', + __METHOD__, + $crmAccount['loyalty']['id'], + $site + ); + + if ($loyalty['loyalty']['active'] === true) { + $actualLoyalty = $crmAccount; + + break; + } + } + + if ($actualLoyalty !== null && $user['UF_LP_ID_INTARO'] != $actualLoyalty['id']) { + $updateUser = new CUser; + $cardNumber = isset($actualLoyalty['cardNumber']) ? $actualLoyalty['cardNumber'] : ''; + + $fields = [ + 'UF_LP_ID_INTARO' => $actualLoyalty['id'], + 'UF_CARD_NUM_INTARO' => $cardNumber + ]; + + if ($updateUser->Update($user['ID'], $fields)) { + Logger::getInstance()->write( + sprintf('Обновлен идентификатор участия ПЛ для пользователя с ID %s', $user['ID']), + 'loyaltyIdsUpdate' + ); + } + } + } catch (Throwable $exception) { + Logger::getInstance()->write($exception->getMessage(), 'loyaltyIdsUpdate'); + + continue; + } + + time_nanosleep(0, 550000000); + } + } + + return $status; + } + + public static function updateLoyaltyAccountIdsAgent() + { + self::updateLoyaltyAccountIds(); + + return ''; + } } diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index 151d099d..2ffb24a1 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1 +1 @@ -- Обновлен тип данных у стоимости доставки +- Добавлена опция обновления участий программы лояльности diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index 07212f76..d9d0bf8d 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,6 +1,6 @@ '6.7.4', - 'VERSION_DATE' => '2025-08-29 9:30:00' + 'VERSION' => '6.7.5', + 'VERSION_DATE' => '2025-09-26 9:30:00' ]; diff --git a/intaro.retailcrm/lang/en/options.php b/intaro.retailcrm/lang/en/options.php index 3a7912c6..8db35ff2 100644 --- a/intaro.retailcrm/lang/en/options.php +++ b/intaro.retailcrm/lang/en/options.php @@ -23,6 +23,9 @@ $MESS ['COUPON_CUSTOM_FIELD'] = 'Select a custom field in the CRM to transfer the applied coupon in the Bitrix order'; $MESS ['SELECT_VALUE'] = '-- Select a value --'; $MESS ['ORDER_UPLOAD'] = 'Re-upload orders'; +$MESS ['LP_IDS_UPDATE'] = 'Update participations'; +$MESS ['IDS_UPDATED'] = 'Task successfully created'; +$MESS ['IDS_NOT_UPDATED'] = 'Task not created. Error'; $MESS ['LP_WARNING'] = 'Loyalty program of RetailCRM is available only with the “Uploading orders by event” options active'; $MESS ['ORDER_NUMBER'] = 'Order numbers: '; $MESS ['ORDER_UPLOAD_INFO'] = 'Click "Start uploading" to upload all the orders . Or list the required order IDs separated by commas, intervals or dashes. For example: 1, 3, 5-10, 12, 13... etc.'; diff --git a/intaro.retailcrm/lang/ru/options.php b/intaro.retailcrm/lang/ru/options.php index 92797a91..5f388882 100644 --- a/intaro.retailcrm/lang/ru/options.php +++ b/intaro.retailcrm/lang/ru/options.php @@ -160,6 +160,8 @@ $MESS ['LP_DEF_TEMP_CREATE_MSG'] = 'Заменить шаблон .default компонента sale.order.ajax шаблоном с функциями Программы лояльности.
Если в папке .local уже есть шаблон .default для sale.order.ajax, то он будет скопирован в папку .default_backup'; $MESS ['LOYALTY_PROGRAM_TITLE'] = 'Программа лояльности'; +$MESS ['IDS_UPDATED'] = 'Агент для обновления участий ПЛ создан'; +$MESS ['IDS_NOT_UPDATED'] = 'Ошибка при добавлении агента'; $MESS ['LOYALTY_PROGRAM_TOGGLE_MSG'] = 'Активность программы лояльности'; $MESS ['LP_CUSTOM_TEMP_CREATE_MSG'] = 'Создать шаблон intaro.retailCRM для компонента оформления заказа sale.order.ajax c функциями Программы лояльности.
Внимение: если шаблон уже существует, то он будет перезаписан'; $MESS ['LP_DEF_TEMP_CREATE_MSG'] = 'Заменить шаблон .default компонента sale.order.ajax шаблоном с функциями Программы лояльности.
Если в папке .local уже есть шаблон .default для sale.order.ajax, то он будет скопирован в папку .default_backup'; @@ -169,6 +171,7 @@ $MESS ['LP_CUSTOM_TEMP_CREATE_MSG'] = 'Создать шаблон default_loyalty для компонента регистрации %s c функциями Программы лояльности.
Внимание: если шаблон уже существует, то он будет перезаписан'; $MESS ['LP_DEF_TEMP_CREATE_MSG'] = 'Заменить шаблон .default компонента %s шаблоном с функциями Программы лояльности.
Если в папке шаблонов компонента уже будет .default, то он будет скопирован в папку .default_backup'; $MESS ['LP_CREATE_TEMPLATE'] = 'Создать шаблон'; +$MESS ['LP_IDS_UPDATE'] = 'Обновить участия'; $MESS ['LP_REPLACE_TEMPLATE'] = 'Заменить шаблон'; $MESS ['LP_SALE_ORDER_AJAX_HEAD'] = ' Управление компонентом Оформление заказа (sale.order.ajax)'; $MESS ['LP_TEMP_CHOICE_MSG'] = 'Выберите, в каких шаблонах сайта будет доступен шаблон компонента с функциями Программы лояльности:'; diff --git a/intaro.retailcrm/lib/component/configprovider.php b/intaro.retailcrm/lib/component/configprovider.php index 2102d923..cda06eeb 100644 --- a/intaro.retailcrm/lib/component/configprovider.php +++ b/intaro.retailcrm/lib/component/configprovider.php @@ -1320,4 +1320,24 @@ public static function getStatusCollector() { return static::getOption(Constants::CRM_COLLECTOR, 'N'); } + + /** + * @param array|null $optionsSitesList + * @return string|null + */ + public static function getUserSite(array $user, array $optionsSitesList): ?string + { + if (!$optionsSitesList) { + return null; + } + + if (isset($user['LID']) && + array_key_exists($user['LID'], $optionsSitesList) && + $optionsSitesList[$user['LID']] !== null + ) { + return $optionsSitesList[$user['LID']]; + } + + return null; + } } diff --git a/intaro.retailcrm/lib/component/constants.php b/intaro.retailcrm/lib/component/constants.php index c0ece108..917e4f58 100644 --- a/intaro.retailcrm/lib/component/constants.php +++ b/intaro.retailcrm/lib/component/constants.php @@ -18,7 +18,7 @@ */ class Constants { - public const MODULE_VERSION = '6.7.4'; + public const MODULE_VERSION = '6.7.5'; public const CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null'; public const BITRIX_USER_ID_PREFIX = 'bitrixUserId-'; public const CRM_USERS_MAP = 'crm_users_map'; diff --git a/intaro.retailcrm/lib/controller/adminpanel.php b/intaro.retailcrm/lib/controller/adminpanel.php index 49f02c9c..959f5e7c 100644 --- a/intaro.retailcrm/lib/controller/adminpanel.php +++ b/intaro.retailcrm/lib/controller/adminpanel.php @@ -6,7 +6,7 @@ use Bitrix\Main\Engine\Controller; use Intaro\RetailCrm\Component\ConfigProvider; use Intaro\RetailCrm\Component\Constants; - +use CAgent; /** * @category Integration * @package Intaro\RetailCrm\Controller @@ -88,6 +88,29 @@ public function createTemplateAction(array $templates, string $donor, string $re ]; } + /** + * @return array + */ + public function updateIdsAction(): array + { + $agentName = 'RetailCrmUser::updateLoyaltyAccountIdsAgent();'; + + CAgent::RemoveAgent($agentName, 'intaro.retailcrm'); + + $agentId = CAgent::AddAgent( + $agentName, + 'intaro.retailcrm', + 'N', + 20, + '', + 'Y', + date('d.m.Y H:i:s', time() + 10), + 30 + ); + + return ['success' => $agentId !== false]; + } + /** * @return string[] * @throws \Bitrix\Main\ArgumentOutOfRangeException diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 8023da3a..925d167f 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -1514,6 +1514,27 @@ function createTemplates(donor) { }); } + function updateIds() { + BX.ajax.runAction('intaro:retailcrm.api.adminpanel.updateIds', + { + data: { + sessid: BX.bitrix_sessid() + } + } + ).then(result => { + if (result.data.success === true) { + BX.UI.Notification.Center.notify({ + content: "" + }); + } else { + BX.UI.Notification.Center.notify({ + content: "" + }); + } + + }); + } + function replaceDefaultTemplates(donor) { let templates = []; let i = 0; @@ -2371,6 +2392,13 @@ function updateAddressList() + + +
+ +
+ +