PHP
#bitrix#catalog#quantity#stock#php#ccatalogProduct

Обновить остатки товара в каталоге и на складе

Обновление остатков товара через CCatalogProduct::Update с установкой количества на складе через CCatalogStoreProduct.

Как использовать

  1. Скопируйте нужный фрагмент кода.
  2. Вставьте в свой проект и при необходимости измените под задачу.
  3. Проверьте зависимости и окружение (версии, переменные).

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

use Bitrix\Main\Loader;

/**
 * Обновить общее количество товара в каталоге
 * @param int $productId ID товара
 * @param float $quantity Новое количество
 * @return bool Успешно ли обновлено
 */
function updateProductQuantity($productId, $quantity) {
    if (!Loader::includeModule('catalog')) {
        return false;
    }
    
    // Получаем текущие данные товара
    $product = CCatalogProduct::GetByID($productId);
    if (!$product) {
        return false;
    }
    
    $fields = [
        'QUANTITY' => $quantity,
        'QUANTITY_TRACE' => $product['QUANTITY_TRACE'] ?: 'Y',
        'CAN_BUY_ZERO' => $product['CAN_BUY_ZERO'] ?: 'N'
    ];
    
    return CCatalogProduct::Update($productId, $fields);
}

/**
 * Обновить количество товара на конкретном складе
 * @param int $productId ID товара
 * @param int $storeId ID склада
 * @param float $quantity Количество
 * @return bool Успешно ли обновлено
 */
function updateProductStoreQuantity($productId, $storeId, $quantity) {
    if (!Loader::includeModule('catalog')) {
        return false;
    }
    
    // Проверяем существование склада
    $store = CCatalogStore::GetByID($storeId);
    if (!$store) {
        return false;
    }
    
    // Получаем текущее количество на складе
    $storeProduct = CCatalogStoreProduct::GetList(
        [],
        [
            'PRODUCT_ID' => $productId,
            'STORE_ID' => $storeId
        ],
        false,
        false,
        ['ID', 'AMOUNT']
    )->Fetch();
    
    if ($storeProduct) {
        // Обновляем существующую запись
        return CCatalogStoreProduct::Update($storeProduct['ID'], [
            'AMOUNT' => $quantity
        ]);
    } else {
        // Создаём новую запись
        return CCatalogStoreProduct::Add([
            'PRODUCT_ID' => $productId,
            'STORE_ID' => $storeId,
            'AMOUNT' => $quantity
        ]);
    }
}

/**
 * Обновить остатки с пересчётом общего количества
 * @param int $productId ID товара
 * @param array $storeQuantities Массив ['STORE_ID' => quantity]
 * @return bool Успешно ли обновлено
 */
function updateProductQuantitiesByStores($productId, $storeQuantities) {
    if (!Loader::includeModule('catalog')) {
        return false;
    }
    
    $totalQuantity = 0;
    
    // Обновляем количество на каждом складе
    foreach ($storeQuantities as $storeId => $quantity) {
        if (updateProductStoreQuantity($productId, $storeId, $quantity)) {
            $totalQuantity += $quantity;
        }
    }
    
    // Обновляем общее количество в каталоге
    return updateProductQuantity($productId, $totalQuantity);
}

Usage:

// Обновить общее количество товара
updateProductQuantity(12345, 100);

// Обновить количество на конкретном складе
updateProductStoreQuantity(12345, 1, 50);

// Обновить остатки по всем складам с пересчётом
updateProductQuantitiesByStores(12345, [
    1 => 30,  // Склад ID=1, количество=30
    2 => 20,  // Склад ID=2, количество=20
    3 => 10   // Склад ID=3, количество=10
]);
// Общее количество станет 60

Notes:

⚠️ CCatalogStoreProduct работает только если включён модуль складского учёта. Для обновления общего количества используйте CCatalogProduct::Update(). При изменении остатков на складах рекомендуется пересчитывать общее количество товара. Модуль catalog должен быть подключен.