• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/admin/orderedit.php
  • Класс: BitrixSaleHelpersAdminOrderEdit
  • Вызов: OrderEdit::fillBasketItems
static function fillBasketItems(Basket &$basket, array $productsFormData, Order $order, array $needDataUpdate = array())
{
	$basketItems = $basket->getBasketItems();
	$result = new OrderEditResult();
	$catalogProductsIds = array();
	$trustData = array();

	// Preparing fields need by provider
	/** @var  BitrixSaleBasketItem  $item */
	foreach($basketItems as $item)
	{
		$basketCode = $item->getBasketCode();

		if(empty($productsFormData[$basketCode]))
			continue;

		$productData = $productsFormData[$basketCode];
		$isDataNeedUpdate = in_array($basketCode, $needDataUpdate);

		if(isset($productData["PRODUCT_PROVIDER_CLASS"]) && $productData["PRODUCT_PROVIDER_CLASS"] <> '')
		{
			$item->setField("PRODUCT_PROVIDER_CLASS", trim($productData["PRODUCT_PROVIDER_CLASS"]));
		}

		/*
		 * Let's extract cached provider product data from field
		 * in case activity is through ajax.
		 */
		if(self::$isTrustProductFormData && !$isDataNeedUpdate)
		{
			if(!empty($productData["PROVIDER_DATA"]) && CheckSerializedData($productData["PROVIDER_DATA"]))
				$trustData[$basketCode] = unserialize($productData["PROVIDER_DATA"], ['allowed_classes' => false]);

			// if quantity changed we must get fresh data from provider
			if(!empty($trustData[$basketCode]) && $trustData[$basketCode]["QUANTITY"] == $productData["QUANTITY"])
			{
				if(!empty($productData["SET_ITEMS_DATA"]) && CheckSerializedData($productData["SET_ITEMS_DATA"]))
					$productData["SET_ITEMS"] = unserialize($productData["SET_ITEMS_DATA"], ['allowed_classes' => false]);

				if(is_array($trustData[$basketCode]) && !empty($trustData[$basketCode]))
					self::setProviderTrustData($item, $order, $trustData[$basketCode]);
			}
			else
			{
				unset($trustData[$basketCode]);
			}
		}

		if (isset($productData['NAME']))
		{
			$item->setField('NAME', $productData['NAME']);
		}
		$res = $item->setField("QUANTITY", $productData["QUANTITY"]);

		if(!$res->isSuccess())
		{
			$result->addErrors($res->getErrors());
			$justAdded = isset($productsFormData[$basketCode]['JUST_ADDED']) && $productsFormData[$basketCode]['JUST_ADDED'] == 'Y';

			if($justAdded)
			{
				foreach($res->getErrors() as $error)
				{
					if($error->getCode() == 'SALE_BASKET_ITEM_WRONG_AVAILABLE_QUANTITY')
					{
						$result->setIsTerminal(true);
						return $result;
					}
				}
			}
		}

		if(isset($productData["MODULE"]) && $productData["MODULE"] == "catalog")
		{
			$catalogProductsIds[] = $item->getField('PRODUCT_ID');
		}
		elseif(empty($productData["PRODUCT_PROVIDER_CLASS"]))
		{
			$availableFields = BasketItemBase::getAvailableFields();
			$availableFields = array_fill_keys($availableFields, true);
			$fillFields = array_intersect_key($productData, $availableFields);
			if (!empty($fillFields))
			{
				$r = $item->setFields($fillFields);
			}
		}
	}

	$catalogData = array();

	if(!empty($catalogProductsIds))
		$catalogData = 	OrderBasket::getProductsData($catalogProductsIds, $order->getSiteId(), array(), $order->getUserId());

	$providerData = array();

	if(!self::$isTrustProductFormData || !empty($needDataUpdate) || self::$needUpdateNewProductPrice)
	{
		$params = array("AVAILABLE_QUANTITY");

		if($order->getId() <= 0)
			$params[] = "PRICE";

		$providerData = Provider::getProductData($basket, $params);

		/*
		foreach($basketItems as $item)
		{
			$basketCode = $item->getBasketCode();

			if($order->getId() <= 0 && !empty($providerData[$basketCode]) && empty($providerData[$basketCode]['QUANTITY']))
			{
				$result->addError(
					new Error(
						Loc::getMessage(
							"SALE_ORDEREDIT_PRODUCT_QUANTITY_IS_EMPTY",
							array(
								"#NAME#" => $item->getField('NAME')
							)
						),
						'SALE_ORDEREDIT_PRODUCT_QUANTITY_IS_EMPTY'
					)
				);
			}
		}
		*/

	}

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

	$data = array();

	foreach($basketItems as $item)
	{
		$basketCode = $item->getBasketCode();
		$productData = $productsFormData[$basketCode];
		if (!$productData)
		{
			continue;
		}

		$isDataNeedUpdate = in_array($basketCode, $needDataUpdate);
		$data[$basketCode] = $item->getFieldValues();

		if(!empty($providerData[$basketCode]))
		{
			if (static::$isRefreshData === true)
			{
				unset($providerData[$basketCode]['QUANTITY']);
			}

			$data[$basketCode] = $providerData[$basketCode];
		}
		elseif(!empty($trustData[$basketCode]))
		{
			$data[$basketCode] = $trustData[$basketCode];
		}
		else
		{
			$data = Provider::getProductData($basket, array("PRICE", "AVAILABLE_QUANTITY"), $item);

			if(is_array($data[$basketCode]) && !empty($data[$basketCode]))
				self::setProviderTrustData($item, $order, $data[$basketCode]);
		}

		/* Get actual info from provider
		 *	cases:
		 *	 1) add new product to basket;
		 *	 2) saving operation;
		 * 	 3) changing quantity;
		 *   4) changing buyerId
		 */
		if($order->getId() <= 0 && (empty($data[$basketCode]) || !self::$isTrustProductFormData || $isDataNeedUpdate))
		{
			if(empty($providerData[$basketCode]) && $productData["PRODUCT_PROVIDER_CLASS"] <> '')
			{
				$name = "";

				if(!empty($productData["NAME"]))
					$name = $productData["NAME"];

				if(!empty($productData["PRODUCT_ID"]))
					$name .= " (".$productData['PRODUCT_ID'].")";

				$result->addError(
					new Error(
						Loc::getMessage(
							"SALE_ORDEREDIT_PRODUCT_IS_NOT_AVAILABLE",
							array(
								"#NAME_ID#" => $name
							)
						)
					)
				);

//					return $result;
			}
		}

		$product = array();

		if(isset($data[$basketCode]) && !empty($data[$basketCode]))
		{
			$product = $data[$basketCode];

			if(isset($productData['PRICE']) && isset($productData['CUSTOM_PRICE']) && $productData['CUSTOM_PRICE'] == 'Y')
				$product['PRICE'] = $productData['PRICE'];
			elseif(isset($product['BASE_PRICE']))
				$product['PRICE'] = $product['BASE_PRICE'] - $product['DISCOUNT_PRICE'];
		}

		if($item->getField("MODULE") == "catalog")
		{
			if(!empty($catalogData[$item->getProductId()]))
			{
				$product = array_merge($product, $catalogData[$item->getProductId()]);
				unset($productData["CURRENCY"]);
			}
		}

		if(!self::$isTrustProductFormData || $isDataNeedUpdate)
		{
			$product = array_merge($productData, $product);
		}
		else
		{
			$needUpdateItemPrice = self::$needUpdateNewProductPrice && self::isBasketItemNew($basketCode);
			$isPriceCustom = isset($productData['CUSTOM_PRICE']) && $productData['CUSTOM_PRICE'] == 'Y';

			if(($order->getId() <= 0 && !$isPriceCustom) || $needUpdateItemPrice)
				unset($productData['PRICE'], $productData['PRICE_BASE'], $productData['BASE_PRICE']);

			$product = array_merge($product, $productData);
		}

		if(isset($product["OFFER_ID"]) && intval($product["OFFER_ID"]) > 0)
			$product["PRODUCT_ID"] = $product["OFFER_ID"];

		$product = array_intersect_key($product, array_flip($item::getAvailableFields()));

		if(isset($product["MEASURE_CODE"]) && $product["MEASURE_CODE"] <> '')
		{
			$measures = OrderBasket::getCatalogMeasures();

			if(isset($measures[$product["MEASURE_CODE"]]) && $measures[$product["MEASURE_CODE"]] <> '')
				$product["MEASURE_NAME"] = $measures[$product["MEASURE_CODE"]];
		}

		if(!isset($product["CURRENCY"]) || $product["CURRENCY"] == '')
			$product["CURRENCY"] = $order->getCurrency();

		if (($productData['IS_SET_PARENT'] ?? null) === 'Y')
		{
			$product['TYPE'] = BasketItem::TYPE_SET;
		}

		OrderEdit::setProductDetails(
			$productData["OFFER_ID"],
			$order->getUserId(),
			$order->getSiteId(),
			array_merge($product, $productData)
		);

		if (!empty($item->getProvider()))
		{
			unset($product['PRODUCT_PROVIDER_CLASS']);
		}

		$res = self::setBasketItemFields($item, $product);

		if(!$res->isSuccess())
		{
			foreach($res->getErrors() as $newError)
			{
				foreach($result->getErrors() as $existError)
					if($newError->getMessage() == $existError->getMessage())
						continue 2;

				$result->addError($newError);
			}
		}
	}

	return $result;
}