Не дать купить товара больше, чем находится на определенных складах

Просмотров: 141

Задача: в магазине 20 складов, на всех есть остатки но нужно ограничить покупку товара только остатками на двух складах, не меняя параметр "Доступное количество" и не включая складской учет.

находится на определенных складах

Получить остаток товара на определенных складах API Битрикс

Для начала ограничим ввод количества товара в карточке товара. Для этого в result_modifier.php шаблона добавляем:

$arResult['HAS_QANTITY'] = 0;
$storeRes = CCatalogStoreProduct::GetList(
    false,
    array(
        "PRODUCT_ID" => $arResult['ID'],
        'STORE_ID' => array(
            6,
            13
        )
    ),
    false,
    false,
    array(
        "AMOUNT"
    )
);
while ($arStoreParam = $storeRes->Fetch()) {
    $arResult['HAS_QANTITY'] += (int)$arStoreParam['AMOUNT'];
}

Создали ключ $arResult['HAS_QANTITY'] с нулевым значением и с помощью метода CCatalogStoreProduct::GetList получили количество товара на складах с ID 6 и 13 и суммировали его в $arResult['HAS_QANTITY']

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

<?if ($arResult['HAS_QANTITY'] > 0) { ?>
     <input type="number" max="<?=$arResult['HAS_QANTITY']?>">
     <button>в корзину</button>
<? } else {?>
     Нет в наличии
<?}?>

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

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

В result_modifier.php корзины добавляем:

foreach ($arResult['BASKET_ITEM_RENDER_DATA'] as $item) {
    $itemCanBye = 0;
    $storeRes = CCatalogStoreProduct::GetList(
        false,
        array(
            "PRODUCT_ID" => $item['PRODUCT_ID'],
            'STORE_ID' => array(6, 13)
        ),
        false, false,
        array("AMOUNT")
    );
    while ($arStoreParam = $storeRes->Fetch()) {
        $itemCanBye += $arStoreParam['AMOUNT'];
    }
    if ($item['QUANTITY'] > $itemCanBye) {
        $arFields = array(
            "QUANTITY" => $itemCanBye,
        );
        $ID = CSaleBasket::Update(
                $item['ID'],
                $arFields
        );
    }
}

Тем же методом CCatalogStoreProduct::GetList получаем остатки каждого товара, находящегося в корзине, на определенных складах.

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

Меняем AVAILABLE_QUANTITY в корзине

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

В mutator.php шаблона корзины, в обходе цикла каждого товара, добавляем (обязательно до формирования массива $rowData):

$row['AVAILABLE_QUANTITY'] = 0;
$storeRes = CCatalogStoreProduct::GetList(
    array(
        "SORT" => "ASC"
    ),
    array(
        "PRODUCT_ID" => $row['PRODUCT_ID'],
        'STORE_ID' => array(
            6,
            13
        )
    ),
    false,
    false,
    array(
        "AMOUNT"
    )
);
while ($arStoreParam = $storeRes->Fetch()) {
    $row['AVAILABLE_QUANTITY'] += (int)$arStoreParam['AMOUNT'];
}

Теперь не получится увеличить количество каждого товара больше чем есть на остатках складов 6 и 12.

Михаил Базаров 28.09.2024
Аналог CCatalogStoreProduct::GetList на D7 это \Bitrix\Catalog\StoreProductTable
Код
use Bitrix\Catalog\StoreProductTable;
use Bitrix\Main\Entity\Query;

// ID товара и ID складов
$productId = $arResult['ID'];
$storeIds = [6, 13];

// Инициализация результата
$arResult['HAS_QUANTITY'] = 0;

// Выполняем запрос с использованием ORM
$storeRes = StoreProductTable::getList([
    'filter' => [
        'PRODUCT_ID' => $productId,
        'STORE_ID' => $storeIds,
    ],
    'select' => ['AMOUNT'],
]);

// Обрабатываем результат
while ($arStoreParam = $storeRes->fetch()) {
    $arResult['HAS_QUANTITY'] += (int)$arStoreParam['AMOUNT'];
}

Блог-note: заметки разработчика

Установка вебсервера на Apple Silicon (нативный ARM стек), оптимизированный для 1С-Битрикс.

Появилась задачка, установить стек MAMP (macOS, Apache, MYSQL, PHP) на рабочий ноутбук с процессором Apple Silicon M1. В...

Смена вида карточек товаров в catalog.section с иммитацией AJAX

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

Глобальные фильтры на всякие случаи жизни

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

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

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

Установка поиска Sphinx на Ubuntu 22.04 для 1С-Битрикс

Задача: установить и сконфигурировать поиск Sphinx под управлением Ubuntu 22.04 и панели управления HestiaCP для использ...

Настройка обмена между 1С:Предприятие и магазином на "1С-Битрикс24: Интернет-магазин + CRM" по REST протоколу

В этой заметке расскажу как настроить синхронизацию между 1С:предприятие и "1С-Битрикс24: Интернет-магазин + CR...

Создание раздела инфоблока при регистрации пользователя в Битрикс

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

CAPTCHA с возможностью обновления без перезагрузки страницы в 1C-Битрикс

Задача: Так как стандартная капча в 1С-Битрикс, может отобразиться не удачно (символы уходят за грань капчи или не у...

Прятать или показывать описание раздела каталога

В новых компонентах и шаблонах catalog.section есть не документированный и не выводимый параметр: "Скрывать описание раз...