• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/order/builder/orderbuilder.php
  • Класс: BitrixSaleHelpersOrderBuilderOrderBuilder
  • Вызов: OrderBuilder::buildShipmentBasket
public function buildShipmentBasket(&$shipment, $shipmentBasket)
{
	/**@var BitrixSaleShipment $shipment */
	$result = new Result();
	$shippingItems = array();
	$idsFromForm = array();
	$basket = $this->order->getBasket();
	$shipmentItemCollection = $shipment->getShipmentItemCollection();
	$useStoreControl = Configuration::useStoreControl();

	if(is_array($shipmentBasket))
	{
		// PREPARE DATA FOR SET_FIELDS
		foreach ($shipmentBasket as $items)
		{
			$items['QUANTITY'] = floatval(str_replace(',', '.', $items['QUANTITY']));
			$items['AMOUNT'] = floatval(str_replace(',', '.', $items['AMOUNT']));

			$r = $this->prepareDataForSetFields($shipment, $items);
			if($r->isSuccess())
			{
				$items = $r->getData()[0];
			}
			else
			{
				$result->addErrors($r->getErrors());
				return $result;
			}

			if (isset($items['BASKET_ID']) && !BasketBuilder::isBasketItemNew($items['BASKET_ID']))
			{
				if (!$basketItem = $basket->getItemById($items['BASKET_ID']))
				{
					$result->addError( new Error(
							Loc::getMessage('SALE_ORDER_SHIPMENT_BASKET_BASKET_ITEM_NOT_FOUND',  array(
								'#BASKET_ITEM_ID#' => $items['BASKET_ID'],
							)),
							'PROVIDER_UNRESERVED_SHIPMENT_ITEM_WRONG_BASKET_ITEM')
					);
					return $result;
				}
				/** @var BitrixSaleBasketItem $basketItem */
				$basketCode = $basketItem->getBasketCode();
			}
			else
			{
				$basketCode = $items['BASKET_CODE'];
				if(!$basketItem = $basket->getItemByBasketCode($basketCode))
				{
					$result->addError( new Error(
							Loc::getMessage('SALE_ORDER_SHIPMENT_BASKET_BASKET_ITEM_NOT_FOUND',  array(
								'#BASKET_ITEM_ID#' => $basketCode,
							)),
							'PROVIDER_UNRESERVED_SHIPMENT_ITEM_WRONG_BASKET_ITEM')
					);
					return $result;
				}
			}

			$isSupportedMarkingCode = false;
			if (isset($items['IS_SUPPORTED_MARKING_CODE']))
			{
				$isSupportedMarkingCode = $items['IS_SUPPORTED_MARKING_CODE'] === 'Y';
			}

			$tmp = [
				'BASKET_CODE' => $basketCode,
				'AMOUNT' => $items['AMOUNT'] ?? 0,
				'ORDER_DELIVERY_BASKET_ID' => $items['ORDER_DELIVERY_BASKET_ID'] ?? 0,
				'IS_SUPPORTED_MARKING_CODE' => $isSupportedMarkingCode ? 'Y' : 'N',
			];
			if (array_key_exists('XML_ID', $items))
			{
				$tmp['XML_ID'] = $items['XML_ID'];
			}
			$idsFromForm[$basketCode] = array();

			if (
				isset($items['BARCODE_INFO'])
				&& $items['BARCODE_INFO']
				&& ($useStoreControl || $isSupportedMarkingCode)
			)
			{
				foreach ($items['BARCODE_INFO'] as $item)
				{
					if (!$basketItem->isReservableItem())
					{
						$shippingItems[] = $tmp;
						continue;
					}

					$barcodeQuantity = ($basketItem->isBarcodeMulti() || $basketItem->isSupportedMarkingCode()) ? 1 : $item['QUANTITY'];
					$barcodeStoreId = $item['STORE_ID'];

					$tmp['BARCODE'] = array(
						'ORDER_DELIVERY_BASKET_ID' => $items['ORDER_DELIVERY_BASKET_ID'] ?? 0,
						'STORE_ID' => $barcodeStoreId,
						'QUANTITY' => $barcodeQuantity,
					);

					$tmp['BARCODE_INFO'] = [
						$item['STORE_ID'] => [
							'STORE_ID' => (int)$barcodeStoreId,
							'QUANTITY' => (float)$barcodeQuantity,
						],
					];

					$barcodeCount = 0;
					if ($item['BARCODE'])
					{
						foreach ($item['BARCODE'] as $barcode)
						{
							$barcode['ID'] = (int)($barcode['ID'] ?? 0);

							$tmp['BARCODE_INFO'][$barcodeStoreId]['BARCODE'] = [$barcode];

							if (isset($barcode['MARKING_CODE']))
							{
								$barcode['MARKING_CODE'] = (string)$barcode['MARKING_CODE'];
							}
							else
							{
								$barcode['MARKING_CODE'] = '';
							}

							$idsFromForm[$basketCode]['BARCODE_IDS'][$barcode['ID']] = true;

							if ($barcode['ID'] > 0)
							{
								$tmp['BARCODE']['ID'] = $barcode['ID'];
							}
							else
							{
								unset($tmp['BARCODE']['ID']);
							}

							$tmp['BARCODE']['BARCODE'] = (string)$barcode['VALUE'];
							$tmp['BARCODE']['MARKING_CODE'] = $barcode['MARKING_CODE'];

							$shippingItems[] = $tmp;
							$barcodeCount++;
						}
					}
					elseif (!$basketItem->isBarcodeMulti() && !$basketItem->isSupportedMarkingCode())
					{
						$shippingItems[] = $tmp;
						continue;
					}


					if ($basketItem->isBarcodeMulti() || $basketItem->isSupportedMarkingCode())
					{
						while ($barcodeCount < $item['QUANTITY'])
						{
							unset($tmp['BARCODE']['ID']);
							$tmp['BARCODE']['BARCODE'] = '';
							$tmp['BARCODE']['MARKING_CODE'] = '';
							$shippingItems[] = $tmp;
							$barcodeCount++;
						}
					}
				}
			}
			else
			{
				$shippingItems[] = $tmp;
			}
		}
	}

	// DELETE FROM COLLECTION
	$r = $this->removeShipmentItems($shipment, $shipmentBasket, $idsFromForm);
	if(!$r->isSuccess())
		$result->addErrors($r->getErrors());

	$isStartField = $shipmentItemCollection->isStartField();

	// SET DATA
	foreach ($shippingItems as $shippingItem)
	{
		if ((int)$shippingItem['ORDER_DELIVERY_BASKET_ID'] <= 0)
		{
			$basketCode = $shippingItem['BASKET_CODE'];
			/** @var BitrixSaleOrder $this->order */
			$basketItem = $this->order->getBasket()->getItemByBasketCode($basketCode);

			/** @var BitrixSaleBasketItem $basketItem */
			$shipmentItem = $shipmentItemCollection->createItem($basketItem);

			if ($shipmentItem === null)
			{
				$result->addError(
					new Error(
						Loc::getMessage('SALE_ORDER_SHIPMENT_BASKET_ERROR_ALREADY_SHIPPED')
					)
				);
				return $result;
			}

			unset($shippingItem['BARCODE']['ORDER_DELIVERY_BASKET_ID']);
		}
		else
		{
			$shipmentItem = $shipmentItemCollection->getItemById($shippingItem['ORDER_DELIVERY_BASKET_ID']);

			if($shipmentItem)
			{
				$basketItem = $shipmentItem->getBasketItem();
			}
			else //It's a possible case when we are creating new shipment.
			{
				/** @var BitrixCrmOrderShipment $systemShipment */
				$systemShipment = $shipment->getCollection()->getSystemShipment();
				/** @var BitrixCrmOrderShipmentItemCollection $systemShipmentItemCollection */
				$systemShipmentItemCollection = $systemShipment->getShipmentItemCollection();

				$shipmentItem = $systemShipmentItemCollection->getItemById($shippingItem['ORDER_DELIVERY_BASKET_ID']);

				if($shipmentItem)
				{
					$basketItem = $shipmentItem->getBasketItem();
					$shipmentItem = $shipmentItemCollection->createItem($basketItem);
					$shipmentItem->setField('QUANTITY', $shipmentItem->getField('QUANTITY'));
				}
				else
				{
					$result->addError(
						new Error(
							Loc::getMessage('SALE_HLP_ORDERBUILDER_SHIPMENT_ITEM_ERROR',[
								'#ID#' => $shippingItem['ORDER_DELIVERY_BASKET_ID'],
							])
						)
					);

					continue;
				}
			}
		}

		if ($shippingItem['AMOUNT'] <= 0)
		{
			$result->addError(
				new Error(
					Loc::getMessage('SALE_ORDER_SHIPMENT_BASKET_ERROR_QUANTITY', array('#BASKET_ITEM#' => $basketItem->getField('NAME'))),
					'BASKET_ITEM_'.$basketItem->getBasketCode()
				)
			);
			continue;
		}

		$r = $this->modifyQuantityShipmentItem($shipmentItem, $shippingItem);
		if(!$r->isSuccess())
			$result->addErrors($r->getErrors());

		if (array_key_exists('XML_ID', $shippingItem))
		{
			$setFieldResult = $shipmentItem->setField('XML_ID', $shippingItem['XML_ID']);
			if (!$setFieldResult->isSuccess())
			{
				$result->addErrors($setFieldResult->getErrors());
			}
		}
	}

	if ($isStartField)
	{
		$hasMeaningfulFields = $shipmentItemCollection->hasMeaningfulField();

		/** @var Result $r */
		$r = $shipmentItemCollection->doFinalAction($hasMeaningfulFields);
		if (!$r->isSuccess())
		{
			$result->addErrors($r->getErrors());
		}
	}

	return $result;
}