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/storeamount.php
<?php

namespace Bitrix\Catalog\Component;

use Bitrix\Catalog\Access\AccessController;
use Bitrix\Catalog\Access\ActionDictionary;
use Bitrix\Catalog\Access\Permission\PermissionDictionary;
use Bitrix\Catalog\Config;
use Bitrix\Catalog\StoreTable;
use Bitrix\Catalog\ProductTable;
use Bitrix\Catalog\StoreProductTable;
use Bitrix\Main\Component\ParameterSigner;

use Bitrix\Main\Engine\Contract\Controllerable;
use Bitrix\Main\Errorable;
use Bitrix\Main\ErrorableImplementation;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\UI\PageNavigation;
use Bitrix\Main\Grid\Options;
use Bitrix\Main\Entity;

Loc::loadLanguageFile($_SERVER['DOCUMENT_ROOT'] . BX_ROOT . '/modules/catalog/install/components/bitrix/catalog.productcard.store.amount/class.php');

class StoreAmount
{
	protected $entityId;
	protected $variationIds;

	protected $storesCount;
	protected $storeTotal;

	protected $measures = [];
	protected $defaultMeasure;

	protected const GRID_NAME = 'productcard_store_amount';

	public function __construct(int $entityId)
	{
		$this->entityId = $entityId;
	}

	public function getEntityId(): int
	{
		return $this->entityId;
	}

	public function getVariationIds(): array
	{
		if (!isset($this->variationIds))
		{
			$productId = $this->getEntityId();
			$variations = \CCatalogSku::getOffersList($productId);
			if (isset($variations[$productId]))
			{
				$this->variationIds = array_column($variations[$productId], 'ID');
			}
			else
			{
				$this->variationIds = [$productId];
			}
		}

		return $this->variationIds;
	}

	public function getStoreAmountGridId(): string
	{
		return self::GRID_NAME . '_' . $this->getEntityId();
	}

	public function getStoresCount(): int
	{
		if (!isset($this->storesCount))
		{
			$filter = [
				'=PRODUCT_ID' => $this->getVariationIds(),
				[
					'LOGIC' => 'OR',
					'!=AMOUNT' => 0,
					'!=QUANTITY_RESERVED' => 0,
				],
				'=STORE.ACTIVE' => 'Y',
			];

			$filter = array_merge(
				$filter,
				AccessController::getCurrent()->getEntityFilter(
					ActionDictionary::ACTION_STORE_VIEW,
					StoreProductTable::class
				)
			);

			$this->storesCount = StoreProductTable::getList([
				'select' => ['CNT'],
				'filter' => $filter,
				'runtime' => [
					new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(DISTINCT(STORE_ID))')
				],
			])->fetch()['CNT'];
		}

		return $this->storesCount;
	}

