403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/component/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/component/reportproductlist.php
<?php

namespace Bitrix\Catalog\Component;

use Bitrix\Catalog;
use Bitrix\Catalog\Access\AccessController;
use Bitrix\Catalog\Access\ActionDictionary;
use Bitrix\Catalog\ProductTable;
use Bitrix\Catalog\StoreDocumentElementTable;
use Bitrix\Catalog\StoreDocumentTable;
use Bitrix\Catalog\StoreProductTable;
use Bitrix\Main\Entity\Base;
use Bitrix\Main\Entity\ReferenceField;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ORM\Fields\ExpressionField;
use Bitrix\Main\ORM\Fields\Relations\Reference;
use Bitrix\Main\ORM\Query\Join;
use Bitrix\Main\ORM\Query\Query;
use Bitrix\Main\Type\DateTime;
use Bitrix\Sale\Internals\BasketTable;
use Bitrix\Sale\Internals\ShipmentItemStoreTable;
use Bitrix\Sale\Internals\ShipmentItemTable;
use Bitrix\Sale\Internals\ShipmentTable;

abstract class ReportProductList extends ProductList
{
	protected int $storeId = 0;
	protected string $navParamName = 'page';
	protected array $catalogData = [];
	protected array $defaultGridSort = ['PRODUCT_ID' => 'desc'];
	protected string $reportFilterClass;
	protected \Bitrix\Main\Grid\Options $gridOptions;

	abstract protected function getGridId(): string;

	abstract protected function getFilterId(): string;

	abstract protected function prepareProductFilter(array $productIds): array;

	abstract protected function getProductFilterDialogContext(): string;

	abstract protected function getReceivedQuantityData(int $storeId, array $formattedFilter): array;

	abstract protected function getOutgoingQuantityData(int $storeId, array $formattedFilter): array;

	abstract protected function getAmountSoldData(int $storeId, array $formattedFilter): array;

	abstract protected function getGridColumns(): array;

	protected static function getEmptyStub(): string
	{
		return Loc::getMessage('CATALOG_REPORT_PRODUCT_LIST_NO_PRODUCTS');
	}

	public function onPrepareComponentParams($arParams)
	{
		$arParams['STORE_ID'] = (int)($arParams['STORE_ID'] ?? 0);

		return parent::onPrepareComponentParams($arParams);
	}

	public function executeComponent()
	{
		if (!$this->checkModules())
		{
			$this->includeComponentTemplate();

			return;
		}

		if (!$this->checkDocumentReadRights())
		{
			$this->arResult['ERROR_MESSAGES'][] = Loc::getMessage('CATALOG_REPORT_PRODUCT_LIST_NO_READ_RIGHTS_ERROR');

			$this->includeComponentTemplate();

			return;
		}

		$this->init();

		$this->loadMeasures();
		$this->arResult['GRID'] = $this->getGridData();
		$this->arResult['STORE_TITLE'] = htmlspecialcharsbx($this->getStoreTitle());
		if (empty($this->arResult['STORE_TITLE']))
		{
			$this->arResult['STORE_TITLE'] = Loc::getMessage('CATALOG_REPORT_PRODUCT_LIST_DEFAULT_STORE_NAME');
		}

		$filterOptions = [
			'GRID_ID' => $this->getGridId(),
			'FILTER_ID' => $this->getFilterId(),
			'FILTER' => $this->getFilterFields(),
			'FILTER_PRESETS' => [],
			'ENABLE_LABEL' => true,
			'THEME' => \Bitrix\Main\UI\Filter\Theme::LIGHT,
		];
		$this->arResult['FILTER_OPTIONS'] = $filterOptions;

		$this->includeComponentTemplate();
	}

	protected function checkModules(): bool
	{
		if (!Loader::includeModule('catalog'))
		{
			$this->arResult['ERROR_MESSAGES'][] = 'Module Catalog is not installed';

			return false;
		}

		if (!Loader::includeModule('report'))
		{
			$this->arResult['ERROR_MESSAGES'][] = 'Module Report is not installed';

			return false;
		}

		return true;
	}

