• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/admin/orderedit.php
  • Класс: BitrixSaleHelpersAdminOrderEdit
  • Вызов: OrderEdit::editOrderByFormData
static function editOrderByFormData(array $formData, Order $order, $userId, $createUserIfNeed, array $files, Result &$result)
{
	/** @var BitrixSaleResult $res */
	$res = self::fillSimpleFields($order, $formData, $userId);

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

	$propCollection = $order->getPropertyCollection();
	$res = $propCollection->setValuesFromPost($formData, $files);

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

	/*
	$currentUserId = $order->getUserId();

	if ($currentUserId && ((int)$currentUserId !== (int)$formData['USER_ID']))
	{
		$paymentCollection = $order->getPaymentCollection();
		/** @var BitrixSalePayment $payment *//*
		foreach ($paymentCollection as $payment)
		{
			if ($payment->isPaid())
			{
				$result->addError(new EntityError(
					Loc::getMessage("SALE_ORDEREDIT_ERROR_CHANGE_USER_WITH_PAID_PAYMENTS")
				, 'SALE_ORDEREDIT_ERROR_CHANGE_USER_WITH_PAID_PAYMENTS'));
				return null;
			}
		}
	}
	*/

	$order->setFieldNoDemand(
		"USER_ID",
		self::getUserId($order, $formData, $createUserIfNeed, $result)
	);

	if(isset($formData["DISCOUNTS"]) && is_array($formData["DISCOUNTS"]))
		$order->getDiscount()->setApplyResult($formData["DISCOUNTS"]);

	//init basket
	$basket = $order->getBasket();
	$itemsBasketCodes = array();
	$maxBasketCodeIdx = 0;
	$productAdded = false;

	if(isset($formData["PRODUCT"]) && is_array($formData["PRODUCT"]) && !empty($formData["PRODUCT"]))
	{
		$sort = 100;

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

			/* Fix collision if price of new product is larger than added earlier 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;

				$needDataUpdate[] = $basketCode;
				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);

		//we choose sku wich already exist in basket, so we must kill one of them.
		if(!empty($formData["ALREADY_IN_BASKET_CODE"]))
		{
			$item = $basket->getItemByBasketCode($formData["ALREADY_IN_BASKET_CODE"]);

			if($item)
			{
				$res = $item->delete();

				if (!$res->isSuccess())
				{
					$errMess = "";

					foreach($res->getErrors() as $error)
						$errMess .= $error->getMessage()."n";

					if($errMess == '')
						$errMess = Loc::getMessage("SALE_ORDEREDIT_BASKET_ITEM_DEL_ERROR");

					$result->addError(new Error($errMess));
//						return null;
				}
			}
		}

		foreach($formData["PRODUCT"] as $basketCode => $productData)
		{
			if (!isset($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)
			{
				DiscountCouponsManager::useSavedCouponsForApply(false);
			}

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

			if(!$item)
			{
				continue;
			}

			$itemsBasketCodes[] = $item->getBasketCode();
		}
	}

	/** @var  BitrixSaleBasketItem  $item */
	$basketItems = $basket->getBasketItems();

	foreach($basketItems as $item)
	{
		if(!in_array($item->getBasketCode(), $itemsBasketCodes))
		{
			$res = $item->delete();

			if (!$res->isSuccess())
			{
				$errMess = "";

				foreach($res->getErrors() as $error)
					$errMess .= $error->getMessage()."n";

				if($errMess == '')
					$errMess = Loc::getMessage("SALE_ORDEREDIT_BASKET_ITEM_DEL_ERROR");

				$result->addError(new Error($errMess));
//					return null;
			}
		}
	}

	BitrixSaleProviderBase::setUsingTrustData(true);
	$isStartField = $order->isStartField();
	$needDataUpdate = array();
	$basketCodeMap = array();

	if(isset($formData["PRODUCT"]) && is_array($formData["PRODUCT"]) && !empty($formData["PRODUCT"]))
	{
		foreach($formData["PRODUCT"] as $basketCode => $productData)
		{
			$providerData = array();

			if($productData["IS_SET_ITEM"] == "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
			;

			//sku was changed
			if($item == null && $basketCode != self::BASKET_CODE_NEW)
			{
				if($item = $basket->getItemByBasketCode($basketCode))
				{
					$res = $item->delete();

					if(!$res->isSuccess())
					{
						$result->addErrors($res->getErrors());
//							return null;
					}

					$item = null;
				}
			}

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

			if(!$item)
			{
				if($basketCode != self::BASKET_CODE_NEW)
					$setBasketCode = $basketCode;
				elseif(intval($maxBasketCodeIdx) > 0)
					$setBasketCode = 'n'.strval($maxBasketCodeIdx+1); //Fix collision part 2.
				else
					$setBasketCode = null;

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

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

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

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

				if(!$productAdded)
					$productAdded = true;
			}
			else
			{
				if ($basketCode != $productData["BASKET_CODE"])
					$productData["BASKET_CODE"] = $item->getBasketCode();

				if(isset($productData["OFFER_ID"]) || intval($productData["OFFER_ID"]) >= 0)
					$productData["PRODUCT_ID"] = $productData["OFFER_ID"];

				$itemFields = array_intersect_key($productData, array_flip($item::getAvailableFields()));

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

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

				if(!empty($productData["PROVIDER_DATA"]) && !self::$needUpdateNewProductPrice && CheckSerializedData($productData["PROVIDER_DATA"]))
				{
					$providerData = unserialize($productData["PROVIDER_DATA"], ['allowed_classes' => false]);
				}

				if(is_array($providerData) && !empty($providerData))
					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]);

				/** @var BitrixSaleResult $res */
				$res = self::setBasketItemFields($item, $itemFields);

				if (!$res->isSuccess())
				{
					$result->addErrors($res->getErrors());
//						return null;
				}
				elseif($res->hasWarnings())
				{
					foreach($res->getWarningMessages() as $warning)
					{
						$result->addError(new Error($warning));
					}
				}
			}

			/*
			 * Could be deleted and than added one more time product.
			 * Or just added product.
			 */
			if($basketCode != $item->getBasketCode())
				$basketCodeMap[$basketCode] = $item->getBasketCode();

			if(!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())
		{
			$result->addErrors($res->getErrors());

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

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

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

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

	return $order;
}