Перейти к содержимому

Дополнительные услуги в заказе - упаковка, сборка, страховка

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

Что нужно знать заранее

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

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

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

Шаги

  1. Решить, услуга станет позицией корзины или свойством заказа с ценой.
  2. Завести услуги отдельным разделом каталога и задать им цены и налог.
  3. Показать выбор услуг на шаге оформления и пересчитать сумму заказа.
  4. Добавлять услугу в корзину с признаками, отличающими её от обычного товара.
  5. Проверить, что услуга попадает в документы и в обмен с учётной системой.

Решение

Заводим услугу позицией каталога:

\Bitrix\Main\Loader::includeModule('catalog');
\CCatalogProduct::Add([
'ID' => $serviceId, 'QUANTITY' => 0, 'QUANTITY_TRACE' => 'N',
'CAN_BUY_ZERO' => 'Y', 'WEIGHT' => 0, 'VAT_ID' => $vatId,
]);
// услуга продаётся при нулевом остатке и не участвует в расчёте доставки

Признак продажи при нулевом остатке обязателен для услуги. Без него упаковка просто не добавится в корзину, а покупатель увидит сообщение об отсутствии товара.

Добавляем услугу в корзину:

$item = $basket->createItem('catalog', $serviceId);
$item->setFields([
'QUANTITY' => 1, 'CURRENCY' => 'RUB', 'LID' => SITE_ID,
'PRODUCT_PROVIDER_CLASS' => \CCatalogProductProvider::class,
'PRODUCT_XML_ID' => 'SERVICE_WRAP', // код для обмена с учётной системой
]);
$basket->save();

Показываем выбор на оформлении:

$props = $order->getPropertyCollection();
$wrap = $props->getItemByOrderPropertyCode('NEED_WRAP');
if ($wrap && $wrap->getValue() === 'Y') { addServiceToBasket($basket, $wrapServiceId); }
// свойство заказа отвечает за выбор, а деньги считает позиция корзины

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

Считаем услуги отдельно от товаров:

$goods = 0; $services = 0;
foreach ($basket as $item) {
$isService = in_array($item->getField('PRODUCT_XML_ID'), $serviceCodes, true);
$isService ? $services += $item->getFinalPrice() : $goods += $item->getFinalPrice();
}
printf("товары: %s, услуги: %s\n", $goods, $services);

Проверяем передачу услуги в учётную систему:

Окно терминала
grep -i 'SERVICE_WRAP' /home/bitrix/www/upload/1c_exchange/*.xml | head -3
# услуга должна приезжать в учётную систему как отдельная строка документа

Типичные проблемы

Услуга не добавляется в корзину покупателю.

У позиции услуги включено списание остатка и запрещена покупка при нуле. Услуге ставят нулевой остаток, разрешают покупку при нуле и убирают вес.

Доставка подорожала после добавления упаковки.

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

Сумма заказа не сходится с составом в учётной системе.

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

Услуга попала в подборки и в фид маркетплейса.

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

Налог по услуге посчитан как по товару.

Ставка налога у позиции услуги не задана и берётся общая по каталогу. Ставку услуге задают явно и сверяют её с бухгалтерией.

Частые вопросы

Позиция корзины или свойство заказа?

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

Как не показывать услуги в каталоге?

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

Влияет ли услуга на доставку?

Влияет, если у неё задан вес или габариты. У услуг эти поля оставляют нулевыми, чтобы расчёт доставки их не учитывал.

Как передать услугу в учётную систему?

Отдельной позицией с понятным внешним кодом, который заведён и на той стороне. Тогда сумма документа сходится с составом заказа.

Можно ли менять цену услуги для конкретного заказа?

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

Смежное

Первоисточник