	protected function getGridRows(): ?array
	{
		$productData = $this->getProductData();
		if (!$productData)
		{
			return null;
		}

		$rows = [];

		$this->catalogData = $this->loadCatalog(array_column($productData, 'PRODUCT_ID'));

		$formattedFilter = $this->getFormattedFilter();
		$receivedQuantityData = $this->getReceivedQuantityData($this->storeId, $formattedFilter);
		$outgoingQuantityData = $this->getOutgoingQuantityData($this->storeId, $formattedFilter);
		$amountSoldData = $this->getAmountSoldData($this->storeId, $formattedFilter);

		$receivedQuantityAmountDifferenceData = [];
		$outgoingQuantityAmountDifferenceData = [];
		$amountSoldAmountDifferenceData = [];

		if (!empty($formattedFilter['REPORT_INTERVAL']))
		{
			$differenceFilter = $formattedFilter;
			$currentTime = new DateTime();
			$filterTimeTo = new DateTime($differenceFilter['REPORT_INTERVAL']['TO']);
			if ($currentTime > $filterTimeTo)
			{
				$differenceFilter['REPORT_INTERVAL']['FROM'] = $differenceFilter['REPORT_INTERVAL']['TO'];
				$differenceFilter['REPORT_INTERVAL']['TO'] = (new DateTime())->toString();
				$receivedQuantityAmountDifferenceData = $this->getReceivedQuantityData($this->storeId, $differenceFilter);
				$outgoingQuantityAmountDifferenceData = $this->getOutgoingQuantityData($this->storeId, $differenceFilter);
				$amountSoldAmountDifferenceData = $this->getAmountSoldData($this->storeId, $differenceFilter);
			}
		}

		foreach ($productData as $key => $item)
		{
			$receivedQuantityAmountDifference = (float)($receivedQuantityAmountDifferenceData[$item['PRODUCT_ID']] ?? 0);
			$outgoingQuantityAmountDifference = (float)($outgoingQuantityAmountDifferenceData[$item['PRODUCT_ID']] ?? 0);
			$amountSoldAmountDifference = (float)($amountSoldAmountDifferenceData[$item['PRODUCT_ID']] ?? 0);
			$item['AMOUNT'] =
				$item['AMOUNT']
				- $receivedQuantityAmountDifference
				+ $outgoingQuantityAmountDifference
				+ $amountSoldAmountDifference
			;

			$receivedQuantity = (float)($receivedQuantityData[$item['PRODUCT_ID']] ?? 0);
			$outgoingQuantity = (float)($outgoingQuantityData[$item['PRODUCT_ID']] ?? 0);
			$amountSold = (float)($amountSoldData[$item['PRODUCT_ID']] ?? 0);
			$item['STARTING_QUANTITY'] = (float)$item['AMOUNT'] - $receivedQuantity + $outgoingQuantity + $amountSold;
			$item['RECEIVED_QUANTITY'] = (float)($receivedQuantityData[$item['PRODUCT_ID']] ?? 0);
			$item['AMOUNT_SOLD'] = (float)($amountSoldData[$item['PRODUCT_ID']] ?? 0);
			$item['QUANTITY'] = (float)$item['AMOUNT'] - (float)$item['QUANTITY_RESERVED'];
			$rows[] = [
				'id' => $item['ID'],
				'data' => $item,
				'columns' => $this->prepareItemColumn($item),
			];
		}

		return $rows;
	}

