- Модуль: catalog
- Путь к файлу: ~/bitrix/modules/catalog/lib/product/catalogprovider.php
- Класс: BitrixCatalogProductCatalogProvider
- Вызов: CatalogProvider::reserveStoreQuantityWithEnabledReservation
static function reserveStoreQuantityWithEnabledReservation(array $productData): SaleResult
{
$result = new SaleResult();
$enableStoreControl = CatalogConfigState::isUsedInventoryManagement();
$resultFields = [];
$fields = []; // fields for update products
$storeFields = []; // rows for update reserve in store
$needShipList = [];
$productId = $productData['PRODUCT_ID'];
$storeProductQuantity = self::getStoreQuantityFromQuantityList($productData); // quantity with stores
// empty store can't updated if used inventory managment
if ($enableStoreControl && isset($storeProductQuantity[Base::EMPTY_STORE_ID]))
{
return $result;
}
$productQuantity = self::getTotalAmountFromQuantityList($productData);
$isNeedReserve = ($productQuantity > 0);
$catalogData = $productData['CATALOG'];
$catalogReservedQuantity = (float)$catalogData['QUANTITY_RESERVED'];
$catalogQuantity = self::getTotalAmountFromPriceList($catalogData);
$sumCatalogQuantity = $catalogQuantity + $catalogReservedQuantity;
if (isset($productData['NEED_SHIP']))
{
$needShipList = $productData['NEED_SHIP'];
}
$setQuantityReserved = $catalogReservedQuantity;
if (!empty($needShipList) && !empty($productData['SHIPMENT_ITEM_DATA_LIST']))
{
$shipmentItemList = $productData['SHIPMENT_ITEM_DATA_LIST'];
foreach ($needShipList as $shipmentItemIndex => $isNeedShip)
{
if ($setQuantityReserved <= 0)
{
$setQuantityReserved = 0;
break;
}
if ($isNeedShip === true)
{
$shipmentItemQuantity = $shipmentItemList[$shipmentItemIndex];
$setQuantityReserved -= $shipmentItemQuantity;
}
}
}
if ($catalogData["QUANTITY_TRACE"] == "N")
{
$fields["QUANTITY_RESERVED"] = $setQuantityReserved;
$resultFields['IS_UPDATED'] = true;
$resultFields['QUANTITY_RESERVED'] = 0;
}
else
{
$resultFields['QUANTITY_RESERVED'] = $catalogReservedQuantity;
if (
$productData['PRODUCT']['TYPE'] === CatalogProductTable::TYPE_PRODUCT
|| $productData['PRODUCT']['TYPE'] === CatalogProductTable::TYPE_OFFER
)
{
$storeFields = $enableStoreControl
? self::loadCurrentStoreReserve($productId, $storeProductQuantity)
: [];
}
if ($isNeedReserve)
{
if ($catalogData["CAN_BUY_ZERO"] == "Y")
{
$fields["QUANTITY_RESERVED"] = $catalogReservedQuantity + $productQuantity;
$fields['QUANTITY'] = $catalogQuantity - $productQuantity;
}
else
{
if ($catalogQuantity >= $productQuantity)
{
$fields["QUANTITY"] = $catalogQuantity - $productQuantity;
$fields["QUANTITY_RESERVED"] = $catalogReservedQuantity + $productQuantity;
}
else
{
$resultFields["QUANTITY_NOT_RESERVED"] = $productQuantity - $catalogQuantity;
$fields["QUANTITY"] = 0;
$fields["QUANTITY_RESERVED"] = $sumCatalogQuantity;
$result->addWarning(
new SaleResultWarning(
MainLocalizationLoc::getMessage(
"RSRV_QUANTITY_NOT_ENOUGH_ERROR",
self::getProductCatalogInfo($productId)
), "ERROR_NOT_ENOUGH_QUANTITY"
)
);
}
}
}
else //undo reservation
{
$correctReserve = 0;
if ($enableStoreControl)
{
foreach (array_keys($storeFields) as $storeId)
{
if ($storeFields[$storeId]['ID'] === null)
{
continue;
}
$storeProductFields = $storeFields[$storeId];
$newReserve = $storeProductFields['QUANTITY_RESERVED'] + $storeProductFields['ADD_QUANTITY_RESERVED'];
if ($newReserve < 0)
{
$correctReserve -= $newReserve;
$storeFields[$storeId]['ADD_QUANTITY_RESERVED'] -= $newReserve;
}
}
}
$needQuantity = abs($productQuantity) - $correctReserve;
$fields["QUANTITY"] = $catalogQuantity + $needQuantity;
$needReservedQuantity = $catalogReservedQuantity - $needQuantity;
if ($needQuantity > $catalogReservedQuantity)
{
$needReservedQuantity = $catalogReservedQuantity;
}
$fields["QUANTITY_RESERVED"] = $needReservedQuantity;
if ($enableStoreControl)
{
foreach (array_keys($storeFields) as $storeId)
{
if ($storeFields[$storeId]['ID'] === null)
{
unset($storeFields[$storeId]);
}
}
}
}
} //quantity trace
if (!$productData['PRODUCT']['USED_RESERVATION'])
{
if (isset($fields['QUANTITY_RESERVED']))
{
unset($fields['QUANTITY_RESERVED']);
}
}
if (!empty($fields) && is_array($fields))
{
$storeSuccess = true;
if ($enableStoreControl)
{
foreach (array_keys($storeFields) as $index)
{
if ($index === Base::EMPTY_STORE_ID)
{
$storeSuccess = false;
}
else
{
$storeProductFields = $storeFields[$index];
$id = $storeProductFields['ID'];
$storeProductFields['QUANTITY_RESERVED'] += $storeProductFields['ADD_QUANTITY_RESERVED'];
unset($storeProductFields['ID'], $storeProductFields['ADD_QUANTITY_RESERVED']);
if ($id === null)
{
$storeProductFields['AMOUNT'] = 0;
$internalResult = CatalogStoreProductTable::add($storeProductFields);
}
else
{
unset($storeProductFields['STORE_ID'], $storeProductFields['PRODUCT_ID']);
$internalResult = CatalogStoreProductTable::update($id, $storeProductFields);
}
if ($internalResult->isSuccess())
{
$storeFields[$index]['ID'] = (int)$internalResult->getId();
}
else
{
$storeFields[$index]['ERROR'] = true;
$storeFields[$index]['ERROR_MESSAGES'] = $internalResult->getErrorMessages();
$storeSuccess = false;
}
}
if (!$storeSuccess)
{
break;
}
}
}
if (!$storeSuccess)
{
return $result;
}
$resultFields['IS_UPDATED'] = false;
$internalResult = CatalogModelProduct::update($productId, $fields);
if ($internalResult->isSuccess())
{
$resultFields['IS_UPDATED'] = true;
$quantityValues = array();
if (isset($fields['QUANTITY']))
{
$quantityValues[QuantityControl::QUANTITY] = $fields['QUANTITY'];
QuantityControl::resetAvailableQuantity($productId);
}
if (isset($fields['QUANTITY_RESERVED']))
{
$quantityValues[QuantityControl::RESERVED_QUANTITY] = $fields['QUANTITY_RESERVED'];
}
if (!empty($quantityValues))
{
QuantityControl::setValues($productId, $quantityValues);
}
}
else
{
self::convertErrors($internalResult);
}
unset($internalResult);
}
if (isset($resultFields['IS_UPDATED']))
{
if (isset($fields['QUANTITY_RESERVED']))
{
$needReserved = $fields["QUANTITY_RESERVED"] - $resultFields['QUANTITY_RESERVED'];
if ($resultFields['QUANTITY_RESERVED'] > $fields["QUANTITY_RESERVED"])
{
$needReserved = $fields["QUANTITY_RESERVED"];
}
$resultFields["QUANTITY_RESERVED"] = $needReserved;
}
if (!empty($resultFields))
{
$result->setData($resultFields);
}
}
return $result;
}