На одном из проектов потребовалось, чтобы на странице оформления заказа расчет стоимости доставки отображался, но при сохранении заказа стоимость доставки не добавлялась бы к стоимости заказа.
Ряд модулей служб доставки позволяют настройками сделать так, чтобы стоимость доставки не добавлялась бы к стоимости доставки. Но не у всех служб доставки так.
Нам нужно было на странице оформления заказа выводить рассчитанную стоимость доставки, но при сохранении заказа не добавлять ее к итоговой стоимости, чтобы покупатель не оплатил бы стоимость доставки сразу при оформлении заказа, а оплачивал бы только товар. При этом рассчитанную и показанную покупателю стоимость товара нужно сохранять в заказе в качестве справочной информации.
Для сохранения расчетной стоимости доставки создали два свойства заказа (для каждого типа плательщика). В нашем примере оба свойства не являются служебным (о причинах будет сказано ниже), но можно их сделать и служебными.
Для пересчета стоимости заказа добавлен обработчик события OnSaleOrderSaved:
Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderSaved',
'OnSaleOrderSavedHandler'
);
function OnSaleOrderSavedHandler(Bitrix\Main\Event $event)
{
/** @var Order $order */
$order = $event->getParameter("ENTITY");
$isNew = $event->getParameter("IS_NEW");
$bNeedSave = false;
if ($isNew)
{//если заказ только создается, то запишем рассчитанную стоимость доставки в отдельное свойство
$originalDeliveryPrice = 0;
$shipmentCollection = $order->getShipmentCollection();
foreach ($shipmentCollection as $shipment) {
$originalDeliveryPrice += $shipment->getPrice();
}
$propertyCollection = $order->getPropertyCollection();
$estShipCostProp = $propertyCollection->getItemByOrderPropertyCode('EST_SHIP_COST');
if ($estShipCostProp) {
$estShipCostProp->setValue($originalDeliveryPrice);
}
$bNeedSave = true;
}
//обнулим стоимость доставки в отгрузке
$shipmentCollection = $order->getShipmentCollection();
foreach ($shipmentCollection as $shipment) {
if($shipment->getPrice() > 0) {
if(!$shipment->isSystem()){
$shipment->setBasePriceDelivery(0, false);
$bNeedSave = true;
}
}
}
//обнулим стоимость доставки в данных самого заказа
if($order->getDeliveryPrice() > 0) {
$order->setFieldNoDemand('PRICE_DELIVERY', 0);
$bNeedSave = true;
}
if($bNeedSave) {
$order->save();
}
}
При таком подходе стоимость заказа получается равной стоимости товаров:
В отгрузке так же нет стоимости доставки:
Но расчетная стоимость доставки сохраняется в свойствах заказа:
Хотелось бы отметить, что для изменения стоимости доставки в заказе используется именно метод:
$order->setFieldNoDemand('PRICE_DELIVERY', 0);
Если использовать setField, то стоимость доставки не поменяется.
Теперь вернемся к тому, делать свойства заказа для хранения расчетной стоимости заказа служебными или нет. Нам требовалось, чтобы информация о расчетной стоимости доставки отображалась бы в подробной информации о заказе в личном кабинете пользователя:
Если вам это не требуется, то делайте свойства с расчетной стоимостью заказа служебными - они будут отображаться в административной части на странице заказа, но не будут видны в публичной части сайта.
Нам же требовалось отобразить в кабинете пользователя. И здесь есть два варианта. Если свойство не является служебным (как и было сделано), то оно там будет отображаться штатно, без доработки. Но в то же время оно будет отображаться в оформлении заказа:
Чтобы его скрыть нужно модифицировать шаблон оформления заказа. Если же сделать свойства служебными, то они не будут отображаться в оформлении заказа, но и не будут отображаться штатно в подробной информации о заказе в кабинете пользователя. То есть придется модифицировать шаблон подробной информации о заказе. По итогу выбор между служебным и неслужебным статусом свойств и состоит в том, какой из шаблонов компонентов будем редактировать. Выбрали модификацию шаблона оформления заказа, так как там уже были изменения. Можно было просто через css скрыть это свойство. Но мы сделали запрет вывода данных свойств в оформлении заказа через добавление кода в order_ajax.js шаблона оформления заказа:
...
getPropertyRowNode: function (property, propsItemsContainer, disabled, with_column) {
if(property.getId() == 26 || property.getId() == 27){
return;
}
...