	protected function getGridData(): array
	{
		$navParams = $this->gridOptions->getNavParams();
		$pageSize = (int)$navParams['nPageSize'];

		$pageNavigation = new \Bitrix\Main\UI\PageNavigation($this->navParamName);
		$pageNavigation->allowAllRecords(false)->setPageSize($pageSize)->initFromUri();

		$totalCount = $this->getTotalCount();

		$pageNavigation->setRecordCount($totalCount);
		$gridRows = $this->getGridRows();
		return [
			'GRID_ID' => $this->getGridId(),
			'COLUMNS' => $this->getGridColumns(),
			'ROWS' => $gridRows,
			'STUB' => $totalCount <= 0 ? ['title' => static::getEmptyStub()] : null,

			'NAV_PARAM_NAME' => $this->navParamName,
			'CURRENT_PAGE' => $pageNavigation->getCurrentPage(),
			'NAV_OBJECT' => $pageNavigation,
			'TOTAL_ROWS_COUNT' => $totalCount,
			'AJAX_MODE' => 'Y',
			'ALLOW_ROWS_SORT' => false,
			'AJAX_OPTION_JUMP' => 'N',
			'AJAX_OPTION_STYLE' => 'N',
			'AJAX_OPTION_HISTORY' => 'N',
			'AJAX_ID' => \CAjax::GetComponentID('bitrix:main.ui.grid', '', ''),
			'SHOW_PAGINATION' => $totalCount > 0,
			'SHOW_NAVIGATION_PANEL' => true,
			'SHOW_PAGESIZE' => true,

			'PAGE_SIZES' => [
				['NAME' => '10', 'VALUE' => '10'],
				['NAME' => '20', 'VALUE' => '20'],
				['NAME' => '50', 'VALUE' => '50'],
				['NAME' => '100', 'VALUE' => '100'],
				['NAME' => '200', 'VALUE' => '200'],
				['NAME' => '500', 'VALUE' => '500'],
			],

			'SHOW_ROW_CHECKBOXES' => false,
			'SHOW_CHECK_ALL_CHECKBOXES' => false,
			'SHOW_ACTION_PANEL' => false,
			'SHOW_GRID_SETTINGS_MENU' => false,
			'SHOW_SELECTED_COUNTER' => false,
			'HANDLE_RESPONSE_ERRORS' => true,
			'ALLOW_STICKED_COLUMNS' => true,
		];
	}

	protected function getProductData(): array
	{
		$navParams = $this->gridOptions->getNavParams();
		$pageSize = (int)$navParams['nPageSize'];
		$gridSort = $this->gridOptions->GetSorting(['sort' => $this->defaultGridSort]);

		$pageNavigation = new \Bitrix\Main\UI\PageNavigation($this->navParamName);
		$pageNavigation->allowAllRecords(false)->setPageSize($pageSize)->initFromUri();

		$this->arResult['GRID']['ROWS'] = [];

		$offset = $pageNavigation->getOffset();
		$order = $gridSort['sort'];
		$limit = $pageNavigation->getLimit();

		$query = $this->buildDataQuery($order, $limit, $offset);

		return $query->exec()->fetchAll();
	}

