Из-за часто меняющегося компонента оформления заказа приведенное здесь решение не является полным и окончательным, а следить за актуальностью я не могу. Поэтому прошу пост рассматривать лишь для подспорья в написании собственного кода, а не использовать «как есть».
ЗЫ: Вот последняя актуальная (примерно на июнь 2014) версия компонента, которую я запилил под одного клиента:
скачать
. Пользуйтесь как есть, пожалуйста. Измененные блоки (менялся только component.php) я выделил фразой customization (конкретно для клиента менял еще некоторые строчки). Кодировка cp1251.
Оформление заказа почти идеально, но есть минус — если гость вводит e-mail, который есть в базе, ему дадут от ворот поворот — мол такой пользователь уже есть. А если подойти с точки зрения покупателя, это ломает — вспоминать пароль, или еще что. В общем, лояльность падает. Исправим ситуацию (сразу хочу огорчить — решение подразумевает +2 байта в системном компоненте, так что если вам не пойдет — пост бесполезен (хотя, вы можете просто вынести компонент в свое пространство, код все равно будет рабочим).
Показать скрытое содержание
Речь пойдет про компонент sale.order.ajax, одношаговое оформление заказа. Почему нельзя вынести компонент в свое пространство и изменить? Потому что это центровой компонент магазина, который постоянно улучшается компанией Битрикс, и лично я против его изменения. Так как же подошел к проблеме я.
Все методы ниже — методы класса CSaleHandlers, внутри которого содержатся необходимые
обработчики событий
.
Также класс имеет переменную
private static $bGuestOrder = false;
Поехали
1. Событие OnSaleComponentOrderOneStepProcess
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepProcess', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepProcessHandler')); public static function OnSaleComponentOrderOneStepProcessHandler($arResult, $arUserResult, $arParams) { if (empty($arResult['ERROR']) && $arUserResult['CONFIRM_ORDER']=='Y' && !$GLOBALS['USER']->IsAuthorized()) { if ($arUser = CUser::GetList($by='id', $order='asc', array('=EMAIL' => $arUserResult['USER_EMAIL']))->Fetch()) { if (!in_array(1, CUser::GetUserGroup($arUser['ID']))) { $GLOBALS['USER']->Authorize($arUser['ID']); self::$bGuestOrder = true; } } } }
Перед самым созданием заказа, перехватываем исполнение и смотрим — если пользователь с введенным e-mail, есть, то авторизуем его. От греха подальше, НЕ авторизуем если пользователь из группы админов. Это достаточно важный момент, потому что ошибка может произойти на любой строчке кода, и тогда гость может остаться админом.
В переменной self::$bGuestOrder запоминаем, что заказ создает гость.
2. Событие OnOrderUpdate
//AddEventHandler('sale', 'OnOrderUpdate', Array('CSaleHandlers', 'OnOrderUpdateHandler')); public static function OnOrderUpdateHandler($ID, $arFields) { if (self::$bGuestOrder && $GLOBALS['USER']->IsAuthorized() && isset($arFields['PRICE'])) { $_SESSION['SAVED_UID'] = $GLOBALS['USER']->GetID(); $GLOBALS['USER']->Logout(); } }
Разавторизовываем пользователя после создания заказа (в понятиях кода, а не сайта). Почему нельзя использовать OnOrderAdd? Потому что после добавления идет еще привязка корзины пользователя, и мы потеряем ее в случае OnOrderAdd. Также в сессии запоминаем предыдущий ID пользователя, который нам пригодится
3. Событие OnSaleComponentOrderOneStepComplete
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepComplete', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepCompleteHandler')); public static function OnSaleComponentOrderOneStepCompleteHandler($ID, $arOrder, $arParams) { if ($ID <= 0) { if (self::$bGuestOrder) { $GLOBALS['USER']->Logout(); } } }
Здесь мы страхуемся и делаем логаут пользователю, если случилась ошибка при создании заказа.
4. Событие OnSaleComponentOrderOneStepFinal
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepFinal', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepFinalHandler')); public static function OnSaleComponentOrderOneStepFinalHandler($ID, $arOrder, $arParams) { if ((!$GLOBALS['USER']->IsAuthorized() && $_SESSION['SAVED_UID']!=$arOrder['USER_ID']) || ($GLOBALS['USER']->IsAuthorized() && $GLOBALS['USER']->GetID()!=$arOrder['USER_ID']) ) { $arOrder = array(); } }
Здесь мы запрещаем просмотр заказа на финальном шаге (оплата), если это гость и не создал его только что сам.
По идее все. Где же надо поправить системный компонент sale.order.ajax/component.php?
Для версии Магазина до 12.5.4. примерно на 2079 строчке (но строчки постоянно скачут при изменениях, так что ориентироваться лучше на окружающий код) идет выборка созданного заказа с проверкой пользователя — вот пользователя надо закомментировать:
После версии 12.5.4 модуля Магазин, код иной:
Обратите внимание. Данное изменение компонента может работать только вкупе с данными обработчиками. Иначе доступ к финальному шагу (системе оплаты) получает любой пользователь.
Изменения компонента не было бы, если бы реализованная
идея
, просьба поддержать.
Класс необходимых обработчиков вы можете скачать ниже. Достаточно просто подключить его в init.php
посмотреть код компонента — https://clip2net.com/s/4fQpIWn Не отрабатывает вот это условие, массив сессии пустой. Может кто сталкивался с подобным?
russian
software
it
bitrix
5
ответов
переодически это через n минут после оплаты?
в общем n минут скорее равно времени жизни сессии
Andrew Zahalski
переодически это через n минут после оплаты?
вот эту закономерность не вычислил. Сейчас при проверке сразу вылазит сообщение, что заказ не найден.
Игорь Захаров
вот эту закономерность не вычислил. Сейчас при про…
старые заказы пробовал? или новый созданный
Andrew Zahalski
старые заказы пробовал? или новый созданный
да как будто все сейчас , и старые и новые
Пользователь 92039 Посетитель Сообщений: 54 |
Здравствуйте. Мне достался готовый сайт. Версия — «1С-Битрикс: Управление сайтом 11.5.1» |
Пользователь 88565 Посетитель Сообщений: 118 |
|
Пользователь 92039 Посетитель Сообщений: 54 |
#3 0 10.04.2013 12:52:17
У меня в «Структуре сайта» в «Контенте» нет пункта «Управление». Наверное, документация для более поздней версии системы. |
||
Пользователь 95726 Эксперт Сообщений: 742 |
#4 0 10.04.2013 13:10:37
Так и редактируй по FTP. Сдался тебе этот редактор.
М.б. если включаемую область редактируешь например. |
||||
Пользователь 92039 Посетитель Сообщений: 54 |
#5 0 10.04.2013 13:15:50
Это не для меня всё делается, а для сеошника, который привык работать с редактором. Так что надо разобраться. |
||||
Пользователь 95726 Эксперт Сообщений: 742 |
Ну если из админки, то нет. А если непосредственно со страницы, то да. |
Пользователь 92039 Посетитель Сообщений: 54 |
Я редактирую из админки. |
Пользователь 173519 Эксперт Сообщений: 493 |
На хостинге clodo имею аналогичную ошибку, создал включаемую область на сайте по фтп, в структуре сайта показывает полный доступ на права системы, но при редактировании пишет «Ошибка при создании файла». Пришлось создавать файл через админку, тогда все работает. Разработка интернет магазина под ключ на 1С-Битрикс www.electroid.org, интеграция битрикс и 1С. |
Пользователь 37620 Эксперт Сообщений: 2549 для СПАСИБО на форуме есть КНОПКА! |
#9 1 25.09.2013 17:26:52
такое бывает, если у вас веб сервер и фтп под разными юзерами работают. Сайт Startup’а — адаптивная Bootstrap вёрстка, композит, микроразметка. бесплатно |
||
Пользователь 266000 Заглянувший Сообщений: 14 |
#10 0 19.07.2020 20:41:11 Здравствуйте! |
Пользователь 1497169 Заглянувший Сообщений: 1 |
#11 0 24.08.2022 13:02:24 Добрый день. Столкнулись с аналогичной проблемой. |
Пользователь 1947629 Эксперт Сообщений: 862 |
#12 0 24.08.2022 16:01:59 место кончилось? |
Данная проблема в Битриксе может появляться при отсутствии нужных прав на каталоги и файлы. В моём случае проблема возникла при многосайтовости, до этого всё было в порядке, но спустя какое-то время после длительной работы, появилось ограничение. За время поиска решения этой задачи, я нашел несколько решений и думаю, что один из вариантов Вам поможет справиться с данной проблемой.
Первое что необходимо сделать — это проверить права на файлы и папки в нужном каталоге. Права на папку должны быть 755, на файлы 664. Ни в коем случае не выставляйте права 777 на папки или файлы, даже на время.
В моём случае этот метод не сработал, я стал копать дальше. Нашел такой совет. в файле /bitrix/php_interface/dbconn.php установить такие константы.
define( "BX_FILE_PERMISSIONS", 0660 );
define( "BX_DIR_PERMISSIONS", 0775 );
@umask( ~BX_DIR_PERMISSIONS );
@ini_set( "memory_limit", "512M" );
Но этого не потребовалось, т.к. эти значения уже были заданы и по идее всё должно было работать. На одном из форумов посоветовали изменить права доступа и владельца к нужной категории через консоль. Но я посчитал, что если всё до этого работало, то не нужно так далеко залазить, проблема явно была в не в этом, для Вас приведу код в котором можно изменить права доступа к каталогам и файлам через консоль. Говорят может помочь.
find . -type d -exec chmod 775 { } ;
find . -type f -exec chmod 664 { } ;
В моём случае решение оказалось куда проще. Все сайты лежали в корневой директории, один из них являлся общим ядром. Но по какой-то причине прекратился общий доступ к «главному сайту» и всё что нужно было сделать — это открыть доступ.
Поскольку сайты на учётных записях закрыты процессы, запущенные на одном сайте, не имеют прав для обращения к каталогам, выходящим за пределы этого сайта. Для доступа из окружения веб-сервера потребуется открыть общий доступ к каталогу. Мой проект находится на beget и эта операция делается очень просто через файловый менеджер.
- Зайдите в нужную директорию
- В верхней части экрана нажмите на кнопку “Инструменты” -> “Настроить общий доступ к текущей директории”:
- Установите переключатели “Чтение и запись” и “Включая вложенные папки”, нажмите кнопку “Открыть доступ”:
Если представленные варианты не принесли желаемого результата, то пишите в комментарии, будет время, что-нибудь придумаем.
Нет. Такие же не надо.
Надо посмотреть от чьего имени работает веб сервер. Тут вообще битрикс не при чем. У вас пробема в том, что все файлы доступны только root и вебсервер не имеет к ним доступ. Попробуйте в каталоге — корне сайта (в терминале через ssh) выполнить команду
там увидите у файлов кто владелец группа. Я так понимаю у части root:root, но у некоторых должно быть нечто другое. Например bitrix:bitrix, www-data:www-data или иное… Тут уже зависит от дистрибутива линукса развернутого на сервере, предыдущего админа и т.п. Вот вам нужно ходить через ftp именно под этим пользователем. (Да и по ssh под root лучше не ходить — обычно это запрещают, а при необходимости логинятся обычным, и уже в терминале меняют пользователя на root)
Ну и необходимо будет поменять права к файлам. Для этого находясь в терминале в корне сайта под root. Выполните (в примере имя искомого пользователя bitrix и группа bitrix:
Bash | ||
|
Но вообще с этим со всем надо аккуратно… Лучше пригласить специалиста. Наверняка на том же хостинге есть услуга помощи админа.
Добавлено через 56 секунд
PS Вопрос, кстати, ваш скорее не для этого раздела. Т.к. битрикс относится лишь косвенно.
Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.
Инфоблоки
Решение типовых проблем не требует вмешательства программистов. Контент-менеджер в большинстве случаев может разрешить их самостоятельно. Самые частые ошибки совершаются при работе с информационными блоками. Это естественно, так как в инфоблоках хранится большая часть информации на сайте. Описание ошибок даётся в формате: Проблема > ошибка > решение, чтобы вам было проще перейти к исправлению ситуации.
Типовые проблемы:
- Выводится сообщение: У вас нет прав на просмотр.
- На странице не выводится информация, добавленная в поля свойств элемента инфоблока.
- В форме добавления элементов не видны добавленные свойства инфоблока.
- Как добавить новые свойства в форму создания элемента.
- Выводится сообщение: Неверный тип файла.
- Выводится сообщение: Превышен максимальный размер.
- Выводится сообщение: элемент не найден.
- Количество сообщений (тем форума, новостей, количество фотографий и т.д.) на странице не совпадает с количеством, указанном в настройке компонента.
- Проблема: выводится сообщение:
«У вас нет прав на просмотр …»
.Ошибка: ненастроенные права доступа к детальной информации: новостей и фотогалереи.
Решение: Настроить группы пользователей для доступа в настройках комплексного компонента в группе параметров Дополнительные настройки:
- Проблема: На странице не выводится информация, добавленная в поля свойств элемента инфоблока. Например, добавляется информация в поле Производитель и Материал, а она
не видна у товара
.Ошибка: в настройках компонента не указаны свойства инфоблока, которые должны отображаться на данной странице.
Решение: В настройках параметров инфоблока указать какие свойства должны отображаться. Для этого надо сначала понять на какой странице не выводятся нужные свойства: на детальной странице товара или на странице списка товаров. Отличить не трудно: на странице списка товаров выводятся все товары раздела. На странице детального отображения товара — только выбранный товар. Соответственно нужно выбирать свойства для показа в нужной секции настроек компонента.
-
Проблема: В форме добавления элементов не видны добавленные свойства инфоблока.
Ошибка: добавленное свойство либо неактивно, либо свойство не выведено в измененной (кастомизированной) форме добавления элемента.
Решения:
- активируйте свойство в форме редактирования инфоблока (Контент > Инфоблоки > Типы инфоблоков > _ваш_тип_инфоблока > _ ваш_инфоблок_) на закладке Свойства.
- добавьте новые свойства в форму создания элемента, как это рассказано в курсе Администратор. Базовый.
Прав контент-менеджера на эти операции может не хватить. В этом случае обратитесь к администратору сайта.
- активируйте свойство в форме редактирования инфоблока (Контент > Инфоблоки > Типы инфоблоков > _ваш_тип_инфоблока > _ ваш_инфоблок_) на закладке Свойства.
- Проблема: При создании элемента инфоблока не удается прикрепить файл, выводится сообщение: Неверный тип файла. При этом не происходит сохранение элемента.
Ошибка: в свойствах инфоблока типа Файл не указаны разрешенные для загрузки форматы.
Решение: разрешенные форматы указываются на закладке Свойства формы настройки инфоблока (Контент > Инфоблоки > Типы инфоблоков > _ваш_тип_инфоблока > _ ваш_инфоблок_). В строке свойства типа Файл с помощью кнопки […] вызовите форму детальной настройки свойства и в поле Типы загружаемых файлов введите нужные форматы или выберите форматы в выпадающем списке:
- Проблема: Не удается прикрепить файл к элементу инфоблока, выводится сообщение: Превышен максимальный размер файла. При этом не происходит сохранение элемента.
Ошибка: ограничения администратора сайта на размер загружаемого файла.
Решение: Для снятия этого ограничения необходимо обратиться к администратору сайта.
- Проблема: При переходе из списка элементов к странице детального просмотра появляется сообщение:
Элемент не найден
.Ошибка: неправильно формируется адрес страницы (не передается идентификатор открываемого элемента или в настройках компонента ошиблись).
Решение: проверить настройки компонента в группе параметров Управление адресами страниц или обратиться к администратору сайта.
- Проблема: Количество сообщений (тем форума, новостей, количество фотографий и т.д.) на странице не совпадает с количеством, указанном в настройке компонента.
Ошибка: в настройках используемого компонента отмечена опция Использовать обратную постраничную навигацию. В этом режиме происходит вывод страниц в обратном порядке (последняя страница становится первой).
Решение: исправить настройки компонента в группе параметров Настройки постраничной навигации.
Необязательная информация: зачем нужна обратная навигация
Назад в раздел
Подписаться на новые материалы раздела:
- Ошибки на стороне веб-сервера
- Ошибки при работе с файлами данных
- Проблемы авторизации
- Ошибки MySQL
- Логические ошибки
- Диагностика отладки
- Отладка обмена на стороне 1С-Битрикс
- Модуль отладки обмена от ИНТЕРВОЛГИ
- Выводы
Настроить обмен между «1С» и «1С-Битрикс» интернет-магазина или сайта – не проблема. Эта функция присутствует «из коробки» начиная с ранних версий продуктов «1С:Предприятие», редакция Управление торговлей и «1С-Битрикс: Управление сайтом» в редакциях Малый бизнес и Бизнес.
Даже с учётом имеющейся документации по продукту, у многих разработчиков сайтов возникают сложности в корректной настройке обмена данными между этими системами. Рассмотрим самые частые проблемы, которые возникают у тех кто пытался.
Мы выделили несколько групп ошибок:
- проблемы авторизации;
- ошибки на стороне сервера;
- ошибки при работе с файлами данных;
- ошибки MySQL;
- логические ошибки.
Далее мы детально рассмотрим сами ошибки и способы их исправления.
Ошибки на стороне веб-сервера
К этой группе относятся ошибки, возникающие в подсистемах веб-сервера, отвечающих за выполнение PHP-кода. Обычно это: Nginx, Apache и сам интерпретатор языка PHP.
Возможны 2 варианта:
- Ошибка действительно вызвана неоптимальными настройками Nginx/Apache/PHP. Если Вы чувствуете неуверенность в своем веб-сервере или совсем недавно на него переехали — привлеките администратора для проверки и изменения настроек.
Название ошибки | Как исправить |
---|---|
Failed sending data to the peer (no headers, no data). |
|
Получен пустой ответ сервера. | |
Ошибка нехватки памяти, например выводится сообщение: Fatal error : Allowed memory size of 67108864 bytes exhausted (tried to allocate 102401…). | Проверить настройку memory_limit в php.ini. Должно быть указано не менее 512Mb, увеличить значение и перезагрузить сервер. Или не изменяя настройки сервера сделать равным таймаут сервера и таймаут «1С-Битрикс: Управление сайтом» (страница Магазин > Настройки магазина > Интеграция с 1С, поле Интервал одного шага в секундах). Если проблема с нехваткой памяти, данное решение не подойдёт. |
- Подобная ошибка может маскировать либо некорректную настройку объема одной порции загружаемых данных (10К товаров за раз, например), либо логическую ошибку в программном коде (например, пересчет каких-нибудь значений в товарах по событию изменения).
Способы решения:
- уменьшать объем передаваемых за раз данных (проверить на 1 товаре, но лучше выставлять значение поочередно, 1, 100, 1000, 10000 и смотреть, какое значение оптимально для ваших настроек);
- временно закомментировать обработчики событий в файле /bitrix/php_interface/init.php, может быть они мешают обмену.
Ошибки при работе с файлами данных
Данные ошибки возникают при неверной настройке прав доступа к файлу. Отображение ошибок звучит следующим образом: «Ошибка открытия файла» и «Ошибка записи файла». Возможные причины и их решение:
Название ошибки | Как исправить |
---|---|
Закончилось место на диске. |
Удалить старые бэкапы или увеличить тариф на хостинге. |
По ftp файлы загружаются, а через веб-интерфейс административного раздела сайта нет. |
Обратиться в техническую поддержку хостинг-провайдера. |
Не работает или некорректно работает сжатие данных при обмене. |
Для начала можно попробовать выключить сжатие в настройках модуля обмена. Также можно проверить работу функции zip_open на сервере Откройте в браузере страницу http://<ваш_сайт>//bitrix/admin/phpinfo.php (Либо выполните команду if (exist_function (“zip_open”)){ echo “OK”; } В браузере отобразится таблица: Для строки ZIP должно стоять «enabled». |
Проблемы авторизации
Самая распространённая проблема, если пользователь не указал данные или указал их неверно.
Название ошибки | Проблема / как исправить |
---|---|
«Не удалось получить данные с сервера. Проверьте правильность адреса сервера, порт, имя пользователя и пароль, а также настройки подключения к Интернет». |
На сервере 1С установлено ПО, которое блокирует исходящие соединения, в этом случае при попытке обмена выдаётся ошибка. Исправляется добавлением адреса сайта в белый список ПО. |
«Авторизация не выполнена. Не удалось установить соединение с сервером. Проверьте имя пользователя и пароль». |
Неверно указаны логин/пароль доступа к сайту. Надо проверить, получается ли по указанному доступу зайти на сайт. И проверить наличие редиректов при переходе по ссылке, например на https версию сайта. Если по ссылке http:// адрес сайта /bitrix/admin/1c_exchange.php появляется сообщение, значит с логином и паролем всё в порядке. |
Ошибки MySQL
Ошибки возникают при соединении с базой данных MySQL, настроенной на сайте.
Название ошибки | Проблема / как исправить |
---|---|
[Illegal mix of collations (russian_swedish_ci,IMPLICIT) and (cp1251_general_ci,COERCIBLE) for operation ‘=’] |
Конфликт кодировок. Причина ошибки — таблицы базы данных в одной кодировке, а сам база в другой. В данном случае база в russian и новые таблицы создаются в не russian. При выгрузке из «1С» создается временная таблица b_xml_tree в «некорректной» кодировке russian. |
Логические ошибки
Ошибки пользователей неверно понимающих процесс обмена данными и, соответственно, неверно выполняющих какие-то действия.
Название ошибки | Проблема / как исправить |
---|---|
Несовместимые версии модуля обмена и базовой конфигурации 1С. |
Проверить на официальном сайте “1С-Битрикс” соответствие версий продуктов. Если версии не совпадают, переустановить модуль обмена на стороне 1С |
«Изменения товаров не зарегистрированы. Выгрузка товаров не произведена». |
Неверно настроен отбор товаров в модуле обмена. Надо проверить эти настройки. Скорей всего, выбраны параметры, которые не позволяют правильно отфильтровать параметры для выгрузки. Также это сообщение выдаётся, если если в настройках Режима обмена данными с WEB-сайтом установлено: Выгружать только измененные объекты с момента последнего обмена. В этом случае это не ошибка, а выгрузки не произошло, потому что данные со стороны 1с не были изменены. |
«Не удалось найти вид номенклатуры». |
Ошибка появляется, если в «1С» нет видов номенклатуры «Услуга» и «Товар». Эти виды критичны для процесса обмена данными с сайтом. Решение – создать в «1С» указанные виды номенклатуры. |
«Поле объекта не обнаружено». |
Не указаны соответствия для полей заказа в «1С-Битрикс: Управление сайтом». Проверьте настройки, заданные в закладке Экспорт в «1С:Предприятие» страницы Настройки > Настройки продукта > Настройки модулей > Интернет-магазин. Два поля «Полное Название» и «Название» критичны для 1С. Если их не задать, экспорт выполняться не будет. Настройка соответствий для разных типов плательщиков производится отдельно. |
Данные выгружаются на сайт, но не обновляются. |
На сайте используют контрольные суммы для ускорения обмена, а на стороне 1С программисты обычно забывают их пересчитывать, когда пытаются доработать модуль обмена. Проверяется отключением контрольных сумм на сайте. Обмен становится дольше, поэтому надо заставить специалиста 1С вернуть отключенную настройку. |
Диагностика отладки
Мы применяем два инструмента отладки обмена между 1С и 1С-Битрикс.
Отладка обмена на стороне 1С-Битрикс
При настройке выгрузки необходимо проверить существование папки /upload/1c_catalog/. В эту папку будут загружаться файлы при обмене.
При необходимости, можно удалять из папки файлы последнего обмена, т.к. по завершению обмена файлы последней операции будут храниться именно в этой папке. Выполнение этой задачи возможно сделать автоматически, например запустить «Режим отладки» процесса обмена на сайте. При включенном «режиме отладки» не будут удаляться старые файлы из этого каталога после успешного обмена.
Включить «режим отладки» можно отредактировав файл dbconn.php. А именно, создать константу такого вида: define(«BX_CATALOG_IMPORT_1C_PRESERVE», true).
На стороне 1С-Битрикс мы можем увидеть только конечные данные. Если данные приходят корректные, то они попадают в инфоблоки и это видно. Если данные приходят некорректные, то либо неверные данные были выгружены из 1С, либо выставлен неверный тип данных. Например вы пытаетесь передать многострочный список как строку.
Модуль отладки обмена от ИНТЕРВОЛГИ
Для упрощения диагностики мы создали модуль отладки обмена.
Он встраивается между 1С и 1С-Битрикс и пишет логи того, что происходит при обмене. По этим логам можно выяснить, где ошибка и исправить её. Отображение логов происходит в административной части сайта.
Модуль отладки обмена от ИНТЕРВОЛГИ лучше логов со стороны 1С-Битрикс, потому что он:
- следит за размером и в результате его работы не закончится место на сайте;
- логирует обмен справочников и заказов;
- логирует время обмена и время выполнения одного шага.
Выводы
Если не разбираться в вопросе и попытаться исправить обмен, то можно сделать только хуже и придётся или переписывать код модуля или ставить модуль обмена заново.
Наша компания обладает компетенциями в вопросе отладки обмена. Если у вас возникла подобная проблема, напишите, обсудим.
Вам может быть интересно:
- Tutorial по стандартному и нестандартному обмену сайта с 1С. Часть первая: стандартный обмен и его хитрости.
- Tutorial по обмену сайта с 1С. Часть вторая: зачем и как писать свой обмен с нуля на очередях и REST API.
- Tutorial по обмену с 1С. Часть третья: Выжимаем максимум из стандарта. Что мы хотели бы знать 1000 проектов назад.
- Tutorial по обмену с 1С. Часть четвертая: Обмен через промежуточную базу данных.
- Tutorial по обмену с 1С. Часть пятая: Наш опыт настройки 1000 и 1 обмена.
03.05.2020
11:13
03.05.2020 11:13:19
в другой статье пример оформления заказа в 1 клик на api d7
Подключаем модули
use BitrixMain, BitrixMainLocalizationLoc as Loc, BitrixMainLoader, BitrixMainApplication, BitrixCurrency, BitrixSaleDelivery, BitrixSalePaySystem, BitrixSale, BitrixSaleOrder, BitrixSaleAffiliate, BitrixSaleDiscountCouponsManager, BitrixMainContext; BitrixMainLoader::includeModule("sale");
Получить заказ
инициализируем класс сдля работы с купонами
если не поключить, то слетят скидки
DiscountCouponsManager::init();
непосредственно получаем заказ
$order = BitrixSaleOrder::load($orderId); //по ID заказа $order = BitrixSaleOrder::loadByAccountNumber($accountNumber); //по номеру заказа (ACCOUNT_NUMBER)
Получить заказы по фильтру
$dbRes = BitrixSaleOrder::getList([ 'select' => ['ID'], 'filter' => [ "USER_ID" => $USER->GetID(), //по пользователю ">=DATE_INSERT" => date($DB->DateFormatToPHP(CSite::GetDateFormat("SHORT")), mktime(0, 0, 0, date("n"), 1, date("Y"))), //по дате "PAY_SYSTEM_ID" => $paysystemId, //по платежной системе "DELIVERY_ID" => $deliveryId, //по службе доставки "STATUS_ID" =>$statusId, //по статусу "PAYED" => "Y", //оплаченные "CANCELED" =>"N", //не отмененные "PROPERTY.ORDER_PROPS_ID" => $propId, //по свойству "PROPERTY.VALUE" => 'значение', //и по его значению ], 'order' => ['ID' => 'DESC'] ]); while ($order = $dbRes->fetch()){ var_dump($order); }
Создать новый заказ
Ид сайта устанавливаем
$siteId = BitrixMainContext::getCurrent()->getSite(); //работает только для публичного раздела $siteId = "s1"; //или указать жестко //или из запроса if (array_key_exists('site_id', $_REQUEST) && is_string($_REQUEST['site_id'])){ $siteId = $_REQUEST['site_id']; if($siteId !== '' && preg_match('/^[a-z0-9_]{2}$/i', $siteId) === 1){ define('SITE_ID', $siteId); } }
идентификатор покупателя (отличается от id пользователя)
$fuser = SaleFuser::getId(); //Идентификатор покупателя текущего пользователя $fuser = SaleFuser::getIdByUserId($userId) //Идентификатор покупателя по id пользователя
получаем валюту базовую («RUB»,»USD»,…)
$currencyCode = Option::get('sale', 'default_currency', 'RUB'); //вариант 1 $currencyCode = BitrixCurrencyCurrencyManager::getBaseCurrency(); //вариант 2 $currencyCode = 'RUB'; //вариант 3
инициализируем класс для работы с купонами
DiscountCouponsManager::init();
создаем заказ
$order = BitrixSaleOrder::create($siteId, $userId,$currencyCode);
Устанавливаем тип плательшика
$order->setPersonTypeId($payTypeId); //вариант 1 $order->setField("PERSON_TYPE_ID",$payTypeId); //вариант 2
Корзина заказа
для работы с корзиной на api d7 отдельная статья
получить текущую корзину покупателя
$basket = SaleBasket::loadItemsForFUser($fuser, $siteId); //по идентификатор покупателя, ид сайта
создать корзину
$basket = BitrixSaleBasket::create($siteId); $item = $basket->createItem('catalog', $productId); $item->setField('QUANTITY', 1); $item->setField('CURRENCY', $currencyCode); $item->setField('PRODUCT_PROVIDER_CLASS', 'BitrixCatalogProductCatalogProvider'); $basket->refresh();
$order->setBasket($basket); //добавляем заказ в корзину
получить корзину заказа
$basket = $order->getBasket();
Доставка заказа
создать доставку
$shipmentCollection = $order->getShipmentCollection(); $shipment = $shipmentCollection->createItem(); $deliveryId = DeliveryServicesEmptyDeliveryService::getEmptyDeliveryServiceId(); //доставка "без доставки" $service = DeliveryServicesManager::getById($deliveryId); $shipment->setFields(array( 'DELIVERY_ID' => $service['ID'], 'DELIVERY_NAME' => $service['NAME'], )); $shipmentItemCollection = $shipment->getShipmentItemCollection(); foreach ($order->getBasket() as $item){ $shipmentItem = $shipmentItemCollection->createItem($item); $shipmentItem->setQuantity($item->getQuantity()); }
получить службу доставки и разрешить оплату
$shipmentCollection = $order->getShipmentCollection(); foreach ($shipmentCollection as $shipment) { if (!$shipment->isSystem()) { $shipment->allowDelivery(); // разрешаем отгрузку } }
Платежная система заказа
добавление
//вариант 1 $paymentCollection = $order->getPaymentCollection(); $payment = $paymentCollection->createItem(); $paySystemService = PaySystemManager::getObjectById($paySystemId); //$paySystemId - ИД платежной системы $payment->setFields(array( 'PAY_SYSTEM_ID' => $paySystemId, 'PAY_SYSTEM_NAME' => $paySystemService->getField("NAME"), 'SUM'=> $order->getPrice() )); //вариант 2 $paymentCollection = $order->getPaymentCollection(); $payment = $paymentCollection->createItem(BitrixSalePaySystemManager::getObjectById($paySystemId)); //$paySystemId - ИД платежной системы $payment->setField('SUM', $order->getPrice());
получить ограничения для доставки, в т.ч. по платежным системам
$dbDelivery = BitrixSaleDeliveryRestrictionsManager::getList(array( 'filter' => array('SERVICE_ID' => $deliveryId) // ID службы доставки )); while ($arDelivery = $dbDelivery->fetch()) { if($arDelivery["PARAMS"]) { // Если есть ограничения у доставки $arParams = $arDelivery["CLASS_NAME"]::prepareParamsValues($arDelivery["PARAMS"], $deliveryId); // Получаем ВСЕ ограничения для данной доставки if ($arParams['PAY_SYSTEMS']){ //тут обрабатываем ограничения по платежным системам } } }
получить объект платежной системы
$service = $payment->getPaySystem(); // BitrixSalePaySystemService
получить настройки платежной системы
$list = CSalePaySystemAction::getParamsByConsumer('PAYSYSTEM_'.$id, $personTypeId);
получить состояния: оплачено или нет
$isPaid = $payment->isPaid(); //true или false
Получение оплаченной суммы по заказу
$paymentCollection = $order->getPaymentCollection(); $paymentCollection->getPaidSum();
Возврат средств
- ‘Y’ — при возврате на внутренний счет
- ‘P’ — при возврате через платежную систему(если она поддерживает данный функционал);
- ‘N’ — при отмене возврата
$result = $payment->setReturn($f); //$f - Y/P/N if (!$result->isSuccess()){ var_dump($r->getErrorMessages()); }
Свойства заказа
Получить свойства
$propertyCollection = $order->getPropertyCollection(); $property = $propertyCollection->getProfileName(); $property = $propertyCollection->getUserEmail(); $property = $propertyCollection->getPhone(); $property = $propertyCollection->getDeliveryLocation(); $property = $propertyCollection->getDeliveryLocationZip(); $property = $propertyCollection->getItemByOrderPropertyCode($orderPropertyCode); //по коду свойства вернет 1 свойство $property = $propertyCollection->getItemsByOrderPropertyCode($orderPropertyCode); //по коду свойства вернет все найденные свойства $property = $propertyCollection->getItemByOrderPropertyId($orderPropertyId); //по id //свой фильтр для свойств $propertyCode = 'CODE_PROP'; $property = $propertyCollection->getItemsByFilter( //тут функция с нужной логикой function ($propertyValue) use ($propertyCode){ return ( $propertyValue->getField('CODE') == $propertyCode ); } );
группы свойств
$ar = $propertyCollection->getArray(); // массив ['properties' => [..], 'groups' => [..] ]; $ar = $propertyCollection->getGroups(); // массив групп $ar = $propertyCollection->getGroupProperties($groupId); // массив свойств, относящихся к группе
Получаем данные совйства
$ar = $property->getProperty(); // массив данных о самом свойстве $propId = $property->getPropertyId(); // ID свойства $propName = $property->getName(); // Название $isRequired = $property->isRequired(); // true, если свойство обязательное $propPerson = $property->getPersonTypeId(); // Тип плательщика $propGroup = $property->getGroupId(); // ID группы $propValue = $property->getValue(); //значение свойства $propCode = $property->getField('CODE'); //любое другое поле свойства
Устанавливаем свойства заказа
$property->setField('VALUE', 'значение свойства'); //вариант 1 $property->setValue('значение свойства'); //вариант 2
Удаляем свойство
Поля заказа
заполняем
$order->setField('CURRENCY', $currencyCode); //валюта $order->setField('USER_DESCRIPTION', $userDescription); //комментарии пользователя $order->setField('COMMENTS', $managerComments); //комментарии служебные $order->setField('AFFILIATE_ID', $affiliateId); //аффилиат $order->setFields('RESPONSIBLE_ID', $managerId); //для crm - ответственный
получаем
$order->getField('USER_DESCRIPTION'); //комментарии пользователя $order->getId(); // ID заказа $order->getSiteId(); // ID сайта $order->getDateInsert(); // объект BitrixMainTypeDateTime $order->getPersonTypeId(); // ID типа покупателя $order->getUserId(); // ID пользователя $order->getPrice(); // Сумма заказа $order->getDiscountPrice(); // Размер скидки $order->getDeliveryPrice(); // Стоимость доставки $order->getSumPaid(); // Оплаченная сумма $order->getCurrency(); // Валюта заказа $order->isPaid(); // true, если оплачен $order->isAllowDelivery(); // true, если разрешена доставка $order->isShipped(); // true, если отправлен $order->isCanceled(); // true, если отменен $order->getTax();//налоги $order->getTaxPrice(); сумма налогов
Cохранение заказа
$order->doFinalAction(true); $result = $order->save(); if ($result->isSuccess()) { echo 'Заказ успешно создан!'; } else { echo $result->getError(); }
Блокировка заказа
$order->lock(); //заблокировать $order->unlock(); //разблокировать
Для CRM связь с контактом, компанией
получить список контактов
$communications = $order->getContactCompanyCollection(); foreach ($communications as $communication) { $arCom = $communication->getFields()->getValues(); //с ключами ID, ORDER_ID, ENTITY_ID, ENTITY_TYPE_ID, SORT, ROLE_ID, IS_PRIMARY }
добавить новый
$itemCom = $communications->createCompany(); //компания $itemCom = $communications->createContact();//контакт изменить поля $itemCom ->setField('ENTITY_ID', 36); //ID контакта или компании $itemCom ->setField('IS_PRIMARY', 'Y'); // необязательно получить поля $itemCom ->getField('IS_PRIMARY');
так теперь не работает, изменилось api
//BitrixCrmBindingOrderContactCompanyTable::bindContactIDs($orderId, array($contactId)); //BitrixCrmBindingOrderContactCompanyTable::bindContacts($orderId, array(array(«ENTITY_ID»=>$contactId,»IS_PRIMARY»=>»Y»)));
Устанавливаем статусы, флаги оплаты у уже созданного заказа
$payment->setPaid("Y"); //вариант 1 $order->setField('PAYED', 'Y'); //вариант 2 $order->setField('STATUS_ID', $statusId); //статус $order->save();
получаем сгенерированную форму оплаты (в виде счета, или ссылка на оплату)
if (!empty($paySystemService)) { $arPaySysAction = $paySystemService->getFieldsValues(); if ($paySystemService->getField('NEW_WINDOW') === 'N' || $paySystemService->getField('ID') == PaySystemManager::getInnerPaySystemId()){ $initResult = $paySystemService->initiatePay($payment, null, PaySystemBaseServiceHandler::STRING); if ($initResult->isSuccess()) $arPaySysAction['BUFFERED_OUTPUT'] = $initResult->getTemplate(); // получаем форму оплаты из обработчика else $arPaySysAction["ERROR"] = $initResult->getErrorMessages(); } } }
Статусы заказа
языконезависимая информация о статусе
$statusResult = BitrixSaleInternalsStatusTable::getList(array( 'order' => array('SORT'=>'ASC'), 'filter' => array('TYPE'=>'O'), )); while($arStatus = $statusResult->fetch()){ print_r($arStatus); //поля статуса ID, TYPE, SORT, NOTIFY }
языкозависимая информация о статусе
‘STATUS.TYPE’=>’O’ статусы заказа
‘STATUS.TYPE’=>’D’ статусы доставки
$statusResult = BitrixSaleInternalsStatusLangTable::getList(array( 'order' => array('STATUS.SORT'=>'ASC'), 'filter' => array('STATUS.TYPE'=>'O','LID'=>LANGUAGE_ID), 'select' => array('STATUS_ID','NAME','DESCRIPTION'), )); while($arStatus = $statusResult->fetch()){ print_r($arStatus); //STATUS_ID, NAME (на нужном языке),DESCRIPTION (на нужном языке) }
не d7
if ($arStatus = CSaleStatus::GetByID($STATUS_ID,LANGUAGE_ID)){ print_r($arStatus); //массив с ключами ID, SORT, NAME, DESCRIPTION }
Обработчики примеры
запретить удаление заказа всем, кроме определенного пользователя
BitrixMainEventManager::getInstance()->addEventHandler( 'sale', 'OnSaleBeforeOrderDelete', 'MyOnSaleBeforeOrderDelete' ); //пользователь с ID 1 function MyOnSaleBeforeOrderDelete(MainEvent $event){ if(!isset($_SESSION["SESS_AUTH"]["USER_ID"]) || ($_SESSION["SESS_AUTH"]["USER_ID"]!=1) || !isset($_SESSION["SESS_AUTH"]["AUTHORIZED"]) || ($_SESSION["SESS_AUTH"]["AUTHORIZED"]!=='Y')){ return new BitrixMainEventResult(BitrixMainEventResult::ERROR, new BitrixSaleResultError('Ошибка при удалении заказа', 'code'), 'sale'); } }
смена статуса, шел корявый статус из 1С, в CRM были ошибки
BitrixMainEventManager::getInstance()->addEventHandler( 'sale', 'OnBeforeSaleOrderItemSetField', 'setRightStatus' ); function setRightStatus(BitrixMainEvent $event){ $name = $event->getParameter('NAME'); if ($name === 'STATUS_ID'){ if($event->getParameter('VALUE') == "CL"){ $event->addResult( new MainEventResult( MainEventResult::SUCCESS, array('VALUE' => "D") ) ); } } }
старый api, после оплаты в нужный статус
AddEventHandler("sale", "OnSalePayOrder", "MyOnSalePayOrderChangeStatus"); function MyOnSalePayOrderChangeStatus($id,$val){ if($val=="Y" && CModule::IncludeModule('sale') && ($arOrder = CSaleOrder::GetByID($id))) { if(in_array($arOrder['STATUS_ID'], array("N","NP"))){//если на стадии "В обработке", "Ожидает оплаты"" CSaleOrder::StatusOrder($id, "P"); //переводим в статус "оплачен, формируется к отправке" } elseif(in_array($arOrder['STATUS_ID'], array("S","Z"))){//если на стадии "Отправлен", "Отправлен, ожидание оплаты" CSaleOrder::StatusOrder($id, "F"); //переводим в статус "выполнен" } } }
что-нибудь для нового заказа сделать
MainEventManager::getInstance()->addEventHandler( 'sale', 'OnSaleOrderSaved', 'MyOnSaleOrderSaved' ); function MyOnSaleOrderSaved(MainEvent $event){ $order = $event->getParameter("ENTITY"); if ($event->getParameter("IS_NEW")){ //Ваша логика } }
Настройка обмена выполнена правильно, но обмен все равно проходит некорректно? Рассмотрим типичные проблемы, возникающие в процессе интеграции сайта с 1С, и способы их решения.
Обмен заказами завершен с ошибками
Проблема. При попытке обмена заказов в 1С выходит сообщение:
Выгружено товаров: 1
Выгружено картинок: 1
Выгрузка товаров успешно завершена
Не установлен реквизит «ГруппаДоступаККонтрагенту». Элемент не записан!
Не установлен реквизит «РегионДоставки». Элемент не записан!
Не установлен реквизит «Основная форма оплаты». Элемент не записан!
{Обработка.ОбменССайтом(3468)}: Ошибка при вызове метода контекста (Записать): Операция не выполнена!
Произошла ошибка: . По причине:
Не удалось найти/создать контрагента.
Не удалось обработать документы, загруженные с сервера.
Обмен не выполнен.
Не выгружен ни один заказ.
Обмен заказами завершен с ошибками!!!
Решение. Скорее всего, в используемой конфигурации предусмотрена обязательность заполнения указанных выше реквизитов для элемента справочника Контрагенты.
Не меняется статус заказа при выгрузке из 1С
Проблема. Не меняется статус заказа при выгрузке из 1С
В соответствие с логикой синхронизации 1С и «1С-Битрикс: Управление сайтом», статус заказа меняется, если из 1С передались дата оплаты либо дата отгрузки товара. Чтобы эти даты попали в XML-файл, который формируется 1С и передаётся на сайт, нужно сформировать и провести нужные документы.
- В 1С:УТ зарегистрировать оплату заказа можно путем ввода на основании заказа документов оплаты, таких как Платежное поручение входящее и Приходный кассовый ордер.
- Отгрузка, как правило, регистрируется вводом на основании заказа документа Реализация товаров и услуг.
- Если в регистре Расчеты с контрагентами остаток по заказу <= 0, заказ считается оплаченным.
- Если в регистре Заказы покупателей остаток по заказу <= 0, заказ считается отгруженным. У конфигурации УПП принцип тот же.
Статусы, в которые будут переводиться заказы при получении дат оплаты и отгрузки, устанавливаются в настройках модуля интернет-магазина: параметры При получении оплаты переводить заказ в статус и При получении разрешения доставки переводить заказ в статус соответственно.
Изменения товаров не зарегистрированы. Выгрузка товаров не произведена
Проблема. 1С заполнена и настроена на обмен с «1С-Битрикс: Управление сайтом», который тоже настроен на интеграцию с 1С. При нажатии на кнопку Выполнить обмен сразу появляется сообщение в 1С: Изменения товаров не зарегистрированы. Выгрузка товаров не произведена.
Решение. Возможные ошибки:
- Обычно появляется из-за некорректной настройки выгрузки товаров на вкладке Выгрузка товаров. Стоит обратить внимание на то, что настраивается именно фильтр(!), а не выбираются поля для выгрузки. Если отмечается поле для фильтра, то значение этого поля в фильтре должно быть задано.
- В 1С: Управление торговлей обратите внимание в справочнике Номенклатура на реквизит вид номенклатуры. Должен быть обязательно признак товар (наименование товар и тип номенклатуры товар).
- Если обмен осуществляется в режиме выгрузки изменений, а этих изменений с момента последнего обмена не зафиксировано, то возникает указанная ошибка. Стоит обратить внимание на следующие моменты:
- Если осуществляется полная выгрузка каталога на сайт, то настройка фильтра необязательна (нужно снять выделение со всех отмеченных полей на вкладке Выгрузка товаров).
- Изменения товара никаким образом не относятся к сайту, т.е. удаление товаров на сайте или их редактирование не фиксируется в 1С. При обмене выгружаются изменения товаров, произведённые именно в 1С с момента последней выгрузки.
Изменения на сайте не приходят в 1С
Проблема. 1С заполнена и настроена на обмен по расписанию с «1С-Битрикс: Управление сайтом». Развернута копия базы 1С. Изменения в «1С-Битрикс: Управление сайтом» не приходят в 1С, т.е. якобы на сайте нет изменений.
Решение. На самом деле, изменения есть и они приходят в копию базы 1С. Чтобы изменения отслеживались в оригинале базы 1С, просто поменяйте пароль у пользователя «1С-Битрикс: Управление сайтом».
Как выгрузить каталоги из 1С в разные типы инфоблоков?
Проблема. Как выгрузить каталоги из 1С в разные типы инфоблоков?
Решение. Чтобы осуществить выгрузку в разные типы инфоблока, следует поместить несколько компонентов catalog.import.1c на разные страницы.
Например, имеем две страницы: http://mysite.ru/1c_import_1.php и http://mysite.ru/1c_import_2.php. На обеих страницах настраиваем компонент catalog.import.1c — указываем в параметрах разные типы инфоблоков и устанавливаем флажок у опции Импортировать с учетом типа инфоблока.
Затем при настройке импорта в 1С, для выгрузки в нужный тип инфоблока указываем разные файлы: http://mysite.ru/1c_import_1.php либо http://mysite.ru/1c_import_2.php.
Пример файла:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetTitle("import1");
?>
<?$APPLICATION->IncludeComponent("bitrix:catalog.import.1c", "", Array(
"IBLOCK_TYPE" => "books",
"SITE_LIST" => array(),
"INTERVAL" => "30",
"GROUP_PERMISSIONS" => array(0 => "1"),
"USE_OFFERS" => "N",
"USE_IBLOCK_TYPE_ID" => "Y",
"SKIP_ROOT_SECTION" => "N",
"ELEMENT_ACTION" => "D",
"SECTION_ACTION" => "D",
"FILE_SIZE_LIMIT" => "204800",
"USE_CRC" => "Y",
"USE_ZIP" => "Y",
"USE_IBLOCK_PICTURE_SETTINGS" => "N",
"GENERATE_PREVIEW" => "Y",
"PREVIEW_WIDTH" => "100",
"PREVIEW_HEIGHT" => "100",
"DETAIL_RESIZE" => "Y",
"DETAIL_WIDTH" => "300",
"DETAIL_HEIGHT" => "300",
"TRANSLIT_ON_ADD" => "Y",
"TRANSLIT_ON_UPDATE" => "Y",
"TRANSLIT_MAX_LEN" => "100",
"TRANSLIT_CHANGE_CASE" => "L",
"TRANSLIT_REPLACE_SPACE" => "_",
"TRANSLIT_REPLACE_OTHER" => "_",
"TRANSLIT_DELETE_REPEAT_REPLACE" => "Y"
),
false
);?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
Не удалось найти вид номенклатуры
Проблема. Не удалось найти вид номенклатуры
В процессе обмена 1С с сайтов возникает ошибка: Не удалось найти вид номенклатуры: Услуга Не удалось найти вид номенклатуры: Товар Не удалось найти/создать номенклатуру. Не удалось обработать документы, загруженные с сервера.
Решение. Ошибка возникает, если в 1С нет типов номенклатуры Услуга и Товар. Эти типы номенклатуры критичны для процесса обмена данными с сайтом. Следует создать в 1С эти типы номенклатуры и только поле этого осуществлять обмен.
Поле объекта не обнаружено
Проблема. В процессе обмена возникает ошибка Поле объекта не обнаружено.
В процессе обмена заказами возникает ошибка: {Обработка.ОбменССайтом(3271)}: Поле объекта не обнаружено (Наименование) >> ОтобразитьСостояние(«Идентификация контрагента: » + СтрокаДД.СтруктураДанныхКонтрагента.Наименование);
Решение. Проверьте настройки интеграции с 1С, закладка Профили обмена: установлены ли соответствия для полей заказа. Обратите внимание на поля Полное Наименование и Наименование. Эти поля критичны для 1С.
Произошла ошибка на стороне сервера. Получен неизвестный статус импорта.
- Возникает ошибка следующего вида:
Выгружено товаров: 679 Выгружено картинок: 469 Произошла ошибка на стороне сервера. Получен неизвестный статус импорта. Обмен не выполнен. Ответ сервера. Fatal error : Allowed memory size of 67108864 bytes exhausted (tried to allocate 102401 bytes) in /var/www/bitrix/modules/iblock/classes/general/cml2.php on line 483 Выгрузка товаров завершена с ошибками!
Решение. Ошибка скорее всего связана с нехваткой ресурсов на масштабирование передаваемых на сервер изображений. Выходом из данной ситуации может служить отключение опции Выгружать картинки (вкладка Выгрузка товаров в настройке обмена в 1С).
Также можно увеличить размер выделяемой памяти в настройках PHP (параметр memory_limit), для этого следует обратиться к хостинг-провайдеру.
- Возникает ошибка следующего вида:
Выгружено товаров: 46 Выгружено картинок: 0 Произошла ошибка на стороне сервера. Получен неизвестный статус импорта. Обмен не выполнен Ответ сервера: DB query error. Please try later. Выгрузка товаров завершена с ошибками!
Решение. Ошибка может возникать в случае некорректной передачи файла на сервер. В процессе отправки файл может «обрезаться» и терять свою целостность, в итоге файл на сервер передаётся некорректным по содержанию.
Причиной может служить прокси-сервер, через который осуществляется обмен. Попробуйте осуществить выгрузку не через прокси-сервер. Также попробуйте отключить опцию Использовать сжатие zip, если доступно в настройках интеграции с 1С — возможно, на сервере не поддерживается ZIP-сжатие. Проверьте настройки интеграции с 1С.
Произошла ошибка на стороне сервера. Файл не отправлен
В процессе обмена возникает такого вида ошибка:
Выгружено товаров: 3 Выгружено картинок: 0 Выгрузка товаров успешно завершена Выгружено заказов: 1 Произошла ошибка на стороне сервера. Файл не отправлен (C:Documents and SettingsUserLocal SettingsTempv8_5075_63.zip). Обмен не выполнен Ответ сервера: Файл для импорта пуст. Обмен заказами завершён с ошибками!
Решение. Причины возникновения ошибки могут быть следующие:
- На компьютере, где установлена 1С, имеется файрволл или антивирус, препятствующий корректной передаче файла или блокирующий отправку файла на сервер.
- Некорректно работает функции расширения ZIP, вследствие чего из архива не распаковываются файлы. Для решения возникшей проблемы рекомендуется:
- Установить последние стабильные версии обновлений модуля интернет-магазина.
- На время обмена отключить на локальной машине все блокирующее ПО (антивирус, файрволлы и т.д.)
- Отключить ZIP-сжатие в настройках интеграции с 1С.
Не работает авторизация при обмене данными с 1С
Решение. Часто проблема возникает в результате работы PHP в режиме CGI. В этом режиме есть проблемы с передачей данных авторизации HTTP в PHP. Можно это проверить, посмотрев phpinfo() в разделе: Server API: CGI. Можно обойти проблему, но необходимо чтобы на сервере была включена обработка .htaccess и поддержка mod_rewrite. Выполните следующие действия:
- В корне сайта в файл .htaccess добавьте строки:
RewriteEngine on
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
- Закомментируйте следующие строки в файле bitrix/admin/.htaccess, которые отключают mod_rewrite:
#<ifmodule mod_rewrite.c="">
# RewriteEngine Off
#</ifmodule>
Примечание: данный файл может отсутствовать, поскольку он создается вручную.
- В файл bitrix/php_interface/dbconn.php добавьте строки:
$remote_user = $_SERVER["REMOTE_USER"]
? $_SERVER["REMOTE_USER"] : $_SERVER["REDIRECT_REMOTE_USER"];
$strTmp = base64_decode(substr($remote_user,6));
if ($strTmp)
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $strTmp);
Для проверки работоспособности HTTP-авторизации воспользуйтесь скриптом
Внимание! Данный вариант обхода не всегда может решить проблему. Если при выполнении всех рекомендаций HTTP-авторизация не заработала, то следует обратиться к хостинг-провайдеру с этой проблемой.
При выгрузке каталога из 1С не ставит галочку «уменьшать количество при заказе»
Проблема. При выгрузке каталога из 1C не ставит галочку уменьшать количество при заказе
Решение. Чтобы исправить это, необходимо в файле init.php добавить код, который будет срабатывать при добавлении продукта (через событие OnProductAdd):
<?
AddEventHandler("sale", "OnProductAdd", "OnProductAdd");
function OnProductAdd($ID,$Fields)
{
$res=Array("QUANTITY_TRACE"=>'Y);
CCatalogProduct::Update($ID,$res);
}
?>
Возможные причины медленного импорта из 1С
Проблема. Медленный импорт из 1C.
Возможные причины:
Включённая индексация. Для ускорения можете в настройках инфоблока выключить индексацию элементов и разделов, а также свойств.
Проактивная защита, которая меняет идентификатор сессии каждую минуту. В случае интеграции с 1C приложение 1C не подхватывает новый идентификатор и пытается получить переменные сессии со старым ID сессии. В сессии хранится шаг импорта, если не удаётся в сессии найти этот шаг, то считается, что шаг равен 1, т.е. импорт начинается сначала. Попробуйте отключить хранение сессий в базе и смену идентификатора сессии.
Если структура каталога в 1С отличается от каталога на сайте?
Задача: Структура каталога на сайте должна отличаться от структуры в 1C.
Варианты решения:
Вариант 1. Делается отдельный классификатор — инфоблок и разделы. У разделов создаётся свойство привязка к разделам, и нужные «человеческие» разделы привязываются к разделам инфоблока с классификатором, который пришел из 1C. Можно сделать множественную привязку — будет проще свести в один раздел из кучи непонятных в 1C.
Вариант 2. В 1C можно создать такой объект как прайс-лист и попробовать настроить обмен с сайтом, уже используя его как прокси. Т.е. если в справочнике Номенклатура бардак и вообще куча всякого, что на сайте не должно показываться, то создаётся прайс-лист, и уже в нём создаются нужные секции. И специально обученный сотрудник добавляет в узлы прайс-листа ссылки на позиции из справочника номенклатура.
Тогда на сайт будет уходить CML, структура которого берётся из прайс-листа, а не из номенклатурного справочника.
Ошибка импорта метаданных
Проблема. На этапе выгрузки свойств после построения таблиц выводится сообщение об ошибке:
Выгружено товаров: 1 832
Выгружено картинок: 0
Выгружено предложений: 0
Произошла ошибка на стороне сервера.
Обмен не выполнен
Ответ сервера:
Ошибка импорта метаданных.
Выгрузка товаров завершена с ошибками!!!
Причина. Ошибка может возникать, если названия свойств начинаются с цифр. Первый знак в названии должен быть буквой.
Проблема. На этапе выгрузки свойств после построения таблиц выводится сообщение об ошибке:
Ошибка импорта метаданных. В редакции Малый Бизнес нет возможности иметь более одного типа цены. Настройте выгрузку из 1С или перейдите на другую редакцию БУС.
Причина. Такая ошибка возникает, когда клиент забывает указать в настройках обмена конкретное соглашение (в настройках 1С), по которому должны выгружаться цены. Соглашение указывается в отборах выгружаемых инфоблоков.
Выгрузка картинок
Проблема. Неполная выгрузка картинок.
Картинки выгружаются из 1С, только при первой полной выгрузке каталога товаров, не важно выгрузка была на в папку на локальном компьютере или на сайт. В последствии картинки выгружаются только новые и измененные.
Если изменены настройки в 1С и картинки не выгрузились в первый раз на сайт, то в настройках модуля обмена выполните обмен через кнопку принудительной полной выгрузке картинок.
Из-за часто меняющегося компонента оформления заказа приведенное здесь решение не является полным и окончательным, а следить за актуальностью я не могу. Поэтому прошу пост рассматривать лишь для подспорья в написании собственного кода, а не использовать «как есть».
ЗЫ: Вот последняя актуальная (примерно на июнь 2014) версия компонента, которую я запилил под одного клиента:
скачать
. Пользуйтесь как есть, пожалуйста. Измененные блоки (менялся только component.php) я выделил фразой customization (конкретно для клиента менял еще некоторые строчки). Кодировка cp1251.
Оформление заказа почти идеально, но есть минус — если гость вводит e-mail, который есть в базе, ему дадут от ворот поворот — мол такой пользователь уже есть. А если подойти с точки зрения покупателя, это ломает — вспоминать пароль, или еще что. В общем, лояльность падает. Исправим ситуацию (сразу хочу огорчить — решение подразумевает +2 байта в системном компоненте, так что если вам не пойдет — пост бесполезен (хотя, вы можете просто вынести компонент в свое пространство, код все равно будет рабочим).
Речь пойдет про компонент sale.order.ajax, одношаговое оформление заказа. Почему нельзя вынести компонент в свое пространство и изменить? Потому что это центровой компонент магазина, который постоянно улучшается компанией Битрикс, и лично я против его изменения. Так как же подошел к проблеме я.
Все методы ниже — методы класса CSaleHandlers, внутри которого содержатся необходимые
обработчики событий
.
Также класс имеет переменную
private static $bGuestOrder = false;
Поехали
1. Событие OnSaleComponentOrderOneStepProcess
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepProcess', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepProcessHandler')); public static function OnSaleComponentOrderOneStepProcessHandler($arResult, $arUserResult, $arParams) { if (empty($arResult['ERROR']) && $arUserResult['CONFIRM_ORDER']=='Y' && !$GLOBALS['USER']->IsAuthorized()) { if ($arUser = CUser::GetList($by='id', $order='asc', array('=EMAIL' => $arUserResult['USER_EMAIL']))->Fetch()) { if (!in_array(1, CUser::GetUserGroup($arUser['ID']))) { $GLOBALS['USER']->Authorize($arUser['ID']); self::$bGuestOrder = true; } } } }
Перед самым созданием заказа, перехватываем исполнение и смотрим — если пользователь с введенным e-mail, есть, то авторизуем его. От греха подальше, НЕ авторизуем если пользователь из группы админов. Это достаточно важный момент, потому что ошибка может произойти на любой строчке кода, и тогда гость может остаться админом.
В переменной self::$bGuestOrder запоминаем, что заказ создает гость.
2. Событие OnOrderUpdate
//AddEventHandler('sale', 'OnOrderUpdate', Array('CSaleHandlers', 'OnOrderUpdateHandler')); public static function OnOrderUpdateHandler($ID, $arFields) { if (self::$bGuestOrder && $GLOBALS['USER']->IsAuthorized() && isset($arFields['PRICE'])) { $_SESSION['SAVED_UID'] = $GLOBALS['USER']->GetID(); $GLOBALS['USER']->Logout(); } }
Разавторизовываем пользователя после создания заказа (в понятиях кода, а не сайта). Почему нельзя использовать OnOrderAdd? Потому что после добавления идет еще привязка корзины пользователя, и мы потеряем ее в случае OnOrderAdd. Также в сессии запоминаем предыдущий ID пользователя, который нам пригодится
3. Событие OnSaleComponentOrderOneStepComplete
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepComplete', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepCompleteHandler')); public static function OnSaleComponentOrderOneStepCompleteHandler($ID, $arOrder, $arParams) { if ($ID <= 0) { if (self::$bGuestOrder) { $GLOBALS['USER']->Logout(); } } }
Здесь мы страхуемся и делаем логаут пользователю, если случилась ошибка при создании заказа.
4. Событие OnSaleComponentOrderOneStepFinal
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepFinal', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepFinalHandler')); public static function OnSaleComponentOrderOneStepFinalHandler($ID, $arOrder, $arParams) { if ((!$GLOBALS['USER']->IsAuthorized() && $_SESSION['SAVED_UID']!=$arOrder['USER_ID']) || ($GLOBALS['USER']->IsAuthorized() && $GLOBALS['USER']->GetID()!=$arOrder['USER_ID']) ) { $arOrder = array(); } }
Здесь мы запрещаем просмотр заказа на финальном шаге (оплата), если это гость и не создал его только что сам.
По идее все. Где же надо поправить системный компонент sale.order.ajax/component.php?
Для версии Магазина до 12.5.4. примерно на 2079 строчке (но строчки постоянно скачут при изменениях, так что ориентироваться лучше на окружающий код) идет выборка созданного заказа с проверкой пользователя — вот пользователя надо закомментировать:
После версии 12.5.4 модуля Магазин, код иной:
Обратите внимание. Данное изменение компонента может работать только вкупе с данными обработчиками. Иначе доступ к финальному шагу (системе оплаты) получает любой пользователь.
Изменения компонента не было бы, если бы реализованная
идея
, просьба поддержать.
Класс необходимых обработчиков вы можете скачать ниже. Достаточно просто подключить его в init.php
Проблемы с оформлением заказа после обновления 1С-Битрикс
ID статьи: 56
, создана 14 апр 2016
После перехода на версию 16.0 1С-Битрикс страница оформления заказа начала работать некорректно.
Решение
Не дожидаясь апдейта, переключите в настройках оформления заказа шаблон компонента на стандартный интернет-магазин 1С-Битрикс.
Инструкция:
- Перейдите на страницу оформления заказа и нажмите кнопку «Настройки».
- В открывшемся окне выберите из списка шаблонов компонента встроенный шаблон магазина 1С-Битрикс и сохраните изменения.
Внимание! Компания 1С-Битрикс настоятельно не рекомендует использовать бета-версию для рабочих проектов, так как это может привести к неожиданным сбоям и ошибкам в работе сайта. При включенной бета-версии мы также не можем гарантировать стабильную работу нашего решения. Пожалуйста, отключите использование бета-версий в соответствии с инструкцией.
Добрый день. Подскажите пожалуйста у меня после оформление заказа когда нажимаю на кнопку ОФОРМИТЬ ЗАКАЗ, выходит какие то непонятные надписи, хотя должно выходит надпись «Ваш заказ успешно оформлен на сайте» (Это выходит в обычном состояний браузера, без инкогнито). Самое интересное что данные загружаются в заказах, и когда я оформляю через режим инкогнито все исправно работает. Купили шаблон aspro next, и установили.
1) Использую предпоследнюю версию sale.order.ajax — который работает на PHP.
2) Код который выводится прикреплю с screenshot — ом.
3) Новая версия Битрикс
4) Заранее спасибо!
Искал в интернете, встретил только одна статейку, и то не было ответа.
посмотреть код компонента — https://clip2net.com/s/4fQpIWn Не отрабатывает вот это условие, массив сессии пустой. Может кто сталкивался с подобным?
russian
software
it
bitrix
5
ответов
переодически это через n минут после оплаты?
в общем n минут скорее равно времени жизни сессии
Andrew Zahalski
переодически это через n минут после оплаты?
вот эту закономерность не вычислил. Сейчас при проверке сразу вылазит сообщение, что заказ не найден.
Игорь Захаров
вот эту закономерность не вычислил. Сейчас при про…
старые заказы пробовал? или новый созданный
Andrew Zahalski
старые заказы пробовал? или новый созданный
да как будто все сейчас , и старые и новые