Свойство заказа адрес доставки ошибка ввода

Практически никого из моих клиентов не устраивает внешний вид sale.order.ajax. Здесь я опишу большую часть приемов, которыми пользуюсь сам при кастомизации данного непростого компонента.

В файле template.php блоки заказа отмечены комментариями:

BASKET ITEMS BLOCK - корзина заказа - таблица товаров
REGION BLOCK - выбор типа плательщика и ввод местоположения - города покупателя
DELIVERY BLOCK - выбор службы доставки
PAY SYSTEMS BLOCK - выбор способа оплаты
BUYER PROPS BLOCK - форма с полями для ввода данных покупателя
ORDER SAVE BLOCK - итог и кнопка подтверждения заказа

Чтобы все блоки были активны, а не только первый комментируем вторую строчку в данном блоке

initFirstSection: function()
{
	var firstSection = this.orderBlockNode.querySelector('.bx-soa-section.bx-active');
	//BX.addClass(firstSection, 'bx-selected');
	this.activeSectionId = firstSection.id;
},

Если доставки выдают ошибку ошибку вычислений, то блоки с доставкой скрываются. Отключить это можно закомментировав следующий код:

/*if (this.result.DELIVERY.length > 0)
{
	BX.addClass(this.deliveryBlockNode, 'bx-active');
	this.deliveryBlockNode.removeAttribute('style');
}
else
{
	BX.removeClass(this.deliveryBlockNode, 'bx-active');
	this.deliveryBlockNode.style.display = 'none';
}*/

Убираем сокрытие блоков при авторизации (при выключенной в настройках опции «регистрировать вместе с оформлением заказа»).

if (this.result.SHOW_AUTH && section.id != this.authBlockNode.id && section.id != this.basketBlockNode.id)
	section.style.display = 'none';
else if (section.id != this.pickUpBlockNode.id)
	section.style.display = '';

Открыть все блоки и убрать лишнее

Чтобы раскрыть все скрытые блоки можно воспользоваться следующими методами (лично использовал на версиях до 20):

Ищем строку var active = section.id == this.activeSectionId и меняем ее на

var active = true

Далее отключаем реагирование на клик по заголовку блока

BX.unbindAll(titleNode);

if (this.result.SHOW_AUTH)
{
	BX.bind(titleNode, 'click', BX.delegate(function(){
		this.animateScrollTo(this.authBlockNode);
		this.addAnimationEffect(this.authBlockNode, 'bx-step-good');
	}, this));
}
else
{
	BX.bind(titleNode, 'click', BX.proxy(this.showByClick, this));
	editButton = titleNode.querySelector('.bx-soa-editstep');
	editButton && BX.bind(editButton, 'click', BX.proxy(this.showByClick, this));
}

Чтобы всегда были открыты Регион и Пользователь

if (this.activeSectionId !== this.regionBlockNode.id)
	this.editFadeRegionContent(this.regionBlockNode.querySelector('.bx-soa-section-content'));

if (this.activeSectionId != this.propsBlockNode.id)
	this.editFadePropsContent(this.propsBlockNode.querySelector('.bx-soa-section-content'));

Чтобы убрать кнопки Далее/Назад

node.appendChild(
	BX.create('DIV', {
		props: {className: 'row bx-soa-more'},
		children: [
			BX.create('DIV', {
				props: {className: 'bx-soa-more-btn col-xs-12'},
				children: buttons
			})
		]
	})
);

Чтобы убрать ссылки «изменить» у всех блоков в editOrder (~2222 стр.)

var editSteps = this.orderBlockNode.querySelectorAll('.bx-soa-editstep'), i;
 for (i in editSteps) {
	if (editSteps.hasOwnProperty(i)) {
	   BX.remove(editSteps[i]);
	}
 }

Чтобы скрыть уведомление о том, что данный заполнены автоматически добавляем в конец файла style.css

.alert.alert-warning{display:none;}

Определение местоположения пользователя в автоматическом режиме

use BitrixMainEventManager; 
$eventManager = EventManager::getInstance();
$eventManager->addEventHandler("sale", "OnSaleComponentOrderProperties", Array("Example", "OnSaleComponentOrderProperties"));

class Example
{
   /**
   * У меня по условию задачи известны ID и NAME местоположения
   */
   static $curCityId = XX;  // числовое значение идентификатора местоположения
   static $curCityName = 'Название города';
   
   /**
   * ID свойств заказа   
   */
   const PROP_LOCATION = 6; 
   const PROP_ZIP = 4; 
   const PROP_LOCATION_NAME = 5;


   static function OnSaleComponentOrderProperties(&$arFields)
   {
      $rsLocaction = CSaleLocation::GetLocationZIP(self::$curCityId); 
      $arLocation = $rsLocaction->Fetch(); 
      $arFields['ORDER_PROP'][self::PROP_ZIP] = $arLocation['ZIP'];
      $arFields['ORDER_PROP'][self::PROP_LOCATION_NAME] = self::$curCityName;
      $arFields['ORDER_PROP'][self::PROP_LOCATION] = CSaleLocation::getLocationCODEbyID(self::$curCityId);
   }
}

А вот такая модификация позволяет определить местоположение только по названию города:

class Example {
   static function OnSaleComponentOrderProperties(&$arFields)
   {
      static $curCityName = 'Название города';
      const PROP_LOCATION = 6;  // - Идентификатор свойства с местоположением
      static function OnSaleComponentOrderProperties(&$arFields)
      {
         $res = BitrixSaleLocationLocationTable::getList(array(
         'filter' => array('=NAME.NAME' => self::$curCityName, '=NAME.LANGUAGE_ID' => LANGUAGE_ID),
         'select' => array('CODE' => 'CODE', 'NAME_RU' => 'NAME.NAME', 'TYPE_CODE' => 'TYPE.CODE') //'*', 
         ));
         while($item = $res->fetch())
         {            
            $code = $item["CODE"];
         }
         $arFields['ORDER_PROP'][self::PROP_LOCATION] = $code;
      }
   }
}

Скрыть какое-то свойство

Если необходимо скрыть какое-то свойство, например, свойство индекс — задать значение по умолчанию и не показывать пользователям это поле, то можно внести корректировку в JS. В функции getPropertyRowNode после switch (propertyType) добавляем скрытие данного свойства:

if(property.getId()==6){// идентификатор скрываемого свойства
   var addressInput=propsItemNode.querySelector('textarea');
   propsItemNode.style='display:none;';
   addressInput.value='нужное значение';
}

Скрываем сообщение «Вы заказывали в нашем интернет-магазине, поэтому мы заполнили все данные автоматически»

Идем в функцию checkNotifications на ~750 стр и находим код

informer.appendChild(
	BX.create('DIV', {
		props: {className: 'row'},
		children: [
			BX.create('DIV', {
				props: {className: 'col-xs-12'},
				style: {position: 'relative', paddingLeft: '48px'},
				children: [
					BX.create('DIV', {props: {className: 'icon-' + className}}),
					BX.create('DIV', {html: text})
				]
			})
		]
	})
);
BX.addClass(informer, 'alert alert-' + className);

И обрамляем данный код доп. проверкой

if(this.params.MESS_SUCCESS_PRELOAD_TEXT.indexOf('Вы заказывали в нашем инте') === false) {
	//Код выше ставим сюда
}

Скрываем сообщение «Выберите свой город в списке. Если вы не нашли свой город, выберите «другое местоположение», а город впишите в поле «Город»

Идем в функцию getDeliveryLocationInput и комментируем код:

/*
if (location && location[0])
{
	node.appendChild(
		BX.create('DIV', {
			props: {className: 'bx-soa-reference'},
			html: this.params.MESS_REGION_REFERENCE
		})
	);
}
*/

Или с помощью стилей скрываем класс bx-soa-reference

#bx-soa-region .bx_soa_location .bx-soa-reference{display: none}

Исключить из показа нулевой цены за доставку

В функции getDeliveryPriceNodes: function(delivery) в блоке «else» заменяем. Вместо:

priceNodesArray = [delivery.PRICE_FORMATED];

пишем:

if(delivery.PRICE>0) priceNodesArray = [delivery.PRICE_FORMATED];

Так мы спрячем нулевую цену из свернутого блока с выбранной доставкой.

Дальше нужно скрыть нули в списке служб доставки. Для этого в функции createDeliveryItem: function(item) делаем строгую проверку на ноль. Вместо:

