При совпадении нескольких факторов синхронизация истории пользователей агентом модуля приводит к порче данных:
- Имя перезаписывается именем предыдущего (в ответе API) пользователя.
- Логин и email перезаписываются сгенерированным значением вида
user_***@example.com
Порча данных происходит при совпадении нескольких факторов:
- В Битриксе включена обязательность номера телефона для регистрации аккаунта.
- В CRM создан (например, при создании диалога из мессенджера) пользователь без email и номера телефона, которого нет в битриксе (поэтому нет
externalId)
- Агент модуля получает историю существующего в битриксе пользователя после истории указанного выше несуществующего в битриксе пользователя без поля
create.
Проблема в RetailCrmHistory->customerHistory() и переиспользовании объекта CustomerBuilder
|
$customerBuilder = new CustomerBuilder(); |
- Eсли из CRM прилетает клиент без поля
create, то пропускается проверка в начале цикла.
|
if (isset($customer['create']) && empty($customer['phones'])) { |
- Если нет email, то CustomerBuilder->build() генерирует его в виде
user_***@example.com.
|
$customerBuilder->setDataCrm($customer)->build(); |
- Далее так как нет
externalId модуль пытается создать пользователя, но без телефона получает ошибку и выходит из цикла, не дойдя до $customerBuilder->reset().
- Состояние билдера теперь содержит имя, полученное из API, и сгенерированный логин и email, которые достаются следующему -- уже реальному пользователю -- и портят учетную запись.
- После этого испорченные данные улетают уже из Битрикса в Retail CRM и другие системы.
$customerBuilder = new CustomerBuilder(); // Переиспользуется в цикле, внутри содержит Customer
foreach ($customers as $customer) {
if (function_exists('retailCrmBeforeCustomerSave')) {
$newResCustomer = retailCrmBeforeCustomerSave($customer);
if (is_array($newResCustomer) && !empty($newResCustomer)) {
$customer = $newResCustomer;
} elseif ($newResCustomer === false) {
RCrmActions::eventLog('RetailCrmHistory::customerHistory', 'retailCrmBeforeCustomerSave()', 'UserCrmId = ' . $customer['id'] . '. Sending canceled after retailCrmBeforeCustomerSave');
continue;
}
}
if (isset($customer['deleted'])) {
continue;
}
if (RetailcrmConfigProvider::isPhoneRequired()) { // Эта проверка пропускается, если не приходит поле create
if (isset($customer['create']) && empty($customer['phones'])) {
Logger::getInstance()->write('$customer["phones"] is empty. Customer ' . $customer['id'] . ' cannot be created', 'createCustomerError');
continue; // Если обязателен номер телефона, а из CRM приходит без него и без email, то здесь переходит на следующую итерацию без сброса билдера
}
}
В качестве хотфикса предлагаю прекратить переиспользовать экземпляр CustomerBuilder и инициализировать его каждый раз в начале цикла.
При совпадении нескольких факторов синхронизация истории пользователей агентом модуля приводит к порче данных:
user_***@example.comПорча данных происходит при совпадении нескольких факторов:
externalId)create.Проблема в
RetailCrmHistory->customerHistory()и переиспользовании объектаCustomerBuilderbitrix-module/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Line 129 in cad15a4
create, то пропускается проверка в начале цикла.bitrix-module/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Line 148 in cad15a4
user_***@example.com.bitrix-module/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Line 158 in cad15a4
externalIdмодуль пытается создать пользователя, но без телефона получает ошибку и выходит из цикла, не дойдя до$customerBuilder->reset().bitrix-module/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
Line 202 in cad15a4
В качестве хотфикса предлагаю прекратить переиспользовать экземпляр
CustomerBuilderи инициализировать его каждый раз в начале цикла.