• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/admin/orderedit.php
  • Класс: BitrixSaleHelpersAdminOrderEdit
  • Вызов: OrderEdit::createOrderFromForm
static function createOrderFromForm(array $formData, $creatorUserId, $createUserIfNeed, array $files, Result &$opResult)
{
	if(!isset($formData["SITE_ID"]) || $formData["SITE_ID"] == '')
		throw new ArgumentNullException('formData["SITE_ID"]');

	$registry = SaleRegistry::getInstance(SaleRegistry::REGISTRY_TYPE_ORDER);
	/** @var SaleOrder $orderClass */
	$orderClass = $registry->getOrderClassName();

	global $APPLICATION, $USER;
	$order = $orderClass::create($formData["SITE_ID"]);
	$saleModulePermissions = $APPLICATION->GetGroupRight("sale");
	$userCompanyId = null;

	if($saleModulePermissions == "P")
	{
		$userCompanyList = CompanyManager::getUserCompanyList($USER->GetID());
		if (!empty($userCompanyList) && is_array($userCompanyList))
		{
			$userCompanyId = reset($userCompanyList);
			if (intval($userCompanyId) > 0 && empty($formData['ORDER']['COMPANY_ID']))
			{
				$formData['ORDER']['COMPANY_ID'] = $userCompanyId;
			}
		}
	}

	/** @var BitrixSaleResult $res */
	$res = self::fillSimpleFields($order, $formData, $creatorUserId);

	if(!$res->isSuccess())
		$opResult->addErrors($res->getErrors());

	$res = self::fillOrderProperties($order, $formData, $files);
	if(!$res->isSuccess())
		$opResult->addErrors($res->getErrors());

	//creates new user if need
	$order->setFieldNoDemand(
		"USER_ID",
		self::getUserId($order, $formData, $createUserIfNeed, $opResult)
	);

	$fUserId = null;

	if ($order->getUserId() > 0)
	{
		$fUserId = Fuser::getIdByUserId($order->getUserId());
	}

	$needDataUpdate = array();
	$basketCodeMap = array();

	//init basket
	if(isset($formData["PRODUCT"]) && is_array($formData["PRODUCT"]) && !empty($formData["PRODUCT"]))
	{
		$isStartField = $order->isStartField();

		$basketClass = $registry->getBasketClassName();
		/** @var Basket $basket */
		$basket = $basketClass::create($formData["SITE_ID"]);

		$res = $order->setBasket($basket);

		if(!$res->isSuccess())
			$opResult->addErrors($res->getErrors());

		$basket->setFUserId($fUserId);
		BitrixSaleProviderBase::setUsingTrustData(true);

		$sort = 100;
		$maxBasketCodeIdx = 0;

		foreach($formData["PRODUCT"] as $basketCode => $productData)
		{
			$formData["PRODUCT"][$basketCode]["SORT"] = $sort;
			$sort += 100;

			/* Fix collision if price of new product is larger than exists have.
			 * After sorting new product pick basket code from existing products.
			 * See below.
			 */
			if(self::isBasketItemNew($basketCode))
			{
				$basketInternalId = intval(mb_substr($basketCode, 1));

				if($basketInternalId > $maxBasketCodeIdx)
					$maxBasketCodeIdx = $basketInternalId;

				if(self::$needUpdateNewProductPrice)
				{
					unset($formData["PRODUCT"][$basketCode]["PROVIDER_DATA"]);
					unset($formData["PRODUCT"][$basketCode]["SET_ITEMS_DATA"]);
				}
			}
		}

		sortByColumn($formData["PRODUCT"], array("BASE_PRICE" => SORT_DESC, "PRICE" => SORT_DESC), '', null, true);

		foreach($formData["PRODUCT"] as $basketCode => $productData)
		{
			if (($productData['IS_SET_ITEM'] ?? null) === 'Y')
			{
				continue;
			}

			if(!isset($productData["PROPS"]) || !is_array($productData["PROPS"]))
			{
				$productData["PROPS"] = array();
			}

			// Always search only by $basketCode so that can add duplicates
			$item =
				$basketCode != self::BASKET_CODE_NEW
				? $basket->getItemByBasketCode($basketCode)
				: null
			;

			if($item == null && $basketCode != self::BASKET_CODE_NEW)
			{
				$item = $basket->getItemByBasketCode($basketCode);
			}

			if($item && $item->isBundleChild())
			{
				$item = null;
			}

			if($item)
			{
				//Let's extract cached provider product data from field
				if(!empty($productData["PROVIDER_DATA"]) && CheckSerializedData($productData["PROVIDER_DATA"]))
				{
					$providerData = unserialize($productData["PROVIDER_DATA"], ['allowed_classes' => false]);
					self::setProviderTrustData($item, $order, $providerData);
				}

				if(!empty($productData["SET_ITEMS_DATA"]) && CheckSerializedData($productData["SET_ITEMS_DATA"]))
					$productData["SET_ITEMS"] = unserialize($productData["SET_ITEMS_DATA"], ['allowed_classes' => false]);

				$res = $item->setField("QUANTITY", $item->getField("QUANTITY")+$productData["QUANTITY"]);

				if(!$res->isSuccess())
					$opResult->addErrors($res->getErrors());
			}
			else
			{
				if($basketCode != self::BASKET_CODE_NEW)
					$setBasketCode = $basketCode;
				elseif(intval($maxBasketCodeIdx) > 0)
					$setBasketCode = 'n'.strval($maxBasketCodeIdx+1); //Fix collision part 2.
				else
					$setBasketCode = null;

				$productId = $productData["PRODUCT_ID"];
				if (isset($productData["OFFER_ID"]) && !empty($productData["OFFER_ID"]))
				{
					$productId = $productData["OFFER_ID"];
				}

				$item = $basket->createItem($productData["MODULE"],	$productId, $setBasketCode);

				if ($basketCode != $productData["BASKET_CODE"])
					$productData["BASKET_CODE"] = $item->getBasketCode();

				if($basketCode == self::BASKET_CODE_NEW)
				{
					$opResult->setData(array("NEW_ITEM_BASKET_CODE" => $productData["BASKET_CODE"]));
					$needDataUpdate[] = $item->getBasketCode();
				}

				if(!empty($productData['REPLACED']) && $productData['REPLACED'] == 'Y')
					$needDataUpdate[] = $item->getBasketCode();

				if($basketCode != $item->getBasketCode())
					$basketCodeMap[$basketCode] = $item->getBasketCode();

				if(isset($productData["PROPS"]) && !empty($productData["PROPS"]) && is_array($productData["PROPS"]))
				{
					/** @var BitrixSaleBasketPropertiesCollection $property */
					$property = $item->getPropertyCollection();
					$property->setProperty($productData["PROPS"]);
				}
			}
		}

		$productsData = $formData["PRODUCT"];

		if(!empty($basketCodeMap))
		{
			foreach($basketCodeMap as $old => $new)
			{
				$productsData[$new] = $productsData[$old];
				unset($productsData[$old]);
			}
		}

		$res = self::fillBasketItems($basket, $productsData, $order, array_unique($needDataUpdate));

		if(!$res->isSuccess())
		{
			$opResult->addErrors($res->getErrors());

			if($res->isTerminal())
			{
				return null;
			}
		}

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

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

		if(isset($formData["DISCOUNTS"]) && is_array($formData["DISCOUNTS"]))
			$order->getDiscount()->setApplyResult($formData["DISCOUNTS"]);
	}
	else
	{
		$opResult->addError(new EntityError(Loc::getMessage("SALE_ORDEREDIT_ERROR_NO_PRODUCTS")));
	}

	return $order;
}