1
0
mirror of synced 2024-11-26 15:26:08 +03:00
bitrix-module/intaro.retailcrm/lib/icml/xmlofferdirector.php
2021-09-08 10:05:09 +03:00

232 lines
8.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Intaro\RetailCrm\Icml;
use Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo;
use Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup;
use Intaro\RetailCrm\Repository\CatalogRepository;
use Intaro\RetailCrm\Repository\FileRepository;
use Intaro\RetailCrm\Repository\HlRepository;
use Intaro\RetailCrm\Repository\MeasureRepository;
use Intaro\RetailCrm\Repository\SiteRepository;
/**
* Class XmlOfferDirector
* @package Intaro\RetailCrm\Icml
*/
class XmlOfferDirector
{
/**
* @var \Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup
*/
private $setup;
/**
* @var \Intaro\RetailCrm\Repository\FileRepository
*/
private $fileRepository;
/**
* @var \Intaro\RetailCrm\Repository\CatalogRepository
*/
private $catalogRepository;
/**
* @var \Intaro\RetailCrm\Icml\XmlOfferBuilder
*/
private $xmlOfferBuilder;
/**
* XmlOfferFactory constructor.
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup $setup
*/
public function __construct(XmlSetup $setup)
{
$this->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;
}
}