• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/internals/catalog/provider.php
  • Класс: BitrixSaleInternalsCatalogProvider
  • Вызов: Provider::tryReserveShipmentItemArray
static function tryReserveShipmentItemArray(array $shipmentItemList, array $context)
{
	$result = new SaleResult();

	/** @var SaleShipmentItem $shipmentItem */
	$shipmentItem = current($shipmentItemList);
	if (!$shipmentItem)
	{
		return $result;
	}

	$availableQuantityList = [];

	$needQuantityList = self::getNeedQuantityByShipmentItemList($shipmentItemList);
	if (!$needQuantityList)
	{
		return $result;
	}

	$creator = SaleInternalsProviderCreator::create($context);
	/** @var SaleShipmentItem $shipmentItem */
	foreach ($shipmentItemList as $shipmentItem)
	{
		$productData = $creator->createItemForReserveByShipmentItem($shipmentItem);
		$creator->addProductData($productData);
	}

	$r = $creator->getAvailableQuantityByStore();
	if ($r->isSuccess())
	{
		$data = $r->getData();
		if (array_key_exists('AVAILABLE_QUANTITY_LIST_BY_STORE', $data))
		{
			$availableQuantityList = $data['AVAILABLE_QUANTITY_LIST_BY_STORE'];
		}
	}
	else
	{
		$result->addErrors($r->getErrors());
	}

	if ($r->hasWarnings())
	{
		$result->addWarnings($r->getWarnings());
	}

	if (!$result->isSuccess())
	{
		return $result;
	}

	$applyItemsList = [];

	$pool = PoolQuantity::getInstance($shipmentItem->getCollection()->getShipment()->getOrder()->getInternalId());

	foreach ($availableQuantityList as $providerName => $productAvailableQuantityList)
	{
		$providerName = trim($providerName);
		foreach ($productAvailableQuantityList as $productId => $quantityByStore)
		{
			if (array_key_exists($productId, $needQuantityList[$providerName]))
			{
				if (SaleConfiguration::getProductReservationCondition() !== SaleReservationConfigurationReserveCondition::ON_SHIP)
				{
					if (!isset($applyItemsList[$providerName][$productId]))
					{
						$applyItemsList[$providerName][$productId] = [];
					}

					foreach ($quantityByStore as $storeId => $quantity)
					{
						if ($quantity < $needQuantityList[$providerName][$productId][$storeId])
						{
							$poolQuantity = (float)$pool->getByStore(
								PoolQuantity::POOL_QUANTITY_TYPE,
								$productId,
								$storeId
							);

							$delta = $needQuantityList[$providerName][$productId][$storeId] - $quantity;

							if ($delta < $poolQuantity)
							{
								$applyItemsList[$providerName][$productId][$storeId] = $needQuantityList[$providerName][$productId][$storeId];
							}
							elseif ($poolQuantity > 0)
							{
								$applyItemsList[$providerName][$productId][$storeId] = $quantity + $poolQuantity;
							}
							else
							{
								$applyItemsList[$providerName][$productId][$storeId] = $quantity;
							}
						}
						else
						{
							$applyItemsList[$providerName][$productId][$storeId] = $quantity;
						}
					}
				}
			}
			else
			{
				/** @var SaleShipmentItem $shipmentItem */
				foreach ($shipmentItemList as $shipmentItem)
				{
					$basketItem = $shipmentItem->getBasketItem();

					if ($basketItem->getProductId() === $productId)
					{
						$result->addWarning(
							new SaleResultWarning(
								MainLocalizationLoc::getMessage(
									'SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY',
									['#PRODUCT_NAME#' => $basketItem->getField('NAME')]
								),
								'SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY'
							)
						);

						break;
					}
				}
			}
		}
	}

	if (!empty($applyItemsList))
	{
		$shipmentItemMap = self::createProductShipmentItemMap($shipmentItemList);

		self::setQuantityAfterReserve($shipmentItemMap, $applyItemsList);
	}

	return $result;
}