• Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/lib/Service/Sale/Reservation/ShipmentService.php
  • Класс: Bitrix\Crm\Service\Sale\Reservation\ShipmentService
  • Вызов: ShipmentService::reserveCanceledShipment
public function reserveCanceledShipment(Shipment $shipment): Result
{
	$result = new Result();

	$order = $shipment->getOrder();
	if (!$order)
	{
		$result->addError(
			new Error('Shipment without order cannot processed.')
		);
		return $result;
	}

	$result = $this->getShipmentOwner($shipment);
	if (!$result->isSuccess())
	{
		return $result;
	}
	[$entityTypeId, $entityId] = $result->getData();

	// only for deal sync
	if ($entityTypeId !== CCrmOwnerType::Deal)
	{
		return $result;
	}

	$basketItems = [];
	foreach ($shipment->getShipmentItemCollection() as $item)
	{
		/**
		 * @var ShipmentItem $item
		 */

		$basketItem = $item->getBasketItem();
		if ($basketItem)
		{
			$basketItems[$basketItem->getId()] = $basketItem;
		}
	}

	$shippedBasketItemsIds = array_keys($basketItems);
	if (empty($shippedBasketItemsIds))
	{
		return $result;
	}

	$productRow2basket = $this->basketService->getRowIdsToBasketIdsByEntity(
		$entityTypeId,
		$entityId
	);
	if (empty($productRow2basket))
	{
		return $result;
	}
	$productRow2basket = array_filter($productRow2basket, fn($basketId) => in_array($basketId, $shippedBasketItemsIds, true));
	$shippedQuantities = $this->shipmentProductService->getShippedQuantityByRowBasketMap($productRow2basket);

	$rowReserves = ProductRowReservationTable::getList([
		'select' => [
			'ID',
			'ROW_ID',
			'STORE_ID',
			'DATE_RESERVE_END',
			'RESERVE_QUANTITY',
		],
		'filter' => [
			'=ROW_ID' => array_keys($productRow2basket),
		],
	]);
	$rowReserves = array_column($rowReserves->fetchAll(), null, 'ROW_ID');

	$reservationResult = new ReservationResult();
	foreach ($productRow2basket as $rowId => $basketId)
	{
		$rowReserve = $rowReserves[$rowId] ?? null;
		if (!isset($rowReserve))
		{
			continue;
		}

		/**
		 * @var BasketItem $basketItem
		 */
		$basketItem = $basketItems[$basketId] ?? null;
		if (!$basketItem || !$basketItem->isReservableItem())
		{
			continue;
		}

		$crmReserveQuantity = (float)$rowReserve['RESERVE_QUANTITY'];
		if (empty($crmReserveQuantity))
		{
			continue;
		}

		$basketReserveQuantity = (float)$basketItem->getReservedQuantity();
		$shippedQuantity = (float)($shippedQuantities[$rowId] ?? 0.0);

		$currentQuantity = $crmReserveQuantity;
		$deltaQuantity = $crmReserveQuantity - $basketReserveQuantity - $shippedQuantity;
		if ($deltaQuantity <= 0.0)
		{
			continue;
		}

		$reserveInfo = $reservationResult->addReserveInfo(
			$rowId,
			$currentQuantity,
			$deltaQuantity
		);

		if (isset($rowReserve['STORE_ID']))
		{
			$reserveInfo->setStoreId((int)$rowReserve['STORE_ID']);
		}

		if (isset($rowReserve['DATE_RESERVE_END']))
		{
			$reserveInfo->setDateReserveEnd((string)$rowReserve['DATE_RESERVE_END']);
		}
	}

	if (!empty($reservationResult->getChangedReserveInfos()))
	{
		$synchronizer = new OrderDealSynchronizer(true);
		$synchronizer->syncOrderReservesFromDeal($entityId, $reservationResult);
	}

	return $result;
}