1
0
mirror of synced 2024-11-29 08:46:09 +03:00

Optimize generator (#215)

This commit is contained in:
Сергей Чазов 2021-09-08 16:31:17 +03:00 committed by GitHub
parent d06cb3c6e6
commit c3216f72d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 342 additions and 209 deletions

View File

@ -1,3 +1,9 @@
## 2021-09-08 v.5.8.1
* Оптимизирована работа генератора icml каталога
* В генератор каталога добавлена возможность указывать свойства выгрузки одновременно для простых товаров и товаров с торговыми предложениями
* Исправлена ошибка выгрузки заказов из неподключенного к CRM магазина при использовании нескольких сайтов на одной лицензии
* Изменена логика обмена оплатами: для интеграционных оплат дата оплаты больше не передается из Битрикса
## 2021-08-19 v.5.8.0 ## 2021-08-19 v.5.8.0
* Добавлена синхронизация ответственного менеджера в заказе * Добавлена синхронизация ответственного менеджера в заказе
* Исправлена ошибка выгрузки заказов с корпоративными клиентами, уже присутствующими в системе * Исправлена ошибка выгрузки заказов с корпоративными клиентами, уже присутствующими в системе

View File

@ -1,3 +1,4 @@
- Добавлена синхронизация ответственного менеджера в заказе - Оптимизирована работа генератора icml каталога
- Исправлена ошибка выгрузки заказов с корпоративными клиентами, уже присутствующими в системе - В генератор каталога добавлена возможность указывать свойства выгрузки одновременно для простых товаров и товаров с торговыми предложениями
- Исправлена ошибка выгрузки остатков при наличии более 100 складов в Битрикс - Исправлена ошибка выгрузки заказов из неподключенного к CRM магазина при использовании нескольких сайтов на одной лицензии
- Изменена логика обмена оплатами: для интеграционных оплат дата оплаты больше не передается из Битрикса

View File

@ -1,6 +1,6 @@
<?php <?php
$arModuleVersion = [ $arModuleVersion = [
'VERSION' => '5.8.0', 'VERSION' => '5.8.1',
'VERSION_DATE' => '2021-08-19 16:00:00', 'VERSION_DATE' => '2021-09-08 14:00:00',
]; ];

View File

@ -161,6 +161,7 @@ class IcmlDirector
$selectParams->pageNumber = 1; $selectParams->pageNumber = 1;
$selectParams->nPageSize = self::OFFERS_PART; $selectParams->nPageSize = self::OFFERS_PART;
$selectParams->parentId = null; $selectParams->parentId = null;
$selectParams->allParams = array_merge($selectParams->configurable, $selectParams->main);
while ($xmlOffers = $this->xmlOfferDirector->getXmlOffersPart($selectParams, $catalogIblockInfo)) { while ($xmlOffers = $this->xmlOfferDirector->getXmlOffersPart($selectParams, $catalogIblockInfo)) {
$this->icmlWriter->writeOffers($xmlOffers); $this->icmlWriter->writeOffers($xmlOffers);
@ -201,6 +202,7 @@ class IcmlDirector
): void { ): void {
$paramsForProduct->pageNumber = 1; $paramsForProduct->pageNumber = 1;
$paramsForProduct->nPageSize = $this->calculateProductPageSize(); $paramsForProduct->nPageSize = $this->calculateProductPageSize();
$paramsForProduct->allParams = array_merge($paramsForProduct->configurable, $paramsForProduct->main);
do { do {
$productsPart = $this->xmlOfferDirector->getXmlOffersPart($paramsForProduct, $catalogIblockInfo); $productsPart = $this->xmlOfferDirector->getXmlOffersPart($paramsForProduct, $catalogIblockInfo);
@ -244,6 +246,7 @@ class IcmlDirector
$paramsForOffer->pageNumber = 1; $paramsForOffer->pageNumber = 1;
$writingOffersCount = 0; $writingOffersCount = 0;
$paramsForOffer->parentId = $product->id; $paramsForOffer->parentId = $product->id;
$paramsForOffer->allParams = array_merge($paramsForOffer->configurable, $paramsForOffer->main);
do { do {
$xmlOffersPart $xmlOffersPart

View File

@ -39,8 +39,12 @@ class QueryParamsMolder
$params->configurable = $userProps ?? []; $params->configurable = $userProps ?? [];
$params->main = [ $params->main = [
'LANG_DIR',
'CODE',
'IBLOCK_ID', 'IBLOCK_ID',
'IBLOCK_CODE',
'IBLOCK_SECTION_ID', 'IBLOCK_SECTION_ID',
'IBLOCK_EXTERNAL_ID',
'NAME', 'NAME',
'DETAIL_PICTURE', 'DETAIL_PICTURE',
'PREVIEW_PICTURE', 'PREVIEW_PICTURE',

View File

@ -503,16 +503,16 @@ class XmlOfferBuilder
{ {
if (isset($measureId) && !empty($measureId)) { if (isset($measureId) && !empty($measureId)) {
return $this->createUnitFromCode($measureId); return $this->createUnitFromCode($measureId);
} else { }
try {
$currentMeasure = ProductTable::getCurrentRatioWithMeasure($itemId);
if (is_array($currentMeasure)) { try {
return $this->createUnitFromProductTable($currentMeasure); $currentMeasure = ProductTable::getCurrentRatioWithMeasure($itemId);
}
} catch (ArgumentException $exception) { if (is_array($currentMeasure)) {
Logger::getInstance()->write(GetMessage('UNIT_ERROR'), 'i_crm_load_log'); return $this->createUnitFromProductTable($currentMeasure);
} }
} catch (ArgumentException $exception) {
Logger::getInstance()->write(GetMessage('UNIT_ERROR'), 'i_crm_load_log');
} }
return null; return null;

View File

@ -2,6 +2,8 @@
namespace Intaro\RetailCrm\Icml; namespace Intaro\RetailCrm\Icml;
use CIBlock;
use CIBlockSection;
use Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo; use Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo;
use Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams; use Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer; use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer;
@ -36,7 +38,12 @@ class XmlOfferDirector
/** /**
* @var \Intaro\RetailCrm\Icml\XmlOfferBuilder * @var \Intaro\RetailCrm\Icml\XmlOfferBuilder
*/ */
private $xmlOfferBuilder; private $xmlOfferBuilder;
/**
* @var array
*/
private $barcodes;
/** /**
* XmlOfferFactory constructor. * XmlOfferFactory constructor.
@ -52,6 +59,7 @@ class XmlOfferDirector
MeasureRepository::getMeasures(), MeasureRepository::getMeasures(),
SiteRepository::getDefaultServerName() SiteRepository::getDefaultServerName()
); );
$this->barcodes = $this->catalogRepository->getBarcodes();
} }
/** /**
@ -64,12 +72,15 @@ class XmlOfferDirector
public function getXmlOffersPart(SelectParams $param, CatalogIblockInfo $catalogIblockInfo): array public function getXmlOffersPart(SelectParams $param, CatalogIblockInfo $catalogIblockInfo): array
{ {
$ciBlockResult = $this->catalogRepository->getProductPage($param, $catalogIblockInfo); $ciBlockResult = $this->catalogRepository->getProductPage($param, $catalogIblockInfo);
$barcodes = $this->catalogRepository->getProductBarcodesByIblockId($catalogIblockInfo->productIblockId);
$offers = []; $offers = [];
while ($offer = $ciBlockResult->GetNext()) { while ($offer = $ciBlockResult->Fetch()) {
$this->setXmlOfferParams($param, $offer, $catalogIblockInfo, $barcodes); $categories = $this->catalogRepository->getProductCategories($offer['ID']);
$this->xmlOfferBuilder->setCategories($this->catalogRepository->getProductCategoriesIds($offer['ID'])); $offer['DETAIL_PAGE_URL'] = $this->replaceUrlTemplate($offer, $categories);
$this->setXmlOfferParams($param, $offer, $catalogIblockInfo);
$this->xmlOfferBuilder
->setCategories(array_column($categories, 'IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'));
$offers[] = $this->xmlOfferBuilder->build(); $offers[] = $this->xmlOfferBuilder->build();
} }
@ -113,8 +124,10 @@ class XmlOfferDirector
$offer->picture = $offer->mergeValues($product->picture, $offer->picture); $offer->picture = $offer->mergeValues($product->picture, $offer->picture);
$offer->weight = $offer->mergeValues($product->weight, $offer->weight); $offer->weight = $offer->mergeValues($product->weight, $offer->weight);
$offer->dimensions = $offer->mergeValues($product->dimensions, $offer->dimensions); $offer->dimensions = $offer->mergeValues($product->dimensions, $offer->dimensions);
$offer->barcode = $offer->mergeValues($product->barcode, $offer->barcode);
$offer->categoryIds = $product->categoryIds; $offer->categoryIds = $product->categoryIds;
$offer->productName = $product->productName; $offer->productName = $product->productName;
$offer->url = $this->mergeUrls($product->url, $offer->url);
} }
return $xmlOffers; return $xmlOffers;
@ -164,13 +177,11 @@ class XmlOfferDirector
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param * @param \Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams $param
* @param array $product * @param array $product
* @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo * @param \Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo $catalogIblockInfo
* @param array $barcodes
*/ */
private function setXmlOfferParams( private function setXmlOfferParams(
SelectParams $param, SelectParams $param,
array $product, array $product,
CatalogIblockInfo $catalogIblockInfo, CatalogIblockInfo $catalogIblockInfo
array $barcodes
): void { ): void {
if ($param->parentId === null) { if ($param->parentId === null) {
$pictureProperty = $this->setup->properties->products->pictures[$catalogIblockInfo->productIblockId]; $pictureProperty = $this->setup->properties->products->pictures[$catalogIblockInfo->productIblockId];
@ -195,7 +206,7 @@ class XmlOfferDirector
)); ));
$this->xmlOfferBuilder->setSelectParams($param); $this->xmlOfferBuilder->setSelectParams($param);
$this->xmlOfferBuilder->setOfferProps($product); $this->xmlOfferBuilder->setOfferProps($product);
$this->xmlOfferBuilder->setBarcode($barcodes[$product['ID']] ?? ''); $this->xmlOfferBuilder->setBarcode($this->barcodes[$product['ID']] ?? '');
$this->xmlOfferBuilder->setCatalogIblockInfo($catalogIblockInfo); $this->xmlOfferBuilder->setCatalogIblockInfo($catalogIblockInfo);
$this->xmlOfferBuilder->setPicturesPath( $this->xmlOfferBuilder->setPicturesPath(
$this $this
@ -204,6 +215,93 @@ class XmlOfferDirector
); );
} }
/**
* @param array $offer
* @param array $categories
*
* @return string
*/
private function replaceUrlTemplate(array $offer, array $categories): string
{
if (strpos($offer['DETAIL_PAGE_URL'], '#PRODUCT_URL#')) {
return $offer['DETAIL_PAGE_URL'];
}
$replaceableUrlParts = [
'#SITE_DIR#'=> 'LANG_DIR',
'#ID#' => 'ID',
'#CODE#' => 'CODE',
'#EXTERNAL_ID#' => 'EXTERNAL_ID',
'#IBLOCK_TYPE_ID#' => 'IBLOCK_TYPE_ID',
'#IBLOCK_ID#' => 'IBLOCK_ID',
'#IBLOCK_CODE#' => 'IBLOCK_CODE',
'#IBLOCK_EXTERNAL_ID#' => 'IBLOCK_EXTERNAL_ID',
'#ELEMENT_ID#' => 'ID',
'#ELEMENT_CODE#' => 'CODE',
];
$resultUrl = $offer['DETAIL_PAGE_URL'];
foreach ($replaceableUrlParts as $key => $replaceableUrlPart) {
if (isset($offer[$replaceableUrlPart])) {
$resultUrl = str_replace($key, $offer[$replaceableUrlPart], $resultUrl);
}
}
if (
isset($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'])
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_ID#') !== false
) {
$resultUrl = str_replace(
'#SECTION_ID#',
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID'],
$resultUrl
);
}
if (
isset($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'])
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_CODE#') !== false
) {
$resultUrl = str_replace(
'#SECTION_CODE#',
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'],
$resultUrl
);
}
if (
isset(
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_CODE'],
$categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID']
)
&& strpos($offer['DETAIL_PAGE_URL'], '#SECTION_CODE_PATH#') !== false
) {
$resultUrl = str_replace(
'#SECTION_CODE_PATH#',
CIBlockSection::getSectionCodePath($categories[0]['IBLOCK_SECTION_ELEMENT_IBLOCK_SECTION_ID']),
$resultUrl
);
}
return str_replace('//', '/', $resultUrl);
}
/**
* @param string $productUrl
* @param string $offerUrl
*
* @return string
*/
private function mergeUrls(string $productUrl, string $offerUrl): string
{
if (strpos($offerUrl, '#PRODUCT_URL#') !== false) {
return $productUrl;
}
return $offerUrl;
}
/** /**
* @param array $offerParams * @param array $offerParams
* @param array $productParams * @param array $productParams

View File

@ -51,4 +51,9 @@ class SelectParams
* @var int * @var int
*/ */
public $parentId; public $parentId;
/**
* @var array
*/
public $allParams;
} }

View File

@ -2,7 +2,9 @@
namespace Intaro\RetailCrm\Repository; namespace Intaro\RetailCrm\Repository;
use Bitrix\Catalog\StoreBarcodeTable;
use Bitrix\Iblock\IblockTable; use Bitrix\Iblock\IblockTable;
use Bitrix\Iblock\SectionElementTable;
use Bitrix\Iblock\SectionTable; use Bitrix\Iblock\SectionTable;
use Bitrix\Main\ArgumentException; use Bitrix\Main\ArgumentException;
use Bitrix\Main\ObjectPropertyException; use Bitrix\Main\ObjectPropertyException;
@ -43,40 +45,41 @@ class CatalogRepository
* @param int $offerId * @param int $offerId
* @return array * @return array
*/ */
public function getProductCategoriesIds(int $offerId): array public function getProductCategories(int $offerId): array
{ {
$query = CIBlockElement::GetElementGroups($offerId, false, ['ID']); try {
$ids = []; $categories = SectionElementTable::query()
->addSelect('IBLOCK_SECTION.ID')
while ($category = $query->GetNext()) { ->addSelect('IBLOCK_SECTION.CODE')
$ids[] = $category['ID']; ->where('IBLOCK_ELEMENT_ID', $offerId)
->fetchAll();
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
return [];
} }
return $ids; return $categories;
} }
/** /**
* Returns products IDs with barcodes by infoblock id * Returns products IDs with barcodes by infoblock id
* *
* @param int $iblockId
*
* @return array * @return array
*/ */
public function getProductBarcodesByIblockId(int $iblockId): array public function getBarcodes(): array
{ {
$barcodes = []; $barcodes = [];
$dbBarCode = CCatalogStoreBarCode::getList(
[],
['IBLOCK_ID' => $iblockId],
false,
false,
['PRODUCT_ID', 'BARCODE']
);
while ($arBarCode = $dbBarCode->GetNext()) { try {
if (!empty($arBarCode)) { $arBarCodes = StoreBarcodeTable::query()
$barcodes[$arBarCode['PRODUCT_ID']] = $arBarCode['BARCODE']; ->addSelect('PRODUCT_ID')
} ->addSelect('BARCODE')
->fetchAll();
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
return [];
}
foreach ($arBarCodes as $arBarCode){
$barcodes[$arBarCode['PRODUCT_ID']] = $arBarCode['BARCODE'];
} }
return $barcodes; return $barcodes;
@ -94,7 +97,7 @@ class CatalogRepository
$this->builder->getWhereForOfferPart($param->parentId, $catalogIblockInfo), $this->builder->getWhereForOfferPart($param->parentId, $catalogIblockInfo),
false, false,
['nPageSize' => $param->nPageSize, 'iNumPage' => $param->pageNumber, 'checkOutOfRange' => true], ['nPageSize' => $param->nPageSize, 'iNumPage' => $param->pageNumber, 'checkOutOfRange' => true],
array_merge($param->configurable, $param->main) $param->allParams
); );
} }

View File

@ -2,7 +2,10 @@
namespace Intaro\RetailCrm\Repository; namespace Intaro\RetailCrm\Repository;
use CCatalogMeasure; use Bitrix\Catalog\MeasureTable;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
/** /**
* Class MeasureRepository * Class MeasureRepository
@ -18,10 +21,20 @@ class MeasureRepository
public static function getMeasures(): array public static function getMeasures(): array
{ {
$measures = []; $measures = [];
$resMeasure = CCatalogMeasure::getList();
while ($measure = $resMeasure->Fetch()) { try {
$measures[$measure['ID']] = $measure; $resMeasures = MeasureTable::query()
->addSelect('ID')
->addSelect('MEASURE_TITLE')
->addSelect('SYMBOL_INTL')
->addSelect('SYMBOL')
->fetchAll();
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
return [];
}
foreach ($resMeasures as $resMeasure) {
$measures[$resMeasure['ID']] = $resMeasure;
} }
return $measures; return $measures;