В модуле старого интернет-магазине всё было гораздо проще. С новым пришлось попыхтеть.

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

Код

//<?php
 
// ID delivery
$deliveryId = 5;
 
$languageId = LANGUAGE_ID;
 
$locationsDeliveryIds = [];
 
\Bitrix\Main\Loader::includeModule('sale');
 
$deliveryLocationIterator = \Bitrix\Sale\Delivery\DeliveryLocationTable::getList([
    'select' => [
        '*',
        'LOCATION_ID' => 'LOCATION.ID',
        'LOCATION_GROUP_ID' => 'GROUP.ID',
        'LOCATION_GROUP_LOCATION_ID' => 'LOCATION_GROUP.LOCATION_ID',
    ],
    'filter' => [
        '=DELIVERY_ID' => $deliveryId,
    ],
    'runtime' => [
        'LOCATION_GROUP' => [
            'data_type' => '\Bitrix\Sale\Location\GroupLocationTable',
            'reference' => [
                '=this.LOCATION_GROUP_ID' => 'ref.LOCATION_GROUP_ID',
            ],
            'join_type' => 'left'
        ],
    ]
]);
 
while ($deliveryLocation = $deliveryLocationIterator->fetch()) {
 
    $locationId = null;
 
    if (
        isset($deliveryLocation['LOCATION_GROUP_ID'])
        && $deliveryLocation['LOCATION_GROUP_ID'] > 0
    ) {
 
        if ($deliveryLocation['LOCATION_GROUP_LOCATION_ID'] <= 0) {
            continue;
        }
 
        $locationId = $deliveryLocation['LOCATION_GROUP_LOCATION_ID'];
    } else if (
        isset($deliveryLocation['LOCATION_ID'])
        && $deliveryLocation['LOCATION_ID'] > 0
    ) {
        $locationId = $deliveryLocation['LOCATION_ID'];
    }
 
    if (!isset($locationId)) {
        continue;
    }
 
    $locationsDeliveryIds[] = $locationId;
 
    $childrenIterator = \Bitrix\Sale\Location\LocationTable::getChildren($locationId, [
        'select' => [
            'ID',
            'CODE',
            'NAME.NAME',
            'PARENT.NAME.NAME',
        ],
        'filter' => [
            '=NAME.LANGUAGE_ID' => $languageId,
            '=PARENT.NAME.LANGUAGE_ID' => $languageId,
        ]
    ]);
 
    foreach ($childrenIterator->fetchAll() as $location) {
        $locationsDeliveryIds[] = $location['ID'];
    }
 
}
 
$locationsDeliveryIds = array_unique($locationsDeliveryIds);
 
echo '<pre>';
print_r($locationsDeliveryIds);
echo '</pre>';

Алгоритм такой:

  • выбираем из таблицы связей b_sale_delivery2location связи
  • если связь - группа, то получаем её детей методом \Bitrix\Sale\Location\LocationTable::getChildren()
  • если связь - местоположение, то так же получаем её детей методом \Bitrix\Sale\Location\LocationTable::getChildren()

В итоге, в переменной $locationsDeliveryIds будет массив ID местоположений.

Есть ещё вот такой метод API получения местоположений доставки:

$locationIterator = \Bitrix\Sale\Delivery\DeliveryLocationTable::getConnectedLocations(
    $deliveryLocation['DELIVERY_ID'],
    array(
        'select' => [
            'LNAME' => 'NAME.NAME',
            'ID',
            'CODE',
        ],
        'filter' => [
            'NAME.LANGUAGE_ID' => $languageId,
        ],
    )
);
 
foreach ($locationIterator->fetchAll() as $location) {
    $locationsDeliveryIds[] = $location['ID'];
}

Но он, увы, не работает с группами местоположений.