setup = $setup; $this->fileRepository = new FileRepository(SiteRepository::getDefaultServerName()); $this->catalogRepository = new CatalogRepository(); $this->xmlOfferBuilder = new XmlOfferBuilder( $setup, MeasureRepository::getMeasures(), SiteRepository::getDefaultServerName() ); } /** * Возвращает страницу (массив) с товарами или торговыми предложениями (в зависимости от $param) * * @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param * @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo * @return XmlOffer[] */ public function getXmlOffersPart(SelectParams $param, CatalogIblockInfo $catalogIblockInfo): array { $ciBlockResult = $this->catalogRepository->getProductPage($param, $catalogIblockInfo); $barcodes = $this->catalogRepository->getProductBarcodesByIblockId($catalogIblockInfo->productIblockId); $offers = []; while ($offer = $ciBlockResult->GetNext()) { $this->setXmlOfferParams($param, $offer, $catalogIblockInfo, $barcodes); $this->xmlOfferBuilder->setCategories($this->catalogRepository->getProductCategoriesIds($offer['ID'])); $offers[] = $this->xmlOfferBuilder->build(); } return $offers; } /** * возвращает массив XmlOffers для конкретного продукта * * @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $paramsForOffer * @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo * @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer $product * @return XmlOffer[] */ public function getXmlOffersBySingleProduct( SelectParams $paramsForOffer, CatalogIblockInfo $catalogIblockInfo, XmlOffer $product ): array { $xmlOffers = $this->getXmlOffersPart($paramsForOffer, $catalogIblockInfo); return $this->addProductInfo($xmlOffers, $product); } /** * Декорирует оферы информацией из товаров * * @param XmlOffer[] $xmlOffers * @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer $product * @return \Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer[] */ private function addProductInfo(array $xmlOffers, XmlOffer $product): array { foreach ($xmlOffers as $offer) { $offer->productId = $product->id; $offer->params = $this->mergeParams($offer->params, $product->params); $offer->unitCode = $offer->unitCode === null ? null : $offer->unitCode->merge($product->unitCode); $offer->vatRate = $offer->vatRate === 'none' ? $product->vatRate : $offer->vatRate; $offer->vendor = $offer->mergeValues($product->vendor, $offer->vendor); $offer->picture = $offer->mergeValues($product->picture, $offer->picture); $offer->weight = $offer->mergeValues($product->weight, $offer->weight); $offer->dimensions = $offer->mergeValues($product->dimensions, $offer->dimensions); $offer->categoryIds = $product->categoryIds; $offer->productName = $product->productName; } return $xmlOffers; } /** * Получение настраиваемых параметров, если они лежат в HL-блоке * * @param int $iblockId //ID инфоблока товаров, даже если данные нужны по SKU * @param array $productProps * @param array $configurableParams * @param array $hls * @return array */ private function getHlParams(int $iblockId, array $productProps, array $configurableParams, array $hls): array { $params = []; foreach ($hls as $hlName => $hlBlockProduct) { if (isset($hlBlockProduct[$iblockId])) { reset($hlBlockProduct[$iblockId]); $firstKey = key($hlBlockProduct[$iblockId]); $hlRepository = new HlRepository($hlName); if ($hlRepository->getHl() === null) { continue; } $result = $hlRepository->getDataByXmlId($productProps[$configurableParams[$firstKey] . '_VALUE']); if ($result === null) { continue; } foreach ($hlBlockProduct[$iblockId] as $hlPropCodeKey => $hlPropCode) { if (isset($result[$hlPropCode])) { $params[$hlPropCodeKey] = $result[$hlPropCode]; } } } } return $params; } /** * @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param * @param array $product * @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo * @param array $barcodes */ private function setXmlOfferParams( SelectParams $param, array $product, CatalogIblockInfo $catalogIblockInfo, array $barcodes ): void { if ($param->parentId === null) { $pictureProperty = $this->setup->properties->products->pictures[$catalogIblockInfo->productIblockId]; } else { $pictureProperty = $this->setup->properties->sku->pictures[$catalogIblockInfo->productIblockId]; } //достаем значения из HL блоков товаров $this->xmlOfferBuilder->setProductHlParams($this->getHlParams( $catalogIblockInfo->productIblockId, $product, $param->configurable, $this->setup->properties->highloadblockProduct )); //достаем значения из HL блоков торговых предложений $this->xmlOfferBuilder->setSkuHlParams($this->getHlParams( $catalogIblockInfo->productIblockId, $product, $param->configurable, $this->setup->properties->highloadblockSku )); $this->xmlOfferBuilder->setSelectParams($param); $this->xmlOfferBuilder->setOfferProps($product); $this->xmlOfferBuilder->setBarcode($barcodes[$product['ID']] ?? ''); $this->xmlOfferBuilder->setCatalogIblockInfo($catalogIblockInfo); $this->xmlOfferBuilder->setPicturesPath( $this ->fileRepository ->getProductPicture($product, $pictureProperty ?? '') ); } /** * @param array $offerParams * @param array $productParams */ private function mergeParams(array $offerParams, array $productParams): array { $offerCodes = []; /** @var \Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam $offerParam */ foreach ($offerParams as $offerParam) { $offerCodes[] = $offerParam->code; } /** @var \Intaro\RetailCrm\Model\Bitrix\Xml\OfferParam $productParam */ foreach ($productParams as $productParam) { if (in_array($productParam->code, $offerCodes, true)) { continue; } $offerParams[] = $productParam; } return $offerParams; } }