	public function getProductStores(array $params = []): array
	{
		$stores = [];

		$offset = $params['offset'] ?? 0;
		$limit = $params['limit'] ?? null;

		$variationIds = $this->getVariationIds();
		$filter = [
			'=PRODUCT_ID' => $variationIds,
			'=STORE.ACTIVE' => 'Y',
		];

		$filter = array_merge(
			$filter,
			AccessController::getCurrent()->getEntityFilter(
				ActionDictionary::ACTION_STORE_VIEW,
				StoreProductTable::class
			)
		);

		$storeProductData = StoreProductTable::getList([
			'select' => ['SID_DISTINCT'],
			'filter' => $filter,
			'runtime' => [
				new \Bitrix\Main\Entity\ExpressionField('SID_DISTINCT', 'DISTINCT(STORE_ID)'),
			],
		])->fetchAll();

		$storeIds = array_column($storeProductData, 'SID_DISTINCT');
		$storeIds = array_slice($storeIds, $offset, $limit);

		$storeProductData = StoreProductTable::getList([
			'select' => [
				'STORE_ID',
				'PRODUCT_ID',
				'AMOUNT',
				'QUANTITY_RESERVED'
			],
			'filter' => [
				'=STORE_ID' => $storeIds,
				'=PRODUCT_ID' => $variationIds,
				'=STORE.ACTIVE' => 'Y',
			],
		])->fetchAll();

		$fetchedVariationIds = array_column($storeProductData, 'PRODUCT_ID');
		$variationsData = $this->getVariationsData($fetchedVariationIds);

		$variations = [];
		foreach ($variationsData as $variationData)
		{
			$variations[$variationData['ID']] = $variationData;
		}

		$storeIds = [];
		foreach ($storeProductData as $storeProduct)
		{
			$productData = $variations[$storeProduct['PRODUCT_ID']];

			if ((float)$storeProduct['QUANTITY_RESERVED'] === 0.0 && (float)$storeProduct['AMOUNT'] === 0.0)
			{
				continue;
			}

			$storeId = (int)$storeProduct['STORE_ID'];
			$amount = (float)$productData['PURCHASING_PRICE'] * (float)$storeProduct['AMOUNT'];

			$measureId = $productData['MEASURE'] ?? (int)$this->getDefaultMeasure()['ID'];
			$currency = $productData['PURCHASING_CURRENCY'];

			if (!isset($stores[$storeId]))
			{
				$storeIds[] = $storeId;

				$stores[$storeId] = [
					'ID' => $storeId,
					'QUANTITY' => [],
					'AMOUNT' => [],
				];
			}

			// MEASURE EXIST CHECK
			if (!isset($stores[$storeId]['QUANTITY'][$measureId]))
			{
				$stores[$storeId]['QUANTITY'][$measureId] = [
					'QUANTITY_COMMON' => (float)$storeProduct['AMOUNT'],
					'QUANTITY_RESERVED' => (float)$storeProduct['QUANTITY_RESERVED'],
					'MEASURE_ID' => $measureId,
				];
			}
			else
			{
				$stores[$storeId]['QUANTITY'][$measureId]['QUANTITY_COMMON'] += (float)$storeProduct['AMOUNT'];
				$stores[$storeId]['QUANTITY'][$measureId]['QUANTITY_RESERVED'] += (float)$storeProduct['QUANTITY_RESERVED'];
			}

			// CURRENCY EXIST CHECK
			if (!isset($stores[$storeId]['AMOUNT'][$currency]))
			{
				$stores[$storeId]['AMOUNT'][$currency] = [
					'AMOUNT' => $amount,
					'CURRENCY' => $currency,
				];
			}
			else
			{
				$stores[$storeId]['AMOUNT'][$currency]['AMOUNT'] += $amount;
			}
		}

		$storesInfo = $this->getStoresInfo($storeIds);

		foreach ($storesInfo as $storeInfo)
		{
			if (isset($stores[(int)$storeInfo['ID']]))
			{
				$stores[(int)$storeInfo['ID']]['TITLE'] = $storeInfo['TITLE'];
			}
		}

		return $stores;
	}

	/**
	 * Return array of information of a stores
	 * @param array $storeIds IDs of stores
	 * @return array
	 */
	protected function getStoresInfo(array $storeIds): array
	{
		if (count($storeIds) > 0)
		{
			return StoreTable::getList([
					'select' => ['ID', 'TITLE'],
					'filter' => [
						'=ID' => $storeIds,
						'ACTIVE' => 'Y',
					],
				])
				->fetchAll()
			;
		}

		return [];
	}

	protected function getVariationsData(array $variationIds): array
	{
		return ProductTable::getList([
			'select' => [
				'ID',
				'PURCHASING_PRICE',
				'PURCHASING_CURRENCY',
				'MEASURE',
			],

			'filter' => ['=ID' => $variationIds],
		])->fetchAll();
	}

