23 private const DISCOUNT_TYPE_MONETARY = 1;
24 private const DISCOUNT_TYPE_PERCENTAGE = 2;
25 private const BRAND_PROPERTY_CODE =
'BRAND_FOR_FACEBOOK';
28 private $detailUrlType;
30 private $priceGroupId;
40 $this->
id = uniqid(
'',
true);
42 'innerId' => $this->id,
50 'catalogPrice' =>
null,
53 'priceExclusive' => 0,
54 'isCustomPrice' =>
'Y',
55 'discountType' => self::DISCOUNT_TYPE_PERCENTAGE,
64 'additionalFields' => [],
73 $basePriceGroup = \CCatalogGroup::GetBaseGroup();
80 private function getField($name)
82 return $this->fields[$name] ??
'';
85 private function getEncodedSkuTree(): string
87 if (!$this->sku || $this->sku->isSimple())
93 $product = $this->sku->getParent();
94 $skuTree = ServiceContainer::make(
'sku.tree', [
'iblockId' => $product->getIblockId()]);
101 $skuTreeItems = $skuTree->loadJsonOffers([
102 $product->getId() => $this->sku->getId(),
105 if (!$skuTreeItems[$product->getId()][$this->sku->getId()])
110 return Json::encode($skuTreeItems[$product->getId()][$this->sku->getId()]);
113 private function getImageInputField(): ?array
120 $variationImageField =
new ImageInput($this->sku);
122 return $variationImageField->getFormattedField();
125 private function getSum(): float
127 return (
float)$this->getField(
'priceExclusive') * (float)$this->getField(
'quantity');
130 private function getDetailUrl(): string
132 if (!$this->sku || $this->sku->isNew())
137 $parent = $this->sku->getParent();
138 $urlBuilder = BuilderManager::getInstance()->getBuilder($this->detailUrlType);
139 if (!$urlBuilder || !$parent)
144 $urlBuilder->setIblockId($parent->getIblockId());
146 return $urlBuilder->getElementDetailUrl($parent->getId());
151 return $this->fields;
163 return $this->sku->getId();
171 return $this->priceItem;
179 $this->fields[
'productId'] = $sku->
getParent()->getId();
181 $this->fields[
'skuId'] = $sku->
getId();
182 $this->fields[
'module'] =
'catalog';
184 $this->fillFieldsFromSku();
192 $this->priceItem =
null;
193 $this->fields[
'productId'] =
'';
194 $this->fields[
'skuId'] =
'';
195 $this->fields[
'module'] =
'';
196 $this->fields[
'properties'] = [];
201 private function fillFieldsFromSku(): void
203 $this->
setName($this->sku->getName());
204 $this->
setType($this->sku->getType());
205 $this->fillProperties();
207 $this->fillMeasureFields();
208 $this->fillTaxFields();
209 $this->fillPriceFields();
210 $this->fillDeliveryFields();
213 private function fillProperties(): void
216 foreach ($this->sku->getPropertyCollection() as $property)
218 $formattedValues = $this->getFormattedProperty($property);
219 if ($formattedValues ===
null)
223 $properties[] = $formattedValues;
226 $this->fields[
'properties'] = $properties;
229 private function fillBrands(): void
232 $product = $this->sku->getParent();
238 $property = $product->getPropertyCollection()->findByCode(self::BRAND_PROPERTY_CODE);
244 $userType = \CIBlockProperty::GetUserType($property->getUserType());
245 $userTypeMethod = $userType[
'GetUIEntityEditorProperty'];
246 $propertySettings = $property->getSettings();
247 $propertyValues = $property->getPropertyValueCollection()->getValues();
248 $description = $userTypeMethod($propertySettings, $propertyValues);
249 $propertyBrandItems = $description[
'data'][
'items'];
251 $selectedBrandItems = [];
253 foreach ($propertyBrandItems as $propertyBrandItem)
255 if (in_array($propertyBrandItem[
'VALUE'], $propertyValues,
true))
257 $selectedBrandItems[] = $propertyBrandItem;
261 $this->fields[
'brands'] = $selectedBrandItems;
264 private function getFormattedProperty(Property $property): ?array
266 $propertyKeys = array_flip([
'ID',
'NAME',
'CODE',
'SORT',
'XML_ID']);
267 $formattedValues = $property->getPropertyValueCollection()->toArray();
268 if (empty($formattedValues))
274 if ($property->getPropertyType() === PropertyTable::TYPE_LIST)
276 $enumIds = array_column($formattedValues,
'VALUE');
277 $enumSettings = PropertyEnumerationTable::getList([
278 'select' => [
'ID',
'VALUE'],
286 $enumValueMap = array_column($enumSettings,
'VALUE',
'ID');
289 $propertySettings = $property->getSettings();
290 foreach ($formattedValues as $propertyValueId => $valueInfo)
292 $value = $valueInfo[
'VALUE'];
294 if ($property->getPropertyType() === PropertyTable::TYPE_LIST)
296 $value = $enumValueMap[$value] ?? $value;
299 $displayProperty = array_merge(
302 'DESCRIPTION' => $valueInfo[
'DESCRIPTION'] ??
null,
303 '~DESCRIPTION' => $valueInfo[
'DESCRIPTION'] ??
null,
309 $displayProperty = \CIBlockFormatProperties::GetDisplayValue([], $displayProperty);
311 $formattedValues[$propertyValueId][
'DISPLAY_VALUE'] = $displayProperty[
'DISPLAY_VALUE'];
314 $propertySettings = array_intersect_key($propertySettings, $propertyKeys);
315 $propertySettings[
'PROPERTY_VALUES'] = $formattedValues;
317 return $propertySettings;
320 private function fillMeasureFields(): void
322 $measureId = (int)$this->sku->getField(
'MEASURE');
325 ? [
'=ID' => $this->sku->getField(
'MEASURE')]
326 : [
'=IS_DEFAULT' =>
'Y']
329 $measureRow = \CCatalogMeasure::getList(
334 [
'CODE',
'SYMBOL',
'SYMBOL_INTL']
337 if ($measure = $measureRow->Fetch())
339 $name = $measure[
'SYMBOL'] ?? $measure[
'SYMBOL_INTL'];
341 ->setMeasureCode((
int)$measure[
'CODE'])
342 ->setMeasureName($name)
346 $ratioItem = $this->sku->getMeasureRatioCollection()->findDefault();
353 private function fillTaxFields(): void
355 $taxId = $this->sku->getField(
'VAT_ID');
358 $taxId = $this->sku->getIblockInfo()->getVatId();
362 ->setTaxId((
int)$taxId)
363 ->setTaxIncluded($this->sku->getField(
'VAT_INCLUDED'))
367 private function fillPriceFields(): void
369 if (!$this->priceGroupId)
374 $this->priceItem = $this->sku->getPriceCollection()->findByGroupId($this->priceGroupId);
375 if ($this->priceItem)
377 $price = (float)$this->priceItem->getPrice();
380 ->setBasePrice($price)
381 ->setPriceExclusive($price)
386 private function fillDeliveryFields(): void
388 $this->fields[
'weight'] = $this->sku->getField(
'WEIGHT');
390 $this->fields[
'dimensions'] = [
391 'LENGTH' => $this->sku->getField(
'LENGTH'),
392 'WIDTH' => $this->sku->getField(
'WIDTH'),
393 'HEIGHT' => $this->sku->getField(
'HEIGHT'),
397 private function hasEditRights(): bool
401 if (!$this->sku || !$USER instanceof \CUser)
407 \CIBlockElementRights::UserHasRightTo($this->sku->getIblockId(), $this->sku->getId(),
'element_edit')
408 && \CIBlockElementRights::UserHasRightTo($this->sku->getIblockId(), $this->sku->getId(),
'element_edit_price')
409 && !AccessController::getCurrent()->check(ActionDictionary::ACTION_PRICE_EDIT)
415 if (!$this->priceItem)
420 return (
float)$this->priceItem->getPrice();
425 $this->fields[
'quantity'] = $value;
430 public function setId(
string $value): self
433 $this->fields[
'innerId'] = $value;
438 public function setName(
string $value =
null): self
440 $this->fields[
'name'] = $value;
447 $this->fields[
'code'] = $value;
454 $this->fields[
'type'] = $value;
461 $this->fields[
'sort'] = $value;
468 $this->fields[
'discountType'] =
469 $value === self::DISCOUNT_TYPE_MONETARY
470 ? self::DISCOUNT_TYPE_MONETARY
471 : self::DISCOUNT_TYPE_PERCENTAGE;
478 $this->fields[
'isCustomPrice'] = ($value ===
'N') ?
'N' :
'Y';
485 $this->fields[
'basePrice'] = $value > 0 ? $value : 0;
492 $this->fields[
'price'] = $value > 0 ? $value : 0;
499 $this->fields[
'priceExclusive'] = $value > 0 ? $value : 0;
508 $this->fields[
'measureCode'] = $code;
516 $this->fields[
'measureName'] = $name;
523 $this->fields[
'measureRatio'] = $ratio > 0 ? $ratio : 1;
530 $this->fields[
'discountRate'] = $value;
537 $this->fields[
'discount'] = $value;
544 $this->fields[
'additionalFields'][$name] = $value;
551 $this->fields[
'taxIncluded'] = ($value ===
'N') ?
'N' :
'Y';
558 $this->fields[
'taxId'] = $value;
565 $this->fields[
'additionalFields'] = [];
574 $this->priceGroupId = $groupId;
582 $this->detailUrlType = $type;
590 'selectorId' => $this->id,
591 'offerId' => $this->sku ? $this->sku->getId() :
null,
592 'fields' => $this->fields,
593 'skuTree' => $this->getEncodedSkuTree(),
594 'showDiscount' => !empty($this->getField(
'discount')) ?
'Y' :
'N',
595 'image' => $this->getImageInputField(),
596 'sum' => $this->getSum(),
598 'detailUrl' => $this->getDetailUrl(),
599 'discountSum' => $this->getField(
'discountSum'),
600 'hasEditRights' => $this->hasEditRights(),