	/**
	 * In this report we don't have to display products that haven't been stored in the store
	 * at any point during the report period, so here we are looking for products that are
	 * not in the store right now but that might have been there before (meaning that they have
	 * been sold or moved to another store)
	 *
	 * @param $order
	 * @param $limit
	 * @param $offset
	 * @return Query
	 */
	protected function buildDataQuery($order = null, $limit = null, $offset = null): Query
	{
		$storeId = $this->storeId;

		$filter = $this->getListFilter();
		$baseStoreFilterValues = $filter['=STORE_ID'] ?? '';
		unset($filter['=STORE_ID']);
		$reportInterval = $filter['REPORT_INTERVAL'] ?? [];
		unset($filter['REPORT_INTERVAL']);

		$storeDocsFilter = ['=DOCUMENT.STATUS' => 'Y'];
		$shipmentsFilter = ['=ORDER_DELIVERY.DEDUCTED' => 'Y'];

		if (!empty($reportInterval))
		{
			$storeDocsFilter += [
				'<=DOCUMENT.DATE_STATUS' => new DateTime($reportInterval['TO']),
			];
			$shipmentsFilter += [
				'<=ORDER_DELIVERY.DATE_DEDUCTED' => new DateTime($reportInterval['TO']),
			];
		}

		if (!$this->isAllStoresGrid())
		{
			$storeDocsFilter[] = [
				'LOGIC' => 'OR',
				'=DOCS_ELEMENT.STORE_FROM' => $storeId,
				'=DOCS_ELEMENT.STORE_TO' => $storeId,
			];

			$shipmentsFilter['=STORE_BARCODE.STORE_ID'] = $storeId;
			$filter[] = ['=STORE_ID' => $storeId];
		}
		elseif (!empty($baseStoreFilterValues))
		{
			$storeDocsFilter[] = $baseStoreFilterValues;
			$shipmentsFilter['=STORE_BARCODE.STORE_ID'] = $baseStoreFilterValues;
			$filter[] = ['=STORE_ID' => $baseStoreFilterValues];
		}

		$filter[] = [
			'LOGIC' => 'OR',
			$storeDocsFilter,
			$shipmentsFilter
		];

		$storeQuery = StoreProductTable::query();
		$storeQuery->setSelect(['ID' ,'PRODUCT_ID', 'AMOUNT', 'QUANTITY_RESERVED', 'MEASURE_ID' => 'PRODUCT.MEASURE']);
		$storeQuery->registerRuntimeField(
			new Reference(
				'DOCS_ELEMENT',
				StoreDocumentElementTable::class,
				Join::on('this.PRODUCT_ID', 'ref.ELEMENT_ID')
			)
		);
		$storeQuery->registerRuntimeField(
			new Reference(
				'DOCUMENT',
				StoreDocumentTable::class,
				Join::on('this.DOCS_ELEMENT.DOC_ID', 'ref.ID')
			)
		);
		$storeQuery->registerRuntimeField(
			new Reference(
				'BASKET',
				BasketTable::class,
				Join::on('this.PRODUCT_ID', 'ref.PRODUCT_ID')
			)
		);
		$storeQuery->registerRuntimeField(
			new Reference(
				'SHIPMENT_ITEM',
				ShipmentItemTable::class,
				Join::on('this.BASKET.ID', 'ref.BASKET_ID')
			)
		);
		$storeQuery->registerRuntimeField(
			new Reference(
				'STORE_BARCODE',
				ShipmentItemStoreTable::class,
				Join::on('this.SHIPMENT_ITEM.ID', 'ref.ORDER_DELIVERY_BASKET_ID')
			)
		);
		$storeQuery->registerRuntimeField(
			new Reference(
				'ORDER_DELIVERY',
				ShipmentTable::class,
				Join::on('this.SHIPMENT_ITEM.ORDER_DELIVERY_ID', 'ref.ID')
			)
		);

		$storeQuery->setFilter($filter);
		$storeQuery->setDistinct();

		if (!$this->isAllStoresGrid())
		{
			if (isset($order))
			{
				$storeQuery->setOrder($order);
			}
			if (isset($limit))
			{
				$storeQuery->setLimit($limit);
			}
			if (isset($offset))
			{
				$storeQuery->setOffset($offset);
			}

			$storeQuery->countTotal(true);

			return $storeQuery;
		}

		$allStoreQuery = ProductTable::query();
		$allStoreQuery->registerRuntimeField('',
			new ReferenceField(
				'SUBQUERY',
				Base::getInstanceByQuery($storeQuery),
				['this.ID' => 'ref.PRODUCT_ID'],
				['join_type' => 'INNER']
			)
		);

		$allStoreQuery->registerRuntimeField(
			new \Bitrix\Main\Entity\ExpressionField(
			'AMOUNT',
			'SUM(%s)',
			'SUBQUERY.AMOUNT'
			)
		);

		$allStoreQuery->registerRuntimeField(
			new \Bitrix\Main\Entity\ExpressionField(
				'QUANTITY_RESERVED',
				'SUM(%s)',
				'SUBQUERY.QUANTITY_RESERVED'
			)
		);

		$allStoreQuery->setSelect([
			'ID',
			'PRODUCT_ID' => 'ID',
			'AMOUNT',
			'QUANTITY_RESERVED',
			'MEASURE_ID' => 'MEASURE',
		]);

		if (isset($order))
		{
			$allStoreQuery->setOrder($order);
		}

		if (isset($limit))
		{
			$allStoreQuery->setLimit($limit);
		}

		if (isset($offset))
		{
			$allStoreQuery->setOffset($offset);
		}

		$allStoreQuery->countTotal(true);

		return $allStoreQuery;
	}