	/**
	 * Form and prepare data to render in total info page block
	 * @return array
	 */
	public function getTotalData(): array
	{
		$storeTotal = $this->getStoreTotal();

		$quantity = '';
		$quantityCommon = '';
		$quantityReserved = '';

		foreach ($storeTotal['QUANTITY'] as $storeQuantity)
		{
			$measureSymbol = htmlspecialcharsbx($this->getMeasure($storeQuantity['MEASURE_ID']));

			$measureInfo =
				"<span class='total-info'>
					<span class='total-info-value'>{$storeQuantity['QUANTITY']}</span>
					{$measureSymbol}
				</span>";

			$measureCommonInfo =
				"<span class='total-info'>
					<span class='total-info-value'>{$storeQuantity['QUANTITY_COMMON']}</span>
					{$measureSymbol}
				</span>";

			$measureReservedInfo =
				"<span class='total-info'>
					<span class='total-info-value'>{$storeQuantity['QUANTITY_RESERVED']}</span>
					{$measureSymbol}
				</span>";

			$quantity .= $measureInfo . '<br>';
			$quantityCommon .= $measureCommonInfo . '<br>';
			$quantityReserved .= $measureReservedInfo . '<br>';
		}

		$amount = '';

		foreach ($storeTotal['AMOUNT'] as $storeAmount)
		{
			if (isset($storeAmount['CURRENCY']))
			{
				$amountValue =
					"<span class='total-info-value'>"
					. \CCurrencyLang::CurrencyFormat($storeAmount['AMOUNT'], $storeAmount['CURRENCY'], false)
					. "</span>";

				$amountBlock =
					"<span class='total-info'>"
					. \CCurrencyLang::getPriceControl(
						$amountValue,
						$storeAmount['CURRENCY']
					)
					. "</span>";

				$amount .= $amountBlock.'<br>';
			}

		}

		return [
			"QUANTITY" => $quantity,
			"QUANTITY_COMMON" => $quantityCommon,
			"QUANTITY_RESERVED" => $quantityReserved,
			"AMOUNT" => $amount,
		];
	}

	/**
	 *  Check exists and return array of total information about product stores
	 * @return array
	 */
	protected function getStoreTotal(): array
	{
		if (!isset($this->storeTotal))
		{
			$this->fillStoreTotal();
		}

		return $this->storeTotal;
	}

	/**
	 * Combine Amount and Quantity info from all stores to one array
	 */
	protected function fillStoreTotal(): void
	{
		$storeTotalData = [
			'QUANTITY' => [],
			'AMOUNT' => [],
		];

		if ($this->getStoresCount() > 0)
		{
			$variationsTotalData = $this->getVariationsTotalData($this->getVariationIds());
			foreach ($variationsTotalData as $variationData)
			{
				$variationData['MEASURE_ID'] = $variationData['MEASURE_ID'] ?? (int)$this->getDefaultMeasure()['ID'];

				if (!isset($storeTotalData['QUANTITY'][$variationData['MEASURE_ID']]))
				{
					$storeTotalData['QUANTITY'][$variationData['MEASURE_ID']] = [
						'QUANTITY' => 0.0,
						'QUANTITY_COMMON' => 0.0,
						'QUANTITY_RESERVED' => 0.0,
						'MEASURE_ID' => $variationData['MEASURE_ID'],
					];
				}

				$quantityValue = (float)$variationData['QUANTITY_COMMON'] - (float)$variationData['QUANTITY_RESERVED'];

				$storeTotalData['QUANTITY'][$variationData['MEASURE_ID']]['QUANTITY'] += $quantityValue;
				$storeTotalData['QUANTITY'][$variationData['MEASURE_ID']]['QUANTITY_COMMON'] += (float)$variationData['QUANTITY_COMMON'];
				$storeTotalData['QUANTITY'][$variationData['MEASURE_ID']]['QUANTITY_RESERVED'] += (float)$variationData['QUANTITY_RESERVED'];

				if (!isset($storeTotalData['AMOUNT'][$variationData['CURRENCY']]))
				{
					$storeTotalData['AMOUNT'][$variationData['CURRENCY']] = [
						'AMOUNT' => 0.0,
						'CURRENCY' => $variationData['CURRENCY'],
					];
				}
				$commonPrice = (float)$variationData['QUANTITY_COMMON'] * (float)$variationData['PRICE'];
				$storeTotalData['AMOUNT'][$variationData['CURRENCY']]['AMOUNT'] += $commonPrice;
			}
		}

		$this->storeTotal = $storeTotalData;
	}

	/**
	 * Get array of variations with a total stores data of it
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	protected function getVariationsTotalData(array $variationIds): array
	{
		$products = [];

		$filter = [
			'=PRODUCT_ID' => $variationIds,
			'=STORE.ACTIVE' => 'Y',
		];

		$filter = array_merge(
			$filter,
			AccessController::getCurrent()->getEntityFilter(
				ActionDictionary::ACTION_STORE_VIEW,
				StoreProductTable::class
			)
		);

		$commonProductData = StoreProductTable::getList([
			'select' => [
				'PRODUCT_ID',
				'MEASURE_ID' => 'PRODUCT.MEASURE',
				'PRICE' => 'PRODUCT.PURCHASING_PRICE',
				'CURRENCY' => 'PRODUCT.PURCHASING_CURRENCY',
				'QUANTITY_COMMON',
			],
			'filter' => $filter,
			'group' => ['PRODUCT_ID'],
			'runtime' => [
				new Entity\ExpressionField('QUANTITY_COMMON', 'SUM(AMOUNT)'),
			],
		])->fetchAll();

		foreach ($commonProductData as $productData)
		{
			$products[$productData['PRODUCT_ID']] = $productData;
		}

		$productQuantityReservedData = StoreProductTable::getList([
			'select' => [
				'PRODUCT_ID',
				'RESERVED_AMOUNT',
			],
			'filter' => [
				'=PRODUCT_ID' => $variationIds,
				'=STORE.ACTIVE' => 'Y',
			],
			'group' => ['PRODUCT_ID'],
			'runtime' => [
				new Entity\ExpressionField('RESERVED_AMOUNT', 'SUM(QUANTITY_RESERVED)'),
			],
		])->fetchAll();

		foreach ($productQuantityReservedData as $productData)
		{
			$products[$productData['PRODUCT_ID']]['QUANTITY_RESERVED'] = $productData['RESERVED_AMOUNT'];
		}

		return $products;
	}

	/**
	 * Return measure symbol from ID
	 *
	 * @param $measureId
	 * @return string
	 */
	public function getMeasure(?int $measureId): string
	{
		if ($measureId === null)
		{
			return $this->getDefaultMeasure()['SYMBOL'];
		}

		if (!isset($this->measures[$measureId]))
		{
			$measure = \CCatalogMeasure::getList([], ['=ID' => $measureId])->Fetch();

			if ($measure)
			{
				$this->measures[$measureId] = $measure['SYMBOL'];
			}
			else
			{
				$this->measures[$measureId] = '';
			}
		}

		return $this->measures[$measureId];
	}

	/**
	 * Return default measure value
	 * @return array
	 */
	protected function getDefaultMeasure(): array
	{
		if (!isset($this->defaultMeasure))
		{
			$fetchedMeasure = \CCatalogMeasure::getList([], ['=IS_DEFAULT' => 'Y'])->Fetch();
			if ($fetchedMeasure)
			{
				$this->defaultMeasure = $fetchedMeasure;
			}
			else
			{
				// default symbol not exist catch
				$this->defaultMeasure = [
					'ID' => 0,
					'SYMBOL' => '',
				];
			}
		}

		return $this->defaultMeasure;
	}

	public function getStoreAmountSignedParameters(): string
	{
		return ParameterSigner::signParameters(
			$this->getStoreAmountComponentName(),
			$this->getStoreAmountParameters()
		);
	}

	protected function getStoreAmountComponentName(): string
	{
		return 'bitrix:catalog.productcard.store.amount';
	}

	protected function getStoreAmountParameters(): array
	{
		return [
			'ENTITY_ID' => $this->getEntityId(),
		];
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit