2namespace Bitrix\Catalog;
5use Bitrix\Main\Localization\Loc;
6use Bitrix\Main\ORM\Data\DataManager;
104 return 'b_catalog_product';
115 'ID' =>
new Main\Entity\IntegerField(
119 'title' => Loc::getMessage(
'PRODUCT_ENTITY_ID_FIELD'),
122 'QUANTITY' =>
new Main\Entity\FloatField(
125 'default_value' => 0,
126 'title' => Loc::getMessage(
'PRODUCT_ENTITY_QUANTITY_FIELD'),
129 'QUANTITY_TRACE' =>
new Main\Entity\EnumField(
133 self::STATUS_DEFAULT,
137 'default_value' => self::STATUS_DEFAULT,
138 'fetch_data_modification' => [__CLASS__,
'modifyQuantityTrace'],
139 'title' => Loc::getMessage(
'PRODUCT_ENTITY_QUANTITY_TRACE_FIELD_MSGVER_1'),
142 'QUANTITY_TRACE_ORIG' =>
new Main\Entity\ExpressionField(
143 'QUANTITY_TRACE_ORIG',
147 'data_type' =>
'string',
150 'WEIGHT' =>
new Main\Entity\FloatField(
153 'default_value' => 0,
154 'title' => Loc::getMessage(
'PRODUCT_ENTITY_WEIGHT_FIELD'),
157 'TIMESTAMP_X' =>
new Main\Entity\DatetimeField(
160 'default_value' =>
function()
164 'title' => Loc::getMessage(
'PRODUCT_ENTITY_TIMESTAMP_X_FIELD'),
170 'values' => self::getPaymentTypes(
false),
171 'default_value' => self::PAYMENT_TYPE_SINGLE,
172 'title' => Loc::getMessage(
'PRODUCT_ENTITY_PRICE_TYPE_FIELD'),
175 'RECUR_SCHEME_LENGTH' =>
new Main\Entity\IntegerField(
176 'RECUR_SCHEME_LENGTH',
178 'default_value' => 0,
179 'title' => Loc::getMessage(
'PRODUCT_ENTITY_RECUR_SCHEME_LENGTH_FIELD'),
182 'RECUR_SCHEME_TYPE' =>
new Main\Entity\EnumField(
185 'values' => self::getPaymentPeriods(
false),
186 'default_value' => self::PAYMENT_PERIOD_DAY,
187 'title' => Loc::getMessage(
'PRODUCT_ENTITY_RECUR_SCHEME_TYPE_FIELD'),
190 'TRIAL_PRICE_ID' =>
new Main\Entity\IntegerField(
193 'title' => Loc::getMessage(
'PRODUCT_ENTITY_TRIAL_PRICE_ID_FIELD'),
196 'WITHOUT_ORDER' =>
new Main\Entity\BooleanField(
203 'default_value' => self::STATUS_NO,
204 'title' => Loc::getMessage(
'PRODUCT_ENTITY_WITHOUT_ORDER_FIELD'),
207 'SELECT_BEST_PRICE' =>
new Main\Entity\BooleanField(
214 'default_value' => self::STATUS_YES,
217 'VAT_ID' =>
new Main\Entity\IntegerField(
220 'default_value' => 0,
221 'title' => Loc::getMessage(
'PRODUCT_ENTITY_VAT_ID_FIELD'),
224 'VAT_INCLUDED' =>
new Main\Entity\BooleanField(
231 'default_value' => self::STATUS_NO,
232 'title' => Loc::getMessage(
'PRODUCT_ENTITY_VAT_INCLUDED_FIELD'),
235 'CAN_BUY_ZERO' =>
new Main\Entity\EnumField(
239 self::STATUS_DEFAULT,
243 'default_value' => self::STATUS_DEFAULT,
244 'fetch_data_modification' => [__CLASS__,
'modifyCanBuyZero'],
245 'title' => Loc::getMessage(
'PRODUCT_ENTITY_CAN_BUY_ZERO_FIELD'),
248 'CAN_BUY_ZERO_ORIG' =>
new Main\Entity\ExpressionField(
253 'data_type' =>
'string',
256 'NEGATIVE_AMOUNT_TRACE' =>
new Main\Entity\EnumField(
257 'NEGATIVE_AMOUNT_TRACE',
260 self::STATUS_DEFAULT,
264 'default_value' => self::STATUS_DEFAULT,
265 'fetch_data_modification' => [__CLASS__,
'modifyNegativeAmountTrace'],
266 'title' => Loc::getMessage(
'PRODUCT_ENTITY_NEGATIVE_AMOUNT_TRACE_FIELD'),
269 'NEGATIVE_AMOUNT_TRACE_ORIG' =>
new Main\Entity\ExpressionField(
270 'NEGATIVE_AMOUNT_TRACE_ORIG',
272 'NEGATIVE_AMOUNT_TRACE',
274 'data_type' =>
'string',
277 'TMP_ID' => New Main\Entity\StringField(
280 'validation' => [__CLASS__,
'validateTmpId'],
281 'title' => Loc::getMessage(
'PRODUCT_ENTITY_TMP_ID_FIELD'),
284 'PURCHASING_PRICE' =>
new Main\Entity\FloatField(
287 'title' => Loc::getMessage(
'PRODUCT_ENTITY_PURCHASING_PRICE_FIELD'),
290 'PURCHASING_CURRENCY' =>
new Main\Entity\StringField(
291 'PURCHASING_CURRENCY',
293 'validation' => [__CLASS__,
'validatePurchasingCurrency'],
294 'title' => Loc::getMessage(
'PRODUCT_ENTITY_PURCHASING_CURRENCY_FIELD'),
297 'BARCODE_MULTI' =>
new Main\Entity\BooleanField(
304 'default_value' => self::STATUS_NO,
305 'title' => Loc::getMessage(
'PRODUCT_ENTITY_BARCODE_MULTI_FIELD'),
308 'QUANTITY_RESERVED' =>
new Main\Entity\FloatField(
311 'title' => Loc::getMessage(
'PRODUCT_ENTITY_QUANTITY_RESERVED_FIELD'),
314 'SUBSCRIBE' =>
new Main\Entity\EnumField(
318 self::STATUS_DEFAULT,
322 'default_value' => self::STATUS_DEFAULT,
323 'fetch_data_modification' => [__CLASS__,
'modifySubscribe'],
324 'title' => Loc::getMessage(
'PRODUCT_ENTITY_SUBSCRIBE_FIELD'),
327 'SUBSCRIBE_ORIG' =>
new Main\Entity\ExpressionField(
332 'data_type' =>
'string',
335 'WIDTH' =>
new Main\Entity\FloatField(
338 'title' => Loc::getMessage(
'PRODUCT_ENTITY_WIDTH_FIELD'),
341 'LENGTH' =>
new Main\Entity\FloatField(
344 'title' => Loc::getMessage(
'PRODUCT_ENTITY_LENGTH_FIELD'),
347 'HEIGHT' =>
new Main\Entity\FloatField(
350 'title' => Loc::getMessage(
'PRODUCT_ENTITY_HEIGHT_FIELD'),
353 'MEASURE' =>
new Main\Entity\IntegerField(
356 'title' => Loc::getMessage(
'PRODUCT_ENTITY_MEASURE_FIELD'),
359 'TYPE' =>
new Main\Entity\EnumField(
367 self::TYPE_FREE_OFFER,
368 self::TYPE_EMPTY_SKU,
371 'default_value' => self::TYPE_PRODUCT,
372 'title' => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_FIELD'),
375 'AVAILABLE' =>
new Main\Entity\BooleanField(
382 'title' => Loc::getMessage(
'PRODUCT_ENTITY_AVAILABLE_FIELD'),
385 'BUNDLE' =>
new Main\Entity\BooleanField(
392 'title' => Loc::getMessage(
'PRODUCT_ENTITY_BUNDLE_FIELD'),
395 'IBLOCK_ELEMENT' =>
new Main\Entity\ReferenceField(
397 '\Bitrix\Iblock\Element',
399 '=this.ID' =>
'ref.ID',
402 'join_type' =>
'LEFT',
405 'TRIAL_IBLOCK_ELEMENT' =>
new Main\Entity\ReferenceField(
406 'TRIAL_IBLOCK_ELEMENT',
407 '\Bitrix\Iblock\Element',
409 '=this.TRIAL_PRICE_ID' =>
'ref.ID',
412 'join_type' =>
'LEFT',
415 'TRIAL_PRODUCT' =>
new Main\Entity\ReferenceField(
417 '\Bitrix\Catalog\Product',
419 '=this.TRIAL_PRICE_ID' =>
'ref.ID',
422 'join_type' =>
'LEFT',
435 return self::USER_FIELD_ENTITY_ID;
496 array(__CLASS__,
'prepareQuantityTrace')
509 array(__CLASS__,
'prepareCanBuyZero')
522 array(__CLASS__,
'prepareNegativeAmountTrace')
535 array(__CLASS__,
'prepareSubscribe')
548 if ($value == self::STATUS_DEFAULT)
550 if (empty(self::$defaultProductSettings))
552 return self::$defaultProductSettings[
'QUANTITY_TRACE'];
566 if ($value == self::STATUS_DEFAULT)
568 if (empty(self::$defaultProductSettings))
570 return self::$defaultProductSettings[
'CAN_BUY_ZERO'];
584 if ($value == self::STATUS_DEFAULT)
586 if (empty(self::$defaultProductSettings))
588 return self::$defaultProductSettings[
'NEGATIVE_AMOUNT_TRACE'];
602 if ($value == self::STATUS_DEFAULT)
604 if (empty(self::$defaultProductSettings))
606 return self::$defaultProductSettings[
'SUBSCRIBE'];
622 $product = (int)$product;
626 'select' =>
array(
'ID'),
627 'filter' =>
array(
'=ID' => $product)
629 return (!empty($existProduct));
651 if (!is_array($product))
652 $product =
array($product);
659 $defaultMeasure = \CCatalogMeasure::getDefaultMeasure(
true,
true);
662 'MEASURE' => (!empty($defaultMeasure) ? $defaultMeasure :
array())
664 $existProduct =
array();
665 $measureMap =
array();
667 $productRows = array_chunk($product, 500);
668 foreach ($productRows as &$row)
671 'select' =>
array(
'ID',
'MEASURE'),
672 'filter' =>
array(
'@ID' => $row),
673 'order' =>
array(
'ID' =>
'ASC')
675 while ($item = $productIterator->fetch())
677 $item[
'ID'] = (int)$item[
'ID'];
678 $item[
'MEASURE'] = (int)$item[
'MEASURE'];
679 $existProduct[] = $item[
'ID'];
680 $result[$item[
'ID']] = $defaultRow;
681 if ($item[
'MEASURE'] > 0)
683 if (!isset($measureMap[$item[
'MEASURE']]))
684 $measureMap[$item[
'MEASURE']] =
array();
685 $measureMap[$item[
'MEASURE']][] = &
$result[$item[
'ID']];
688 unset($item, $productIterator);
690 unset($row, $productRows);
691 unset($defaultRow, $defaultMeasure);
692 if (empty($existProduct))
696 if (!empty($ratioResult))
698 foreach ($ratioResult as $ratioProduct => $ratio)
699 $result[$ratioProduct][
'RATIO'] = $ratio;
700 unset($ratio, $ratioProduct);
703 unset($existProduct);
705 if (!empty($measureMap))
709 array(
'@ID' => array_keys($measureMap)),
716 $measure[
'ID'] = (int)$measure[
'ID'];
717 if (empty($measureMap[$measure[
'ID']]))
720 foreach ($measureMap[$measure[
'ID']] as &$product)
721 $product[
'MEASURE'] = $measure;
741 return self::STATUS_NO;
744 if (isset(
$fields[
'QUANTITY']) && isset(
$fields[
'QUANTITY_TRACE']) && isset(
$fields[
'CAN_BUY_ZERO']))
746 if (empty(self::$defaultProductSettings))
750 if (
$fields[
'QUANTITY_TRACE'] == self::STATUS_DEFAULT)
752 $fields[
'QUANTITY_TRACE'] = self::$defaultProductSettings[
'QUANTITY_TRACE'];
754 if (
$fields[
'CAN_BUY_ZERO'] == self::STATUS_DEFAULT)
756 $fields[
'CAN_BUY_ZERO'] = self::$defaultProductSettings[
'CAN_BUY_ZERO'];
761 (
float)
$fields[
'QUANTITY'] <= 0
762 &&
$fields[
'QUANTITY_TRACE'] == self::STATUS_YES
763 &&
$fields[
'CAN_BUY_ZERO'] == self::STATUS_NO
770 return self::STATUS_NO;
781 if (isset(
$fields[
'QUANTITY_TRACE']) && isset(
$fields[
'CAN_BUY_ZERO']))
783 if (empty(self::$defaultProductSettings))
787 if (
$fields[
'QUANTITY_TRACE'] == self::STATUS_DEFAULT)
789 $fields[
'QUANTITY_TRACE'] = self::$defaultProductSettings[
'QUANTITY_TRACE'];
791 if (
$fields[
'CAN_BUY_ZERO'] == self::STATUS_DEFAULT)
793 $fields[
'CAN_BUY_ZERO'] = self::$defaultProductSettings[
'CAN_BUY_ZERO'];
796 return (
$fields[
'QUANTITY_TRACE'] === self::STATUS_YES &&
$fields[
'CAN_BUY_ZERO'] === self::STATUS_NO);
810 self::$defaultProductSettings = [
812 'CAN_BUY_ZERO' => (
Main\
Config\Option::get(
'catalog',
'default_can_buy_zero') ===
'Y' ?
'Y' :
'N'),
814 'SUBSCRIBE' => (
Main\
Config\Option::get(
'catalog',
'default_subscribe') ===
'N' ?
'N' :
'Y'),
829 self::TYPE_PRODUCT => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_PRODUCT'),
830 self::TYPE_SET => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_SET_MSGVER_1'),
831 self::TYPE_SKU => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_SKU'),
832 self::TYPE_EMPTY_SKU => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_EMPTY_SKU'),
833 self::TYPE_OFFER => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_OFFER'),
834 self::TYPE_FREE_OFFER => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_FREE_OFFER'),
835 self::TYPE_SERVICE => Loc::getMessage(
'PRODUCT_ENTITY_TYPE_SERVICE'),
843 self::TYPE_FREE_OFFER,
844 self::TYPE_EMPTY_SKU,
860 self::PAYMENT_TYPE_SINGLE => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_TYPE_SINGLE'),
861 self::PAYMENT_TYPE_REGULAR => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_TYPE_REGULAR'),
862 self::PAYMENT_TYPE_TRIAL => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_TYPE_TRIAL')
866 self::PAYMENT_TYPE_SINGLE,
867 self::PAYMENT_TYPE_REGULAR,
868 self::PAYMENT_TYPE_TRIAL
883 self::PAYMENT_PERIOD_HOUR => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_HOUR'),
884 self::PAYMENT_PERIOD_DAY => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_DAY'),
885 self::PAYMENT_PERIOD_WEEK => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_WEEK'),
886 self::PAYMENT_PERIOD_MONTH => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_MONTH'),
887 self::PAYMENT_PERIOD_QUART => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_QUART'),
888 self::PAYMENT_PERIOD_SEMIYEAR => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_SEMIYEAR'),
889 self::PAYMENT_PERIOD_YEAR => Loc::getMessage(
'PRODUCT_ENTITY_PAYMENT_PERIOD_YEAR'),
893 self::PAYMENT_PERIOD_HOUR,
894 self::PAYMENT_PERIOD_DAY,
895 self::PAYMENT_PERIOD_WEEK,
896 self::PAYMENT_PERIOD_MONTH,
897 self::PAYMENT_PERIOD_QUART,
898 self::PAYMENT_PERIOD_SEMIYEAR,
899 self::PAYMENT_PERIOD_YEAR,
911 'AVAILABLE' => self::STATUS_NO,
913 'QUANTITY_TRACE' => self::STATUS_YES,
914 'CAN_BUY_ZERO' => self::STATUS_NO,
922 case self::TYPE_PRODUCT:
925 case self::TYPE_OFFER:
926 $result = Loc::getMessage(
'PRODUCT_ENTITY_ENTITY_NAME_ANY_PRODUCT');
928 case self::TYPE_SERVICE:
929 $result = Loc::getMessage(
'PRODUCT_ENTITY_ENTITY_NAME_ANY_SERVICE');
931 case self::TYPE_FREE_OFFER:
932 case self::TYPE_EMPTY_SKU:
933 $result = Loc::getMessage(
'PRODUCT_ENTITY_ENTITY_NAME_ANY_RESTLESS');
955 self::TYPE_EMPTY_SKU,
static getCurrentRatio($product)
static array $defaultProductSettings
static prepareSubscribe($value)
static validatePurchasingCurrency()
static validatePriceType()
const PAYMENT_PERIOD_YEAR
static getTradingEntityNameByType(int $type)
static prepareNegativeAmountTrace($value)
static isNeedCheckQuantity(array $fields)
const PRICE_MODE_QUANTITY
static getPaymentPeriods($descr=false)
static modifyCanBuyZero()
static getDefaultAvailableSettings()
static getStoreDocumentRestrictedProductTypes()
const PAYMENT_TYPE_SINGLE
static isExistProduct($product)
const PAYMENT_TYPE_REGULAR
static getCurrentRatioWithMeasure($product)
static prepareCanBuyZero($value)
const PAYMENT_PERIOD_MONTH
const PAYMENT_PERIOD_SEMIYEAR
static getPaymentTypes($descr=false)
static modifyQuantityTrace()
static calculateAvailable($fields)
static loadDefaultProductSettings()
static clearProductCache($product=0)
static getProductTypes($descr=false)
const PAYMENT_PERIOD_WEEK
static prepareQuantityTrace($value)
const PAYMENT_PERIOD_QUART
static validateRecurSchemeType()
const USER_FIELD_ENTITY_ID
static modifyNegativeAmountTrace()
const PAYMENT_PERIOD_DOUBLE_YEAR
const PAYMENT_PERIOD_HOUR
static get($moduleId, $name, $default="", $siteId=false)
static getList(array $parameters=array())
static normalizeArrayValuesByInt(&$map, $sorted=true)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(! $useStoreControl) $measureIterator