[Яндекс.Маркет] Автоматизированные службы доставки Битрикс v14

Решаем проблему вывода автоматизированных служб доставки интернет-магазина Битрикс v14 при оформлении заказа на Яндекс.Маркете.

Речь пойдет вот об этом, оказывается не сделано, работают только настраиваемые службы, сегодня это исправим.
Тут я тестирую оформление заказа в панели Яндекс.Маркет, покупателю будет выводиться тоже самое, когда он будет оформлять заказ на Яндекс.Маркете.
#

Выбор автоматизированных служб

Сначала нам нужно добавить автоматизированные службы доставки в настройка модуля Интернет-магазина в разделе Покупки на маркете

#

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

Настройки задаются в административной странице в файле
/bitrix/modules/sale/admin/ymarket.php

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

Итак, находим где в файле формируется массив настраиваемых служб $arDeliveryList и добавляем к нему автоматизированные
$arDeliveryFilter = array(
    "LID" => $arTab["SITE_ID"],
    "ACTIVE" => "Y"
);

//STATIC DELIVERY
$dbDeliveryList = CSaleDelivery::GetList(
    array("NAME" => "ASC"),
    $arDeliveryFilter,
    false,
    false,
    array("ID", "NAME")
);

$arDeliveryList=array();
while ($arDelivery = $dbDeliveryList->Fetch())
    $arDeliveryList[$arDelivery["ID"]] = $arDelivery["NAME"];


//AUTOMATIC DELIVERY
$dbRes = CSaleDeliveryHandler::GetList(
    array('NAME' => 'ASC'),
    $arDeliveryFilter
);
while($delivery = $dbRes->Fetch())
{
    $deliveryId = ($delivery["ID"] ? $delivery["ID"] : $delivery["SID"]);
    $arDeliveryList[ $deliveryId ] = $delivery["NAME"];
}

Далее находим блок вывода доставок и добавляем в список опцию для почты, в моем случае она была закомментирована, у вас скорее всего все тоже самое будет.
<option value="POST"<?=$selected == "POST" ? "selected" : ""?>><?=GetMessage("SALE_YM_DELIVERY_POST")?></option>

Вот так готовый селект выглядит, который выводит службы доставки в админке
<tr class="heading"><td colspan="2"><?=GetMessage("SALE_YM_DELIVERY")?></td></tr>
<?foreach ($arDeliveryList as $deliveryId => $deliveryName):
    $selected = isset($siteSetts["DELIVERIES"][$deliveryId]) ? $siteSetts["DELIVERIES"][$deliveryId] : '';
?>
    <tr>
        <td width="40%"><?=htmlspecialcharsbx($deliveryName)?>:</td>
        <td width="60%">
            <select name="YMSETTINGS[<?=htmlspecialcharsbx($arTab["SITE_ID"])?>][DELIVERIES][<?=$deliveryId?>]">
                <option value=""><?=GetMessage("SALE_YM_NOT_USE")?></option>
                <option value="DELIVERY"<?=$selected == "DELIVERY" ? "selected" : ""?>><?=GetMessage("SALE_YM_DELIVERY_DELIVERY")?></option>
                <option value="PICKUP"<?=$selected == "PICKUP" ? "selected" : ""?>><?=GetMessage("SALE_YM_DELIVERY_PICKUP")?></option>
                <option value="POST"<?=$selected == "POST" ? "selected" : ""?>><?=GetMessage("SALE_YM_DELIVERY_POST")?></option>
            </select>
        </td>
    </tr>
<?endforeach;?>

С настройками все, осталось доработать скрипт на который приходят запросы с Яндекс.Маркета, он и говорит маркету, какие доставки показать покупателю при оформлении заказа на Яндекс.Маркете.

Запросы Яндекс.Маркет

Все запросы с Яндекс.Маркета в Битрикc приходят сначала в этот файл, в нем только подключение другого файла
/bitrix/services/ymarket/index.php

В том файле подключается само API Битрикс для взаимодействия Яндекс.Маркета с вашим интернет-магазином
/bitrix/modules/sale/services/ymarket/index.php

В этом файле интересует метод, который идет дальше, к нужному нам файлу для изменений, в этом ничего не меняем
$result = $YMHandler->processRequest($requestObject, $method, $postData);

А вот и наш файл, в котором вся логика взаимодействия Битрикса с Яндекс.Маркетом, работает с ним
/bitrix/modules/sale/general/ym_handler.php


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

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

Итак, какие были изменения в классе CSaleYMHandler
1) Добавлена переменная, в которой будет храниться полная информация о товарах в корзине для расчета доставки автоматизированными службами доставки.
protected $basketItems = array();

2) Изменен метод, который слушает корзину на маркете, получает информацию о товарах (корзине) и возвращает службы доставки и способы оплаты
protected function processCartRequest($arPostData)

3) Изменен метод, который получает информацию о товарах в корзине на маркете (id, цена, количество, вес, габариты и т.д.)
protected function getItemCartInfo($arItem, $currency)

4) Изменен метод, который получает информацию о местоположении покупателя, доступные ему службы доставки по фильтру, считает доставку и показывает ее покупателю на маркете.
protected function getDeliveryOptions($delivery, $price, $weight = 0, $arBasketItems = array())

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

Обратите здесь внимание!

В моем случае магазин находится в Москве и для Москвы все автоматизированные службы доставки отключены, для покупателя из Москвы они показываться не должны, там Самовывоз и курьерская доставка работает, в коде это условие (стр. 432):
if($locationTo == 2691) continue;

Тут еще добавил к доставке почтой 7 дней, т.к. часто не получается получить клиентом заказ почтой в тот срок, который она возвращает (стр. 481)
$dopDays = 7;

5) Изменен метод, который добавляет на вашем сайте заказ, говорит маркету "Все ок" и возвращает его номер Яндекс.Маркету
protected function processOrderAcceptRequest($arPostData)

Конкретно строка 911, в ней получаем Номер заказа, это либо ID заказа, либо Код заказа при включенной нумерации заказа по шаблону
$arResult["order"]["id"] = $this->getOrderNumber($orderID);

6) Добавлен метод, который вернет на Яндекс.Маркет номер заказа на вашем сайте (ID заказа или Код-заказа)
protected function getOrderNumber($orderId)

Дополнительно

Еще на сайте загружены местоположения 2.0, делал я это в прошлом 2015 году, помню была проблема с Яндекс.Маркетом, неправильно Битрикс искал местоположения и Яндекс.Маркет сообщал об ошибке, вот где я это делал уже не помню, я добавил на всякий случай в архив файл ym_location.php  если найдете, сообщите пожалуйста, я дополню статью этим моментом.

Заключение

При оформлении заказа на Яндекс.Маркете покупатель будет видеть список доставок в таком виде, их возвращает ваш магазин.
#


Файлы используемые в статье, все разложено по папочкам, где найти какой файл будет несложно.
Имя *
Логин (мин. 3 символа)
E-mail *
*— обязательные для заполнения поля
Логин или e-mail
TUNING-SOFT.RU Разработка умных веб-сервисов