if (item.PRICE >= 0 || typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined')

пишем:

if (item.PRICE > 0 || typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined')

А также вместо:

else if (deliveryCached && (deliveryCached.PRICE >= 0 || typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined'))

пишем:

else if (deliveryCached && (deliveryCached.PRICE > 0 || typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined'))

И последним нужно скрыть нулевую доставку из итоговых сумм. Для этого в функции editTotalBlock: function() также ставим строгую проверку на ноль. Вместо

if (parseFloat(total.DELIVERY_PRICE) >= 0 && this.result.DELIVERY.length)

пишем:

if (parseFloat(total.DELIVERY_PRICE) > 0 && this.result.DELIVERY.length)

В результате нулевая доставка не будет показана пользователю.

Убираем поле «Адрес доставки» из вывода блока «Пользователь»

Описанные у моих коллег способы в моем случае не сработали. Решил пойти некрасивым, но действенным способом

Идем в функцию editPropsItemsи находим код:

if (
	this.deliveryLocationInfo.loc == property.getId()
	|| this.deliveryLocationInfo.zip == property.getId()
	|| this.deliveryLocationInfo.city == property.getId()
)

Меняем его на:

if (
	this.deliveryLocationInfo.loc == property.getId()
	|| this.deliveryLocationInfo.zip == property.getId()
	|| this.deliveryLocationInfo.city == property.getId()
	|| property.getName()=='Адрес доставки (улица, дом, квартира)' //где property.getName() приравниваем к названию поля адреса в вашей системе
)

В базовом стандартном шаблоне поле индекс достаточно легко перенести. Давайте перенесем поле Индекс из блока местоположений в блок пользовательских свойств

Находим функцию getDeliveryLocationInput (~4451 стр.) и комментируем код this.getZipLocationInput(node);

Идем в функцию editPropsItems (~6728 стр.) и перед propsNode.appendChild(propsItemsContainer) добавляем код this.getZipLocationInput(propsItemsContainer);.

По идее этого должно хватить. Но если все равно не получается, то перейдите по адресу /bitrix/admin/sale_order_props.php?lang=ru и в поле Индекс переведите его а группу свойств Личные данные

Вывод поля «Адрес доставки» в блоке «Доставка»

Идем в функцию editDeliveryInfo и в самый конец добавляем код:

var deliveryItemsContainer = BX.create('DIV', {props: {className: 'col-sm-12 bx-soa-delivery'}}),
	group, property, groupIterator = this.propertyCollection.getGroupIterator(), propsIterator;

if (!deliveryItemsContainer)
	deliveryItemsContainer = this.propsBlockNode.querySelector('.col-sm-12.bx-soa-delivery');

while (group = groupIterator())
{
	propsIterator =  group.getIterator();
	while (property = propsIterator())
	{
		if (property.getName()=='Адрес доставки (улица, дом, квартира)') { //Если свойство совпадает с названием поля адреса в вашей системе

			this.getPropertyRowNode(property, deliveryItemsContainer, false); //вставляем свойство в подготовленный контейнер
			deliveryNode.appendChild(deliveryItemsContainer); //контейнер вместе со свойством в нём добавляем в конце блока с описанием (deliveryInfoContainer)

		}
	}
}

Переносим поле «Адрес доставки» в отдельный новый(!) блок

Данная необходимость возникает, например, в шаблонах Аспро, где поле «Адрес доставки» в блоке с выбором доставок выглядит чужеродно и некрасиво

В шаблоне template.php компонента sale.order.ajax добавляем новый блок в наиболее удобное нам место

<!--	ADRESS BLOCK	-->
<div id="bx-soa-adress-dostavki" data-visited="false" class="bx-soa-section bx-active">
	<div class="bx-soa-section-title-container">
		<h2 class="bx-soa-section-title col-sm-9">
			<span class="bx-soa-section-title-count"></span>Данные для доставки
		</h2>
	</div>
	<div class="bx-soa-section-content container-fluid"></div>
</div>

Идем в файл order_ajax.js и в функции init на ~77 стр добавляем вызов вновь добавленного блока

this.orderAdresBlockNode = BX('bx-soa-adress-dostavki');

Скрываем вывод поля «Адрес доставки» как показано выше

if (
	this.deliveryLocationInfo.loc == property.getId()
	|| this.deliveryLocationInfo.zip == property.getId()
	|| this.deliveryLocationInfo.city == property.getId()
	|| property.getName()=='Адрес доставки' //где property.getName() приравниваем к названию поля адреса в вашей системе
)

Реализуем вывод нового поля в дополнительном блоке. В стандартном случае придется учесть, что поле «Адрес доставки» генерируется отдельно для каждого из типов плательщиков, имеет разный id свойства, а сам наш блок надо скрывать, если выбраны оплаты и доставки при которых поле «Адрес доставки» не выводится. Поэтому код будет таким.

Идем в функцию editDeliveryInfo (любую аналогичную или свою) и после строки deliveryNode.appendChild(deliveryInfoContainer) или в конце функции добавляем:

var deliveryItemsContainer = BX.create('DIV', {props: {className: 'col-sm-12 bx-soa-delivery'}}),
	group, property, groupIterator = this.propertyCollection.getGroupIterator(), propsIterator;

if (!deliveryItemsContainer)
	deliveryItemsContainer = this.propsBlockNode.querySelector('.col-sm-12.bx-soa-delivery');

while (group = groupIterator())
{
	propsIterator =  group.getIterator();
	while (property = propsIterator())
	{

		var personType = this.getSelectedPersonType();

		this.orderAdresBlockNode.querySelector('.bx-soa-section-content').innerHTML = '';

		if (property.getName()=='Адрес доставки' && personType.ID === '1' && property.getId() == '7') {
			this.getPropertyRowNode(property, deliveryItemsContainer, false); //вставляем свойство в подготовленный контейнер
			this.orderAdresBlockNode.querySelector('.bx-soa-section-content').appendChild(deliveryItemsContainer); 

			this.orderAdresBlockNode.classList.remove('hidden');
		}else if (property.getName()=='Адрес доставки' && personType.ID === '2' && property.getId() == '19') { 
			this.getPropertyRowNode(property, deliveryItemsContainer, false); //вставляем свойство в подготовленный контейнер
			this.orderAdresBlockNode.querySelector('.bx-soa-section-content').appendChild(deliveryItemsContainer);

			this.orderAdresBlockNode.classList.remove('hidden');
		}else{
			this.orderAdresBlockNode.classList.add('hidden');
		}

	}
}

Код не самый красивый и правильный, но работает

Переносим поле «Комментарии к заказу» в конец формы

Идем в функцию editActivePropsBlock и комментируем строчку:

this.editPropsComment(propsNode);

Для вывода поля ищем в шаблоне функцию последнего блока. В моем случае это вывод состава заказа. Ищем функцию editBasketItems и в самый конец дописываем:

this.editPropsComment(basketItemsNode);

Переносим поле «Местоположения» в блок пользовательских свойств

По умолчанию данное поле искуственно исключено из блока пользовательских свойств. Чтобы его вернуть на место идем в функцию editPropsItems и удаляем код:

if (
	this.deliveryLocationInfo.loc == property.getId()
	|| this.deliveryLocationInfo.zip == property.getId()
	|| this.deliveryLocationInfo.city == property.getId()
)
	continue;

Запрет Битриксу выбирать доставку по умолчанию

В случае, если у пользователя есть сохраненный профиль, ему автоматически выберется последняя выбранная им доставка, но битрикс ничего не знает о том, что у нас там еще и обязательные поля. Поэтому убираем дефолтный выбор доставки в обработчике OnSaleComponentOrderJsDataHandler. Он у нас уже есть, дописываем в него:

if (isset($arResult['JS_DATA']['LAST_ORDER_DATA']['DELIVERY'])
 && $arResult['JS_DATA']['LAST_ORDER_DATA']['DELIVERY']!='') {
    $arResult['JS_DATA']['LAST_ORDER_DATA']['DELIVERY'] = '';}

В данном случае блок с доставками всегда будет открыт, и пользователь сразу обратит внимание на необходимость заполнения полей. Но! Если пользователь в кабинете удаляет профиль, поле с местоположением будет у него незаполнено, и после его заполнения блок с доставками автоматически закроется без возможности его отредактировать (пропадет кнопка «Изменить»). Это очень трудно пофиксить, чтобы не посыпалось всё остальное, поэтому мы приняли решение убрать возможность редактирования профилей в кабинете пользователя (делается снятием галочки в настройках компонента личного кабинета)

На данный момент у меня всё. Конечно, этот код был написан для конкретного проекта и с определенными допущениями. Но надеюсь, что данная заметка оказалась вам полезной и наведет вас на путь истинный при решении вашей задачи. Ибо документации по методам класса OrderAjaxComponent нет и не будет. Если Вам есть что добавить или поправить — буду рада комментариям.

order_ajax_ext.js

Создаём файл order_ajax_ext.js в папке с шаблоном компонента sale.order.ajax (там же, где лежит файл order_ajax.js) с содержимым:

(function () {
    'use strict'; 
 
    var initParent = BX.Sale.OrderAjaxComponent.init,
        getBlockFooterParent = BX.Sale.OrderAjaxComponent.getBlockFooter,
        editOrderParent = BX.Sale.OrderAjaxComponent.editOrder
        ;
 
    BX.namespace('BX.Sale.OrderAjaxComponentExt');    
 
    BX.Sale.OrderAjaxComponentExt = BX.Sale.OrderAjaxComponent;
 
	//Пример перехвата стандартной функции
    BX.Sale.OrderAjaxComponentExt.init = function (parameters) {
        initParent.apply(this, arguments);
 
        var editSteps = this.orderBlockNode.querySelectorAll('.bx-soa-editstep'), i;
        for (i in editSteps) {
            if (editSteps.hasOwnProperty(i)) {
                BX.remove(editSteps[i]);
            }
        }
 
    }; 
})();

В отдельных переменных определяем функции-методы родительского BX.Sale.OrderAjaxComponent, чтобы их можно было вызвать в дочерних функциях и не получить ошибку Maximum call stack size exceeded.

Копируем ссылку с BX.Sale.OrderAjaxComponent в BX.Sale.OrderAjaxComponentExt.

В методе BX.Sale.OrderAjaxComponentExt.init вызываем родительский init, следом прибиваем ссылки «изменить» у всех блоков. Они нам не нужны.

В методе BX.Sale.OrderAjaxComponentExt.getBlockFooter прибиваем кнопки «Назад» и «Вперед» у блоков. Они нам тоже не понадобятся — все блоки у нас развёрнуты.

В методе BX.Sale.OrderAjaxComponentExt.editOrder ненужным блокам-секциям добавляем css-класс bx-soa-section-hide. По нему мы и будем скрывать ненужные блоки. А так же в этом методе раскрываем только нужные нам блоки: «Покупатель» и «Товары в заказе».

Метод BX.Sale.OrderAjaxComponentExt.initFirstSection оставляем просто пустым. Если этого не сделать, то у анонимов при попытке оформления будет вываливаться эксепшен, по поводу отсутствия необходимых обязательных полей.

Идем дальше.

В файле template.php нашего шаблона нового оформления добавляем подключение нашего скрипта order_ajax_ext.js

После строчки:

$this->addExternalJs($templateFolder.'/order_ajax.js');

добавляем:

$this->addExternalJs($templateFolder.'/order_ajax_ext.js');

А так же в файле template.php меняем все вызовы BX.Sale.OrderAjaxComponent на BX.Sale.OrderAjaxComponentExt

Ну и не забываем добавить в файл стилей, чтобы ненужные блоки скрылись

.bx-soa-section-hide {
    display: none;
}

Краткое описание функций sale.order.ajax

showValidationResult: function(inputs, errors) — функция в которой полям с ошибкой добавляется класс hasError, который помечает ошибкой(в стандартном варианте добавляет обводку красным).

showErrorTooltip: function(tooltipId, targetNode, text) — функция в которой добавляются тултипы для полей с ошибкой.

showError: function(node, msg, border) — функция в которой выводятся ошибки в «групповой контейнер»

refreshOrder: function(result) — функция в которой происходит разбор ошибок, которые приходят от сервера. Там есть ветка result.error

Первые 3 функции отвечают за валидацию на форме без перезагрузки, а четвёртая за обработку результатов от сервера.

Выполнение кода после перезагрузки страницы

Бывает, что нужно регулярно выполнить код после перезагрузки страницы (изменения опций заказа). Например, требуется перерисовать селект. Это просто. Откройте файл order_ajax.js и в самый конец допишите:

(function ($) {
	$(function() {
		BX.addCustomEvent('onAjaxSuccess', function(){
			$(function() {
				$('select').ikSelect({
					autoWidth:false,
					ddFullWidth:false
				});
			});
		});

		$('select').ikSelect({
			autoWidth:false,
			ddFullWidth:false
		});

		window.onresize = function() {
			$('select').ikSelect('redraw');
		}
	});
})(jQuery);

Штатный ajax возвращает данные во фрейм-контейнер. Соответственно, весь js, уже загруженный на странице, находится на уровень выше. Соотв, чтобы обратиться к нему из html, загруженном через ajax, необходимо это указать (top.имя_функции или top.имя_переменной). Спасибо Евгению Жукову

top.$

Для стилизации селектов, которые по умолчанию выглядят ужасно лучше всего использовать замечательную библиотеку ikSelect

Программная смена города в sale.order.ajax на javascript

Часто, по техническому заданию, требуется программная смена города на javascript с ajax перезагрузкой страницы и перерасчетом формы. Покажу как сделать это.

Будем считать, что у вас уже есть code локации из местоположений Битрикс. Тогда в части кода где необходимо произвести смену локации пишем:

//Данный код будет работать не только внутри sale.order.ajax, но и во внешних скриптах, поскольку мы обращается к его функциям через пространство имен BX.Sale.OrderAjaxComponent
var code = '0000000001';//Ваш код локации. В данном случае это Белоруссия

$('.dropdown-field').val(code);//Обновляем код в скрытом инпуте
//$('.bx-ui-sls-fake').val(code);

BX.Sale.OrderAjaxComponent.params.newCity=code; //Записываем в параметры компонента необходимый нам город
BX.Sale.OrderAjaxComponent.sendRequest();//Обновляем форму

Здесь мы заполнили скрытый input нужным нам кодом и записали его в переменную, которой воспользуемся при перестроении формы. Идем в функцию prepareLocations (~1557 стр.).Находим код:

temporaryLocations.push({

И выше него пишем:

//Делаем двойную проверку.
if(typeof this.params!='undefined'){//В первом случае на то, что параметры вообще установлены, поскольку код выполняется первый раз до их инициализации
	if(typeof this.params.newCity!='undefined'){//Вторая проверка - установлена ли наша переменная
		locations[i].lastValue = this.params.newCity;//Если переменная установлена, то подставляем ее в локацию
		delete this.params.newCity;//Обнуляем нашу переменную
	}
}

В итоге у меня получилось так:

for (k in output)
{
	if (output.hasOwnProperty(k))
	{
		//Делаем двойную проверку.
		if(typeof this.params!='undefined'){//В первом случае на то, что параметры вообще установлены, поскольку код выполняется первый раз до их инициализации
			if(typeof this.params.newCity!='undefined'){//Вторая проверка - установлена ли наша переменная
				locations[i].lastValue = this.params.newCity;//Если переменная установлена, то подставляем ее в локацию
				delete this.params.newCity;//Обнуляем нашу переменную
			}
		}


		temporaryLocations.push({
			output: BX.processHTML(output[k], false),
			showAlt: locations[i].showAlt,
			lastValue: locations[i].lastValue,
			coordinates: locations[i].coordinates || false
		});
	}
}

Расчет стоимости доставки для всех служб доставки

Будем полагать, что компонент sale.order.ajax вынесен у вас в отдельную папку

Тогда идем в файл /local/components/YOUR_NAMESPACE/sale.order.ajax/class.php и находим функцию protected function calculateDeliveries(Order $order) (~4289 стр)

Находим условие if ((int)$shipment->getDeliveryId() === $deliveryId) и в области else сразу после кода:

$mustBeCalculated = $this->arParams['DELIVERY_NO_AJAX'] === 'Y'
						|| ($this->arParams['DELIVERY_NO_AJAX'] === 'H' && $deliveryObj->isCalculatePriceImmediately());

пишем:

$mustBeCalculated = true;
$calcResult = $deliveryObj->calculate($shipment);
$calcOrder = $order;

Теперь после обращения к серверу в наш order_ajax.js приходят службы доставки с рассчитанными стоимостями. Остается их только обработать и вывести.

В скрипте находим функциюcreateDeliveryItem: function(item) и работаем с параметром item.PRICE или item.PRICE_FORMATED и выводим его куда нужно.

Получение стоимости доставки для продукта после применения скидок, правил корзины и …

/**
 * Получение стоимости доставки для продукта после применения скидок, правил корзины и ...
 *
 * @param string|int $bitrixProductId Id битриксового продукта
 * @param string     $siteId          Id битриксового сайта, например "s1"
 * @param string|int $userId          Id битриксового пользователя
 * @param string|int $personTypeId    Id битриксового "Тип плательщика" /bitrix/admin/sale_person_type.php?lang=ru
 * @param string|int $deliveryId      Id битриксового "Службы доставки" /bitrix/admin/sale_delivery_service_list.php?lang=ru&filter_group=0
 * @param string|int $paySystemId     Id битриксового "Платежные системы" /bitrix/admin/sale_pay_system.php?lang=ru
 * @param array      $userCityId      Id битриксового города ("куда доставлять")
 *
 * @return null|float null - не удалось получить; float - стоимость (может быть 0 (после применения скидок на доставку))
 *
 * @throws BitrixMainArgumentException
 * @throws BitrixMainArgumentNullException
 * @throws BitrixMainArgumentOutOfRangeException
 * @throws BitrixMainArgumentTypeException
 * @throws BitrixMainLoaderException
 * @throws BitrixMainNotImplementedException
 * @throws BitrixMainNotSupportedException
 * @throws BitrixMainObjectException
 * @throws BitrixMainObjectNotFoundException
 * @throws BitrixMainSystemException
 */
function getDeliveryPriceForProduct($bitrixProductId, $siteId, $userId, $personTypeId, $deliveryId, $paySystemId, $userCityId)
{
    $result = null;

    BitrixMainLoader::includeModule('catalog');
    BitrixMainLoader::includeModule('sale');

    $products = array(
        array(
            'PRODUCT_ID' => $bitrixProductId,
            'QUANTITY'   => 1,
            // 'NAME'       => 'Товар 1', 
            // 'PRICE' => 500,
            // 'CURRENCY' => 'RUB',
        ),
    );
    /** @var BitrixSaleBasket $basket */
    $basket = BitrixSaleBasket::create($siteId);
    foreach ($products as $product) {
        $item = $basket->createItem("catalog", $product["PRODUCT_ID"]);
        unset($product["PRODUCT_ID"]);
        $item->setFields($product);
    }

    /** @var BitrixSaleOrder $order */
    $order = BitrixSaleOrder::create($siteId, $userId);
    $order->setPersonTypeId($personTypeId);
    $order->setBasket($basket);

    /** @var BitrixSalePropertyValueCollection $orderProperties */
    $orderProperties = $order->getPropertyCollection();
    /** @var BitrixSalePropertyValue $orderDeliveryLocation */
    $orderDeliveryLocation = $orderProperties->getDeliveryLocation();
    $orderDeliveryLocation->setValue($userCityId); // В какой город "доставляем" (куда доставлять).

    /** @var BitrixSaleShipmentCollection $shipmentCollection */
    $shipmentCollection = $order->getShipmentCollection();

    $delivery = BitrixSaleDeliveryServicesManager::getObjectById($deliveryId);
    /** @var BitrixSaleShipment $shipment */
    $shipment = $shipmentCollection->createItem($delivery);

    /** @var BitrixSaleShipmentItemCollection $shipmentItemCollection */
    $shipmentItemCollection = $shipment->getShipmentItemCollection();
    /** @var BitrixSaleBasketItem $basketItem */
    foreach ($basket as $basketItem) {
        $item = $shipmentItemCollection->createItem($basketItem);
        $item->setQuantity($basketItem->getQuantity());
    }

    /** @var BitrixSalePaymentCollection $paymentCollection */
    $paymentCollection = $order->getPaymentCollection();
    /** @var BitrixSalePayment $payment */
    $payment = $paymentCollection->createItem(
        BitrixSalePaySystemManager::getObjectById($paySystemId)
    );
    $payment->setField("SUM", $order->getPrice());
    $payment->setField("CURRENCY", $order->getCurrency());

    // $result = $order->save(); // НЕ сохраняем заказ в битриксе - нам нужны только применённые "скидки" и "правила корзины" на заказ.
    // if (!$result->isSuccess()) {
    //     //$result->getErrors();
    // }

    $deliveryPrice = $order->getDeliveryPrice();
    if ($deliveryPrice === '') {
        $deliveryPrice = null;
    }
    $result = $deliveryPrice;

    return $result;
}

// Использование
$deliveryPriceForProductCourier = getDeliveryPriceForProduct(
    $bitrixProductId,
    SITE_ID,
    $USER->GetID(),
    '1', // Юридическое лицо  /bitrix/admin/sale_person_type.php?lang=ru
    '1386', // Доставка курьером до дома (в случае наличия "профиля" - указываем его id)  /bitrix/admin/sale_delivery_service_edit.php?lang=ru
    '37', // Наличными или картой при получении  /bitrix/admin/sale_pay_system.php?lang=ru
    $userCity['ID'] // Город пользователя
);

Делаем бесплатную доставку по России с условием

Допустим у нас есть задача сделать доставку по России бесплатной, если стоимость товаров в корзине превышает определенную сумму.

В моем случае в свойствах заказа есть отдельное поле «Страна», поэтому задача упрощается и весь код можно свести к паре проверок

<?php
use BitrixMainEventManager;
use BitrixMainEvent;
use BitrixMainEventResult;

// Получить цену товаров при создании корзины
EventManager::getInstance()->addEventHandler(
    'sale',
    'OnSaleComponentOrderCreated',
    'OnSaleComponentOrderCreated'
);

function OnSaleComponentOrderCreated($order, &$arUserResult, $request, &$arParams, &$arResult, &$arDeliveryServiceAll, &$arPaySystemServiceAll)
{
	//Записываем стоимость товаров
    $_SESSION['ORDER_BASKET_PRICE'] = $order->getBasket()->getPrice();
	
	//Записываем код текущей страны из свойства заказа с id = 24
    $_SESSION['ORDER_LOCATION'] = $arUserResult['ORDER_PROP']['24'];
}

//Изменяем стоимость доставки во время каждого расчета стоимости доставки
EventManager::getInstance()->addEventHandler(
    'sale',
    'onSaleDeliveryServiceCalculate',
    'onSaleDeliveryServiceCalculate'
);

function onSaleDeliveryServiceCalculate(BitrixMainEvent $event)
{

    $baseResult = $event->getParameter('RESULT');
    $shipment = $event->getParameter('SHIPMENT');

    //Если установлена цена, страна Россия и служба доставки не EMS
    if(isset($_SESSION['ORDER_BASKET_PRICE'])
        && $_SESSION['ORDER_LOCATION']=='0000073738'
        && $event->getParameter('DELIVERY_ID') != 45
        && $event->getParameter('DELIVERY_ID') != 31
        && $event->getParameter('DELIVERY_ID') != 33){

		//Смотрим, если настройки доставки мы уже в текущем сеансе получали, то пропускаем блок
        if(!$_SESSION['DELIVERY_PRICE_WHILE_RUSSIA']){
            //Получаем настройки стоимости товара при котором доставка должна быть бесплатной
            $arSelect = Array('ID','PROPERTY_VAL');
            $arFilter = Array(
                '=IBLOCK_ID' => 27, //Настройки
                '=IBLOCK_SECTION_ID' => 86, //Настройки бесплатной доставки по России
                '=ACTIVE' => 'Y',
                '=ID' => array(1776), //Доставка по России бесплатна при стоимости цены больше
            );

            $res = CIBlockElement::GetList(Array(), $arFilter, false, Array(), $arSelect);

            //Ищем настройки бесплатной доставки
            while($ob = $res->GetNextElement())
            {
                $arFields = $ob->GetFields();

                $_SESSION['DELIVERY_PRICE_WHILE_RUSSIA'] = (int)$arFields['PROPERTY_VAL_VALUE'];
            }
        }

        $basketPrice = $_SESSION['ORDER_BASKET_PRICE'];

		//Если цена товаров больше значения из настроек
        if($basketPrice > $_SESSION['DELIVERY_PRICE_WHILE_RUSSIA']) {
            //делаем доставку бесплатной
            $baseResult->setDeliveryPrice(0);
        }
    }

    //Пересохраняем результат
    $event->addResult(
        new BitrixMainEventResult(
            BitrixMainEventResult::SUCCESS, array('RESULT' => $baseResult)
        )
    );
}


/*
// Так же обработчик можно вызвать старым способом
AddEventHandler("sale", "onSaleDeliveryServiceCalculate", "onSaleDeliveryServiceCalculate");
function onSaleDeliveryServiceCalculate($result, $shipment, $deliveryID){
    // Проверка id службы доставки
    //17 - Почта России
    //20 - Доставка курьером
    //21 - Пункт выдачи СДЭК
    //24 - Пункт выдачи Boxberry
    //33 - EMS Почта России
	
    if($deliveryID == 20 ){
        if(isset($_SESSION['ORDER_BASKET_PRICE']) )
        {
            $basketPrice = $_SESSION['ORDER_BASKET_PRICE'];

            if($basketPrice > 1000){
                // Записываем новое значение цены на доставку
                $shipment->setBasePriceDelivery(0, true);
            }
        }
    }
	
    if($deliveryID == 31 || $deliveryID == 33){
        $shipment->setBasePriceDelivery(2500, true);
    }
}*/

Не забываем, что код нужно разместить в init.php

Если вы знаете более изящные способы, то буду рад если вы ими поделитесь.

Полезные переменные order_ajax.js

this.result.TOTAL //Данные о текущей цене и стоимости корзины

Массив соответствия международных двухбуквенных кодов стран

const C_COUNTRIES = [
"RU" => 1,  //Россия
"AZ" => 2,  //Азербайджан
"AM" => 3,  //Армения
"BY" => 4,  //Беларусь
"GE" => 5,  //Грузия
"KZ" => 6,  //Казахстан
"KG" => 7,  //Киргизия
"LV" => 8,  //Латвия
"LT" => 9,  //Литва
"MD" => 10,  //Молдавия
"TJ" => 11,  //Таджикистан
"TM" => 12,  //Туркменистан
"UZ" => 13,  //Узбекистан
"UA" => 14,  //Украина
"EE" => 15,  //Эстония
"AU" => 16,  //Австралия
"AT" => 17,  //Австрия
"AL" => 18,  //Албания
"DZ" => 19,  //Алжир
"AO" => 20,  //Ангола
"AE" => 21,  //Арабские Эмираты
"AR" => 22,  //Аргентина
"AW" => 23,  //Аруба
"AF" => 24,  //Афганистан
"BS" => 25,  //Багамские острова
"BD" => 26,  //Бангладеш
"BB" => 27,  //Барбадос
"BE" => 28,  //Бельгия
"BJ" => 29,  //Бенин
"BM" => 30,  //Бермудские острова
"BG" => 31,  //Болгария
"BO" => 32,  //Боливия
"BA" => 33,  //Босния и Герцеговина
"BR" => 34,  //Бразилия
"BN" => 35,  //Бруней
"GB" => 36,  //Великобритания
"HU" => 37,  //Венгрия
"VE" => 38,  //Венесуэлла
"VN" => 39,  //Вьетнам
"HT" => 40,  //Гаити
"GM" => 41,  //Гамбия
"HN" => 42,  //Гондурас
"GP" => 43,  //Гваделупа
"GT" => 44,  //Гватемала
"GN" => 45,  //Гвинея
"DE" => 46,  //Германия
"GI" => 47,  //Гибралтар
"NL" => 48,  //Нидерланды
"HK" => 49,  //Гонконг
"GD" => 50,  //Гренада
"GL" => 51,  //Гренландия
"GR" => 52,  //Греция
"GU" => 53,  //Гуана
"DK" => 54,  //Дания
"DO" => 55,  //Доминиканская Республика
"EG" => 56,  //Египет
"CD" => 57,  //Демократическая республика Конго
"ZM" => 58,  //Замбия
"ZW" => 59,  //Зимбабве
"IL" => 60,  //Израиль
"IN" => 61,  //Индия
"ID" => 62,  //Индонезия
"JO" => 63,  //Иордания
"IQ" => 64,  //Ирак
"IR" => 65,  //Иран
"IE" => 66,  //Ирландия
"IS" => 67,  //Исландия
"ES" => 68,  //Испания
"IT" => 69,  //Италия
"YE" => 70,  //Йемен
"KY" => 71,  //Каймановы острова
"CM" => 72,  //Камерун
"CA" => 73,  //Канада
"KE" => 74,  //Кения
"CY" => 75,  //Кипр
"CN" => 76,  //Китай
"CO" => 77,  //Колумбия
"KH" => 78,  //Камбоджа
"CG" => 79,  //Конго
"KR" => 80,  //Корея (Южная)
"CR" => 81,  //Коста Рика
"CU" => 82,  //Куба
"KW" => 83,  //Кувейт
"LR" => 84,  //Либерия
"LI" => 85,  //Лихтенштейн
"LU" => 86,  //Люксембург
"MR" => 87,  //Мавритания
"MG" => 88,  //Мадагаскар
"MK" => 89,  //Македония
"MY" => 90,  //Малайзия
"ML" => 91,  //Мали
"MT" => 92,  //Мальта
"MX" => 93,  //Мексика
"MZ" => 94,  //Мозамбик
"MC" => 95,  //Монако
"MN" => 96,  //Монголия
"MA" => 97,  //Морокко
"NA" => 98,  //Намибия
"NP" => 99,  //Непал
"NG" => 100,  //Нигерия
"NI" => 102,  //Никарагуа
"NZ" => 103,  //Новая Зеландия
"NO" => 104,  //Норвегия
"PK" => 105,  //Пакистан
"PA" => 106,  //Панама
"PG" => 107,  //Папуа Новая Гвинея
"PY" => 108,  //Парагвай
"PE" => 109,  //Перу
"PL" => 110,  //Польша
"PT" => 111,  //Португалия
"PR" => 112,  //Пуэрто Рико
"RO" => 113,  //Румыния
"SA" => 114,  //Саудовская Аравия
"SN" => 115,  //Сенегал
"SG" => 116,  //Сингапур
"SY" => 117,  //Сирия
"SK" => 118,  //Словакия
"SI" => 119,  //Словения
"SO" => 120,  //Сомали
"SD" => 121,  //Судан
"US" => 122,  //США
"TW" => 123,  //Тайвань
"TH" => 124,  //Таиланд
"TT" => 125,  //Тринидад и Тобаго
"TN" => 126,  //Тунис
"TR" => 127,  //Турция
"UG" => 128,  //Уганда
"UY" => 129,  //Уругвай
"PH" => 130,  //Филиппины
"FI" => 131,  //Финляндия
"FR" => 132,  //Франция
"TD" => 133,  //Чад
"CZ" => 134,  //Чехия
"CL" => 135,  //Чили
"CH" => 136,  //Швейцария
"SE" => 137,  //Швеция
"LK" => 138,  //Шри-Ланка
"EC" => 139,  //Эквадор
"ET" => 140,  //Эфиопия
"ZA" => 141,  //ЮАР
"RS" => 142,  //Сербия
"JM" => 143,  //Ямайка
"JP" => 144,  //Япония
"BH" => 145,  //Бахрейн
"AD" => 146,  //Андорра
"BZ" => 147,  //Белиз
"BT" => 148,  //Бутан
"BW" => 149,  //Ботсвана
"BF" => 150,  //Буркина Фасо
"BI" => 151,  //Бурунди
"CF" => 152,  //Центральноафриканская Республика
"KM" => 153,  //Коморос
"CI" => 154,  //Кот-Д`ивуар
"DJ" => 155,  //Джибути
"TL" => 156,  //Восточный Тимор
"SV" => 157,  //Эль Сальвадор
"GQ" => 158,  //Экваториальная Гвинея
"ER" => 159,  //Эритрея
"FJ" => 160,  //Фижи
"GA" => 161,  //Габон
"GH" => 162,  //Гана
"GW" => 163,  //Гвинея-Биссау
"KP" => 164,  //Корея (Северная)
"LB" => 165,  //Ливан
"LS" => 166,  //Лесото
"LY" => 167,  //Ливия
"MV" => 168,  //Мальдивы
"MH" => 169,  //Маршалские острова
"NE" => 170,  //Нигер
"OM" => 171,  //Оман
"QA" => 172,  //Катар
"RW" => 173,  //Руанда
"WS" => 174,  //Самоа
"SC" => 175,  //Сейшеллы
"SL" => 176,  //Сьерра-Леоне
"SR" => 177,  //Суринам
"SZ" => 178,  //Свазиленд
"TZ" => 179,  //Танзания
"EH" => 180,  //Западная Сахара
"HR" => 181,  //Хорватия
"AI" => 182,  //Ангилья
"AQ" => 183,  //Антарктида
"AG" => 184,  //Антигуа и Барбуда
"BV" => 185,  //Остров Буве
"IO" => 186,  //Британские территории в Индийском Океане
"VG" => 187,  //Британские Виргинские острова
"MM" => 188,  //Мьянма
"CV" => 189,  //Кабо-Верде
"CX" => 190,  //Остров Рождества
"CC" => 191,  //Кокосовые острова
"CK" => 192,  //Острова Кука
"DM" => 193,  //Доминика
"FK" => 194,  //Фолклендские острова
"FO" => 195,  //Фарерские острова
"GF" => 196,  //Гвиана
"PF" => 197,  //Французская Полинезия
"TF" => 198,  //Южные Французские территории
"HM" => 199,  //Острова Херд и Макдоналд
"KI" => 200,  //Кирибати
"LA" => 201,  //Лаос
"MO" => 202,  //Макао
"MW" => 203,  //Малави
"MQ" => 204,  //Мартиника
"MU" => 205,  //Маврикий
"YT" => 206,  //Майотта
"FM" => 207,  //Микронезия
"MS" => 208,  //Монтсеррат
"NR" => 209,  //Науру
//  210  Антильские острова - они же Карибы, относятся к нескольким государствам, каое имеется ввиду в Битриксе - хз
"NC" => 211,  //Новая Каледония
"NU" => 212,  //Ниуэ
"NF" => 213,  //Остров Норфолк
"PW" => 214,  //Палау
"PS" => 215,  //Палестина
"PN" => 216,  //Остров Питкэрн
"RE" => 217,  //Реюньон
"SH" => 218,  //Остров Св.Елены
"KN" => 219,  //Острова Сент-Киттс и Невис
"LC" => 220,  //Санта-Лючия
"PM" => 221,  //Острова Сен-Пьер и Микелон
"VC" => 222,  //Сент-Винсент и Гренадины
"SM" => 223,  //Сан-Марино
"SB" => 224,  //Соломоновы острова
"LK" => 225,  //Южная Георгия и Южные Сандвичевы острова
"SJ" => 226,  //Острова Шпицберген и Ян-Майен
"TG" => 227,  //Того
"TK" => 228,  //Токелау
"TO" => 229,  //Тонга
"TC" => 230,  //Острова Тёркс и Кайкос
"TV" => 231,  //Тувалу
"VI" => 232,  //Американские Виргинские острова
"VU" => 233,  //Вануату
"VA" => 234,  //Ватикан
"WF" => 235,  //Острова Уоллис и Футуна
"ME" => 236,  //Черногория    
];

Альтернативные (кастомные) sale.order.ajax

Интересный кастомный sale.order.ajax предложил alorian в компоненте Opensource Bitrix Order

Ошибка в Битрикс при оформлении заказа window.__jsonp_ymaps_map is not a function

Скорей всего вы используете несколько служб доставки, таких как СДЭК или Boxberry. Зайдите в настройки этих служб и в одной из них отключите использование Яндекс карт. Для работы будет достаточно одного подключения API Яндекс

Баг при автозаполнении телефона. После любого действия начальная цифра (7) дублируется, стирая актуальную цифру телефона

С проблемой столкнулся на одном из шаблонов Аспро Оптимус. Решил обходным путем.

Идем в функцию alterProperty и отключаем штатный механизм маскирования закомментировав данные строки:

//if (settings.IS_PHONE == 'Y')
//textNode.setAttribute('autocomplete', 'tel');

Подключил библиотеку Inputmask и добавил в конец файла order_ajax.js следующие строки, где #soa-property-3 это идентификатор нашего свойства с телефоном

$(function() {
$('#soa-property-3').inputmask({"mask": "7 (999) 999-99-99"});
BX.addCustomEvent('onAjaxSuccess', function(){
$('#soa-property-3').inputmask({"mask": "7 (999) 999-99-99"});
});
});

Появилось свободное время и я решил выложить рабочий пример компонента оформления заказа, не просто статью, а проверенный, работающий и функциональный код. За всё время работы с битриксом я довольно много кастомизировал штатный компонент. Написал несколько своих компонентов оформления заказа (первый еще без d7, приблизительно в 2010 году, быстрое оформление во всплывающем окне). Видел варианты реализации от других разработчиков. В общем смею надеяться некоторый опыт в оформлении заказа у меня есть. И весь свой опыт я постарался вложить в новый универсальный компонент.

Вот ссылка на github https://github.com/alorian/bxorder. Это не обрезанный код с существующего проекта. Компонент я писал с нуля, сразу с прицелом на универсальность.

Для начала давайте поговорим о смысле жизни. Зачем это всё вообще надо?

Содержимое статьи

  • 1 Зачем нужен компонент?
    • 1.1 Что можно улучшить?
    • 1.2 Кристально ясное оформление
    • 1.3 Стартовое состояние
    • 1.4 Работа с пользователями
  • 2 Как установить?
    • 2.1 Установка с маркетплейс
    • 2.2 Установка через composer
    • 2.3 Ручная установка
    • 2.4 Добавление на страницу
  • 3 Как использовать?
  • 4 Базис
    • 4.1 Файл class.php компонента
    • 4.2 Файл result_modifier.php
    • 4.3 Шаблон компонента
  • 5 Куда отправлять аякс запросы?
    • 5.1 Поиск местоположений
    • 5.2 Расчет стоимости доставки
    • 5.3 Сохранение заказа
  • 6 Демонстрационные шаблоны
    • 6.1 Дефолтный шаблон
    • 6.2 Переключение типа плательщика
    • 6.3 Обновление списка доставок
  • 7 Что делать если не хватает функционала?
  • 8 Дальнейшие планы

TL;DR. Ставим компонент из композера, архивом с гитхаба или из маркетплейс. Пишем собственный шаблон компонента. В шаблоне достаточно сформировать обычную форму с пятью переменными. Компонент отдает в шаблон объект заказа и коллекцию ошибок, превращаем объекты в массив, в файле result_modifier и формируем шаблон как обычно. По необходимости используем готовый аякс для поиска местоположений, расчета доставки или сохранения заказа. Под конкретный проект если не хватает функционала дописываем нужное на событиях или через наследование компонента.

Зачем нужен компонент?

В этом разделе будет немного философии, о том почему сделано именно так, а не иначе и как именно получился итоговый результат, возможности и ограничения Если вам это не особо интересно, то можете сразу перейти к следующему разделу с установкой и просто пользоваться.

Штатный компонент оформления заказа работает хорошо. Как бы кто к нему не относился, в целом сама процедура заказа со стороны покупателя довольно продумана и постоянно совершенствуется. Со стороны разработчика компонент можно более менее модифицировать в каких то рамках. В связи с этим возникает вопрос — а надо ли что-то менять?

Каждый сам должен ответить на этот вопрос. Ответ будет зависеть от конкретного проекта, от бюджета, от сложности доработок, от нужной процедуры оформления. Универсального ответа тут не существует.

На мой взгляд сразу стоит отказаться от варианта с доработкой дефолтного шаблона, от правки html/js. Когда вы захотите это сделать, вы попросту потеряетесь в тысячах строк готового кода. Каждая правка будет вызывать длительную фрустрацию и желание от всего отказаться. Не исключено, что вы доживёте (или уже дожили) до стадии принятия и всё станет хорошо, в этом случае вас остается только поздравить, но большинство останавливается на стадии гнева.

Если штатный шаблон вас в целом устраивает, то вполне можно жить используя разные хаки — что-то придумывать в событиях компонента, писать js скрипты для правок поверх шаблона, жонглировать стилями и т.д.

Однако же если вам нужна простая и лаконичная форма заказа, или более сложная, или даже просто другая, то проще отказаться от штатного шаблона вообще. И возможно от штатного компонента тоже.

Что можно улучшить?

Для понимания масштаба, весь фреймворк symfony в минимальной комплектации это 13к строк в php файлах. Папка с компонентом sale.order.ajax это 11к строк в php файлах и 18,5к строк в js файлах. Эти цифры не для того чтобы кого-то обвинить, совсем нет. По ним вы можете грубо прикинуть количество времени необходимое для изучения темы.

Для начала подумаем о том какой функционал реализует штатный компонент. Почему он такой сложный. И в процессе анализа можно обнаружить, что оформление заказа это довольно простое действие, а значительная часть сложности возникает из-за стороннего никак напрямую не связанного с оформлением функционала. Если бегло пройтись по функционалу, то помимо самого оформления штатный компонент авторизует старых пользователей (да, это прямо в коде компонента), регистрирует новых, работает с профилями покупателей, применяет скидочные купоны. Это всё полито толстым таким слоем галочек из параметров, обработкой событий и набором аякс методов. Тщательно размешиваем и получаем идеальный хаос 🙂

Повторять весь функционал старого компонента в новом и надеяться, что в этот раз получится наоборот, нечто кристально ясное и прекрасное — это тупиковый путь. Нужно пробовать кардинально другой подход.

Чутка подумаем над общей архитектурой. Для получения кристальной ясности мы должны разбить код на слабосвязанные блоки. Каждый блок должен осуществлять какую-то отдельную функцию, делать ее хорошо и при этом быть такого размера, чтобы любой разработчик мог целиком поместить его в голову без долгих многодневных медитаций.

Выделим три главных блока — работа с пользователями (авторизация и регистрация), работа с профилями пользователей (стартовое состояние страницы заказа) и собственно суть всей процедуры — блок оформления заказа.

Для авторизации и регистрации у нас уже есть готовые компоненты, нужно только разобраться как их правильно использовать. Работу с профилями пользователей пока вынесем за скобки. Сначала сосредоточимся на главной части, подумаем о том что мы хотим видеть в процедуре оформления заказа.

Кристально ясное оформление

Битрикс развивается и довольно много удобных вещей уже реализовано. ООП архитектура интернет магазина на мой взгляд получилась крайне удачной. Люди привыкли работать с объектами в реальном мире, поэтому мне кажется довольно просто понять что такое объект заказа и держать его в голове. Яблоки на прилавке — товар, яблоки в пакете по дороге домой — сохраненный объект заказа. Можно оптимизировать внутренности объекта заказа, делать его более понятным и функциональным, однако же в плане концептов тут уже нечего улучшать. У тебя есть условный пакет яблок и ты можешь делать с ним что захочешь.

А что люди реально хотят делать с объектом заказа? Вариантов миллион. Яблоко можно просто съесть, сделать компот, сделать повидло, фруктовый салат, можно достать семена и посадить яблоню. И если мы в самом компоненте будем формировать массив $arResult, который пригодится вообще во всех возможных случаях, то мы опять придем к тому, что компонент разрастется и перестанет быть доступным для понимания. Это список новостей всегда будет выглядеть примерно одинаково, а в процедуре оформления заказа фантазия может разгуляться. Отсюда первый вывод — для универсальности мы должны полностью отказаться от массива $arResult в компоненте. Компонент на выходе должен отдавать только объект заказа.

Но ведь $arResult реально удобен и в шаблоне компонента гораздо понятнее выглядит строка «echo $arResult[‘SUM’]», чем вызов «SaleFormatCurrency($order->getPrice(), $order->getCurrency())». Ничего страшного во втором варианте нет, однако же первый выглядит проще и лаконичнее, а мы боремся за кристальную ясность. В структуре компонента битрикс есть идеальное место для формирования массива $arResult — это файл result_modifier.php. Отсюда второй вывод, чтобы упростить понимание процедуры заказа мы должны формировать массив $arResult до старта шаблона компонента, а в шаблоне уже пользоваться заранее подготовленным массивом.

Что еще не учтено? Обработка ошибок. В процессе заполнения объекта заказа компонент может сгенерировать какие либо ошибки, которые мы пока что никак не передаем в шаблон. В объекте заказа они не хранятся, от $arResult мы отказались. Поэтому все же придется чуть усложнить концепт, компонент оформления заказа должен возвращать не только объект заказа, но и коллекцию ошибок. В битриксе для коллекции ошибок опять таки есть готовая реализация, это класс «BitrixMainErrorCollection». Сами ошибки внутри хранятся тоже в виде объектов.

Расставим всё по полкам в последний раз. В коде компонента мы формируем два публичных объекта — объект заказа и коллекцию ошибок. Далее из этих двух объектов в result_modifier мы собираем массив $arResult. И уже в шаблоне формируем с помощью $arResult итоговый html+js+css.

Стартовое состояние

Важной частью штатного sale.order.ajax является работа с профилями. Что такое профиль покупателя, если смотреть в самую суть? Это только стартовое состояние формы заказа. Если мы переключаем профиль, то стартовое состояние формы (заполненные значения в полях) меняется. При этом любые исправления стартового состояния имеют безусловный приоритет, если пользователь поменял текст в каком то поле, то значение из профиля мы должны игнорировать.

Таким образом что должен делать блок работы с профилями? Где-то выше компонента оформления заказа он должен сформировать массив со стартовыми полями заказа. И далее передать этот массив в компонент.

Как мы можем красиво передать данные в компонент? Для этого опять таки есть хороший штатный вариант — параметры компонента. Именно поэтому при отсутствии данных в http post запросе, объект заказа наполняется данными из параметров компонента.

Многие отказываются от штатной системы профилей и хранят данные так как им удобно (например в hl-блоках), данные с реквизитами компании отдельная сущность, данные о контактных лицах отдельно, адреса отдельно и т.д.. В текущей реализации опенсорсного компонента абсолютно неважно как вам нравится хранить данные, просто формируете массив и кидаете его в параметры компонента.

Работа с пользователями

Я вижу всего три сценария работы с пользователями. Первый, когда пользователи нам вообще не важны, работаем по каждому конкретному заказу отдельно, возможно даже без регистрации пользователя вообще. Второй, когда нам пользователи очень важны и мы даже не показываем форму заказа без авторизации. И третий промежуточный, когда мы регистрируем нового пользователя в момент сохранения заказа.

На текущий момент опенсорный компонент оформления заказа вообще никак не взаимодействует с пользователями. Если в момент сохранения заказа пользователь не авторизован, то сам битрикс (не компонент) вернет ошибку «Не заполнено обязательное поле «USER_ID»». Таким образом сразу после установки компонент может работать только по второму сценарию, когда пользователи нам очень важны.

Что же касается первого и третьего сценария работы с пользователями, то вам придется доработать нужную логику самостоятельно. Там опять таки слишком много возможных вариантов. О том как это сделать в одном из разделов статьи ниже. Ничего волшебного там нет, для реализации первого сценария хватит пары строк в обработчике OnSaleOrderBeforeSaved, для реализации третьего сценария можно уложиться в двадцать.

Как установить?

Установка доступна с помощью композера, через маркетплейс битрикс и просто вручную, архивом.

Установка с маркетплейс

Чтобы воспользоваться компонентом без участия композера, перейдите по ссылке на маркетплейс битрикса — http://marketplace.1c-bitrix.ru/solutions/opensource.order/. И установите решение как обычно (если там пусто, то возможно я его еще не подготовил, либо оно еще на модерации).

Установка через composer

Для начала пропишите в своем composer.json путь до папки bitrix. Обратите внимание на блок extra:

{
"name": "your/project",
"authors": [
{
"name": "Alexander Shubin",
"email": "alorian@yandex.ru"
}
],
"require": {},
"extra": {
"bitrix-dir": "./"
}
}

Путь до папки bitrix нужно прописывать относительно файла composer.json. Например если файл composer.json лежит в /local/libs,
то нужно прописать «bitrix-dir»: «../../bitrix». По дефолту установщик считает, что файл composer.json лежит в document_root.
Если не указать корректный bitrix-dir, то будет создана папка bitrix/modules/opensource.order/ рядом с composer.json.

После того как прописали правильный bitrix-dir выполните:

$ composer require alorian/bxorder

После выполнения команды откройте список модулей маркетплейс в админке /bitrix/admin/partner_modules.php?lang=ru, если
bitrix-dir был указан корректно, то вы увидите строку с модулем opensource.order. Нажмите «Установить» в выпадающем меню.

Ручная установка

Скачайте архив https://github.com/alorian/bxorder/archive/master.zip и самостоятельно распакуйте его содержимое в папку модулей битрикса — /bitrix/modules, либо /local/modules.

В папке модулей у вас должна быть папка opensource.order, а не bxorder-master, папку bxorder-master которая лежит
в архиве необходимо переименовать. Таким образом полный путь до файла include.php у вас должен быть /bitrix/modules/opensource.order/include.php, либо /local/modules/opensource.order/include.php

После распаковки архива откройте список модулей маркетплейс в админке /bitrix/admin/partner_modules.php?lang=ru,
найдите строку с модулем opensource.order и нажмите «Установить» в выпадающем меню

Добавление на страницу

Вне зависимости от того как вы установили модуль, через композер или через маркетплейс, в любом случае открываем какую-либо страницу в визуальном редакторе и размещаем компонент на странице:

Размещение компонента оформления заказа на странице

После этого, даже без каких либо дополнительных настроек вы увидите дефолтный демонстрационный шаблон:

дефолтный демонстрационный шаблон

В зависимости от шаблона сайта визуально страница может выглядеть по другому, но основные блоки будут такими же как на скриншоте.

Как использовать?

Что вам нужно сделать как программисту для интеграции верстки? В самом простом случае вам всего лишь нужно сформировать форму (html тэг <form>) в шаблоне компонента, которая при отправке передаст на сервер пять переменных:

  1. person_type_id. Переменная которая содержит тип плательщика.
  2. properties[]. Массив переменных со свойствами заказа. Например, если у свойства символьный код — FIO, то атрибут name у инпута ставьте properties[FIO]. Если переменная множественная то ставьте name=properties[FIO][]
  3. delivery_id. В самом простом случае это просто input типа radio, у которого атрибут name=delivery_id
  4. pay_system_id. Так же как и с доставкой, просто radio инпут, только атрибут name=pay_system_id
  5. save. Если переменная save=y, то компонент сохранит заказ. Во всех остальных случаях компонент просто обновит данные в объекте заказа и отдаст шаблон.

Да, всё настолько просто. Формируете форму с этими пятью переменными и вы великолепны. Это далеко не всё что можно сделать с помощью опенсорсного компонента. Но даже в самых сложных шаблонах суть останется прежней. Оформление заказа это не магия, просто обычная форма в браузере, просто чуть больше полей чем в обратной связи.

Базис

У компонента есть три отдельных части, три кита на которых всё держится. Каждый из них отвечает за свою область и строго специализирован. Постарайтесь понять цель каждой отдельной части.

Рассматривайте каждую из частей как черный ящик. С одной стороны запихиваем в ящик какие то данные, трясем, и на выходе с другой стороны получаем нечто новое. У ящика есть вход и выход.

Если вы поймете этот базис, этот ключевой концепт, то сможете построить любую процедуру оформления.

Файл class.php компонента

Именно с этого файла начинается работа всего компонента. Основная цель этого файла — создать объект заказа и передать его дальше.

Массив $arResult вообще не используется. Компонент в результате своей работы формирует всего две публичные переменные — переменную $this->order с объектом заказа и переменную $this->errorCollection с ошибками.

Для построения объекта заказа могут быть использованы два источника — параметры компонента и переменные запроса. При первом открытии никаких переменных запроса у нас разумеется нет, в этом случае все пять переменных будут получены из параметров компонента. Но данные из запроса приоритетнее. То есть при наличии данных в запросе, параметры компонента будут проигнорированы.

Итого. На вход компоненту мы подаем массив параметров компонента и массив данных из http запроса. На выходе из компонента мы получаем объект заказа и коллекцию ошибок.

Файл result_modifier.php

Основная цель этого файла — сформировать массив $arResult и передать этот массив в шаблон.

На выходе из компонента мы получили объект заказа. В принципе можно сразу в шаблоне компонента пользоваться методами этого объекта, без формирования $arResult вообще. Однако же с предварительно сформированным $arResult, в шаблоне код получается более чистым и понятным. Помимо чистоты кода массив $arResult вам понадобится для использования во vue.js или react.js, так как для передачи на фронт переменные в любом случае придется доставать из объектов.

На вход в result_modifier.php мы получаем объект заказа и коллекцию ошибок, на выходе мы отдаем $arResult с данными для шаблона.

Шаблон компонента

Как и в любом другом шаблоне битрикса мы должны сформировать html код который будет отображаться в браузере. Плюс по необходимости в шаблоне мы можем подключить дополнительные скрипты и стили.

На вход шаблона мы получаем массив $arResult, на выходе шаблон отдает готовый html код, плюс скрипты и стили если это необходимо. Если вы используете webpack+vue/react, то в шаблоне просто передаем массив $arResult в браузер через глобальный window.

Куда отправлять аякс запросы?

Ничто не мешает вам отправить данные в какой то свой контроллер и полностью самостоятельно формировать ответ сервера, однако же возможно вам хватит готовых функций.

Аякс работает с помощью нового механизма аякс, о котором я писал в статье по ссылке. В простом случае никакие аякс запросы вам не понадобятся. Достаточно просто сформировать html форму без скриптов вообще и отправить ее по кнопке submit на эту же страницу. Однако для чуть более сложных сценариев вы можете воспользоваться следующими готовыми методами:

Поиск местоположений

Файл ajax.php в папке компонента. Метод searchLocationAction в классе OpenSourceOrderAjaxController. Сам поиск осуществляется с помощью штатного метода BitrixSaleLocationSearchFinder::find. Далее по каждому из найденных местоположений собирается полная информация, в том числе путь от корня — страна, регион, область, и т.д. Можно получить эту же информацию в обратном порядке — местоположение, область, регион, страна.

На вход метод принимает четыре параметра:

1. Поисковая строка string $q, любая фраза по которой осуществляется поиск. Например при вводе «санкт» битрикс с большой долей вероятности найдет «Санкт-Петербург».

2. Количество поисковых результатов, int $limit = 5. Сколько найденных местоположений вам придет в ответе. В коде стоит проверка — не меньше одного местоположения и не больше пятидесяти.

3. Тип местоположений, string $typeCode. Если вам нужны только города, то передайте аргумент $typeCode = ‘CITY’. По умолчанию поиск осуществляется вообще по всем типам местоположений.

4. Исключение каких то частей и найденного названия, array $excludeParts = []. Если в названии найденного местоположения вам не нужна страна и округ, то просто передайте в этот аргумент значение [COUNTRY, COUNTRY_DISTRICT] и в ответе вам придет название местоположения начиная с региона.

Всего в битриксе есть семь дефолтных типов местоположений. Любое местоположения которое хранится штатно в таблице местоположений будет принадлежать одному из семи типов — COUNTRY, COUNTRY_DISTRICT, REGION, SUBREGION, CITY, VILLAGE, STREET.

5. Порядок формирования имени, string $sortOrder = ‘desc’. Как я говорил выше, найденное местоположение может быть отдано в формате страна, округ, регион и т.д., а может быть наоборот в формате регион, округ, страна. В этом параметре вы можете указать нужный порядок.

Возвращает массив найденных местоположений:

Array
(
[0] => Array
(
[name] => Москва
[code] => 0000073738
[type] => CITY
[type_name] => Город
[label] => Москва, Центр, Россия
[parts] => Array
(
[CITY] => Array
(
[name] => Москва
[code] => 0000073738
[type] => CITY
[type_name] => Город
)
[COUNTRY_DISTRICT] => Array
(
[name] => Центр
[code] => 0000028024
[type] => COUNTRY_DISTRICT
[type_name] => Округ
)
[COUNTRY] => Array
(
[name] => Россия
[code] => 0000028023
[type] => COUNTRY
[type_name] => Страна
)
)
)
[...]     
)

Расчет стоимости доставки

Файл ajax.php в папке компонента. Метод calculateDeliveriesAction в классе OpenSourceOrderAjaxController. В методе как обычно создается объект заказа и отгрузка. По отгрузке выбираются все доступные доставки и рассчитывается стоимость этих доставок.

На вход принимает три параметра:

1. Тип плательщика, int $person_type_id.

2. Массив свойств, array $properties. В массиве должно быть как минимум одно свойство — свойство с местоположением. Иначе доставки ничего не смогут рассчитать. Лучше всего передавать вообще все свойства из формы заказа.

3. Массив ID доставок, array $delivery_ids. Может быть пустым, но если задан, то будут рассчитаны доставки только с указанными ID. Доставки в любом случае должны быть доступны для заказа.

Возвращает массив с рассчитанной стоимостью доставок:

Array
(
[2] => Array
(
[id] => 2
[success] => 1
[name] => Доставка курьером
[logo_path] => /upload/sale/delivery/logotip/789/78984a7a84ff245422e5abd911c1972a.png
[period] => 
[base_price] => 500
[base_price_display] => 500 руб.
[price] => 350
[price_display] => 350 руб.
[discount] => 150
[discount_display] => 150 руб.
[errors] => Array
(
)
)
[...]
)

Сохранение заказа

Файл ajax.php в папке компонента. Метод saveOrderAction в классе OpenSourceOrderAjaxController. По сути вызываются те же самые методы основного компонента, что и при отправке формы на страницу. Полный аналог executeComponent, за исключением вывода шаблона. Результат сохранения заказа, либо ошибки отдаются в виде чистых данных.

Демонстрационные шаблоны

На текущий момент все готовые шаблоны это просто демонстрация возможностей для программистов. Сам компонент полностью готов и хорошо спроектирован, однако готовых шаблонов на текущий момент нет. Возможно в будущем они появятся.

Дефолтный шаблон

Скрин с дефолтной формой заказа я приводил в начале статьи. Там есть пять основных блоков:

1. Таблица со списком свойств. В шаблоне реализовано отображение свойств типа строка, чекбокс Да/Нет, выбор из списка значений, заполнение даты и поиск местоположений.

При наличии ошибок по какому либо свойству, например если свойство не заполнено, или заполнено неверно, текст ошибки отобразится отдельно прямо в строке со свойством.

2. Выбор службы доставки. Стоимость доставок рассчитывается при открытии страницы, при смене местоположения стоимость не меняется. При наличии ошибок связанных с доставкой, текст ошибок отобразится прям в этом блоке.

3. Выбор платежной системы. Блок из обычных радио инпутов плюс вывод списка ошибок связанных с оплатой.

4. Таблица с товарами в корзине. Текстовая информация, можно посмотреть как именно правильно доставать различные цифры из корзины, как получить значение скидки, как работать со свойствами товаров корзине и отображать единицы измерения.

5. Итоговая информация по заказу. Опять же просто информационный текст, в этом блоке ничего не заполняется. Я показал как можно отобразить девять самых популярных цифр по заказу. Выводить их или нет в своем шаблоне — решать вам.

Переключение типа плательщика

По сравнению с дефолтным шаблоном здесь добавилось не так и много. В result_modifier немного изменено получение списка свойств, так как нужны свойства не только по текущему плательщику, но и по всем остальным.

В самом шаблоне формируются отдельные таблицы свойств для каждого типа плательщика. Добавлен переключатель типа плательщика. При переключении скрываются все таблицы свойств, кроме таблицы выбранного плательщика. Всем элементам ввода свойств при переключении добавляется атрибут disabled, таким образом при отправке формы они будут проигнорированы, реально отправятся только инпуты из таблицы свойств выбранного плательщика.

Обновление списка доставок

Это тот же самый дефолтный шаблон, но в файле script.js шаблона добавлен обработчик на изменение свойств типа location. При изменении свойства с типом location отправляется аякс запрос на расчет стоимости доставки. После получения результата расчета текущий список доставок очищается и строится заново по данным пришедшим из аякс.

То есть по сути отличается только файл script.js и немного отличается вывод списка доставок, чтобы можно было из скрипта удобнее их очищать.

Что делать если не хватает функционала?

Если вы считаете, что не хватает какого-то общего функционала, то вы можете написать его самостоятельно и отправить pull request. Кратко для тех кто не сталкивался с опенсорсом. Вы делаете форк репозитория, в своем форке добавляете функционал и отправляете pull request из форка в оригинал. Я увижу что именно вы добавили, если код хорошо написан и будет полезен многим, а не только вам, то этот pull request будет влит в основную ветку.

Если вы хотите написать какой то функционал под конкретный проект, то у вас есть две пути — события и наследование компонента.

Для начала про события. Допустим вы хотите отображать форму вообще всем пользователям даже без авторизации, и регистрировать пользователя в момент сохранения заказа. Можете использовать обработчик перед сохранением заказа OnSaleOrderBeforeSaved. В этот обработчик вы получаете объект заказа. Если это новый заказ ($order->isNew()), то регистрируете пользователя как вам хочется, а потом подставляете ID только что созданного пользователя в заказ через $order->setFieldNoDemand(‘USER_ID’, $userId).

В OnSaleOrderBeforeSaved можно добавить любые проверки по данным заказа и возвращать ошибки. Эти ошибки будут добавлены в общую коллекцию ошибок и переданы в шаблон.

Второй путь — наследование компонента. Вы можете прочитать об этом в документации. Допустим вы считаете, что проверка свойств слишком простая. Наследуете компонент и перекрываете метод validateProperties() в классе компонента. У вас будет новый класс компонента всего с одним методом:

<?php
use BitrixMainResult;
CBitrixComponent::includeComponentClass('opensource:order');
class InheritedOpenSourceOrderComponent extends OpenSourceOrderComponent
{
/**
* @return Result
*
* @throws Exception
*/
public function validateProperties()
{
$parentResult = parent::validateProperties();
$result = new Result();
//добавляем свою логику
if (!$parentResult->isSuccess()) {
$result->addErrors($parentResult->getErrors());
}
return $result;
}
}

Аналогичным образом можно переписать любой метод компонента. Можно даже не вызывать родительский метод, если ваша логика отличается от дефолтной. Не обязательно только переписывать какие то методы, можно добавлять новые.

Дальнейшие планы

Скорее всего будет пример шаблона на vue. Я пробовал сделать пример на bx.vue, но без транспиляции кода и импорта я чувствую себя очень не комфортно. Многие готовые компоненты vue не получается добавить подключением из CDN. Поэтому пока что отложил эту задачу. Посмотрим как это лучше всего реализовать. Планирую написать отдельную статью по процедуре заказа на vue.

Сам компонент будет развиваться. Есть некоторые вещи которые я хочу улучшить. Кардинально ничего не поменяется, вы всё так же можете рассчитывать на объект заказа и коллекцию ошибок в шаблоне.

А так в целом, жду пул реквесты и просто текстовые предложения по улучшению функционала в комментариях к этой статье или в issues на гитхабе https://github.com/alorian/bxorder/.

Описанные в этом разделе настройки являются стандартным функционалом платформы и являются обязательными для корректной работы модуля.

1. Свойства заказа

Чтобы проверить настройки свойств заказа нужно перейти в раздел Магазин -> Настройки -> Свойства заказа ->Список свойств, или перейти по адресу <доменное имя сайта>/bitrix/admin/sale_order_props. php? lang=ru.

Если на сайте указано несколько типов платильщиков (Юр.лицо, физ.лицо и т.п.), то указанные ниже свойства должны быть заведены и настроенны для каждого типа платильщиков.

Для полноценной работы модуля должны быть настроены следующие свойства: 

  • Местоположение
    Свойство такого типа должно обязательно присутствовать, без него невозможен расчет доставки и передача заказов ЛК Shiptor. Обязательно укажите тип данных «Местоположение» и проставьте активность чек-бокса «Использовать как местоположение, для расчета доставки» 
    Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • Фамилия Имя Отчество
    Обязательное свойство, без которого не возможен расчет и передача заказа в Shiptor. 
    Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • Телефон
    Обязательное поле, без которого не возможна передача заказа в Shiptor. Важно: должен быть активным чек-бокс «Является телефоном»
    Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • E-mail
    Обязательна активность чек-бокса «Использовать как e-mail»
    Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • Адрес доставки
    Обязательное поле для передачи заказа в Shiptor. Необходимо активировать чек-бокс «Является адресом». Если у Вас составной адрес из нескольких полей (улица, дом, квартира), то настройте каждое из них аналогично.
    Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • Почтовый код
    Свойство «Индекс» обязательно для экспортных посылок и крайне желательно для доставки Shiptor Почтой. Это связано с тем, что по почтовому индексу уточняется адрес после передачи заказа в ЛК Shiptor. Должен быть активен чек-бокс «Использовать как почтовый индекс». Проверьте, чтобы настройки на сайте соответствовали настройкам на скриншоте:
  • Пункт выдачи
    Это свойство создается при установке модуля и будет присутствовать в свойствах заказа автоматически. Оно используется для сохранения в заказе номера пункта самовывоза.

2. Местоположения

Модуль использует стандартные местоположения системы. Рекомендуем загрузить актуальный справочник местоположений на сайт до начала работы. Для этого необходимо зайти в Магазин -> Настройки -> Местоположения -> Импорт местоположений или <доменное имя сайта>/bitrix/admin/sale_location_import.php?lang=ru

Обратите внимание, что необходимо выбрать страны для которых нужно загрузить местоположения. Рекомендуем загружать включительно до села. Так же необходимо выбрать загружать расширенный или стандартный справочник. 

3. Товары и торговые предложения. Настройка веса и габаритов товара.

Для верного расчета веса и габаритов посылки необходимо максимально точно указать эти параметры для товара. В примере будут рассмотрены простые товары и товары с предложениями. 

Обратите внимание, что указывать необходимо габариты упаковки товара. Например, если в каталоге имеется этажерка с размерами в готовом состоянии: высоты 60 см, длинны 50 см и глубины 20 см, то указать необходимо ее габариты в собраном состоянии (упаковки): 60х20х10. Так же стоит учитывать, что в Bitrix габариты задаются в граммах и милиметрах — не забудьте привести данные к верным значениям. 

Простые товары: 

Откройте каталог товаров и в контекстном меню товара выберите пункт «Изменить» или нажмите на название товара. 

В открывшемся окне перейдите на вкладку «Торговый каталог» -> «Параметры».

Пропишите габариты и вес в открывшейся вкладке: 

Товар с предложениями:

Откройте каталог товаров и в контекстном меню товара выберите пункт «Изменить» или нажмите на название товара. 

В открывшемся окне выберете вкладку «Торговые предложения»

Из списка торговых предложений выберите нужное и откройте его с помощью контекстного меню выбрав «Изменить»

В открывшемся окне перейдите на вкладку «Торговый каталог» -> «Параметры».

Пропишите габариты и вес в открывшейся вкладке: 

Повторите операцию для всех предложений опубликованных на сайте. 

4. Автоматизация процессов.

Автоматизация внутренних процессов 1С-Bitrix может потребоваться для автоматической передачи заказов в Shiptor или упрощения в работе с другими операциями модуля Shiptor.

Будьте осторожны при выполнении действий в этом разделе — некорректные настройки интернет магазина могут привести к ошибкам всего магазина. Выполняйте эти действия только в случае необходимости и пропустите эту настройку если Вы пользуетесь нашим модулем с настройками «по-умолчанию»

Пример:

Настроить автоматическое разрешение доставки возможно используя стандартный функционал Bitrix. Например, можно задать параметр «Разрешить доставку» при поступлении оплаты от покупателя. Для этого необходимо зайти в Настройки -> Настройки модулей -> Интернет -магазин.

Открываем вкладку «Автоматизация процессов»  и указываем необходимые настройки. Например, настройка автоматического разрешения доставки при полной оплате, необходимая для работы агента с заказами с онлайн оплатой:

Аналогичным образом можно настроить триггеры на выполнение других действий, которые необходимо производить вручную для нашего модуля.

Основные настройки модуля

Общие настройки модуля расположены по адресу Настройки -> Настройки продукта -> Настройки модулей -> Настройки модуля -> Агрегатор служб доставки или по адресу: <доменное имя сайта>/bitrix/admin/settings. php? lang=ru&mid=shiptor. delivery

1. Настройки

В этой вкладке производятся основные настройки интеграции модуля и сайта. Для корректной работы модуля необходимо настроить следующие параметры: 

  • Ключ API Shiptor — скопируйте первый «API токен для интеграции» из личного кабинета Shiptor.

  • API URL — Адрес по умолчанию для запросов. Не требует изменений.

  • URL страницы оформления заказа —  укажите адрес Вашей страницы оформления заказа, к которой будет подключаться модуль. По умолчанию в магазинах Битрикс страница оформления заказа расположена по адресу /personal/order/make/. Если у вас другой адрес страницы оформления заказа вы должны указать свой. Допускается указание нескольких адресов страниц, разделенных точкой с запятой. Обратите внимание, что если адрес страницы оформления заказа содержит имя файла, например /personal/order/make/order. php , то необходимо указывать адрес без имени файла (например, /personal/order/make/).

  • Округление стоимости доставки — позволяет включить или отключитьокругление стоимости доставки.

  • Точность округления — укажите точность округления до знака. Опция активна, если значение «Округление стоимости доставки» отлично от «Не округлять». Допустимые значения: от 0.01 (копейка) до 100 (рубли). Если нужно округление до рублей, укажите в поле 1, если до десятков — укажите 10.

  • Выводить кнопку выбора ПВЗ —  задайте место вывода кнопки ПВЗ в шаблоне оформления заказа. По умолчанию поле имеет значение «В описании расчета доставки»

  • Проверять ПВЗ при оформлении заказа — определите режим работы параметра. Он позволяет исправить ошибки на странице оформления заказа при некорректном ответе API Shiptor или ошибочных действиях пользователя. При этом проводится проверка на присутствие точек ПВЗ в каждом профиле доставки, а также на возможность оплаты в выбранной точке ПВЗ через выбранный пользователем способ оплаты. Не прошедшие проверку профили доставки и точки ПВЗ будут удалены из заказа. Проверка ПВЗ всегда работает при редактировании заказа в админпанели, но ее можно отключить для страницы оформления заказа, что увеличит скорость загрузки. По умолчанию включено. 

  • Окно выбора ПВЗ принудительно открывается, если не выбран ПВЗ — включите/выключите для автоматического открытия карты точек самовывоза(ПВЗ) в случае выбора такого способа доставки. Карта также откроется если покупатель вернулся к авторизованной сессии с доставкой самовывозом.

  • Дата и время в комментарии к заказу  — позволяет включить или выключить для копирования выбранных даты и времени доставки в текстовом формате в комментарий. При этом  в настройках профиля доставки опция выбора даты и времени должна быть включена. Выбор даты и временного интервала доставки возможен только на способах доставки Shiptor. 

  • Подключать Яндекс.Карты из модуля — отображает карты точек самовывоза через Яндекс.Карты. Выключите, если при повторном подключении карт из другого компонента возникли конфликты. 

  • Ключ для API Яндекс.Карт — используется для поиска по карте ПВЗ.  Чтобы получить ключ, перейдите в «Кабинет разработчика», нажмите «Подключить API» и в новом окне выберите «JavaScript API и HTTP Геокодер». Обратите внимание: поиск будет работать корректно только в случае однократного подключения Яндекс.Карт из модуля Shiptor. При этом у поля «Подключать Яндекс.Карты из модуля» должно быть выбрано значение «Да» и отсутствовать обращения в любым другим картам. Также в блоке «Внешний вид» компонента оформления заказа сделайте неактивным чек-бокс «Показывать карту в блоке свойств заказа».

  • Сортировка способов доставки — выберите тип сортировки отображаемых при заказе профилей (способов) доставки от модуля Shiptor. Может быть проигнорирована, если у вас в шаблоне оформления заказа осуществляется принудительная сортировка программным способом.

    • по настройке профилей (используется значение сортировки из профиля доставки)

    • по сроку доставки (от быстрой к долгой)

    •  по цене доставки (от дешевой к дорогой)

  • Если не выбран ПВЗ на странице оформления заказа — выберите поведение модуля на странице оформления заказа в случае его завершения без выбранной точки самовывоза(ПВЗ). 

    •  Выводить предупреждение — покупатель информируется об отсутствующем ПВЗ в заказе, заказ можно сохранить.

    •  Выводить ошибку — покупатель информируется об отсутствующем ПВЗ в заказе, заказ сохранить нельзя.

  • Включить логирование — включите/выключите для записи всех сеансов обмена данными с сервером Shiptor. Не рекомендуется долгое включение — запись ведется в файл Журнала событий, расположенный на Вашем хостинге и большое кол-во запросов может привести к существенному увеличению его размера.

  • Выберите свойство/Выберите свойство для торгового предложения — укажите значение одного из строковых свойств инфоблока.

  • Способы оплаты наличными — отметьте платежные системы которые у вас на сайте предполагают оплату наличными при получении(наложенный платеж наличными) заказа. Оставшиеся не выбранными платежные системы считаются оплатой по карте как на сайте так и при получении (наложенный платеж) заказа. Можно выбрать несколько оплат зажимая клавишу CTRL. Также Вы можете ознакомится с примером настройки модуля на работу со способами оплаты.

2. Доставка от склада

Эта вкладка позволяет настроить умолчания для доставки от склада. Для этого в поле «Склад Shiptor» укажите подходящий вариант. 

Склад можно переопределить в настройках профилей доставки. Нажмите «Сохранить»

Важно: Выбор склада влияет на количество доступных методов доставки и их стоимость.

В том случае, если склад не выбран, то при расчете доставки будут использоваться значения, используемые в Shiptor по умолчанию.

3. Сквозная доставка

Эта вкладка позволяет настроить умолчания для «сквозной »доставки (прямая доставка из регионов). Пропустите её, если отправляете заказы только через склад Shiptor или со сборкой на фулфилменте. 

Город отправления для настроек по умолчанию берется из свойства «Местоположения магазина» в модуле «Интернет-магазин» платформы 1С-Bitrix.

Заполните поля следующим образом:

  • ФИО отправителя — фамилия, имя и отчество  отправителя.
  • Телефон — телефон отправителя.
  • E-mail — адрес электронной почты отправителя.
  • Почтовый код — индекс отправителя в случае отгрузки курьеру.
  • Улица — улица отправителя в случае отгрузки курьеру.
  • Дом — номер дома отправителя в случае отгрузки курьеру.
  • Офис/Квартира — номер квартиры отправителя в случае отгрузки курьеру.
  • Комментарий — комментарий к отгрузке.
  • Дата отгрузки/забора — выберите тип указания даты отгрузки.
    • Ближайшая — следующий день после передачи в Shiptor заказа с отгрузкой. Обратите внимание, что курьерские службы и ПВЗ не принимают посылки в официальные выходные, поэтому они исключаются из расчета даты отгрузки. Например, если заказ был передан в четверг, то датой отгрузки будет пятница. Для заказа, переданного в пятницу, дата отгрузки – понедельник.
    • С отсрочкой — дополнительное время на подготовку заказа перед отгрузкой в транспортную компанию. 
  • Отсрочка в днях — число рабочих дней, которое будет прибавляться к ближайшей дате отгрузки. В качестве примера рассмотрим отсрочку в 1 день. Если заказ передан в среду, то датой отгрузки будет пятница, если в четверг, то – понедельник.
  • Подтверждение автоматически — режим подтверждения отгрузки при сохранении заказа. После этого она будет оплачена, а заявка – передана в транспортную компанию. По умолчанию поле имеет значение «Нет», при котором подтверждение делается в ЛК Shiptor.   

Указанные настройки можно индивидуально переопределить в профилях на сквозные методы доставки.

4. Работа с товарами

Для определения товарных умолчаний настройте следующие параметры: 

Пропустите этот раздел, если не используете фулфилмент Shiptor.

  • Отгружать отгрузку при передаче в Shiptor — выберите способ изменения статуса отгрузки при ее передаче в Shiptor:
    • Нет (по умолчанию) —  расход осуществляется в соответствии с настройками 1С-Bitrix. 
    • Создана посылка в Shiptor —  товары списываются при успешном создании посылки в Shiptor. 
    • По статусу доставки — выбор опции открывает дополнительное поле «Статус доставки Shiptor». Из него нужно выбрать тот статус, при котором отгрузка будет меняться автоматически. 
  • Артикул товара/Артикул торгового предложения — выберите уникальный идентификатор для товара/торгового предложения в интернет-магазине. Опция необходима для создания и поиска номенклатуры в Shiptor при передаче заказа. Её значение может браться из:
    • Индекс [«ID»] — ID элемента (PRODUCT_ID из позиции корзины b_sale_basket).
    • Внешний код [«XML_ID»] — поле XML_ID (PRODUCT_XML_ID из позиции корзины b_sale_basket). С этим вариантом также связана дополнительная опция «Обработка сложных внешних кодов».
    • Свойство инфоблока [«PROPERTY_*»] — подключение дополнительного поля «Выберите свойство»
  • Выбрать склад для фулфилмента — выберите склад для фулфилмента из выпадающего списка. При необходимости его можно создать, нажав на кнопку «Создать склад». Опция позволяет выбрать место хранения остатков со склада фулфилмента Shiptor . Недоступна при активном чек-бокс «Перезаписывать общие остатки»
  • Перезаписывать общие остатки — настройте процесс обновления общего количества товаров в поле «Доступное количество». По умолчанию чек-бокс отключен.
  • Получать кол-во товаров — выберите поле в номенклатуре ЛК Shiptor, из которого будут перезаписываться остатки. По умолчанию выбрано «Фактическое». 
  • Выгрузить товары в ЛК Shiptor — нажмите «Выгрузить» для передачи товаров со статусом «Активен» из Bitrix в Shiptor. Если на момент выгрузки каких-то из них нет, то они будут созданы автоматически. При этом обновится информация по уже существующим товарам. Процесс осуществляется в соответствии со значениями, выбранными для полей «Артикул товара» и «Артикул торгового предложения». Обратите внимание: выгружаются все товары! При большом объёме номенклатур воспользуйтесь CSV-файлом.
  • Обновить товарные остатки — нажмите для однократной перезаписи имеющихся остатков. Место хранения определяется настройками «Перезаписывать общие остатки» и «Выбрать склад фулфилмента».
  • Создать агент автоматического обновления/Агент создан, нажмите, чтобы перейти — создайте или активируйте агент ShiptorDeliveryAgents::importWares(), который выполняет обновление товарных остатков через заданный интервал или в установленное время. Процедура ресурсоемкая, поэтому может перегружать сервер и сайт. Чтобы этого избежать, перенесите агент на cron. О том, как это сделать, написано здесь.

5. Статусы заказа

Можно настроить сопоставление внутренних статусов заказа в ЛК Shiptor со статусами отгрузок  и заказов в 1С-Bitrix. 

При получении статуса заказа от Shiptor модуль автоматически переведет отгрузку/заказ в ассоциированный статус.

6. Свойства заказа

Здесь содержатся настройки, задающие ассоциации свойств заказа из 1С-Битрикс и свойств заказа необходимых Shiptor. Произведите сопоставление ранее настроенных свойств для их последующей передачи вместе с заказом. В случае неверного сопоставления может возникнуть ошибка и данные по заказу не будут переданы в Shiptor.

  • Тип поля Адрес — выберите тип в зависимости от используемого способа заполнения адреса покупателем: «Единое» (в одно поле) или «Составное» (в несколько полей: улица, дом, квартира). При этом в 1С-Битрикс должны быть корректно настроены свойства заказа.
  • Тип поля Покупатель — выберите тип в зависимости от используемого способа заполнения ФИО покупателем: «Единое» (в одно поле) или «Составное» (в несколько полей: имя, фамилия, отчество). При выборе «Составное» должно быть настроено минимум одно прямое сопоставление. остальные, остальные настройки указываются по желанию. 
  • Копировать адрес ПВЗ в свойство Адрес доставки — позволяет заполнять свойство заказа Адрес доставки адресом выбранной покупателем точки самовывоза (ПВЗ). Опция недоступна при типе поля адрес «Составное» и игнорируется для доставки курьером. 

7. Обработка заказов

На этой вкладке настраиваются параметры обработки заказов.  

  • Отправка — выберите способ передачи заказов в Shiptor:
    1. Вручную — заказы, которые удовлетворяют условиям передачи, можно отправить в Shiptor вручную.
    2. Автоматически — заказы, которые удовлетворяют условиям передачи, будет отправлены в Shiptor агентом через заданный интервал времени.
  • Триггер для передачи в Shiptor — техническое свойство, игнорируемое агентом автоматической передачи. Используется только для полуавтоматической отправки: например, если в настройках «Интернет-магазина» определено свойство «При получении разрешения доставки переводить отгрузку в статус». При выполнении этого условия заказ автоматически отправляется в Shiptor. По умолчанию свойство имеет значение «Не использовать».
  • Статус отгрузки после передачи заказа — статус, в который будет переведена отгрузка сразу после успешной передачи заказа в Shiptor.
  • Автоматическая проверка статусов переданных заказов — агент ShiptorDeliveryAgents::checkOrders() выполняет обновление статусов заказов через заданный интервал или в установленное время. 
  • Автоматическая отправка заказов — агент ShiptorDeliveryAgents::sendOrders() добавляется при выборе в поле «Отправка» варианта «Автоматически». Он отвечает за передачу заказов в Shiptor через заданный интервал или в определённое время. При настройке агента НЕ рекомендуется устанавливать интервал запуска менее 3600 сек. Это позволит избежать большой нагрузки на сайт и сервер Shiptor. Также ускорить работу можно при помощи перевода агента на cron. Более подробно процесс описан здесь.

    Созданный агент также доступен в меню заказов по адресу Магазин > Доставка Shiptor и в платформе 1С-Bitrix по адресу Настройки > Настройки продукта > Агенты.

8. Кеширование

В этой вкладке можно включить кеширования средствами модуля Shiptor для формы оформления заказа.

Управляемый кеш — выберите если используете стандартное автокеширование Bitrix. Основной и оптимальный способ кеширования.

Файловый кеш — выберите если хотите использовать кеш модуля (полезно если кеширование Bitrix не работает).

Служба доставки

Для отображения нужных методов доставки необходимо создать и настроить службу доставки Shiptor. 

Модуль доставки Shiptor реализует модель функционирования типа Родительская служба с профилями. Это значит, что вы создаете родительскую службу, которая будет содержать в себе общие настройки, касающиеся функционирования расчета доставки и передачи заказов в ЛК Shiptor, а конкретные методы доставки реализуются созданием профилей у этой службы доставки. По умолчанию считается, что такая родительская служба доставки существует в единственном экземпляре, однако вы можете создать неограниченное количество родительских служб доставки со своими профилями, если возникнет такая потребность. Единственное ограничение — необходимо будет вновь настраивать каждую родительскую службу доставки. 

1. Создание службы доставки Shiptor

Чтобы создать службу доставки типа Shiptor, вам необходимо перейти в админ-панели по адресу Магазин->Настройки->Службы доставки или <доменное имя сайта>/bitrix/admin/sale_delivery_service_list. php? lang=ru  

Далее необходимо нажать кнопку [ + Добавить] и из выпадающего списка выбрать пункт «Служба доставки Shiptor».

Для настройки созданной службы зайдите в редактирование службы доставки Shiptor.

2. Общие настройки службы доставки

Здесь содержатся общие настройки, касающиеся отображения службы доставки в списке других служб доставки, а также в админ-панели заказов.

  • Название — укажите название родительской службы доставки.
  • Активность — включите/выключите родительскую службу доставки. При выключении все ее дочерние профили станут неактивными.

3. Настройки обработчика

На этой вкладке расположены настройки, касающиеся расчета стоимости доставки.

  • Величина наценки — укажите при необходимости наценку, которая будет прибавляться к стоимости доставки от Shiptor.
  • Тип наценки — выберите тип наценки в% или в рублях.
  • Увеличить показываемые сроки доставки в днях — укажите при необходимости кол-во рабочих дней, которые будут прибавляться к сроку доставки от Shiptor.
  • Показывать сроки доставки — включите/выключите отображение срока доставки на странице оформления заказа.
  • Расчет габаритов — выберите способ расчета итоговых габаритов заказа для получения стоимости доставки.
    — автоматически для товаров:

    • модуль автоматически произведет расчет итоговых габаритов посылки на основании измерений указанных в карточке товара. При отсутствии измерений в карточке товара — берутся умолчанию габаритов из настройки модуля в качестве измерения 1 ед. товара корзине. Обратите внимание, что модуль НЕ гарантирует точный автоматический расчет.
    • вес посылки складывается из данных в карточках товаров. При отсутствии веса в карточке товара — берется умолчание веса из настройки модуля в качестве веса 1 ед. товара в корзине.

    — по умолчанию для посылки:

    • если в заказе 1 товар в кол-ве 1 ед, то берутся габариты из карточки товара, вес — из габаритов по-умолчанию. При отсутствии измерений в карточке товара — берутся значения по-умолчанию габаритов из настройки модуля.
    • если в заказе 2 и более единицы товара одного или разного вида, то, вне зависимости от измерений в карточке товара, берутся габариты по умолчанию как измерения всей посылки в целом.
    • вне зависимости от кол-ва товаров в посылке ее вес заменяется на умолчание из настроек модуля.

    — вес по товарно, габариты для посылки

    • если в заказе 1 товар в кол-ве 1 ед, то берутся габариты из карточки товара, вес — из карточки товара. При отсутствии  измерений в карточке товара — берутся значения по-умолчанию габаритов из настройки модуля.
    • если в заказе 2 и более единицы товара одного или разного вида, то, вне зависимости от измерений в карточке товара, берутся габариты по умолчанию как измерения всей посылки в целом.
    • вес посылки складывается из данных в карточках товаров. При отсутствии веса в карточке товара — берется умолчание веса из настройки модуля в качестве веса 1 ед. товара в корзине.
  • Длина — укажите усредненное значение в качестве измерения по умолчанию для 1 ед. товара/ посылки в целом (в зависимости от опции расчет габаритов).
  • Ширина — укажите усредненное значение в качестве измерения по умолчанию для 1 ед. товара/ посылки в целом (в зависимости от опции расчет габаритов).
  • Высота — укажите усредненное значение в качестве измерения по умолчанию для 1 ед. товара/посылки в целом (в зависимости от опции расчет габаритов).
  • Вес — укажите усредненное значение в качестве измерения по умолчанию для 1 ед. товара или всей посылки в зависмости от опции Расчет габаритов.
  • Включить передачу НДС в заказе — активируйте чек-бокс, если требуется выделение отдельной строки под НДС в передаваемом заказе. Размер ставки берётся из карточки товара и используемого профиля доставки. Обратите внимание: опция работает только если в Shiptor включена поддержка такого режима. В противном случае при передаче заказа система вернет ошибку. 

4. Наложенный платеж и страхование

На этой вкладке настраивается механизм расчета стоимости доставки. Выполненные настройки также применяются и при передаче заказа в Личный кабинет Shiptor.

Условия по наложенному платежу:

  • Услуга доступна только для отправлений по РФ. Учитывайте это при настройке профилей доставки и оформления заказа. При необходимости используйте возможности 1С-Bitrix по ограничению службы доставки,её профилей и типов оплаты для настройки их взаимодействия.
  • За пользование услугой взимается коммиссия, размер которой можно уточнить в Личном кабинете Shiptor.

Условия по страхованию:

  • Услуга доступна для любого типа отправления.
  • Услуга автоматически добавляется для заказов с наложенным платежом.
  • Услуга имеет макс. лимит по страховой сумме.
  • За пользование услугой взимается коммиссия, размер которой можно уточнить в Личном кабинете Shiptor.

Итоговая стоимость доставки, отображаемая модулем складывается из следующих факторов:

  • непосредственно стоимость доставки в зависимости от пункта отпрваления, пункта назначения,, габаритов, веса заказа, способа доставки и отгрузки
  • коммиссия за прием и перевод наложенного платежа (если есть)
  • коммиссия за страхование отправления (если подключена для предоплаченных заказов, заказы с наложенным платежом страхуются по умолчанию)

На вкладке модуля выберите или настройите:

  • Считать доставку с наложенным платежом — выберите схему работы с наложенным платежом для модуля Shiptor:
    • всегда
      Модуль будет отображать цены и возможность доставки, а также передавать в Shiptor заказы ВСЕГДА с наложенным платежом ВНЕ зависимости от выбранного способа оплаты если статус оплаты «не оплачен»
    • никогда
      Модуль будет отображать цены и возможность доставки, а также передавать в Shiptor заказы ВСЕГДА без наложенного платежа ВНЕ зависимости от выбранного способа оплаты если статус оплаты «оплачено»
    • только для платежных систем с включенным наложенным платежом
      Модуль будет отображать цены и возможность доставки, а также передавать в Shiptor заказы в зависимости от выбранного способа оплаты. При выборе этой опции доступно окно с выбором способов оплат в качестве наложенного платежа.
  • Выберите способы оплаты для которых действует услуга — выберите и назначьте имеющиеся в магазине способы оплаты в качестве наложенного платежа. Можно выбрать несколько оплат зажимая клавишу CTRL. В комбинации с опцией «Оплата наличными» из настроек модуля эта опция позволяет организовать наложенный платеж наличными или по карте. Например — если ваша платежная система Х выбрана в настройках модуля в опции «Оплата наличными», модуль будет считать ее оплатой наличными, и если для нее здесь включен «Наложенный платеж», то модуль будет расценивать платежную систему Х, как наложенный платеж наличными. Если платежная система У, которая не выбрана в настройках модуля в качестве оплаты наличными (модуль будет считать такую платежную систему оплатой по карте), будет выбрана здесь в опции «Наложенный платеж» — модуль будет расценивать такую платежную систему, как оплату ПО КАРТЕ наложенным платежом. Если же она не будет выбрана в опции «Наложенный платеж» — тогда модуль будет считать, что платежная система У — это предоплата заказа по карте.
  • Включить комиссию за наложенный платеж — включите прибавление комиссии за перечисление наложенного платежа в стоимость доставки для покупателя. Отключите в том случае, если готовы оплачивать комиссию самостоятельно.
  • Включать страховку в стоимость доставки — включите/отключите прибавление комиссии за услугу страхования в стоимость доставки заказов с онлайн оплатой. Опция НЕ действует на заказы с наложенным платежом — они страхуются по умолчанию на сумму наложенного платежа.

Настройка профилей доставки

На этой вкладке отображаются профили доставки, подчиненные родительской службе. Каждый профиль представляет собой метод(способ) доставки доступный для выбора при оформлении заказа.

При необходимости Вы можете создавать несколько одинаковых профилей доставки, но с разными ограничениями по отображению на сайте.

1. Создание профилей доставки

В зависимости от Вашей логистической модели используйте методы со стандартной доставкой через склад Shiptor, методы «сквозной» доставки из региона в регион минуя склад Shiptor или экспортные методы. При необходимости Вы можете использовать все типы методов доставки одновременно.

От склада  — доставка через склад Shiptor/Сберлогистика. Стандартная логистическая модель для магазинов, зарегистрированных в Shiptor на Юр.Лицо.

    Типы отгрузки: самостоятельный привоз на склад Shiptor, курьеру Shiptor (в пределах МКАД)
    Фулфилмент: доступен
    География доставки: по РФ, Белоруссии, Казахстану,
    Способы доставки: до двери, пункты самовывоза, постоматы, отделение почты
    Транспортные компании: максимально возможный выбор (полный перечень на сайте Shiptor)

Сквозная — прямой тип доставки, минуя сортировочный склад склад Shiptor/Сберлогистика. Упрощенная  логистическая модель для магазинов, зарегистрированных в Shiptor на Физ.Лицо.

    Типы отгрузки: самостоятельный привоз на принимающий пункт самовывоза транспортной компании, курьеру транспортной компании
    Фулфилмент: НЕ доступен
    География доставки: из регионов по РФ
    Способы доставки: до двери, пункты самовывоза
    Транспортные компании: ограниченный выбор (полный перечень на сайте Shiptor)

Экспорт — доставка через склад Shiptor/Сберлогистика.

    Типы отгрузки: самостоятельный привоз на склад Shiptor, курьеру Shiptor (в пределах МКАД)
    Фулфилмент: доступен
    География доставки: в страны, не входящие в ТС.
    Способы доставки: до двери
    Транспортные компании: ограниченный выбор (информация на сайте Shiptor)

Создавайте и активируйте только только нужные Вам профили! Каждый действующий профиль вызывает обращение к серверу Shiptor, что увеличивает время расчета стоимости доставки в оформлении заказа.

Чтобы создать профили доставки, перейдите на вкладку Профили в настройках ранее созданной службы доставки Shiptor.

Выберите действие:

Добавить профиль — нажмите для выбора метода доставки из всех доступных, на основании которого будет создан один профиль доставки.

Добавить профили от склада — нажмите для добавления всех доступных профилей доставки от склада включая экспорт. Их активация происходит в ручном режиме. Если в системе есть ранее загруженные профили доставки от склада, то нажатие на эту кнопку приведет к их дублированию.

Добавить сквозные профили — нажмите для добавления всех доступных профилей сквозной доставки. Их активация происходит в ручном режиме. Если в системе есть ранее загруженные профили сквозной доставки, то нажатие на эту кнопку приведет к их дублированию.

Пример доступных профилей: 

2. Общие настройки профиля доставки

После создания профиля доставки откроется раздел настройки профиля. Так же можно попасть в настройки профиля нажав на название профиля или выбрав «Редактировать» в меню профиля:

В открывшемся разделе можно выполнить общие индивидуальные настройки для каждого профиля доставки: 

  • Название — укажите отображаемое название профиля доставки.
  • Активность — включите/выключите профиль доставки.
  • Сортировка — укажите порядок сортировки среди активных профилей доставки. Чем меньше значение, тем выше профиль среди доступных при оформлении заказа. Данная опция действует только если в настройке агрегатора установлена опция «по настройке профилей».
  • Описание — укажите описание профиля доставки для отображения при оформлении заказа.
  • Логотип — загрузите свой логотип профиля доставки для отображения при оформлении заказа. По умолчанию используются встроенные в модуль стандартные логотипы.

3. Настройки профиля доставки

  • Фиксированная цена — укажите фиксированную стоимость если не хотите получать цены от Shiptor.
  • Название профиля Shiptor — оригинальное наименования метода доставки от Shiptor.
  • group — служебный параметр с уникальным значением для используемого метода доставки, позволяющий Вам визуально идентифицировать профиль доставки в Bitrix с соответствующим ему способом доставки из Shiptor.
  • Собирать со склада — включите/отключите сборку посылок, переданных с этим профилем, на складе Shiptor только если Вы используете услугу фулфилмента. При отключенной сборке посылка автоматически собираться не будет и Вы сможете привезти ее на склад в собранном виде самостоятельно или передать через забор курьером Shiptor. Если Вы не используете услуги фулфилмента Shiptor — проигнорируйте настройку этой опции.

4. Ограничения профиля доставки

Вы можете установить правила доступности конкретного профиля в зависимости от условий при оформлении заказа. Ограничения можно установить также и на всю родительскую службу, в этом случае они распространяются на все профили в ней.
При задании ограничений служба будет доступна только при выполнении условий, задаваемых в ограничении.

  • По весу — профиль доступен в указанном диапазоне веса.
  • По категории товара — профиль доступен для указанных типов товара.
  • По максимальному размеру/размерам — профиль доступен для товаров с габаритами, не превышающими указанные
  • По местоположению — профиль доступен только в указанном местоположении (страна/регион/город)
  • По местоположению (исключая) — профиль доступен во всех местоположениях кроме указанных (страна/регион/город) , если также доступен в Shiptor
  • По платежным системам — профиль доступен только для указанных платежных систем.
  • По публичной части — профиль доступен только в панели администратора.
  • По сайтам — профиль доступен только на указанных сайтах, включен режим многосайтовости.
  • По стоимости заказа — профиль доступен в указанном диапазоне суммы заказа.
  • По типу плательщика — профиль доступен только для указанных типов плательщика.

Важно: Профиль созданный на метод доставки Shiptor Today (shiptor_one_day) будет автоматически скрываться при оформлении заказа в интервале времени 12:00 — 21:00 вне зависимости от установленных в профиле ограничений. Обратите внимание что заказы на доставку этим методом должны быть переданы в Shiptor не позднее 13:00, чтобы на складе фулфилмента успели собрать заказ и передать его в доставку на текущий день. 

5. Дополнительные услуги

Только для профилей, созданных на метод доставки Сберкурьер (sber_courier) доступны дополнительные необязательные опции. К ним относятся: отложенная дата и временной интервал доставки. В профилях, созданных на другие методы, эта вкладка будет отсутствовать.

Добавить доп. услугу — нажмите и выберите необходимые опции, чтобы покупатель смог ими воспользоваться при оформлении заказа (первые две услуги «время доставки» и/или «дата доставки»). Вы можете добавить отдельно «дату доставки» или обе услуги вместе.

Особенности:

  • Выбор отложенной даты доставки возможен в интервале +1..+14 дней от даты оформления заказа. За пределами этого интервала дата доставки будет сброшена на завтрашний день. Если Вы не используете услуги фулфилмента в Shiptor, а передаете готовые посылки, при использовании опции учитывайте время на доставку посылки в Shiptor.
  • Выбор времени доставки возможен только для будних дней. При совместном использовании с опцией «Дата доставки» выбор временного интервала в выходной день будет недоступен для покупателя.
  • Чтобы возле названия услуги не указывалась нулевая стоимость доставки, при редактировании дополнительной услуги сотрите 0 из поля «Стоимость услуги» и сохраните ее.
  • Опции можно использовать вместе и раздельно.
  • Дополнительные услуги могут не поддерживаться в некоторых населенных пунктах. Уточнить их доступность можно на сайте. Чтобы избежать ошибок, введите географические ограничения для таких профилей. О том, как это сделать, читайте в инструкции.

6. Настройка профиля доставки от склада

В профилях, созданных для методов доставки через склад Shiptor, доступна вкладка для индивидуальной настройки данных по отправлению. В поле «Склад Shiptor» выберите актуальную информацию по местоположению склада отправления или используйте умолчание из настроек модуля.

Указанные настройки в профиле доставки от склада переопределяют глобальные настройки модуля. При указании «Не выбран» будет использовано значение по умолчанию из настроек модуля.

Если у склада реализована функция фулфилмента, но вы самостоятельно собираете заказы, просто снимите галочку в чек-боксе «Собирать со склада». Нажмите «Сохранить»

Обратите внимание, что выбранный склад Shiptor может не поддерживать доставку через метод, по которому создан профиль.

7. Настройка профиля сквозной доставки

В профилях, созданных для методов сквозной доставки (регион-регион, минуя склад Shiptor), доступна вкладка с данными по отправителю. Настройте следующие поля:

  • Населенный пункт — укажите населенный пункт отправления. По умолчанию он берётся из настроек модуля «Интернет-магазин».
  • Отправитель — выберите «Взять из настроек модуля», если используете умолчания, или «Указать вручную», если хотите задать индивидуальные настройки для профиля.
  • Адрес отправителя — выберите «Взять из настроек модуля», если используете умолчания, или «Указать вручную», если хотите задать индивидуальные настройки для профиля. Настройка требуется только в профилях, созданных на методы «сквозной» доставки вида «ДВЕРЬ-ДВЕРЬ» и «ДВЕРЬ-ПВЗ».
  • Дата и время отправлений — выберите «Взять из настроек модуля», если используете умолчания, или «Указать вручную», если хотите задать индивидуальные настройки для профиля.
  • Подтверждение отгрузки — укажите наиболее удобный способ подтверждения отгрузки. Это действие необходимо ее оплаты, после которой заявка будет передана в транспортную компанию. Доступные варианты:
    • Взять из настроек модуля — отгрузка подтверждается в соответствии с настройками по умолчанию.
    • Автоматически — отгрузка подтверждается автоматически при сохранении заказа.
    • Вручную — отгрузка подтверждается в ручном режиме через ЛК Shiptor без привязки к моменту сохранения заказа. 
  • Адрес ПВЗ — выберите пункт самовывоза для отгрузки посылки. Настройка требуется только в профилях, созданных на методы сквозной доставки вида «ПВЗ-ДВЕРЬ» и «ПВЗ-ПВЗ».

Работа с заказами и отслеживание

Все сформированные через модуль заказы отображаются на вкладке Магазин > Доставки Shiptor или по адресу <доменное имя сайта>/bitrix/admin/shiptor.delivery_unload.php? lang=ru.

Для переключения между заказами на методы «сквозной» доставки (регион-регион), заказами на экспорт и заказами на методы доставки через склад Shiptor воспользуйтесь фильтром.

1. Редактирование заказов

Перед передачей заказа в Shiptor его можно отредактировать используя стандартные возможности платформы 1С-Bitrix.
Особенности:

  • служба доставки, профиль доставки и ее стоимость можно изменить в документе отгрузки

  • ПВЗ доставки для методов с самовывозом можно изменить в документе заказа.

  • при изменении города назначения(местоположения) или товаров в документе заказа необходимо перевыбрать актуальный профиль доставки в документе отгрузки.

2. Необходимые условия для передачи заказа в Shiptor

Заказ можно передать в Личный кабинет Shiptor только при выполнении следующих условий:

  • Заказ разрешен к доставке. При необходимости можно настроить триггеры в модуле Интернет Магазин для автоматического разрешения доставки. Разрешить доставку можно не только в стандартном меню заказов 1С-Bitrix, но и на вкладке «Доставки Shiptor».
  • В отгрузке отсутствует идентификатор отправления. При ручной передаче заказа это условие НЕ проверяется, т.е. при необходимости его можно выгрузить повторно.
  • Статус «оплачено» для заказа БЕЗ наложенного платежа (онлайн-оплата). Заказы с оплатой при получении не проверяются на факт оплаты, но при добавлении оплаты сумма передаваемого наложенного платежа будет соразмерно уменьшена. При необходимости можно настроить триггеры в модуле «Интернет Магазин» для автоматического проставления статуса оплаты для предоплаченных заказов..

3. Способы передачи заказа в Личный Кабинет Shiptor.

Возможные варианты передачи заказов в Личный Кабинет Shiptor:

  1. Автоматически — используйте настройку агента для обработки заказов на методы доставки через склад Shiptor, в т. ч. фулфилмент.
  2. Вручную — отметьте один или несколько заказов. После этого в списке действий внизу страницы выберите «Отправить» и нажмите «Применить».

После каждой передачи заказов вверху списка выводится статистика с информацией о том, какие заказы были успешно выгружены, а какие вызвали ошибки.

При ручной передаче «сквозных» заказов необходимо учитывать тот факт, что «сквозные» заказы автоматически формируют отгрузки в ЛК Shiptor. Выделите несколько заказов в списке и отправьте в Shiptor. Заказы сгруппируются по службам доставки и при выгрузке создадут отгрузки по числу разных служб доставки в передаваемых заказах. Например, были выбраны для передачи 3 заказа, два из них сделаны на профиль DPD ПВЗ-ПВЗ, а один на профиль CDEK Дверь-Дверь. При передаче первые два заказа сформируют одну отгрузку, а третий — другую. Не рекомендуем передачу «сквозных» заказов по одному — иначе для каждого из них будет сформирована своя отдельная отгрузка!

Подтвердить отгрузку (вызвать курьера) и отредактировать ее Вы можете в ЛК Shiptor. 

Если в процессе передачи сквозных заказов, в одном из заказов какой-либо отгрузки возникнет ошибка передачи, будет остановлена передача всей отгрузки, в сообщениях об ошибках будет указана причина, по вине каких заказов отгрузка не была сформирована. Исправьте ошибки и выгрузите их повторно.

Рассмотрим следующий пример. Ниже была произведена попытка передачи заказов 193,194 и 195. Все относились к одному сквозному профилю доставки поэтому были сгруппированы в одну отгрузку. Однако заказы 193 и 194 вызвали ошибки, поэтому вся отгрузка была остановлена. Во всех заказах появились сообщения о причине неудачи при передаче.

4. Удаление переданного заказа из Личного Кабинета Shiptor.

Вы можете удалить заказы со сборкой на складе фулфилмента пока они в статусе «New» и «сквозные» заказы пока они в статусе «Packed». Другие типы заказов удаляются из ЛК автоматически: по истечению 30 дней с момента создания для обычных заказов и по истечении 7 дней для заказов «сквозной» доставки.
Отметьте один или несколько ранее переданных заказов, выберите «Отменить» и «Применить».

5. Специфические поля таблицы заказов.

Вы можете изменить отображение информации в таблице заказов воспользовавшись стандартной настройкой «Настроить»

Стоимость доставки — рассчитанная от Shiptor или установленная вручную стоимость доставки.
Статус посылки в Shiptor — текущий внутренний статус заказа в Shiptor.
Трек-номер — номер отслеживания от Shiptor вида RPxxxxx.
Причина пометки — ошибка при передаче заказа.

6. Способы получения и обновления статусов заказа от Shiptor

При обработке в Shiptor заказ проходит несколько стадий, каждая из которых отмечена отдельным статусом. При необходимости Вы можете связать статусы заказа от Shiptor со статусами отгрузки в 1С-Bitrix
Ручное получение статусов — отметьте один или несколько заказов, выберите «Обновить статус» и «Применить».


Автоматическое получение статусов — используйте настройку агента.

7. Получение штрихкода для посылки

Отметьте один или несколько заказов, выберите «Получить штрихкод» и нажмите «Применить». После обработки команды появится ссылка на PDF-файл. Воспользуйтесь ей для печати штрихкодов.

Если на хостинге сайта не подключена графическая библиотека php-imagick, то штрихкоды печатаются по отдельности.

Примеры 

В данном разделе будут описаны примеры настройки модуля Shiptor совместно с платформой Bitrix под Ваши бизнес-процессы.

1. Настройка бесплатной доставки для города N при сумме корзины Х

Для задания правил на стоимость доставки по определённому населенному пункту, при достижении суммы заказа для бесплатной доставки, в настройках Bitrix Вам нужно создать две службы доставки.

Для примера создадим бесплатную доставку для города Москва при сумме корзины более 3000 р.

Для этого Вам необходимо перейти в админ-панели по адресу Магазин->Настройки->Службы доставки.
Далее необходимо нажать кнопку [+Добавить] и из выпадающего списка выбрать пункт «Служба доставки Shiptor».

Задайте общие настройки службы доставки.

В разделе «Службы доставки» выберете созданную Вами службу и перейдите в её настройки.

Во вкладке «Ограничения» добавьте ограничение «По местоположению».

В этой службе доставки необходимо указать фиксированную стоимость доставки на необходимые Вам профили. 
На вкладке «Профили» выберите профиль:

В настройках профиля укажите стоимость доставки:

Далее нужно задать стандартные правила работы с корзиной, добавив скидку в 100% при условии, что стоимость товара в корзине равна желаемой сумме, как показано ниже.

Теперь нужно создать вторую службу доставки, исключая г. Москву.
Так же в админ-панели по адресу Магазин->Настройки->Службы доставки добавляем службу доставки.
Во вкладке «Ограничения» добавьте ограничение «По местоположению (исключая)» и так же выберите г. Москва.

Для второй службы доставки создайте профили и оставьте стандартные настройки.

2. Создание скидки на доставку в определенный населенный пункт при выполнении определенного условия в заказе.

Создание обусловленных скидок/наценок на доставку использует механизм ограничений служб доставки Bitrix, а также правила работы с корзиной.

Допустим, у вас стоит задача сделать доставку бесплатной для заказов дороже 12 000 рублей в Москве.

Создайте новый профиль доставки в родительской службе Shiptor, и задайте на него ограничение по населенному пункту равное г. Москва (см. раздел Ограничения). Далее надо создать правило работы с корзиной.
Для этого переходим в раздел Маркетинг — Товарный маркетинг — Правила работы с корзиной.

Нажмите Добавить правило. Откроется окно с настройками правила. Во вкладке Общие параметры установите название скидки (по своему желанию) и приоритет применимости скидки (чем больше, тем лучше).

Далее на вкладке Действия и условия выберите действие изменить стоимость доставки и установите нужную вам скидку или наценку в процентах или валюте. Добавьте условия применимости скидки: служба доставки равна Shiptor Курьер (тот профиль, который мы ранее создали с ограничением по городу Москва), и стоимость всех товаров больше либо равна 12 000 RUB.

Далее во вкладке Ограничения выберите группы пользователей, для которых будет действовать данная скидка.

Нажмите Сохранить.

Подобным образом можно создавать скидки/наценки по другим параметрам заказа — например вес товаров в заказе.

3. Создание зависимых полей для разных служб доставки.

Допустим, нам нужно скрыть поле «Адрес доставки» из оформления заказа, когда покупатель выбирает профиль с доставкой в ПВЗ.

Для этого переходим в раздел Магазин — Настройки — Свойства заказа — Список свойств и находим там нужное нам.

Открываем его и переходим на вкладку Привязка свойства.

Здесь доступны два типа привязки — по платежной системе и по службе доставки.

Если не выбрано ни одной платежной системы, свойство будет отображаться для всех платежных систем. Однако если выбрать хотя бы одну — отображаться будет только для нее. Аналогично и со службами доставки. В нашем случае нужно будет выбрать все курьерские профили доставки, оставив не выбранными все профили с ПВЗ.

Если присутствует несколько типов плательщиков (физическое лицо, юридическое лицо), то все манипуляции надо будет проделать для каждого свойства, заведенного у плательщиков. В нашем случае их два.

После сохранения изменений правила вступят в силу немедленно.

4. Настройка платежных систем.

Рассмотрим настройку платежных систем, влияющих на отображение ПВЗ, а также на расчет стоимости доставки и наложенный платеж. Для примера возьмем случай когда магазин предлагает покупателю весь набор способов оплаты заказа: на сайте дистанционно и при получении заказа.

Оплата при получении вомзожна двумя способами: наличными и картой через терминал. Если подходящего по смыслу способа оплаты в 1С-Bitrix нет, то создадим его.

Обратимся к настройкам платежных систем в настройках модуля.

Отметим только способ оплаты, который подразумевает оплату передачей непосредственно наличных средств.

Теперь проследуем в настройки службы доставки.

Здесь нас интересует вкладка Наложенный платеж и страхование.

Опция Считать доставку с наложенным платежом с вариантом Только для платежных систем с включенным наложенным платежом означает, что расчет доставки и передача заказа будут происходить с наложенным платежом если покупатель при заказе выбрал одну из отмеченных здесь платежных систем , и без наложенного платежа для всех остальных платежных систем.

Отметим способы оплаты которые модуль будет воспринимать оплатой при получении (наложенный платеж). При настройке, указанной на скриншоте способы оплаты «Наличные курьеру» и «Картами при получении» модуль будет считать наложенным платежом .В то же время в связи с ранее проделанной настройкой для способа оплаты «Картами при получении» модуль будет требовать необходимость терминала для карт, т.к. он не отмечен как наличные

У каждого ПВЗ из профилей доставки с ПВЗ могут присутствовать или отсутствовать возможности по оплате картой или наличными, причем некоторые ПВЗ, будучи пунктами самовывоза, вообще не поддерживают наложенный платеж и предназначены только для забора ранее оплаченного отправления. Именно по этой причине на карте выбора точек ПВЗ вы можете увидеть следующую картину

Некоторые ПВЗ недоступны при выбранной покупателем платежной системе, о чем можно увидеть соответствующее сообщение при наведении на недоступный ПВЗ в списке.
Очень важно правильно настроить платежные системы в модуле, чтобы не получить проблему с передачей заказа в ЛК Shptor, когда в заданном ПВЗ может не оказаться возможности оплаты той платежной системой, которую выбрал в заказе покупатель.

Внимание! Случай, когда покупатель выбрал оплату по карте, для которой не подключена услуга Наложенный платеж, учитывается модулем при передаче заказа и при отображении списка ПВЗ, как предоплаченный заказ, то есть ограничения по возможным способам оплаты при отображении списка ПВЗ не учитываются. При расчете доставки такого заказа принимается во внимание значение настройки Считать доставку с наложенным платежом. В случае, когда выбран вариант Всегда, такой заказ также посчитается с наложенным платежом, в противном случае доставки рассчитается без наложенного платежа.

5. Изменение внешнего вида.

Чтобы управлять внешним видом контента, выводимого модулем на странице оформления заказа, потребуется знание HTML и CSS. Под контентом имеется в виду выводимые к описанию служб доставки с ПВЗ кнопка и адрес постамата, а также всплывающее окно с выбором ПВЗ. Для вывода всплывающего окна используется стандартная оконная библиотека Bitrix, поэтому большая часть стилей берется непосредственно из ядра Bitrix.
Вносить изменения (изменять классы, id или тип и порядок выводимых модулем DOM узлов) в HTML не рекомендуется, поскольку модуль подключает JS файлы, которые опираются на конкретную структуру выводимого HTML. Вместо этого нужно воспользоваться всеми возможностями современного стандарта CSS.
Файл со стилями модуля расположен по адресу /bitrix/css/shiptor. delivery/styles. css
Вы можете внести изменения прямо в него, однако при выходе обновления модуля (иногда выходят обновления, затрагивающие стили модуля) эти изменения могут быть затерты. Выгоднее создать свою копию этого файла и подключать ее после той, что подключается модулем. В своей копии этого файла вы сможете переопределить любые стили отображения без риска потерять изменения.

6. Отслеживание обновлений модуля.

Чтобы узнавать о выходе новой версии, вы можете вывести на свой рабочий стол администратора Bitrix специальный гаджет, который будет проверять наличие обновлений.
Щелкните на кнопке Добавить гаджет, выберите пункт Настройки и в нем наш гаджет. Он разместится на рабочем столе и будет проверять обновления при заходе на страницу. Проверка обновлений выполняется посредством AJAX запроса и не блокирует загрузку страницы.

7. Расчет доставки в СНГ.

Для доставки в страны СНГ в Shiptor не доступна услуга «Наложенный платеж»
Для того чтобы доставка по странам таможенного союза рассчитывалась корректно, необходимо полностью отключить возможность наложенного платежа для этих стран. 
Для этого Вам потребуется создать две родительских службы доставки Shiptor и задать для них общие настройки.

Для службы доставки, которая предназначена для России, установить ограничение по местоположению для России соответственно. 
В настройках службы доставки, которая предназначена для доставки по СНГ, установить ограничение по местоположению для Казахстана и Беларуси.

Далее на вкладке «Наложенный платёж и страхование» отключите возможность расчета с наложенным платежом.

На вкладке «Ограничения» добавить ограничение по платёжным системам, указав только те методы оплаты, которые у Вас предполагают оплату онлайн на сайте. 


В профилях доставки укажите «DPD Курьер Авто», это единственный метод доставки в СНГ согласно тарифам Shiptor.

8. Расчет доставки на экспорт

Создайте отдельную родительскую службу доставки Shiptor и добавьте в нее профили экспорта. Подробно о том, как это сделать, читайте в разделе «Создание профилей доставки».

На вкладке «Ограничения» экспортной службы доставки установите ограничения:

  • по местоположению — исключите Россию, Казахстан и Беларусь;
  • по платёжным системам — укажите только те методы оплаты, которые предполагают оплату онлайн на сайте. 

После этого перейдите на вкладку «Наложенный платёж и страхование» и для поля «Считать доставку с наложенным платежом» выберите значение «Никогда».

Нажмите «Сохранить».

Для уточнения адреса используется индекс. Для настройки этого параметра перейдите в Магазин > Настройки > Свойства заказа > Список свойств > Индекс и в подразделе «Типы данных» сделайте активными чек-боксы «Обязательное» и «Использовать как почтовый индекс». На вкладке «Привязка свойства» можно ограничить отображение индексов только для экспортных посылок.

Нажмите «Сохранить».

Для корректной обработки посылок таможенными службами необходимо, чтобы все выбранные местоположения имели:

9. Создание ставки НДС

Будьте осторожны при выполнении действий в этом разделе: некорректные настройки интернет-магазина могут привести к глобальным ошибкам. Используйте их только при необходимости. 

Для добавления ставки НДС перейдите Магазин > Налоги > НДС и нажмите «Добавить». В открывшейся форме заполните поля «Наименование» и «Ставка» и нажмите «Сохранить». В результате она отобразится в общей таблице.

После этого перейдите Настройки > Настройки модулей и в поле рядом с заголовком выберите «Интернет-магазин». На вкладке «Настройки» активируйте чек-бокс «Рассчитывать налог для доставки».

Нажмите «Сохранить».

НДС для товаров и торговых предложений

Чтобы добавить ставку к товару, перейдите Магазин > Список товаров и щелкните по нужному варианту. В окне настроек перейдите на вкладку «Торговый каталог» и выберите актуальное значение для поля «Ставка НДС». При этом чек-бокс «НДС включен в цену» должен быть активен.

Добавление НДС к торговым предложениям происходит по аналогичному сценарию.

НДС для услуги доставки 

Чтобы добавить НДС для отдельных профилей доставки, перейдите Магазин > Настройки > Службы доставки и из общего списка выберите «Служба доставки Shiptor». В окне настроек перейдите на вкладку «Профили» и выберите тот метод доставки, к которому требуется добавить НДС. На вкладке «Общие настройки» в поле НДС укажите требуемое значение.

Нажмите «Сохранить».

Включение передачи НДС вместе с заказом

После этого вернитесь к основным настройкам Службы доставки Shiptor. На вкладке «Настройки обработчика» сделайте активным чек-бокс «Включить передачу НДС в заказе». Обратите внимание: опция работает только если в Shiptor включена поддержка такого режима. В противном случае при передаче заказа система вернет ошибку.

Нажмите «Сохранить».

Юрий Волошин,
Ну вы ведь являетесь администратором, разработчиком данной системы, ну почему вам тоже приходится все объяснять на пальцах)

Цитата
Юрий Волошин пишет:
Из вашего текста непонятно каким способом выбирается например город в местоположение

Ну я ведь привел два варианта, первый «по умолчанию» (из списка), второй «строка поиска». Это два Шаблон местоположения, которые выбираются в настройках компонента

1. Если выбрали «строка поиска».

Ввели в поле Местоположение: село Барановка (т.е человек быстро написал какой-то свой населенный пункт, а не выбрал его из списка, который который должен погрузится. К тому же если писать быстро, список не появится вообще, если нет подходящего местоположения)

здесь мы пишем местоположение :

А в заказах вы видим :

2. Если выбрали «по умолчанию».

А в заказах вы видим :

Тогда мы вообще видим два разных города.

На втором вашем слайде можно убрать Значение по умолчанию — Москва, т.е. оставив его пустым, тогда хоть можно убрать этот лишний город в заказах, который на самом деле не выбирали. Но все равно это не дело, пункт город там все равно будет.

Если с режимом «по умолчанию» еще как-то можно смирится, убрав город из значения по умолчанию в настройках свойства Город (хотя это все равно не совсем логично),
то «строка поиска» все таки совсем не логично работает. Нужно как-то сделать так, что если пользователь не кликнул по всплывающему городу, то нужно значит принимать то значение, которое он ввел сам.

Думаю я все объяснил. Если вы считаете, что такое поведение местоположения нормальное, то у меня вопросов нет!

0

http://www.lensday.ru/

Вот сайт
чтобы проверить работу — положите что-нибудь в корзину перейдите к оформлению заказа и заполните поле Адрес

  • Ответить
  • |

0

На рассмотрении

Укажите, пожалуйста, версию Битрикса и какие модули вы на него устанавливали?

  • Ответить
  • |

0

Так же не работает.
Пробовал по разному, местоположение само не определяется. А без этого модуль можно считать безполезным. Придётся пока вернутся на решение от Долганина, хоть и оно не идеально.

  • Ответить
  • |

0

Та же проблема. Появилась после установки последних обновлений. В ней Битрикс радикально заменил структуру местоположений, из-за чего не правильно работают ява-скрипты.

  • Ответить
  • |

0

Начат

Разбираемся, статус буду писать здесь.

  • Ответить
  • |

0

Здравствуйте. Почините заодно гранулярные подсказки для битрикса. А то там сейчас свойство constraints нигде не используется. Нормально можно пользоваться только целиком строкой адреса.

  • Ответить
  • |

0

Подпишусь, тоже не работают :(

  • Ответить
  • |

0

Проблема есть на 14 версии Битрикса, сейчас разбираемся. На 15 версии работает.

  • Ответить
  • |

0

Дело не версии битрикса, а версии модуля местоположений. Для местоположений 2.0 битрикс генерирует другую структуру html и javascript не может найти нужный тег с полем местоположения.

  • Ответить
  • |

0

Есть какие новости? Малый Бизнес, версия 15.0.6. Местоположения не заполняются

  • Ответить
  • |

0

обновление не встает, накосячили :)
Ошибка в updater’e 1.1.0 модуля dadata.suggestions: [UCDF02] Путь «/home/bitrix/www/home/bitrix/www/install/components/dadata.suggestions» не существует.
. Установка обновлений модуля dadata.suggestions прервана. [CL04] Обновление не установлено

  • Ответить
  • |

0

Константин Листратов, там было два обновления подряд — первое тестировали, второе было корректно. Поставьте еще раз.  

  • Ответить
  • |

0

ну как сказать.. что не так делаю?

  • Ответить
  • |

0

Константин, мне кажется, у вас все-таки что-то не то с обновлением, только что проверяла на тестовой платформе http://bitrix.hflabs.ru — не воспроизводится.

Можете рассказать, в каком порядке вы заполняете указанные поля? 

И посмотрите, пожалуйста, какая версия плагина у вас стоит? В админке Битрикса Администрирование-> Marketplace -> Установленные решения -> в таблице — Подсказки DaData.ru есть поле версия. Чему у вас равно это значение?

  • Ответить
  • |

0

Заполняю только Адрес доставки, который в настройках стоит как адрес одной строкой
veizemat.ru — зайдите, попробуйте оформить заказ

  • Ответить
  • |

0

Константин, посмотрели — переустановите, пожалуйста, плагин (удалить и установить заново). У вас криво поставилась версия 1.1.1.

Если после этого не заработает — можете кинуть нам контакты админки на info@dadata.ru, мы сами посмотрим в чем дело.

  • Ответить
  • |

0

сейчас плагин начал выдавать такую ошибку Fatal error: Call to undefined method CSaleLocation::isLocationProEnabled() in %путь%

и вся корзина отвалилась

  • Ответить
  • |

0

Не учли, что может быть не обновлен Битрикс, но обновлен плагин. 
Вы можете обновить Битрикс? Это должно решить проблему.

Сегодня-завтра исправим.

  • Ответить
  • |

0

Исправили, зарелизили версию 1.1.2 — Данное обновление решает проблему совместимости со старым модулем интернет магазина (без Местоположений 2.0). http://marketplace.1c-bitrix.ru/solutions/dadata.suggestions/

  • Ответить
  • |

0

у меня модуль все равно не проставляет местоположение

http://www.lensday.ru/

Вот сайт
чтобы проверить работу — положите что-нибудь в корзину перейдите к оформлению заказа и заполните поле Адрес

  • Ответить
  • |

0

А какая у вас версия Битрикса и какие сторонние плагины установлены (с версиями)?

  • Ответить
  • |

0

Только ваш плагин версии 1.1.2
это старый скрин

  • Ответить
  • |

0

Не знаю, что значит починили, но я так и не смог нормально настроить. Такое чувство что разработчики не понимают что нужно интернет магазинам.
1. Битриксовское поле Location должно быть отключаемым, не должна от него зависеть работа модуля. Никому не надо чтобы в дополнение к адресу ещё показывался список местоположений.
2. Модуль не работает в режиме гранулярных подсказок. Нет зависимости от предыдущего уровня.
вот пример кода » if ($(‘[name=ORDER_PROP_5]’).length > 0) $(‘[name=ORDER_PROP_5]’).suggestions({
serviceUrl: ‘https://dadata.ru/api/v2’,
token: ‘4908ec472047ec32567cc125bd3559b37594d729’,
type: ‘ADDRESS’,
bounds: ‘city-settlement’,
onSelect: function (suggestion) {
$(‘[name=ORDER_PROP_5]’).val(suggestion.data.city);
}
});

if ($(‘[name=ORDER_PROP_22]’).length > 0) $(‘[name=ORDER_PROP_22]’).suggestions({
serviceUrl: ‘https://dadata.ru/api/v2’,
token: ‘4908ec472047ec32567cc125bd3559b37594d729’,
type: ‘ADDRESS’,
bounds: ‘street’,
onSelect: function (suggestion) {
$(‘[name=ORDER_PROP_22]’).val(suggestion.data.street);
}
});»
Как видим в поле ORDER_PROP_22 задали что это УЛИЦА, но что она зависит от поля ORDER_PROP_5 с указанным городом, не задали. Соответственно в подсказках вываливается всякая фигня.
3. При выборе ввода адреса одной строкой, адрес потом не раскидывается по остальным полям, если они отмечены как служебные (т.е. не отображаются на форме).

  • Ответить
  • |

0

Спасибо за замечания, постараемся исправить в следующих релизах.

  • Ответить
  • |

0

Зарелизили и, похоже, на этом остановимся в разработке этого плагина. Разработка довольно трудоемкая, а польза для интернет-магазинов для нас не очень очевидная. 

 По вашим комментариям:
1. Невозможно отключить это поле, т.к. оно напрочь интегрировано в экосистему битрикса, в инструкции есть рекомендация выносить это поле вниз формы. чтобы оно заполнялось раньше чем пользователь до него дойдет
2. Пофикшено.
3. Служебные поля, к сожалению, не отображаются на форме (т.е. вообще, даже как input type=hidden), в новом релизе убрали их из настроек.

  • Ответить
  • |

Возникает ошибка при оформлении заказа на битрикс (вроде что то связанное с JSON), вот что выходит:

({«order»:{«ERROR»:{«property»:[«\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u0430 \u0022\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0022 — \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430» ] } } })

Куда копать? Как можно исправить?

  • javascript
  • json

задан 15 янв 2020 в 8:41

Валерий's user avatar

2

  • ({"order":{"ERROR":{"property":["Свойство заказа "Местоположение" - ошибка ввода"] } } })

    15 янв 2020 в 9:34

  • Спасибо! Буду копать

    15 янв 2020 в 10:29

Свойства заказа — это значения заказа, которые должны быть указаны клиентом интернет-магазина при оформлении заявки. Они различаются по типам плательщиков. Подробнее о создании и настройке свойств читайте в документации 1С-Битрикс.

В этом уроке рассмотрим пример настройки заказа для способа «Самовывоз» и «Доставка».

Настройка свойств заказа для способа доставки «Самовывоз»

Рядом со способом доставки отображается дополнительная информация: условия доставки, услуги грузчиков, VIP обслуживание вне очереди и подарочная упаковка. В зависимости от заполнения этих полей формируются условия самовывоза: бесплатно или за определенную сумму с дополнительными услугами компании.

При выборе способа доставки «Самовывоз» оформление заказа выглядит так:

  • Покупатель сразу видит карту точек самовывоза, откуда можно забрать заказ, а также контактные данные, режим работы и описание.

  • После пунктов самовывоза поле «Адрес доставки» не отображается (в отличие от других способов доставки).

Однако при некорректной настройке свойств заказа и служб доставки поле для ввода адреса доставки может выводиться (причем в качестве поля, обязательного для заполнения):

Ниже рассмотрим, как настроить склады, службы доставки и свойства заказа так, чтобы при выборе способа доставки «Самовывоз» поле для ввода адреса не отображалось.

Настройка свойств заказа, службы доставки и складов

Перейдите в настройки складов. Для этого проделайте путь в административной части сайта: Магазин → Складской учет → Склады.


Найдите нужный склад, который хотите задействовать в качестве пункта самовывоза, и перейдите в его настройки. Кликните на ID или в меню «Гамбургер» выберите редактирование элемента.


Активируйте параметр «Пункт выдачи» и сохраните изменения.


Перейдите в настройки служб доставки: Магазин → Настройки → Службы доставки.


Найдите в списке служб доставки «Самовывоз» и нажмите «Изменить».


На вкладке «Общие настройки» активируйте поле «Выбрать склады самовывоза». Выберите города, склады в которых будут пунктами самовывоза товаров. Сохраните изменения.


Если вы используете редакцию 1С-Битрикс: Малый бизнес, вам будет доступен только 1 пункт самовывоза. Для редакции 1С-Битрикс: Бизнес количество пунктов самовывоза не ограничено.

Далее перейдите в свойства заказа: Магазин → Настройки → Свойства заказа → Список свойств.

Найдите свойство, которое необходимо отредактировать. В нашем случае это свойство №7 — адрес доставки для типа плательщика «Физическое лицо (s1)». Перейдите в настройки параметров свойства.

Перейдите на вкладку «Привязка свойства». В поле «Службы доставки» отключите пункт «Самовывоз». Если пункт отключен, поле для заполнения адреса в блоке с информацией о покупателе будет отсутствовать.

Сохраните изменения и проверьте результат на сайте. После пунктов самовывоза отсутствует поле для ввода адреса доставки.

Понравилась статья? Поделить с друзьями:
  • Своя будущая профессия мне очень нравится ошибка
  • Сгибание ног лежа ошибки
  • Сделал большую ошибку
  • Свою ошибку учла
  • Сгенерировать ошибку delphi