1
0
mirror of synced 2024-11-22 13:26:10 +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
* Добавлена синхронизация ответственного менеджера в заказе
* Исправлена ошибка выгрузки заказов с корпоративными клиентами, уже присутствующими в системе

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,8 @@
namespace Intaro\RetailCrm\Icml;
use CIBlock;
use CIBlockSection;
use Intaro\RetailCrm\Model\Bitrix\Orm\CatalogIblockInfo;
use Intaro\RetailCrm\Model\Bitrix\Xml\SelectParams;
use Intaro\RetailCrm\Model\Bitrix\Xml\XmlOffer;
@ -38,6 +40,11 @@ class XmlOfferDirector
*/
private $xmlOfferBuilder;
/**
* @var array
*/
private $barcodes;
/**
* XmlOfferFactory constructor.
* @param \Intaro\RetailCrm\Model\Bitrix\Xml\XmlSetup $setup
@ -52,6 +59,7 @@ class XmlOfferDirector
MeasureRepository::getMeasures(),
SiteRepository::getDefaultServerName()
);
$this->barcodes = $this->catalogRepository->getBarcodes();
}
/**
@ -64,12 +72,15 @@ class XmlOfferDirector
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']));
while ($offer = $ciBlockResult->Fetch()) {
$categories = $this->catalogRepository->getProductCategories($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();
}
@ -113,8 +124,10 @@ class XmlOfferDirector
$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->barcode = $offer->mergeValues($product->barcode, $offer->barcode);
$offer->categoryIds = $product->categoryIds;
$offer->productName = $product->productName;
$offer->url = $this->mergeUrls($product->url, $offer->url);
}
return $xmlOffers;
@ -164,13 +177,11 @@ class XmlOfferDirector
* @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
CatalogIblockInfo $catalogIblockInfo
): void {
if ($param->parentId === null) {
$pictureProperty = $this->setup->properties->products->pictures[$catalogIblockInfo->productIblockId];
@ -195,7 +206,7 @@ class XmlOfferDirector
));
$this->xmlOfferBuilder->setSelectParams($param);
$this->xmlOfferBuilder->setOfferProps($product);
$this->xmlOfferBuilder->setBarcode($barcodes[$product['ID']] ?? '');
$this->xmlOfferBuilder->setBarcode($this->barcodes[$product['ID']] ?? '');
$this->xmlOfferBuilder->setCatalogIblockInfo($catalogIblockInfo);
$this->xmlOfferBuilder->setPicturesPath(
$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 $productParams

View File

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

View File

@ -2,7 +2,9 @@
namespace Intaro\RetailCrm\Repository;
use Bitrix\Catalog\StoreBarcodeTable;
use Bitrix\Iblock\IblockTable;
use Bitrix\Iblock\SectionElementTable;
use Bitrix\Iblock\SectionTable;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ObjectPropertyException;
@ -43,40 +45,41 @@ class CatalogRepository
* @param int $offerId
* @return array
*/
public function getProductCategoriesIds(int $offerId): array
public function getProductCategories(int $offerId): array
{
$query = CIBlockElement::GetElementGroups($offerId, false, ['ID']);
$ids = [];
while ($category = $query->GetNext()) {
$ids[] = $category['ID'];
try {
$categories = SectionElementTable::query()
->addSelect('IBLOCK_SECTION.ID')
->addSelect('IBLOCK_SECTION.CODE')
->where('IBLOCK_ELEMENT_ID', $offerId)
->fetchAll();
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
return [];
}
return $ids;
return $categories;
}
/**
* Returns products IDs with barcodes by infoblock id
*
* @param int $iblockId
*
* @return array
*/
public function getProductBarcodesByIblockId(int $iblockId): array
public function getBarcodes(): array
{
$barcodes = [];
$dbBarCode = CCatalogStoreBarCode::getList(
[],
['IBLOCK_ID' => $iblockId],
false,
false,
['PRODUCT_ID', 'BARCODE']
);
while ($arBarCode = $dbBarCode->GetNext()) {
if (!empty($arBarCode)) {
$barcodes[$arBarCode['PRODUCT_ID']] = $arBarCode['BARCODE'];
try {
$arBarCodes = StoreBarcodeTable::query()
->addSelect('PRODUCT_ID')
->addSelect('BARCODE')
->fetchAll();
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
return [];
}
foreach ($arBarCodes as $arBarCode){
$barcodes[$arBarCode['PRODUCT_ID']] = $arBarCode['BARCODE'];
}
return $barcodes;
@ -94,7 +97,7 @@ class CatalogRepository
$this->builder->getWhereForOfferPart($param->parentId, $catalogIblockInfo),
false,
['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;
use CCatalogMeasure;
use Bitrix\Catalog\MeasureTable;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
/**
* Class MeasureRepository
@ -18,10 +21,20 @@ class MeasureRepository
public static function getMeasures(): array
{
$measures = [];
$resMeasure = CCatalogMeasure::getList();
while ($measure = $resMeasure->Fetch()) {
$measures[$measure['ID']] = $measure;
try {
$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;