Обмен заказами с 1С - выгрузка на сайт и возврат статусов
Настраиваем двусторонний обмен заказами с 1С и разбираемся, почему заказы дублируются, а статусы не возвращаются.
Решение
Включаем обмен заказами и протоколирование:
COption::SetOptionString('sale', 'secure_1c_exchange', 'N'); // без шифрования пакетаCOption::SetOptionString('sale', 'log_level_1c', '3'); // лог выключен по умолчаниюCOption::SetOptionString('sale', '1C_SALE_EXPORT_PAYED', 'Y'); // выгружать оплаченные// уровень протоколирования выше нуля пишет каждый шаг сеанса обменаЛог заказов пишется в /upload/1c_exchange/ и по умолчанию выключен. Без него
разбирать сбой нечем: окно 1С показывает только итог сеанса.
Сопоставляем статусы сайта со статусами 1С:
$statuses = CSaleStatus::GetList([], [], false, false, ['ID', 'NAME', 'XML_ID']);while ($status = $statuses->Fetch()) { printf("%-4s %-24s xml_id=%s\n", $status['ID'], $status['NAME'], $status['XML_ID']);}Статус с пустым внешним кодом заведён на сайте руками, и возврат из 1С в него не попадёт. Заказ при этом обменяется успешно, а статус останется прежним.
Это одна из самых обидных поломок обмена заказами: ошибки нет нигде, лог чистый, а менеджер видит в админке вчерашний статус. Проверять сопоставление стоит сразу после первого успешного сеанса, а не когда накопится сотня расхождений.
Смотрим, какие заказы уже выгружены:
$orders = Bitrix\Sale\Internals\OrderTable::getList([ 'select' => ['ID', 'ACCOUNT_NUMBER', 'STATUS_ID', 'UPDATED_1C', 'VERSION_1C'], 'filter' => ['=UPDATED_1C' => 'Y'], 'limit' => 20,]);foreach ($orders as $order) { print_r($order);}Поле UPDATED_1C помечает заказы, побывавшие в обмене, VERSION_1C хранит
версию от 1С. По ним отличают «ещё не выгружался» от «выгружался, но не
обновился».
Ищем дубли по составу и номеру:
SELECT ACCOUNT_NUMBER, COUNT(*) AS cnt, GROUP_CONCAT(ID) AS idsFROM b_sale_orderGROUP BY ACCOUNT_NUMBERHAVING cnt > 1;Сопоставление идёт по номеру заказа, а не по внутреннему идентификатору. Смена нумерации на живом магазине - самая частая причина, по которой 1С перестаёт узнавать прежние заказы и заводит их заново.
Снимаем отметку выгрузки, чтобы отдать заказ в 1С заново:
Bitrix\Sale\Internals\OrderTable::update($orderId, [ 'UPDATED_1C' => 'N', // следующий сеанс заберёт заказ как новый 'VERSION_1C' => '', // версия от 1С сбрасывается вместе с отметкой]);Так возвращают в обмен заказы, созданные до его включения. Делать это лучше пачками по сотне: годовая история за один сеанс укладывает обмен в таймаут.
Отсюда правило: нумерацию заказов выбирают до запуска обмена и больше не трогают. Префикс, счётчик, формат номера - всё это часть договорённости с учётной системой, а не оформление письма покупателю. Менять формат на работающем обмене означает разорвать связь по всем прежним заказам разом.
Типичные проблемы
При каждом обмене заказы задваиваются.
Номер заказа изменился после создания: включили свою нумерацию или префикс. Сопоставление идёт по ACCOUNT_NUMBER, и 1С не находит прежний заказ.
Статус из 1С не применяется к заказу.
У статуса на сайте пустой внешний код. Возврат статуса сопоставляется по XML_ID, названия при этом не используются вовсе.
Заказ уехал, а позиции в 1С неопознанные.
Внешние коды товаров разошлись. Заказ сам по себе выгрузится, но подбор номенклатуры в 1С не сработает, и строки придётся сопоставлять руками.
В логе пусто, хотя обмен идёт.
Протоколирование обмена заказами выключено по умолчанию и включается отдельно от лога каталога, настройкой модуля продаж.
Выгружаются не все заказы.
В настройках ограничен список типов плательщиков или выгружаются только оплаченные. Заказы других типов обмен просто не берёт.
Частые вопросы
Как обмениваться заказами на мультисайте?
Каждый сайт выгружается отдельным узлом обмена со своим адресом и своим пользователем. Разделить потоки внутри одного узла нечем: обмен работает в контексте одного сайта.
Можно ли выгрузить в 1С заказы, созданные до включения обмена?
Да, у них снимают отметку UPDATED_1C, и следующий сеанс заберёт их как новые. Делать это лучше пачками: разовая выгрузка годовой истории укладывает сеанс в таймаут.
Что происходит с заказом, если его правят и на сайте, и в 1С?
Побеждает 1С: при возврате она перезаписывает поля заказа целиком. Поля, которые ведёт сайт, защищают обработчиком на событиях сохранения заказа, по тому же принципу, что и свойства товара.
Как выгрузить офлайн-заказы из 1С на сайт?
Тем же обменом: 1С шлёт их как обычные заказы, а сайт создаёт недостающие. Покупателя при этом сопоставляют по электронной почте, поэтому у офлайн-клиентов её надо заполнять.
Смежное
- Обмен: заказы - оглавление подтемы
- Обмен с 1С и HTTP - устройство обмена целиком
- Выгрузка товаров из 1С на сайт - обмен каталогом
- Каталог и продажи - заказ и его коллекции
- Настройка обмена с 1С: точка обмена, доступ, порядок шагов - доступ и параметры обмена
- Не выгружаются заказы в 1С - разбор причин, когда документы не приходят
- Заказ из кода: чтение, поиск по номеру, изменение состава - что выгружается в учётную систему
- Статусы заказа при обмене: возврат из 1С - что приезжает обратно на сайт
- Несколько баз и организаций: разведение заказов - когда учётных баз больше одной
- Состав заказа и контрагенты при обмене: позиции, покупатели, дубли - из чего собираются позиции и покупатели
- Направления и режимы обмена заказами: кто кому и когда отдаёт - какое направление за что отвечает