	protected function getFormattedFilter(): array
	{
		$result = [];

		$incomingFilter = $this->arParams['INCOMING_FILTER'] ?? [];

		if (!empty($incomingFilter))
		{
			if (!empty($incomingFilter['PRODUCTS']))
			{
				$result['PRODUCTS'] = $this->prepareProductFilter($incomingFilter['PRODUCTS']);
			}

			if
			(
				!empty($incomingFilter['REPORT_INTERVAL_from'])
				&& !empty($incomingFilter['REPORT_INTERVAL_to'])
			)
			{
				$result['REPORT_INTERVAL'] = [
					'FROM' => $incomingFilter['REPORT_INTERVAL_from'],
					'TO' => $incomingFilter['REPORT_INTERVAL_to'],
				];
			}

			if (!empty($incomingFilter['STORES']) && $this->isAllStoresGrid())
			{
				$result['STORE_ID'] = $incomingFilter['STORES'];
			}
		}
		else
		{
			$getListFilter = $this->getListFilter();
			if (!empty($getListFilter['=PRODUCT_ID']))
			{
				$result['PRODUCTS'] = $getListFilter['=PRODUCT_ID'];
			}

			$userFilter = $this->getUserFilter();
			if
			(
				!empty($userFilter['>=REPORT_INTERVAL'])
				&& !empty($userFilter['<=REPORT_INTERVAL'])
			)
			{
				$result['REPORT_INTERVAL'] = [
					'FROM' => $userFilter['>=REPORT_INTERVAL'],
					'TO' => $userFilter['<=REPORT_INTERVAL'],
				];
			}
		}

		return $result;
	}

	protected function prepareItemColumn(array $item): array
	{
		$column = $item;

		$column['PRODUCT_ID'] = $this->getProductView($column);

		foreach (['STARTING_QUANTITY', 'RECEIVED_QUANTITY', 'AMOUNT', 'QUANTITY_RESERVED', 'QUANTITY', 'AMOUNT_SOLD'] as $totalField)
		{
			$column[$totalField] = $this->formatNumberWithMeasure($column[$totalField], (int)$column['MEASURE_ID']);
		}

		unset($column['MEASURE_ID']);

		$column['QUANTITY_RESERVED'] = $this->getReservedDealListLink((int)$item['PRODUCT_ID'], $column['QUANTITY_RESERVED']);

		return $column;
	}

	protected function getReservedDealListLink(int $productId, string $quantityReservedView): string
	{
		return
			'<a
				class="main-grid-cell-content-store-amount-reserved-quantity"
				onclick="BX.SidePanel.Instance.open(\'' . $this->getReservedDealsSliderLink($productId) . '\')"
			>' . $quantityReservedView . '</a>'
			;
	}

	protected function getReservedDealsSliderLink(int $productId): string
	{
		$sliderUrl = \CComponentEngine::makeComponentPath('bitrix:catalog.productcard.reserved.deal.list');
		$sliderUrl = getLocalPath('components'.$sliderUrl.'/slider.php');
		$sliderUrlEntity = new \Bitrix\Main\Web\Uri($sliderUrl);
		$sliderUrlEntity->addParams([
			'storeId' => $this->storeId,
			'productId' => $productId,
		]);

		return $sliderUrlEntity->getUri();
	}

	protected function formatNumberWithMeasure($number, int $measureId)
	{
		if (!$measureId)
		{
			$measureId = $this->getDefaultMeasure()['ID'];
		}
		return Loc::getMessage(
			'CATALOG_REPORT_PRODUCT_LIST_MEASURE_TEMPLATE',
			[
				'#NUMBER#' => $number,
				'#MEASURE_SYMBOL#' => $this->getMeasureSymbol($measureId),
			]
		);
	}

	protected function getMeasureSymbol(int $measureId): string
	{
		return htmlspecialcharsbx($this->measures[$measureId]['SYMBOL']);
	}

