static function prepareForUpdate(ORMDataUpdateResult $result, $id, array &$data): void
{
$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;
$fields = $data['fields'];
parent::prepareForUpdate($result, $id, $fields);
if (!$result->isSuccess())
return;
if (self::$separateSkuMode === null)
{
self::$separateSkuMode = MainConfigOption::get('catalog', 'show_catalog_tab_with_offers') === 'Y';
}
static $quantityFields = null,
$paymentPeriods = null,
$tripleFields = null,
$booleanFields = null,
$nullFields = null,
$sizeFields = null,
$blackList = null;
if ($quantityFields === null)
{
$quantityFields = ['QUANTITY', 'QUANTITY_RESERVED'];
$paymentPeriods = CatalogProductTable::getPaymentPeriods(false);
$tripleFields = ['QUANTITY_TRACE', 'CAN_BUY_ZERO', 'SUBSCRIBE'];
$booleanFields = ['WITHOUT_ORDER', 'SELECT_BEST_PRICE', 'VAT_INCLUDED', 'BARCODE_MULTI', 'BUNDLE', 'AVAILABLE'];
$nullFields = ['MEASURE', 'TRIAL_PRICE_ID', 'VAT_ID', 'RECUR_SCHEME_LENGTH'];
$sizeFields = ['WIDTH', 'LENGTH', 'HEIGHT'];
$blackList = [
'ID' => true,
'NEGATIVE_AMOUNT_TRACE' => true
];
}
$fields = array_diff_key($fields, $blackList);
$allowedTypes = self::getProductTypes($iblockData['CATALOG_TYPE']);
if (array_key_exists('TYPE', $fields))
{
$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;
}
}
foreach ($quantityFields as $fieldName)
{
if (array_key_exists($fieldName, $fields))
{
if ($fields[$fieldName] === null)
unset($fields[$fieldName]);
else
$fields[$fieldName] = (float)$fields[$fieldName];
}
}
foreach ($tripleFields as $fieldName)
{
if (array_key_exists($fieldName, $fields))
{
if (
$fields[$fieldName] != CatalogProductTable::STATUS_NO
&& $fields[$fieldName] != CatalogProductTable::STATUS_YES
&& $fields[$fieldName] != CatalogProductTable::STATUS_DEFAULT
)
unset($fields[$fieldName]);
}
}
if (isset($fields['SUBSCRIBE']))
$data['actions'][self::ACTION_SEND_NOTIFICATIONS] = true;
foreach ($booleanFields as $fieldName)
{
if (array_key_exists($fieldName, $fields))
{
if (
$fields[$fieldName] != CatalogProductTable::STATUS_NO
&& $fields[$fieldName] != CatalogProductTable::STATUS_YES
)
unset($fields[$fieldName]);
}
}
foreach ($nullFields as $fieldName)
{
if (isset($fields[$fieldName]))
{
$fields[$fieldName] = (int)$fields[$fieldName];
if ($fields[$fieldName] <= 0)
{
$fields[$fieldName] = null;
}
}
}
foreach ($sizeFields as $fieldName)
{
if (isset($fields[$fieldName]))
{
$fields[$fieldName] = (float)$fields[$fieldName];
if ($fields[$fieldName] <= 0)
{
$fields[$fieldName] = null;
}
}
}
unset($fieldName);
if (array_key_exists('PRICE_TYPE', $fields))
{
if (
$fields['PRICE_TYPE'] != CatalogProductTable::PAYMENT_TYPE_REGULAR
&& $fields['PRICE_TYPE'] != CatalogProductTable::PAYMENT_TYPE_TRIAL
&& $fields['PRICE_TYPE'] != CatalogProductTable::PAYMENT_TYPE_SINGLE
)
unset($fields['PRICE_TYPE']);
}
if (array_key_exists('RECUR_SCHEME_TYPE', $fields))
{
if (!in_array($fields['RECUR_SCHEME_TYPE'], $paymentPeriods, true))
unset($fields['RECUR_SCHEME_TYPE']);
}
if (array_key_exists('WEIGHT', $fields))
{
if ($fields['WEIGHT'] === null)
{
unset($fields['WEIGHT']);
}
else
{
$fields['WEIGHT'] = (float)$fields['WEIGHT'];
$data['actions'][self::ACTION_RECALCULATE_SETS] = true;
}
}
if (isset($fields['TMP_ID']))
{
$fields['TMP_ID'] = mb_substr($fields['TMP_ID'], 0, 40);
}
if (array_key_exists('QUANTITY_RESERVED', $fields) && (float)$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'
));
}
/* purchasing price */
$existPurchasingPrice = array_key_exists('PURCHASING_PRICE', $fields);
$existPurchasingCurrency = array_key_exists('PURCHASING_CURRENCY', $fields);
if ($existPurchasingPrice)
{
$fields['PURCHASING_PRICE'] = static::checkPriceValue($fields['PURCHASING_PRICE']);
if ($fields['PURCHASING_PRICE'] === null)
{
$fields['PURCHASING_CURRENCY'] = null;
$existPurchasingCurrency = false;
}
}
if ($existPurchasingCurrency)
{
$fields['PURCHASING_CURRENCY'] = static::checkPriceCurrency($fields['PURCHASING_CURRENCY']);
if ($fields['PURCHASING_CURRENCY'] === null)
{
$result->addError(new ORMEntityError(
Loc::getMessage('BX_CATALOG_MODEL_PRODUCT_ERR_WRONG_PURCHASING_CURRENCY')
));
}
}
/* purchasing price end */
if ($result->isSuccess())
{
if (isset($fields['CAN_BUY_ZERO']))
$fields['NEGATIVE_AMOUNT_TRACE'] = $fields['CAN_BUY_ZERO'];
$fields['TIMESTAMP_X'] = new MainTypeDateTime();
if (isset($fields['AVAILABLE']))
{
$copyFields =
isset($fields['TYPE'])
? $fields
: array_merge(static::getCacheItem($id, true), $fields)
;
$copyFields['TYPE'] = (int)$copyFields['TYPE'];
$isService = $copyFields['TYPE'] === CatalogProductTable::TYPE_SERVICE;
if ($isService)
{
//TODO: remove this hack after reservation resource
$fields['QUANTITY'] = $fields['AVAILABLE'] !== CatalogProductTable::STATUS_YES ? 0 : 1;
}
if (!$isService)
{
$data['actions'][self::ACTION_CHANGE_PARENT_AVAILABLE] = true;
}
$data['actions'][self::ACTION_RECALCULATE_SETS] = true;
$data['actions'][self::ACTION_SEND_NOTIFICATIONS] = true;
}
else
{
$needCalculateAvailable = (isset($fields['TYPE'])
|| isset($fields['QUANTITY'])
|| isset($fields['QUANTITY_TRACE'])
|| isset($fields['CAN_BUY_ZERO'])
);
if ($needCalculateAvailable)
{
$needCache = (!isset($fields['TYPE'])
|| !isset($fields['QUANTITY'])
|| !isset($fields['QUANTITY_TRACE'])
|| !isset($fields['CAN_BUY_ZERO'])
);
$copyFields = (
$needCache
? array_merge(static::getCacheItem($id, true), $fields)
: $fields
);
$copyFields['TYPE'] = (int)$copyFields['TYPE'];
self::calculateAvailable($copyFields, $data['actions']);
if ($copyFields['AVAILABLE'] !== null)
$fields['AVAILABLE'] = $copyFields['AVAILABLE'];
unset($copyFields, $needCache);
}
unset($needCalculateAvailable);
}
$data['fields'] = $fields;
}
unset($fields);
}