• Модуль: catalog
  • Путь к файлу: ~/bitrix/modules/catalog/lib/model/product.php
  • Класс: BitrixCatalogModelProduct
  • Вызов: Product::prepareForAdd
static function prepareForAdd(ORMDataAddResult $result, $id, array &$data): void
{
	if (isset($data['fields']['ID']))
		$id = $data['fields']['ID'];
	$id = (int)$id;
	if ($id <= 0)
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_WRONG_PRODUCT_ID')
		));
		return;
	}

	$iblockId = 0;
	if (isset($data['external_fields']['IBLOCK_ID']))
		$iblockId = (int)$data['external_fields']['IBLOCK_ID'];
	if ($iblockId <= 0)
		$iblockId = CIBlockElement::GetIBlockByID($id);
	if (empty($iblockId))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_ELEMENT_NOT_EXISTS')
		));
		return;
	}
	$iblockData = CCatalogSku::GetInfoByIBlock($iblockId);
	if (empty($iblockData))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_SIMPLE_IBLOCK')
		));
		return;
	}
	$data['external_fields']['IBLOCK_ID'] = $iblockId;

	$allowedTypes = self::getProductTypes($iblockData['CATALOG_TYPE']);

	$fields = $data['fields'];
	parent::prepareForAdd($result, $id, $fields);
	if (!$result->isSuccess())
		return;

	if (self::$separateSkuMode === null)
	{
		self::$separateSkuMode = MainConfigOption::get('catalog', 'show_catalog_tab_with_offers') === 'Y';
	}

	static $defaultValues = null,
		$blackList = null,
		$paymentPeriods = null,
		$tripleFields = null,
		$booleanFields = null,
		$nullFields = null,
		$sizeFields = null;
	if ($defaultValues === null)
	{
		$defaultValues = [
			'QUANTITY' => 0,
			'QUANTITY_RESERVED' => 0,
			'QUANTITY_TRACE' => CatalogProductTable::STATUS_DEFAULT,
			'CAN_BUY_ZERO' => CatalogProductTable::STATUS_DEFAULT,
			'WEIGHT' => 0,
			'PRICE_TYPE' => CatalogProductTable::PAYMENT_TYPE_SINGLE,
			'RECUR_SCHEME_LENGTH' => null,
			'RECUR_SCHEME_TYPE' => CatalogProductTable::PAYMENT_PERIOD_DAY,
			'TRIAL_PRICE_ID' => null,
			'WITHOUT_ORDER' => CatalogProductTable::STATUS_NO,
			'SELECT_BEST_PRICE' => CatalogProductTable::STATUS_NO,
			'VAT_ID' => null,
			'VAT_INCLUDED' => CatalogProductTable::STATUS_NO,
			'BARCODE_MULTI' => CatalogProductTable::STATUS_NO,
			'SUBSCRIBE' => CatalogProductTable::STATUS_DEFAULT,
			'BUNDLE' => CatalogProductTable::STATUS_NO,
			'PURCHASING_PRICE' => null,
			'PURCHASING_CURRENCY' => null,
			'TMP_ID' => null,
			'MEASURE' => null,
			'WIDTH' => null,
			'LENGTH' => null,
			'HEIGHT' => null,
		];

		$blackList = [
			'NEGATIVE_AMOUNT_TRACE' => true
		];

		$paymentPeriods = CatalogProductTable::getPaymentPeriods(false);
		$tripleFields = ['QUANTITY_TRACE', 'CAN_BUY_ZERO', 'SUBSCRIBE'];
		$booleanFields = ['WITHOUT_ORDER', 'SELECT_BEST_PRICE', 'VAT_INCLUDED', 'BARCODE_MULTI', 'BUNDLE'];
		$nullFields = ['MEASURE', 'TRIAL_PRICE_ID', 'VAT_ID', 'RECUR_SCHEME_LENGTH'];
		$sizeFields = ['WIDTH', 'LENGTH', 'HEIGHT'];
	}
	$defaultValues['TYPE'] = self::getDefaultProductType($iblockData['CATALOG_TYPE']);

	$fields = array_merge($defaultValues, array_diff_key($fields, $blackList));

	$fields['TYPE'] = (int)$fields['TYPE'];
	if (!isset($allowedTypes[$fields['TYPE']]))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_BAD_PRODUCT_TYPE')
		));
		return;
	}

	$isSpecialType = (
		$fields['TYPE'] === CatalogProductTable::TYPE_EMPTY_SKU
		|| $fields['TYPE'] === CatalogProductTable::TYPE_FREE_OFFER
	);
	if ($isSpecialType)
	{
		$fields['AVAILABLE'] = CatalogProductTable::STATUS_NO;
		$fields['QUANTITY'] = 0;
		$fields['QUANTITY_RESERVED'] = 0;
		$fields['QUANTITY_TRACE'] = CatalogProductTable::STATUS_YES;
		$fields['CAN_BUY_ZERO'] = CatalogProductTable::STATUS_NO;
	}
	$isService = $fields['TYPE'] === CatalogProductTable::TYPE_SERVICE;
	if ($isService)
	{
		$fields['QUANTITY_RESERVED'] = 0;
		$fields['QUANTITY_TRACE'] = CatalogProductTable::STATUS_NO;
		$fields['CAN_BUY_ZERO'] = CatalogProductTable::STATUS_YES;
	}

	if (is_string($fields['QUANTITY']) && !is_numeric($fields['QUANTITY']))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage(
				'BX_CATALOG_MODEL_PRODUCT_ERR_BAD_NUMERIC_FIELD',
				['#FIELD#' => 'QUANTITY']
			)
		));
	}

	if ($isService)
	{
		$fields['QUANTITY'] = (int)$fields['QUANTITY'];
		if ($fields['QUANTITY'] !== 1)
		{
			$fields['QUANTITY'] = 0;
		}
	}
	else
	{
		$fields['QUANTITY'] = (float)$fields['QUANTITY'];
	}

	if (is_string($fields['QUANTITY_RESERVED']) && !is_numeric($fields['QUANTITY_RESERVED']))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage(
				'BX_CATALOG_MODEL_PRODUCT_ERR_BAD_NUMERIC_FIELD',
				['#FIELD#' => 'QUANTITY_RESERVED']
			)
		));
	}
	$fields['QUANTITY_RESERVED'] = (float)$fields['QUANTITY_RESERVED'];

	if ($fields['QUANTITY_RESERVED'] < 0)
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_QUANTITY_RESERVE_LESS_ZERO'),
			'BX_CATALOG_MODEL_PRODUCT_ERR_QUANTITY_RESERVE_LESS_ZERO'
		));
	}

	foreach ($tripleFields as $fieldName)
	{
		if (
			$fields[$fieldName] != CatalogProductTable::STATUS_NO
			&& $fields[$fieldName] != CatalogProductTable::STATUS_YES
		)
			$fields[$fieldName] = $defaultValues[$fieldName];
	}
	foreach ($booleanFields as $fieldName)
	{
		if ($fields[$fieldName] != CatalogProductTable::STATUS_YES)
			$fields[$fieldName] = $defaultValues[$fieldName];
	}
	foreach ($nullFields as $fieldName)
	{
		if ($fields[$fieldName] !== null)
		{
			$fields[$fieldName] = (int)$fields[$fieldName];
			if ($fields[$fieldName] <= 0)
				$fields[$fieldName] = null;
		}
	}
	foreach ($sizeFields as $fieldName)
	{
		if ($fields[$fieldName] !== null)
		{
			$fields[$fieldName] = (float)$fields[$fieldName];
			if ($fields[$fieldName] <= 0)
				$fields[$fieldName] = null;
		}
	}
	unset($fieldName);

	if (
		$fields['PRICE_TYPE'] != CatalogProductTable::PAYMENT_TYPE_REGULAR
		&& $fields['PRICE_TYPE'] != CatalogProductTable::PAYMENT_TYPE_TRIAL
	)
		$fields['PRICE_TYPE'] = $defaultValues['PRICE_TYPE'];
	if (!in_array($fields['RECUR_SCHEME_TYPE'], $paymentPeriods, true))
		$fields['RECUR_SCHEME_TYPE'] = $defaultValues['RECUR_SCHEME_TYPE'];

	if (is_string($fields['WEIGHT']) && !is_numeric($fields['WEIGHT']))
	{
		$result->addError(new ORMEntityError(
			Loc::getMessage(
				'BX_CATALOG_MODEL_PRODUCT_ERR_BAD_NUMERIC_FIELD',
				['#FIELD#' => 'WEIGHT']
			)
		));
	}
	$fields['WEIGHT'] = (float)$fields['WEIGHT'];
	if ($fields['TMP_ID'] !== null)
		$fields['TMP_ID'] = mb_substr($fields['TMP_ID'], 0, 40);

	/* purchasing price */
	$purchasingCurrency = null;
	$purchasingPrice = static::checkPriceValue($fields['PURCHASING_PRICE']);
	if ($purchasingPrice !== null)
	{
		$purchasingCurrency = static::checkPriceCurrency($fields['PURCHASING_CURRENCY']);
		if ($purchasingCurrency === null)
		{
			$result->addError(new ORMEntityError(
				Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_WRONG_PURCHASING_CURRENCY')
			));
			$purchasingPrice = null;
		}
	}
	$fields['PURCHASING_PRICE'] = $purchasingPrice;
	$fields['PURCHASING_CURRENCY'] = $purchasingCurrency;
	unset($purchasingCurrency, $purchasingPrice);
	/* purchasing price end */

	if (array_key_exists('AVAILABLE', $fields))
	{
		if (
			$fields['AVAILABLE'] != CatalogProductTable::STATUS_YES
			&& $fields['AVAILABLE'] != CatalogProductTable::STATUS_NO
		)
		{
			unset($fields['AVAILABLE']);
		}
		else
		{
			if (!$isSpecialType)
			{
				if ($isService)
				{
					//TODO: remove this hack after reservation resource
					$fields['QUANTITY'] = $fields['AVAILABLE'] !== CatalogProductTable::STATUS_YES ? 0 : 1;
				}
				else
				{
					$data['actions'][self::ACTION_CHANGE_PARENT_AVAILABLE] = true;
				}
			}
		}
	}

	if ($result->isSuccess())
	{
		$fields['ID'] = $id;
		$fields['NEGATIVE_AMOUNT_TRACE'] = $fields['CAN_BUY_ZERO'];
		$fields['TIMESTAMP_X'] = new MainTypeDateTime();

		if (!isset($fields['AVAILABLE']))
		{
			self::calculateAvailable($fields, $data['actions']);
			if ($fields['AVAILABLE'] === null)
				$fields['AVAILABLE'] = CatalogProductTable::STATUS_NO;
		}
		if ($fields['TYPE'] === CatalogProductTable::TYPE_OFFER)
		{
			$data['actions'][self::ACTION_CHANGE_PARENT_TYPE] = true;
		}
	}

	if ($result->isSuccess())
		$data['fields'] = $fields;
	unset($fields);
}