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

	/** @var SaleOrder $order */
	$order = $shipment->getOrder();

	$pool = PoolQuantity::getInstance($order->getInternalId());

	/** @var SaleShipmentItem $shipmentItem */
	foreach ($shipment->getShipmentItemCollection() as $shipmentItem)
	{
		/** @var SaleBasketItem $basketItem */
		if (!$basketItem = $shipmentItem->getBasketItem())
		{
			continue;
		}

		if ((int)$shipmentItem->getReservedQuantity() === 0)
		{
			continue;
		}

		$shipmentItemReserveQuantity = $shipmentItem->getReservedQuantity();

		/** @var SaleReserveQuantityCollection $reserveCollection */
		$reserveCollection = $basketItem->getReserveQuantityCollection();
		if (!$reserveCollection)
		{
			continue;
		}

		/** @var SaleShipmentItemStoreCollection $shipmentItemStoreCollection */
		$shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection();
		if ($shipmentItemStoreCollection)
		{
			/** @var SaleShipmentItemStore $itemStore */
			foreach ($shipmentItemStoreCollection as $itemStore)
			{
				if ($shipmentItemReserveQuantity == 0)
				{
					break;
				}

				/** @var SaleReserveQuantity $reserve */
				foreach ($reserveCollection as $reserve)
				{
					if ($reserve->getStoreId() !== $itemStore->getStoreId())
					{
						continue;
					}

					// try to guess reserved quantity on shipment item store
					if ($shipmentItemReserveQuantity > $itemStore->getQuantity())
					{
						$reserveStoreQuantity =  $itemStore->getQuantity();
					}
					else
					{
						$reserveStoreQuantity =  $shipmentItemReserveQuantity;
					}

					if ($reserveStoreQuantity >= $reserve->getQuantity())
					{
						$poolQuantity = $reserve->getQuantity();

						$reserve->deleteNoDemand();
					}
					else
					{
						$poolQuantity = $reserveStoreQuantity;

						$reserve->setFieldNoDemand('QUANTITY', $reserve->getQuantity() - $reserveStoreQuantity);
					}

					$shipmentItemReserveQuantity -= $reserveStoreQuantity;
					$pool->addByStore(
						PoolQuantity::POOL_RESERVE_TYPE,
						$basketItem->getProductId(),
						$itemStore->getStoreId(),
						-$poolQuantity
					);
				}
			}
		}


		if ($shipmentItemReserveQuantity > 0)
		{
			$storeId = SaleConfiguration::getDefaultStoreId();

			foreach ($reserveCollection as $reserve)
			{
				if ($shipmentItemReserveQuantity == 0)
				{
					break;
				}

				if ($reserve->getStoreId() !== $storeId)
				{
					continue;
				}

				if ($shipmentItemReserveQuantity >= $reserve->getQuantity())
				{
					$poolQuantity = $reserve->getQuantity();
					$shipmentItemReserveQuantity -= $poolQuantity;

					$reserve->deleteNoDemand();
				}
				else
				{
					$reserve->setFieldNoDemand('QUANTITY', $reserve->getQuantity() - $shipmentItemReserveQuantity);
					$shipmentItemReserveQuantity = 0;

					$poolQuantity = $shipmentItemReserveQuantity;
				}

				$pool->addByStore(
					PoolQuantity::POOL_RESERVE_TYPE,
					$basketItem->getProductId(),
					$storeId,
					-$poolQuantity
				);
			}
		}

		$shipmentItem->getFields()->set('RESERVED_QUANTITY', 0);

		if (!SaleInternalsActionEntity::isTypeExists(
				$order->getInternalId(),
				SaleInternalsActionEntity::ACTION_ENTITY_SHIPMENT_COLLECTION_RESERVED_QUANTITY
			)
		)
		{
			SaleInternalsActionEntity::add(
				$order->getInternalId(),
				SaleInternalsActionEntity::ACTION_ENTITY_SHIPMENT_COLLECTION_RESERVED_QUANTITY,
				[
					'METHOD' => 'BitrixSaleShipment::updateReservedFlag',
					'PARAMS' => [$shipment],
				]
			);
		}

		$foundItem = false;
		$poolItems = SaleInternalsItemsPool::get($order->getInternalId(), $basketItem->getProductId());
		if (!empty($poolItems))
		{
			/** @var SaleShipment $poolItem */
			foreach ($poolItems as $poolItem)
			{
				if (
					$poolItem instanceof SaleShipmentItem
					&& $poolItem->getInternalIndex() == $shipmentItem->getInternalIndex()
				)
				{
					$foundItem = true;
					break;
				}
			}
		}

		if (!$foundItem)
		{
			SaleInternalsItemsPool::add($order->getInternalId(), $basketItem->getProductId(), $shipmentItem);
		}
	}

	return $result;
}