	protected function getProductView(array $column): string
	{
		global $APPLICATION;

		$product = $this->catalogData[(int)$column['PRODUCT_ID']];

		ob_start();
		$APPLICATION->IncludeComponent(
			'bitrix:catalog.grid.product.field',
			'',
			[
				'BUILDER_CONTEXT' => $this->arParams['BUILDER_CONTEXT'],
				'GRID_ID' => $this->getGridId(),
				'ROW_ID' => $column['ID'],
				'GUID' => 'catalog_document_grid_' . $column['ID'],
				'PRODUCT_FIELDS' => [
					'ID' => $product['FIELDS']['PRODUCT_ID'],
					'NAME' => $product['FIELDS']['NAME'],
					'IBLOCK_ID' => $product['FIELDS']['IBLOCK_ID'],
					'SKU_IBLOCK_ID' => $product['FIELDS']['OFFERS_IBLOCK_ID'],
					'SKU_ID' => $product['FIELDS']['OFFER_ID'] ?? null,
					'BASE_PRICE_ID' => $product['FIELDS']['BASE_PRICE_ID'] ?? null,
				],
				'SKU_TREE' => $product['FIELDS']['SKU_TREE'],
				'MODE' => 'view',
				'VIEW_FORMAT' => 'short',
				'ENABLE_SEARCH' => false,
				'ENABLE_IMAGE_CHANGE_SAVING' => false,
				'ENABLE_IMAGE_INPUT' => false,
				'ENABLE_INPUT_DETAIL_LINK' => true,
				'ENABLE_EMPTY_PRODUCT_ERROR' => false,
				'ENABLE_SKU_SELECTION' => false,
				'HIDE_UNSELECTED_ITEMS' => true,
				'IS_NEW' => false,
			]
		);

		return ob_get_clean();
	}

	protected function init(): void
	{
		$this->storeId = $this->arParams['STORE_ID'];
		$this->gridOptions = new \Bitrix\Main\Grid\Options($this->getGridId());

		if ($this->arParams['OPENED_FROM_REPORT'])
		{
			$this->getFilterOptions()->reset();
		}

		if (isset($this->arParams['INCOMING_FILTER']) && is_array($this->arParams['INCOMING_FILTER']))
		{
			$this->initFilterFromIncomingData($this->arParams['INCOMING_FILTER']);
		}
	}

	protected function isAllStoresGrid(): bool
	{
		return $this->storeId <= 0;
	}

	protected function prepareFilterIncomingData(array $incomingFilter): array
	{
		$filterFields = [];
		if (isset($incomingFilter['PRODUCTS'], $incomingFilter['PRODUCTS_label']))
		{
			$filterFields['PRODUCTS'] = $incomingFilter['PRODUCTS'];
			$filterFields['PRODUCTS_label'] = $incomingFilter['PRODUCTS_label'];
		}

		return $filterFields;
	}

	protected function initFilterFromIncomingData(array $incomingFilter): void
	{
		$filterFields = $this->prepareFilterIncomingData($incomingFilter);

		if (count($filterFields) > 0)
		{
			$this->setFilterFields($filterFields);
		}
	}

	protected function setFilterFields(array $filterFields): void
	{
		$filterOptions = $this->getFilterOptions();
		$currentFilterSettings = $filterOptions->getFilterSettings('tmp_filter');
		$currentFilterSettings['fields'] = $filterFields;
		$filterOptions->setFilterSettings(
			\Bitrix\Main\UI\Filter\Options::TMP_FILTER,
			$currentFilterSettings,
			true,
			false
		);
		$filterOptions->save();
	}

	protected function checkDocumentReadRights(): bool
	{
		if (
			!AccessController::getCurrent()->check(ActionDictionary::ACTION_CATALOG_READ)
			|| !AccessController::getCurrent()->check(ActionDictionary::ACTION_INVENTORY_MANAGEMENT_ACCESS)
		)
		{
			return false;
		}

		return
			$this->arParams['STORE_ID'] > 0
				? AccessController::getCurrent()->checkByValue(ActionDictionary::ACTION_STORE_VIEW, $this->arParams['STORE_ID'])
				: AccessController::getCurrent()->check(ActionDictionary::ACTION_STORE_VIEW)
		;
	}

