• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/providerbase.php
  • Класс: BitrixSaleProviderBase
  • Вызов: ProviderBase::tryShipment
static function tryShipment(Shipment $shipment)
{
	$result = new Result();
	$needShip = $shipment->needShip();
	if ($needShip === null)
		return $result;

	$resultList = array();
	$storeData = array();

	/** @var ShipmentItemCollection $shipmentItemCollection */
	$shipmentItemCollection = $shipment->getShipmentItemCollection();
	if (!$shipmentItemCollection)
	{
		throw new ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
	}

	/** @var Shipment $shipment */
	$shipment = $shipmentItemCollection->getShipment();
	if (!$shipment)
	{
		throw new ObjectNotFoundException('Entity "ShipmentCollection" not found');
	}

	/** @var ShipmentCollection $shipmentCollection */
	$shipmentCollection = $shipment->getCollection();
	if (!$shipmentCollection)
	{
		throw new ObjectNotFoundException('Entity "ShipmentCollection" not found');
	}

	$r = static::tryShipmentItemList($shipmentItemCollection);

	$basketList = static::getBasketFromShipmentItemCollection($shipmentItemCollection);

	$bundleIndexList = static::getBundleIndexFromShipmentItemCollection($shipmentItemCollection);

	$basketCountList = static::getBasketCountFromShipmentItemCollection($shipmentItemCollection);

	$basketProviderMap = static::createProviderBasketMap($basketList, array('RESERVED', 'SITE_ID'));
	$basketProviderList = static::redistributeToProviders($basketProviderMap);

	if (Configuration::useStoreControl())
	{
		/** @var Result $r */
		$r = static::getStoreDataFromShipmentItemCollection($shipmentItemCollection);
		if ($r->isSuccess())
		{
			$resultStoreData = $r->getData();
			if (!empty($resultStoreData['STORE_DATA_LIST']))
			{
				$storeDataList = $resultStoreData['STORE_DATA_LIST'];
			}
		}
		else
		{
			$result->addErrors($r->getErrors());
		}

	}

	if (!empty($basketProviderList))
	{
		foreach ($basketProviderList as $provider => $providerBasketItemList)
		{
			if ($provider && array_key_exists("IBXSaleProductProvider", class_implements($provider)))
			{
				foreach ($providerBasketItemList as $providerBasketItem)
				{
					if ($providerBasketItem['BASKET_ITEM']->isBundleParent())
					{
						continue;
					}

					$resultProduct = new Result();


					$quantity = 0;
					$basketStoreData = array();

					$basketCode = $providerBasketItem['BASKET_CODE'];

					/** @var BasketItem $basketItem */
					if (!$basketItem = $providerBasketItem['BASKET_ITEM'])
					{
						throw new ObjectNotFoundException('Entity "BasketItem" not found');
					}

					if (Configuration::useStoreControl())
					{
						$quantity = $basketCountList[$basketCode];

						if (!empty($storeDataList) && is_array($storeDataList)
						&& isset($storeDataList[$basketCode]))
						{
							$basketStoreData = $storeDataList[$basketCode];
						}

						if (!empty($basketStoreData))
						{
							$allBarcodeQuantity = 0;
							foreach($basketStoreData as $basketShipmentItemStore)
							{
								$allBarcodeQuantity += $basketShipmentItemStore['QUANTITY'];
							}

							if ($quantity > $allBarcodeQuantity)
							{
								$resultProduct->addError(new ResultError(Loc::getMessage('SALE_PROVIDER_SHIPMENT_SHIPPED_LESS_QUANTITY', array(
									'#PRODUCT_NAME#' => $basketItem->getField('NAME')
								)), 'SALE_PROVIDER_SHIPMENT_SHIPPED_LESS_QUANTITY'));
							}
							elseif ($quantity < $allBarcodeQuantity)
							{
								$resultProduct->addError(new ResultError(Loc::getMessage('SALE_PROVIDER_SHIPMENT_SHIPPED_MORE_QUANTITY', array(
									'#PRODUCT_NAME#' => $basketItem->getField('NAME')
								)), 'SALE_PROVIDER_SHIPMENT_SHIPPED_MORE_QUANTITY'));
							}
						}

					}

					if ($resultProduct->isSuccess())
					{

						if ($needShip === true)
						{
							if (method_exists($provider, 'tryShipmentProduct'))
							{
								/** @var Result $resultProductData */
								$resultProduct = $provider::tryShipmentProduct($basketItem, $providerBasketItem['RESERVED'], $basketStoreData, $quantity);
							}
						}
						else
						{
							if (method_exists($provider, 'tryUnshipmentProduct'))
							{
								/** @var Result $resultProductData */
								$resultProduct = $provider::tryUnshipmentProduct($providerBasketItem['PRODUCT_ID']);
							}
						}
					}

					$resultList[$basketCode] = $resultProduct;

				}
			}
			elseif (class_exists($provider))
			{

				/** @var ShipmentCollection $shipmentCollection */
				if (!$shipmentCollection = $shipment->getCollection())
				{
					throw new ObjectNotFoundException('Entity "ShipmentCollection" not found');
				}

				/** @var Order $order */
				if (!$order = $shipmentCollection->getOrder())
				{
					throw new ObjectNotFoundException('Entity "Order" not found');
				}

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

				$context = array(
					'SITE_ID' => $order->getSiteId(),
					'CURRENCY' => $order->getCurrency(),
				);

				if ($order->getUserId() > 0)
				{
					$context['USER_ID'] = $order->getUserId();
				}
				else
				{
					global $USER;
					$context['USER_ID'] = $USER->getId();
				}

				$creator = InternalsProviderCreator::create($context);

				$tryShipProductList = array();
				/** @var ShipmentItem $shipmentItem */
				foreach ($shipmentItemCollection as $shipmentItem)
				{
					$basketItem = $shipmentItem->getBasketItem();
					$providerClass = $basketItem->getProviderEntity();

					if ($providerClass instanceof SaleProviderBase)
					{
						$shipmentProductData = $creator->createItemForShip($shipmentItem);
						$creator->addProductData($shipmentProductData);
					}
				}

				$r = $creator->tryShip();
				if ($r->isSuccess())
				{
					if ($r->hasWarnings())
					{
						$result->addWarnings($r->getWarnings());
					}
					else
					{
						$data = $r->getData();
						if (array_key_exists('TRY_SHIP_PRODUCTS_LIST', $data))
						{
							$tryShipProductList = $data['TRY_SHIP_PRODUCTS_LIST'] + $tryShipProductList;

							$creator->setItemsResultAfterTryShip($pool, $tryShipProductList);

						}
					}
				}
				else
				{
					$result->addWarnings($r->getErrors());
				}
			}
		}
	}

	if (!empty($resultList)
		&& !empty($bundleIndexList) && is_array($bundleIndexList))
	{

		foreach ($bundleIndexList as $bundleParentBasketCode => $bundleChildList)
		{
//				$tryShipmentBundle = false;
			foreach($bundleChildList as $bundleChildBasketCode)
			{
				if (!isset($resultList[$bundleChildBasketCode]))
				{
					if (!isset($resultList[$bundleParentBasketCode]))
					{
						$resultList[$bundleParentBasketCode] = new Result();
					}

					$resultList[$bundleParentBasketCode]->addError(new ResultError('Bundle child item not found', 'SALE_PROVIDER_SHIPMENT_SHIPPED_BUNDLE_CHILD_ITEM_NOT_FOUND'));
				}

			}
		}

	}

	if (!empty($resultList))
	{
		/** @var ShipmentCollection $shipmentCollection */
		if (!$shipmentCollection = $shipment->getCollection())
		{
			throw new ObjectNotFoundException('Entity "ShipmentCollection" not found');
		}

		/** @var Order $order */
		if (!$order = $shipmentCollection->getOrder())
		{
			throw new ObjectNotFoundException('Entity "Order" not found');
		}

		$hasErrors = false;

		/** @var ShipmentItem $shipmentItem */
		foreach ($shipmentItemCollection as $shipmentItem)
		{
			/** @var BasketItem $basketItem */
			if(!$basketItem = $shipmentItem->getBasketItem())
			{
				throw new ObjectNotFoundException('Entity "BasketItem" not found');
			}

			if (isset($resultList[$basketItem->getBasketCode()]) && !$resultList[$basketItem->getBasketCode()]->isSuccess())
			{
				$hasErrors = true;
				break;
			}
		}

		if (!$hasErrors)
		{
			/** @var ShipmentItem $shipmentItem */
			foreach ($shipmentItemCollection as $shipmentItem)
			{
				/** @var BasketItem $basketItem */
				if(!$basketItem = $shipmentItem->getBasketItem())
				{
					throw new ObjectNotFoundException('Entity "BasketItem" not found');
				}

				if (isset($resultList[$basketItem->getBasketCode()]) && $resultList[$basketItem->getBasketCode()]->isSuccess())
				{
					static::addQuantityPoolItem($order->getInternalId(), $basketItem, ($needShip? -1 : 1) * $shipmentItem->getQuantity());

					if ($needShip)
						$shipmentItem->setFieldNoDemand("RESERVED_QUANTITY", 0);

				}
			}
		}

		$result->setData($resultList);
	}

	return $result;
}