retailcrm / bitrix-module Goto Github PK
View Code? Open in Web Editor NEWBitrix integration plugin
Home Page: http://www.retailcrm.ru
License: MIT License
Bitrix integration plugin
Home Page: http://www.retailcrm.ru
License: MIT License
Возможно, проявляется только в режиме "Выгрузка заказов с помощью агента" - сейчас модуль работает в этом режиме.
По моим наблюдениям, проявляется, когда оплата происходит не сразу. Если оплата происходит достаточно быстро и попадает в передачу вновь созданного заказа, то статус заказа retailCRM верный.
На скриншотах видно, что информация об изменении платежа поступила в retailCRM, а о новом статусе - нет.
История заказа в Bitrix:
В дополнение, в 00:13 модуль retailCRM поменял статус заказа обратно на "Ждём оплату" (собственно это и обратило внимание на проблему).
assemblyOrderHistory.log
:
Array
(
[TIME] => 2020-04-20 00:13:02
[DATA] => Array
(
[id] => 28719
[externalId] => 27768
[managerId] => 27
[site] => xxxxxxxxxxxxxxxxx
[status] => waiting-for-payment
[payments] => Array
(
[32715] => Array
(
[id] => 32715
[type] => bank-card
[externalId] => 31960_5c0fd719161cc
[status] => Array
(
[code] => paid
)
)
)
)
)
В следствие чего, чтобы узнать ID заказа Bitrix, приходится делать запрос в retailCRM API.
Предлагаемое решение: заполнять $order[externalId] = $newOrder->getId()
после вызова ordersFixExternalIds
.
Обновление ref #315 поломало отправку адреса из отдельных полей, т.к ранее он собирался таким образом:
if (!empty($prop['VALUE'][0])) {
$order['delivery']['address'][$search] = $prop['VALUE'][0];
}
Конкретно не отправляет улицу, дом, квартиру.
intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
Кейс, когда это помешало передаче изменённого адреса доставки в заказе из CRM в Bitrix.
Новый заказ передаётся из Bitrix в CRM с таким адресом (orderHistory.log
):
[address] => Array
(
[id] => 29720
[text] => 123182, г. Москва, Науки проспект. Дом 17 корпус 2 подезд 4
)
Менеджер почти сразу правит адрес. Изменения возвращаются в Bitrix в таком виде (assemblyOrderHistory.log
):
[address] => Array
(
[id] => 29720
[text] => 123182, г. Москва, Науки проспект. Дом 17 корпус 2 подезд 4
[building] => 7
[city] => Санкт-Петербург
[region] => Санкт-Петербург город
[street] => Науки
[block] => 4
[housing] => 2
)
Как я понимаю, это результат объединения изменения с флагом created=true
с последующими изменениями полей.
В итоге адрес в Bitrix остаётся прежним - 123182, г. Москва, Науки проспект. Дом 17 корпус 2 подезд 4 - не то, чего ожидает менеджер.
Есть вероятность, что при генерации фида в /classes/general/icml/RetailCrmICML.php:391 попадет пустой массив $products . Из за чего будут дубли торговых предложений в фиде.
Удалось такое поймать на версии модуля 5.2.6
Здравствуйте.
Если приходит новая оплата из RetailCRM то позже идёт обновление externalId в системе.
Сейчас http://joxi.ru/Rmz1b8GiR1KEjr
Как исправить http://joxi.ru/VrwXb1vc8N365m
Проблема для товаров новых в заказе, каждый новый берет id предыдущего уже существующего товара в заказе, так как id не сбрасывается
Обнаружил некорректную работу передачи типа доставки при выгрузке истории из CRM в Bitrix.
Здесь
модуль берет отгрузки заказа в битриксе и исключает системные отгрузки из цикла (по умолчанию в заказе всегда есть системная скрытая отгрузка https://dev.1c-bitrix.ru/api_d7/bitrix/sale/technique/shipment.php), ходит по циклу отгрузок и меняет все несистемные отгрузки на те данные, что пришли в истории изменений из CRM.Но есть исключение. Если по какой-то причине в заказе в битриксе отсутствует отгрузка (её не создали или удалили), то модуль ничего не обновит, так как он ходит по циклу из одного элемента, которым является системная отгрузка.
В итоге если в заказе в CRM менять тип доставки, то в заказе в битриксе ничего не изменится в блоке отгрузки. Предложение следующее:
$updated = false;
После того как модуль смог отредактировать сущетсвующую в заказе отгрузку добавить $updated = true;
А затем:
foreach
добавить следующий код:
if (!$updated) {
$shipment = $shipmentColl->createItem($delivery);
$shipment->setFields(array(
'BASE_PRICE_DELIVERY' => $orderCrm['delivery']['cost'],
'CURRENCY' => $order->getCurrency(),
'DELIVERY_NAME' => $delivery->getName(),
'CUSTOM_PRICE_DELIVERY' => 'Y'
));
}
Он как раз будет выполняться в случае если ни одной отгрузки нет в заказе битрикса и корректно будут переданы изменения типа доставки из CRM. И плюс заработает данный код:
$noDeliveryId = \Bitrix\Sale\Delivery\Services\EmptyDeliveryService::getEmptyDeliveryServiceId();
if ($crmCode === false || !isset($optionsDelivTypes[$crmCode])) {
$deliveryId = $noDeliveryId;
}
В случае если в заказе в CRM будет снят тип доставки, то в заказе в битриксе будет создана стандартная битриксовая отгрузка "Без доставки". Полагаю такая работа модуля и задумывалась.
Информация актуальна и для 5.6.2 и для 5.8.4, так как метод deliveryUpdate
не изменялся.
Как я понимаю, так происходит, если в истории заказа CRM нет изменения какой либо части ФИО.
В bitrix/modules/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
сначала идёт блок if
if ($order['firstName'] || $order['lastName'] || $order['patronymic']) {
//...
}
затем, вне указанного if
$order['fio'] = str_replace("clear", "", $order['fio']);
Т.о. всегда, когда if
не выполняется, в $order['fio']
оказывается пустая строка, что и записывается в заказ Bitrix.
Здравствуйте.
purchasePrice — закупочная цена торгового предложения (товара), не является обязательной; При отсутствии тега в файле значение не будет сбрасываться; Закупочная цена может быть целой или дробной с точностью до 2 знаков после запятой в промежутке от 0 до 99 999 999;
Поэтому логично было бы сделать сброс закупочной цены на 0 если она не указана, т.к. возможны случаи что цена ранее была указана, попала в црм, а потом её удалили из битрикс. И данные в crm будут ложные и могут вводить в заблуждение менеджеров.
if ($arOffer['PURCHASE_PRICE'] && $this->loadPurchasePrice) {
$offer .= "<purchasePrice>" . $this->PrepareValue($arOffer['PURCHASE_PRICE']) . "</purchasePrice>\n";
}else{
$offer .= "<purchasePrice>0</purchasePrice>\n";
}
Агент перестал отрабатывать, в лог сыпется ошибка вида:
2022-07-12 20:15:45 - Host: NULL - UNCAUGHT_EXCEPTION - [TypeError]
Return value of Intaro\RetailCrm\Component\Builder\Bitrix\LoyaltyDataBuilder::getResult() must be of the type array, null returned (0)
/home/bitrix/ext_www/site.ru/www/bitrix/modules/intaro.retailcrm/lib/component/builder/bitrix/loyaltydatabuilder.php:118
#0: Intaro\RetailCrm\Component\Builder\Bitrix\LoyaltyDataBuilder->getResult()
/home/bitrix/ext_www/site.ru/www/bitrix/modules/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php:1202
#1: RetailCrmHistory::orderHistory()
/home/bitrix/ext_www/site.ru/www/bitrix/modules/intaro.retailcrm/classes/general/RCrmActions.php:234
#2: RCrmActions::orderAgent()
/home/bitrix/ext_www/site.ru/www/bitrix/modules/main/classes/mysql/agent.php(163) : eval()'d code:1
#3: eval
/home/bitrix/ext_www/site.ru/www/bitrix/modules/main/classes/mysql/agent.php:163
#4: CAgent::ExecuteAgents()
/home/bitrix/ext_www/site.ru/www/bitrix/modules/main/classes/mysql/agent.php:21
#5: CAgent::CheckAgents()
/home/bitrix/ext_www/site.ru/www/bitrix/php_interface/cron_events.php:16
Версия последняя на текущий момент 6.1.2
Проблема оказалась в пустом заказе. У заказа нет товаров, отсюда в LoyaltyDataBuilder $this->data = null
В классе ApiClient_v5 объявлены два метода для работы с интеграциями доставки: deliverySettingsGet, deliverySettingsEdit
Они обращаются к методам АПИ v4 судя по официальной документации. Не должны ли они соответственно обращаться к новым методам: http://www.retailcrm.ru/docs/Developers/ApiVersion5#get--api-v5-integration-modules-code и http://www.retailcrm.ru/docs/Developers/ApiVersion5#post--api-v5-integration-modules-code-edit
Возможно в классе для АПИ v5 есть и другие неточности
При формировании ICML каталога закупочная цена явно приводится к int
https://github.com/retailcrm/bitrix-module/blob/v5.8.1/intaro.retailcrm/lib/icml/xmlofferbuilder.php#L254
private function getPurchasePrice(array $product, ?bool $isLoadPrice, string $purchasePriceNull): ?int
Если в каталоге Bitrix задана цена с копейками, то генератор отбрасывает копейки, в итоге в CRM получаем некорректную закупочную цену. Например, вместо 58.64
получаем 58
.
Необходимо отдавать число во float
В тех.поддержку retailCRM сделано обращение 102820
В битриксе у пользователей в БД id имеет тип int.
Пользователи из retailCRM chat имеют в external_id какой-то гуид (например, 11ac021fa531e4ba30080a6e2447c063).
Далее в RetailCrmHistory_v5 идет перенос данных пользователя, в БД, скорее всего, уходит запрос вида: update b_user (..) set (...) where id = '11ac021fa531e4ba30080a6e2447c063'. В итоге обновляется пользователь с ключом 11, который к исходному пользователю чата retailCRM не имеет никакого отношения.
На запрос select * from b_user where id = '11ac021fa531e4ba30080a6e2447c063' MySQL возвращает данные для id=11 и warning "Truncated incorrect DOUBLE value '11ac021fa531e4ba30080a6e2447c063'". Если делать id = 11ac021fa531e4ba30080a6e2447c063, то выдаётся ошибка
Сейчас приходится ходить за пользовательскими полями в API CRM - хотелось бы обойтись без этого.
В указанном методе в блоке
if ($found) {
//...
}
производится запись в лог $log->write($customer, 'customerSend');
- на мой взгляд, рано, т.к. далее происходит вызов retailCrmBeforeCustomerSend()
, который модифицирует $customer
или отменяет передачу. Предалагаю разместить логирование непосредственно перед вызовом RCrmActions::apiMethod()
, а-то лог вводит в заблуждение.
Например, если в retailCrmBeforeOrderSend()
задать значение
$order['delivery']['date'] = '';
то нормализер перепишет текущей датой. Это не то, чего ожидаешь, когда есть цель убрать дату доставки.
Не работает история. Подскажите, пожалуйста, как настроить агента или крон для работы истории?
А $orderPayment->getId()
так может... (Даже не пытаюсь понять, почему он так может.)
В следствие чего в блоке if (!empty($newHistoryPayments)) { ... }
вызов \Bitrix\Sale\Internals\PaymentTable::update($paymentId, array('XML_ID' => ''))
приводит к исключению и прерыванию работы программы, не записывается sinceId
, в следующий раз обработчик начинает с того же места и так до бесконечности.
Столкнулись с ситуацией, когда апи возвращает на первой странице истории пустой массив, а на следующих есть изменения (видимо за счет отбрасывания изменений о множественных оплатах)
http://joxi.ru/n2Y00nkFo13bYm
Этот код в такой ситуации останавливается и дальше загрузка не идет
https://github.com/retailcrm/bitrix-module/blob/master/intaro.retailcrm/classes/general/history/RetailCrmHistory.php#L303
В условии нужно проверять не пустой массив, а что текущая страница равна последней
Как мне кажется это вызвано тем, что на строке 467 (orderHistory) выставляется $propsRemove = true;
Далее на 520 строке идет замена заказа сформированного assemblyOrder на весь заказ полученный из crm $order = $orderCrm['order'];
А на 612 строке проверка if (array_key_exists($key, $order))
не проходит, так как массив $order содержит весь заказ, а там такие параметры как к примеру инн хранятся в виде order[contragent][INN]
, сама проверка же сделана для массива assemblyOrder
где инн хранится сразу без [contragent]
P.S. если поменять физлицо на юрлицо, дать отработать истории, а потом внести юр реквизиты то всё будет нормально. Что косвенно подтверждает мою теорию насчет проблемы в замене массива заказа
P.P.S. Примерная говнокодерское расширение if решает проблему
if (array_key_exists($key, $order)) {
$somePropValue = $propertyCollection->getItemByOrderPropertyId($propsKey[$orderProp]['ID']);
self::setProp($somePropValue, $order[$key]);
}elseif(array_key_exists($key, $order['contragent'])){
$somePropValue = $propertyCollection->getItemByOrderPropertyId($propsKey[$orderProp]['ID']);
self::setProp($somePropValue, $order['contragent'][$key]);
}
при отправке данных в crm, цена со скидкой формируется исходя из базовой цены BASE_PRICE
и цены скидки DISCOUNT_PRICE
$discount = (double) $product['DISCOUNT_PRICE'];
$dpItem = $product['BASE_PRICE'] - $product['PRICE'];
if ( $dpItem > 0 && $discount <= 0) {
$discount = $dpItem;
}
$item['discountManualPercent'] = 0;
$item['discountManualAmount'] = $discount;
$item['initialPrice'] = (double) $product['BASE_PRICE'];
но когда цена назначена через CUSTOM_PRICE = Y
, поле скидка не актуально, отсюда в crm попадают неверные данные
полагаю нужно просто скидку всегда назначать через (базовая - цена)
Нет каких либо префиксов/постфиксов у externalId оплат из битрикс. Из-за этого если к crm подключено несколько сайтов на bitrix с этим модулем то возникает конфликт externalId оплат, т.к. они должны быть уникальны на всю crm, а не только на магазин
Добрый день, после обновления модуля до последней версии 6+, у нас перестали работать кастомизации с файла RetailCrmICML.php, судя по файлу export_run.php он нигде не используется в новой генерации кроме его подключения в include.php . Как нам кастомизировать генерацию на данный момент?
При обновлении перезаписывается файл ./intaro.retailcrm/classes/general/config/options.xml. В результате слетают настройки кастомных полей
http://screenshot.irisdigital.ru/r0j8o_2021-04-01_16.11.47.png
Если со стороны retailCrm в поле "Город" поставить точку, то во время обмена с битриксом из за отсуствия проверки на пустоту строки, \Bitrix\Sale\Location\Search\Finder::find падает на Assert::expectStringNotNull . Получилось повторить два раза со строкой, которая содержит только точку.
В классе RCrmActions есть статический метод unserializeArrayRecursive, внутри которого есть вызов несуществующего в классе метода unserializeRecursive.
Если в црм на товар указать скидку, то в битриксе проставится новая цена. Однако при любых изменениях заказа в битриксе, информация вновь отправляется в црм с ценой с учетом скидки, на которую црм вновь ее применяет.
Это ошибка или можно как-то с галок сделать, чтобы такого не проиходило?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.