	protected function getTotalCount(): int
	{
		return $this->buildDataQuery()->exec()->getCount();
	}

	protected function getListFilter(): array
	{
		if (!$this->isAllStoresGrid())
		{
			$filter = [
				'=STORE_ID' => $this->storeId,
			];
		}
		else
		{
			$filter =
				AccessController::getCurrent()
				->getEntityFilter(
					ActionDictionary::ACTION_STORE_VIEW,
					StoreProductTable::class
				)
			;

			$incomingFilter = $this->arParams['INCOMING_FILTER'] ?? [];
			if (isset($incomingFilter['STORES']))
			{
				$filter['=STORE_ID'] = $incomingFilter['STORES'];
			}
		}

		$searchString = trim($this->getFilterOptions()->getSearchString());
		if ($searchString)
		{
			$filter['%PRODUCT.IBLOCK_ELEMENT.SEARCHABLE_CONTENT'] = mb_strtoupper($searchString);
		}

		$userFilter = $this->getUserFilter();
		if (!empty($userFilter['PRODUCTS']))
		{
			$filter['=PRODUCT_ID'] = $this->prepareProductFilter($userFilter['PRODUCTS']);
		}

		if
		(
			!empty($userFilter['>=REPORT_INTERVAL'])
			&& !empty($userFilter['<=REPORT_INTERVAL'])
		)
		{
			$filter['REPORT_INTERVAL'] = [
				'FROM' => $userFilter['>=REPORT_INTERVAL'],
				'TO' => $userFilter['<=REPORT_INTERVAL'],
			];
		}

		$filter['@PRODUCT.TYPE'] = [
			ProductTable::TYPE_PRODUCT,
			ProductTable::TYPE_OFFER,
		];

		return $filter;
	}

	protected function getStoreTitle(): string
	{
		$storeData = \Bitrix\Catalog\StoreTable::getList([
			'select' => ['TITLE'],
			'filter' => ['=ID' => $this->storeId],
			'limit' => 1,
		])->fetch();

		return $storeData['TITLE'] ?? '';
	}

	protected function getFilterFields(): array
	{
		$entities = [];

		if (Loader::includeModule('crm'))
		{
			$entities[] = [
				'id' => 'product_variation',
				'options' => [
					'iblockId' => \Bitrix\Crm\Product\Catalog::getDefaultId(),
					'basePriceId' => Catalog\GroupTable::getBasePriceTypeId(),
					'showPriceInCaption' => false,
				],
			];
		}

		return [
			'PRODUCTS' => [
				'id' => 'PRODUCTS',
				'name' => Loc::getMessage('CATALOG_REPORT_PRODUCT_LIST_FILTER_PRODUCTS_TITLE'),
				'type' => 'entity_selector',
				'default' => true,
				'partial' => true,
				'params' => [
					'multiple' => true,
					'showDialogOnEmptyInput' => false,
					'dropdownMode' => true,
					'dialogOptions' => [
						'hideOnSelect' => false,
						'context' => $this->getProductFilterDialogContext(),
						'entities' => $entities,
						'recentTabOptions' => [
							'stub' => true,
							'stubOptions' => [
								'title' => Loc::getMessage('CATALOG_REPORT_PRODUCT_LIST_PRODUCT_FILTER_STUB'),
							],
						],
						'events' => [
							'onBeforeSearch' => 'onBeforeDialogSearch',
						],
					],
				],
			]
		];
	}

	protected function getUserFilter(): array
	{
		$filterOptions = $this->getFilterOptions();
		$filterFields = $this->getFilterFields();

		return $filterOptions->getFilterLogic($filterFields);
	}

	protected function getFilterOptions(): \Bitrix\Main\UI\Filter\Options
	{
		static $filterOptions = null;
		if (is_null($filterOptions))
		{
			$filterOptions = new \Bitrix\Main\UI\Filter\Options($this->getFilterId());
		}

		return $filterOptions;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit