• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/basketitembase.php
  • Класс: BitrixSaleBasketItemBase
  • Вызов: BasketItemBase::onFieldModify
protected function onFieldModify($name, $oldValue, $value)
{
	$result = new Result();

	if ($name === "QUANTITY")
	{
		if ($value == 0)
		{
			$result->addError(new MainError(
				LocalizationLoc::getMessage(
					'SALE_BASKET_ITEM_ERR_QUANTITY_ZERO',
					['#PRODUCT_NAME#' => $this->getField('NAME')]
				)
			));
			return $result;
		}

		$value = (float)$value;
		$oldValue = (float)$oldValue;
		$deltaQuantity = $value - $oldValue;

		/** @var Basket $basket */
		$basket = $this->getCollection();
		$context = $basket->getContext();

		/** @var Result $r */
		$r = InternalsCatalogProvider::getAvailableQuantityAndPriceByBasketItem($this, $context);
		if (!$r->isSuccess())
		{
			$result->addErrors($r->getErrors());
			$result->setData($r->getData());

			return $result;
		}

		$providerData = $r->getData();

		if ($this->getField('SUBSCRIBE') !== 'Y')
		{
			if ($providerData)
			{
				if (array_key_exists('AVAILABLE_QUANTITY', $providerData) && $providerData['AVAILABLE_QUANTITY'] > 0)
				{
					$availableQuantity = $providerData['AVAILABLE_QUANTITY'];
				}
				else
				{
					$result->addError(
						new ResultError(
							LocalizationLoc::getMessage(
								'SALE_BASKET_ITEM_WRONG_AVAILABLE_QUANTITY_2',
								['#PRODUCT_NAME#' => $this->getField('NAME')]
							),
							'SALE_BASKET_ITEM_WRONG_AVAILABLE_QUANTITY'
						)
					);

					return $result;
				}
			}
			else
			{
				$errorMessageCode = 'SALE_BASKET_PRODUCT_NOT_AVAILABLE';
				if ($this->isService())
				{
					$errorMessageCode = 'SALE_BASKET_SERVICE_NOT_AVAILABLE';
				}

				$result->addError(
					new ResultError(
						LocalizationLoc::getMessage(
							$errorMessageCode,
							['#PRODUCT_NAME#' => $this->getField('NAME')]
						),
						'SALE_BASKET_ITEM_WRONG_AVAILABLE_QUANTITY'
					)
				);

				return $result;
			}
		}
		else
		{
			$availableQuantity = $value;
		}

		if (isset($providerData['PRICE_DATA']['CUSTOM_PRICE']))
		{
			$this->markFieldCustom('PRICE');
		}

		$notPurchasedQuantity = $this->getNotPurchasedQuantity();

		if ($value != 0
			&& (
				(
					$deltaQuantity > 0
					&& roundEx($availableQuantity, SALE_VALUE_PRECISION) < roundEx($notPurchasedQuantity, SALE_VALUE_PRECISION)
				) // plus
				|| (
					$deltaQuantity < 0
					&& roundEx($availableQuantity, SALE_VALUE_PRECISION) > roundEx($notPurchasedQuantity, SALE_VALUE_PRECISION)
				) // minus
			)
		)
		{
			if ($deltaQuantity > 0)
			{
				$canAddCount = $availableQuantity - $this->getReservedQuantity();
				if ($canAddCount > 0)
				{
					$mess = LocalizationLoc::getMessage(
						'SALE_BASKET_AVAILABLE_FOR_ADDING_QUANTITY_IS_LESS',
						[
							'#PRODUCT_NAME#' => $this->getField('NAME'),
							'#QUANTITY#' => $oldValue,
							'#ADD#' => $canAddCount,
						]
					);
				}
				else
				{
					$mess = LocalizationLoc::getMessage(
						'SALE_BASKET_AVAILABLE_FOR_ADDING_QUANTITY_IS_ZERO',
						[
							'#PRODUCT_NAME#' => $this->getField('NAME'),
							'#QUANTITY#' => $oldValue,
						]
					);
				}
			}
			else
			{
				$mess = LocalizationLoc::getMessage(
					'SALE_BASKET_AVAILABLE_FOR_DECREASE_QUANTITY',
					[
						'#PRODUCT_NAME#' => $this->getField('NAME'),
						'#AVAILABLE_QUANTITY#' => $availableQuantity
					]
				);
			}

			$result->addError(new ResultError($mess, "SALE_BASKET_AVAILABLE_QUANTITY"));
			$result->setData([
				"AVAILABLE_QUANTITY" => $availableQuantity,
				"REQUIRED_QUANTITY" => $deltaQuantity
			]);

			return $result;
		}

		/** @var BasketItemCollection $collection */
		$collection = $this->getCollection();

		/** @var BasketBase $basket */
		$basket = $collection->getBasket();

		if ((!$basket->getOrder() || $basket->getOrderId() == 0) && !($collection instanceof BundleCollection))
		{
			if (!$this->isMarkedFieldCustom('PRICE') && $value > 0)
			{
				$r = $basket->refresh(RefreshFactory::createSingle($this->getBasketCode()));
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
					return $result;
				}
			}
		}

		if (!$this->isMarkedFieldCustom('PRICE'))
		{
			$providerName = $this->getProviderName();
			if (strval($providerName) == '')
			{
				$providerName = $this->getCallbackFunction();
			}


			if (!empty($providerData['PRICE_DATA']))
			{
				if (isset($providerData['PRICE_DATA']['PRICE']))
				{
					$this->setField('PRICE', $providerData['PRICE_DATA']['PRICE']);
				}

				if (isset($providerData['PRICE_DATA']['BASE_PRICE']))
				{
					$this->setField('BASE_PRICE', $providerData['PRICE_DATA']['BASE_PRICE']);
				}

				if (isset($providerData['PRICE_DATA']['DISCOUNT_PRICE']))
				{
					$this->setField('DISCOUNT_PRICE', $providerData['PRICE_DATA']['DISCOUNT_PRICE']);
				}
			}
			elseif ($providerName && !$this->isCustom())
			{
				$result->addError(
					new ResultError(
						LocalizationLoc::getMessage(
							'SALE_BASKET_ITEM_WRONG_PRICE',
							['#PRODUCT_NAME#' => $this->getField('NAME')]
						),
						'SALE_BASKET_ITEM_WRONG_PRICE'
					)
				);

				return $result;
			}
		}
	}

	$r = parent::onFieldModify($name, $oldValue, $value);
	if ($r->isSuccess())
	{
		if ($r->hasWarnings())
		{
			$result->addWarnings($r->getWarnings());
		}

		if (
			$name === 'BASE_PRICE'
			|| $name === 'DISCOUNT_PRICE'
		)
		{
			if (!$this->isCustomPrice())
			{
				$price = $this->getField('BASE_PRICE') - $this->getField('DISCOUNT_PRICE');
				$r = $this->setField('PRICE', $price);
				if (!$r->isSuccess())
					$result->addErrors($r->getErrors());
			}
		}
	}
	else
	{
		$result->addErrors($r->getErrors());
	}

	return $result;
}