3namespace Bitrix\Catalog\Component;
6use Bitrix\Catalog\Access\AccessController;
7use Bitrix\Catalog\Access\ActionDictionary;
8use Bitrix\Catalog\Config\State;
9use Bitrix\Catalog\v2\Property\Property;
10use Bitrix\Currency\CurrencyManager;
11use Bitrix\Currency\Integration\IblockMoneyProperty;
12use Bitrix\Iblock\ElementTable;
13use Bitrix\Iblock\PropertyTable;
14use Bitrix\Main\Engine\Response\AjaxJson;
15use Bitrix\Main\Grid\Editor\Types;
16use Bitrix\Main\Grid\Options;
17use Bitrix\Main\Loader;
18use Bitrix\Main\Localization\Loc;
19use Bitrix\Main\Text\HtmlFilter;
33 return static::formatFieldName(
$name);
45 return static::formatFieldName(
$name);
50 if (State::isExternalCatalog())
63 static::formatFieldName(
'VAT_ID'),
64 static::formatFieldName(
'VAT_INCLUDED'),
66 'TITLE' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_TITLE_VAT_INCLUDED'),
67 'DESCRIPTION' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_DESC_VAT_INCLUDED'),
69 if (AccessController::getCurrent()->check(ActionDictionary::ACTION_PRODUCT_PURCHASE_INFO_VIEW))
71 $result[
'PURCHASING_PRICE_FIELD'] = [
73 static::formatFieldName(
'PURCHASING_PRICE_FIELD'),
75 'TITLE' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_TITLE_PURCHASING_PRICE_FIELD'),
76 'DESCRIPTION' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_DESC_PURCHASING_PRICE_FIELD'),
81 static::formatFieldName(
'HEIGHT'),
82 static::formatFieldName(
'LENGTH'),
83 static::formatFieldName(
'WIDTH'),
84 static::formatFieldName(
'WEIGHT'),
86 'TITLE' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_TITLE_MEASUREMENTS'),
87 'DESCRIPTION' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_DESC_MEASUREMENTS'),
91 static::formatFieldName(
'MEASURE_RATIO'),
93 'TITLE' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_TITLE_MEASURE_RATIO'),
94 'DESCRIPTION' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_SETTINGS_DESC_MEASURE_RATIO_MSGVER_1'),
102 $headers = static::getHeaderIdsBySettingId($settingId);
107 $allUsedColumns =
$options->getUsedColumns();
109 if (empty($allUsedColumns))
111 $allUsedColumns = $currentHeaders;
114 if ($selected ===
'true')
118 $currentHeadersInDefaultPosition = array_values(
119 array_intersect($defaultHeaders, array_merge($allUsedColumns,
$headers))
125 $insertPosition = array_search($header, $currentHeadersInDefaultPosition,
true);
126 array_splice($allUsedColumns, $insertPosition, 0, $header);
131 $allUsedColumns = array_diff($allUsedColumns,
$headers);
134 $options->setColumns(implode(
',', $allUsedColumns));
138 return AjaxJson::createSuccess();
154 case 'PURCHASING_PRICE_FIELD':
155 if (AccessController::getCurrent()->check(ActionDictionary::ACTION_PRODUCT_PURCHASE_INFO_VIEW))
158 'PURCHASING_PRICE_FIELD',
162 case 'MEASURE_RATIO':
177 $id = static::formatFieldName($id);
187 parent::buildDescriptions(),
195 $description = parent::getPropertyDescription($property);
210 'TYPE' => Types::MULTISELECT,
212 'ITEMS' => $dropdownItems,
221 $dropdownItems[] = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_NOT_SELECTED');
228 $dropdownItems[$item[
'VALUE']] = $item[
'NAME'];
232 'TYPE' => Types::DROPDOWN,
233 'items' => $dropdownItems,
244 'TYPE' => Types::CUSTOM,
258 'TYPE' => Types::MONEY,
259 'CURRENCY_LIST' => CurrencyManager::getSymbolList(),
260 'HTML_ENTITY' =>
true,
267 $nonEditableUserTypes = [
279 || in_array(
$description[
'settings'][
'USER_TYPE'], $nonEditableUserTypes,
true)
299 $values = $this->getShowedValues($allowDefaultValues);
304 if (!isset($values[
$name]))
309 $currentValue = $values[
$name];
315 if (!empty($values[
$name]))
321 $values[
$name] = (float)($values[
$name] ?: 0);
324 if (is_array($currentValue))
334 foreach ($currentValue as $multipleItemValue)
336 $formatted[] =
$items[$multipleItemValue];
339 $values[
$name] = $formatted;
344 $description[
'id'] === static::formatFieldName(
'ACTIVE')
345 ||
$description[
'id'] === static::formatFieldName(
'AVAILABLE')
346 ||
$description[
'id'] === static::formatFieldName(
'VAT_INCLUDED')
349 $code = $currentValue ===
'Y' ?
'YES' :
'NO';
353 $code = ($currentValue !==
'') ?
'YES' :
'NO';
355 $values[
$name] = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_VALUE_' .
$code);
365 if ($currentValue === $item[
'VALUE'])
379 $currentVat = (int)$values[
$name];
383 foreach ($this->getVats() as
$vat)
385 if ((
int)
$vat[
'ID'] === $currentVat)
395 is_array($values[
$name])
396 ? array_column($values[
$name],
'BARCODE')
405 $separatedValues = IblockMoneyProperty::getSeparatedValues($values[
$name]);
406 $amount = (float)($separatedValues[
'AMOUNT'] .
'.' . $separatedValues[
'DECIMALS']);
407 $currency = $separatedValues[
'CURRENCY'];
413 if (is_array($values[
$name]))
415 $values[
$name] = implode(
', ', $values[
$name]);
426 $headerName = static::getHeaderName(
'NAME');
430 'id' => static::formatFieldName(
'NAME'),
431 'name' => $headerName[
'NAME'],
432 'title' => $headerName[
'TITLE'],
438 'TYPE' => Types::TEXT,
439 'PLACEHOLDER' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_NEW_VARIATION_PLACEHOLDER_MSGVER_1'),
443 'width' => $defaultWidth,
454 if (State::isUsedInventoryManagement())
469 'AVAILABLE',
'VAT_ID',
'VAT_INCLUDED',
'QUANTITY',
'QUANTITY_RESERVED',
470 'QUANTITY_TRACE',
'CAN_BUY_ZERO',
471 'WEIGHT',
'WIDTH',
'LENGTH',
'HEIGHT',
472 'SHOW_COUNTER',
'CODE',
'TIMESTAMP_X',
'MODIFIED_BY',
473 'DATE_CREATE',
'XML_ID',
489 return self::$headers;
502 $columns = array_fill_keys(
509 $name = $property[
'name'];
515 unset($columns[
$name]);
519 return array_keys($columns);
526 $numberFields = [
'QUANTITY',
'QUANTITY_RESERVED',
'QUANTITY_COMMON',
'MEASURE_RATIO',
'WEIGHT',
'WIDTH',
'LENGTH',
'HEIGHT'];
527 $numberFields = array_fill_keys($numberFields,
true);
529 $immutableFields = [
'TIMESTAMP_X',
'MODIFIED_BY',
'DATE_CREATE',
'CREATED_USER_NAME',
'AVAILABLE'];
530 $immutableFields = array_fill_keys($immutableFields,
true);
532 $defaultFields = [
'QUANTITY',
'MEASURE',
'NAME'];
533 if (State::isUsedInventoryManagement())
535 $defaultFields[] =
'BARCODE';
537 $defaultFields = array_fill_keys($defaultFields,
true);
540 'QUANTITY' =>
'QUANTITY',
541 'AVAILABLE' =>
'AVAILABLE',
544 'MEASURE' =>
'MEASURE',
545 'TIMESTAMP_X' =>
'TIMESTAMP_X',
546 'MODIFIED_BY' =>
'MODIFIED_BY',
547 'DATE_CREATE' =>
'CREATED',
548 'CREATED_USER_NAME' =>
'CREATED_BY',
550 'EXTERNAL_ID' =>
'EXTERNAL_ID',
551 'XML_ID' =>
'XML_ID',
553 'SHOW_COUNTER' =>
'SHOW_COUNTER',
554 'SHOW_COUNTER_START' =>
'SHOW_COUNTER_START',
555 'PREVIEW_PICTURE' =>
'HAS_PREVIEW_PICTURE',
556 'DETAIL_PICTURE' =>
'HAS_DETAIL_PICTURE',
561 $type = isset($numberFields[
$code]) ?
'number' :
'string';
577 case 'QUANTITY_TRACE':
586 if (!isset($immutableFields[
$code]))
589 'TYPE' => Types::TEXT,
596 'TYPE' => Types::CHECKBOX,
602 ? [
'TYPE' => Types::CHECKBOX]
611 $type =
'readOnlyVat';
616 $defaultVat = $this->getDefaultVat();
618 $defaultVat[
'ID'] => $defaultVat[
'NAME'],
621 if ($defaultVat[
'ID'] !== static::NOT_SELECTED_VAT_ID_VALUE && !Loader::includeModule(
'bitrix24'))
623 $vatList[static::NOT_SELECTED_VAT_ID_VALUE] = Loc::getMessage(
"CATALOG_PRODUCT_CARD_VARIATION_GRID_NOT_SELECTED");
626 foreach ($this->getVats() as
$vat)
628 if (
$vat[
'RATE'] === $defaultVat[
'RATE'] &&
$vat[
'EXCLUDE_VAT'] === $defaultVat[
'EXCLUDE_VAT'])
636 'TYPE' => Types::DROPDOWN,
647 if (empty($measureList[$measure[
'ID']]))
649 $measureList[$measure[
'ID']] = \CCatalogMeasureClassifier::getMeasureTitle(
656 'TYPE' => Types::DROPDOWN,
657 'items' => $measureList,
662 case 'QUANTITY_RESERVED':
663 case 'QUANTITY_COMMON':
664 if (State::isUsedInventoryManagement())
671 'TYPE' => Types::NUMBER,
677 case 'MEASURE_RATIO':
679 'TYPE' => Types::NUMBER,
686 'TYPE' => Types::CUSTOM,
691 case 'QUANTITY_TRACE':
697 $items[$field[
'VALUE']] = $field[
'NAME'];
701 'TYPE' => Types::DROPDOWN,
709 $code ===
'MODIFIED_BY'
710 ? static::getHeaderName(
'USER_NAME')
711 : static::getHeaderName(
$code)
714 $sortField = $sortableFields[
$code] ??
false;
717 'id' => static::formatFieldName(
$code),
718 'name' => $headerName[
'NAME'],
719 'title' => $headerName[
'TITLE'],
720 'sort' => $sortField,
722 'headerHint' =>
null,
724 'align' =>
$type ===
'number' ?
'right' :
'left',
725 'editable' => $editable,
726 'width' => $defaultWidth,
727 'default' => isset($defaultFields[
$code]),
747 && $property[
'settings'][
'USER_TYPE'] ===
'directory'
750 $sortField =
'PROPERTY_' . $property[
'propertyId'];
752 $property[
'multiple']
753 || $property[
'propertyCode'] ===
'CML2_LINK'
761 'id' => $property[
'name'],
762 'name' => $property[
'title'],
763 'title' => $property[
'title'],
764 'type' => $property[
'type'],
765 'align' => $property[
'type'] ===
'number' ?
'right' :
'left',
766 'sort' => $sortField,
767 'default' => $property[
'propertyCode'] === self::MORE_PHOTO,
768 'data' => $property[
'data'],
769 'width' => $isDirectory ? 160 :
null,
770 'editable' => $property[
'editable'],
772 if (!empty($property[
'isEnabledOfferTree']))
774 $header[
'hint'] = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_OFFER_TREE_HINT_MSGVER_1');
776 if ($property[
'propertyCode'] === self::MORE_PHOTO)
778 $header[
'hint'] = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_MORE_PHOTO_SIZE');
779 $header[
'hintHtml'] =
true;
784 && $property[
'multiple'] ===
true
785 && $property[
'propertyCode'] !==
'MORE_PHOTO'
788 $header[
'hint'] = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_FILE_MULTIPLE_HINT_MSGVER_1');
809 $headerName = static::getHeaderName(
'PURCHASING_PRICE');
812 'id' => static::formatFieldName(
'PURCHASING_PRICE_FIELD'),
813 'name' => $headerName[
'NAME'],
814 'title' => $headerName[
'TITLE'],
815 'sort' =>
'PURCHASING_PRICE',
821 'TYPE' => Types::MONEY,
822 'CURRENCY_LIST' => CurrencyManager::getSymbolList(),
823 'HTML_ENTITY' =>
true,
827 'width' => $defaultWidth,
845 $currencyList = CurrencyManager::getSymbolList();
849 $columnName = $priceType[
'NAME_LANG'] ?? $priceType[
'NAME'];
854 'name' => $columnName,
855 'title' => $columnName,
856 'sort' =>
'SCALED_PRICE_'.$priceType[
'ID'],
862 'TYPE' => Types::MONEY,
863 'CURRENCY_LIST' => $currencyList,
864 'HTML_ENTITY' =>
true,
872 : Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_PRICE_EDIT_RESTRICTED_HINT')
874 'base' => $priceType[
'BASE'] ===
'Y',
875 'width' => $defaultWidth,
876 'default' => $priceType[
'BASE'] ===
'Y',
883 private function getShowedValues(
bool $allowDefaultValues =
true):
array
885 if (!self::$usedHeaders)
888 self::$usedHeaders =
$options->getUsedColumns();
890 if (!self::$usedHeaders)
892 $defaultHeaders = array_filter(
894 static function ($header)
896 return ($header[
'default'] ===
true);
900 self::$usedHeaders = array_column($defaultHeaders,
'id');
905 $filteredDescriptions = array_filter(
913 return parent::getValues($allowDefaultValues, $filteredDescriptions);
918 $values = $this->getShowedValues($allowDefaultValues);
924 if (!isset($values[
$name]))
938 'NAME' => $descriptionData[
'amount'],
939 'VALUE' => $values[$descriptionData[
'amount']],
942 'NAME' => $descriptionData[
'currency'][
'name'],
943 'VALUE' => $values[$descriptionData[
'currency'][
'name']],
949 $variants = $descriptionData[
'items'] ?? [];
950 foreach ($variants as $variant)
952 if ($values[
$name] === $variant[
'ID'])
954 $values[
$name] = $variant[
'NAME'];
982 $pricePrefix = self::GRID_FIELD_PREFIX . self::PRICE_FIELD_PREFIX;
983 $purchacingPricePrefix = self::GRID_FIELD_PREFIX .
'PURCHASING_PRICE';
988 $value = $dirtyValues[
$name] ??
null;
997 if (
$type ===
'multilist' && empty($value))
1003 $result[
'PROPERTIES'][$propertyId] = $value;
1009 && isset($value[
'PRICE'][
'NAME'], $value[
'PRICE'][
'VALUE'], $value[
'CURRENCY'][
'VALUE'])
1012 $priceGroupId = str_replace($pricePrefix,
'', $value[
'PRICE'][
'NAME']);
1015 $result[
'PRICES'][$priceGroupId] = [
1016 'PRICE' => (float)$value[
'PRICE'][
'VALUE'],
1017 'CURRENCY' => (
string)$value[
'CURRENCY'][
'VALUE'],
1022 elseif (mb_strpos(
$name, $purchacingPricePrefix) === 0)
1024 if (is_array($value) && isset($value[
'PRICE'][
'VALUE'], $value[
'CURRENCY'][
'VALUE']))
1026 $result[
'PURCHASING_PRICE'] = (float)$value[
'PRICE'][
'VALUE'];
1027 $result[
'PURCHASING_CURRENCY'] = (string)$value[
'CURRENCY'][
'VALUE'];
1037 if (is_array($value))
1039 array_push(
$result[
'BARCODES'], ...$value);
1043 $result[
'BARCODES'][] = $value;
1048 $result[
'MEASURE_RATIO'] = $value;
1057 $additionalValues = parent::getAdditionalValues($values,
$descriptions);
1059 $numberFields = [
'MEASURE_RATIO',
'QUANTITY'];
1060 foreach ($numberFields as $fieldName)
1063 if (isset($values[$fieldName]) && $values[$fieldName] == 0)
1065 $additionalValues[$fieldName] =
null;
1069 return $additionalValues;
1074 $settings = parent::getPropertySettings($property);
1085 if (!empty($value) && !is_array($value))
1090 if (is_array($value))
1092 $fileCount = min(
count($value), 3);
1093 $value = reset($value);
1100 $image = \CFile::GetFileArray($value);
1103 $imageSrc = $image[
'SRC'];
1107 $multipleClass = match ($fileCount)
1109 3 =>
' ui-image-input-img-block-multiple',
1110 2 =>
' ui-image-input-img-block-double',
1111 0 =>
' ui-image-input-img-block-empty',
1117 $imageSrc =
' src="' . $imageSrc .
'"';
1121<div
class=
"ui-image-input-img-block{$multipleClass}">
1122 <div
class=
"ui-image-input-img-block-inner">
1123 <div
class=
"ui-image-input-img-item">
1124 <img
class=
"ui-image-input-img"{$imageSrc}>
1135 if (isset($property[
'settings'][
'MULTIPLE']) && $property[
'settings'][
'MULTIPLE'] ===
'Y')
1145 if ($field[
'entity'] ===
'money')
1150 if ($field[
'entity'] ===
'barcode')
1155 if (isset($field[
'originalName']) && $field[
'originalName'] ===
'QUANTITY_COMMON')
1160 return parent::getFieldValue($field);
1165 if ($field[
'priceTypeId'] ===
'PURCHASING_PRICE')
1167 $price = $this->entity->getField(
'PURCHASING_PRICE');
1168 $currency = $this->entity->getField(
'PURCHASING_CURRENCY');
1172 $priceItem = $this->entity
1173 ->getPriceCollection()
1174 ->findByGroupId($field[
'priceTypeId'])
1176 $price = $priceItem?->getPrice();
1182 return \CCurrencyLang::CurrencyFormat($price,
$currency,
true);
1191 $commonQuantityName =
'QUANTITY_COMMON';
1194 'entity' =>
'product',
1196 'originalName' => $commonQuantityName,
1197 'title' => Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_DESCRIPTION_COMMON_QUANTITY_TITLE'),
1199 'editable' =>
false,
1200 'required' =>
false,
1201 'placeholders' =>
null,
1202 'defaultValue' =>
null,
1214 $quantity = (float)$this->entity->getField(
'QUANTITY');
1215 $quantityReserved = (float)$this->entity->getField(
'QUANTITY_RESERVED');
1216 return $quantity + $quantityReserved;
1221 if (!State::isUsedInventoryManagement())
1226 $headerName = static::getHeaderName(
'BARCODE');
1230 'entity' =>
'barcode',
1231 'name' => static::formatFieldName(
'BARCODE'),
1232 'title' => $headerName[
'NAME'],
1233 'type' =>
'barcode',
1236 'required' =>
false,
1247 foreach ($this->entity->getBarcodeCollection() as $barcodeItem)
1250 'ID' => $barcodeItem->getId(),
1251 'BARCODE' => $barcodeItem->getBarcode(),
1265 $headerName = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_HEADER_NAME_' .
$code);
1266 $headerTitle = Loc::getMessage(
'CATALOG_PRODUCT_CARD_VARIATION_GRID_HEADER_TITLE_' .
$code);
1269 'NAME' => $headerName,
1270 'TITLE' => $headerTitle ?? $headerName,
if($strVal !='') $productFields
static encode($string, $flags=ENT_COMPAT, $doubleEncode=true)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
if(!function_exists("bx_hmac")) $amount
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
getMeasures($arBasketItems)