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/cvetdv.ru/bitrix/modules/yandex.market/lib/trading/entity/sale/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/yandex.market/lib/trading/entity/sale/delivery.php
<?php

namespace Yandex\Market\Trading\Entity\Sale;

use Yandex\Market;
use Yandex\Market\Trading\Entity as TradingEntity;
use Bitrix\Main;
use Bitrix\Sale;
use Sale\Handlers as SaleHandlers;

class Delivery extends Market\Trading\Entity\Reference\Delivery
{
	use Market\Reference\Concerns\HasLang;

	/** @var Environment */
	protected $environment;
	/** @var Sale\Delivery\Services\Base[] */
	protected $deliveryServices = [];
	/** @var array<string, bool> */
	protected $existsDeliveryDiscount = [];

	protected static function includeMessages()
	{
		Main\Localization\Loc::loadMessages(__FILE__);
	}

	public function __construct(Environment $environment)
	{
		parent::__construct($environment);
	}

	public function isRequired()
	{
		$saleVersion = Main\ModuleManager::getVersion('sale');

		return !CheckVersion($saleVersion, '17.0.0');
	}

	public function getEnum($siteId = null)
	{
		$deliveries = $this->loadActiveList();
		$deliveries = $this->filterBySite($deliveries, $siteId);

		return $deliveries;
	}

	protected function loadActiveList()
	{
		$listByParent = [];

		foreach (Sale\Delivery\Services\Manager::getActiveList(true) as $id => $fields)
		{
			if ($delivery = Sale\Delivery\Services\Manager::createObject($fields))
			{
				$name = $delivery->getName();
				$parent = $delivery->getParentService();
				$parentId = $parent ? $parent->getId() : 0;

				if (!isset($listByParent[$parentId]))
				{
					$listByParent[$parentId] = [];
				}

				$listByParent[$parentId][] = [
					'ID' => $id,
					'VALUE' => sprintf('[%s] %s', $id, $name),
					'TYPE' => $this->getDeliveryServiceType($delivery),
					'GROUP' => $parent ? $parent->getName() : null,
				];
			}
		}

		return !empty($listByParent) ? array_merge(...$listByParent) : [];
	}

	protected function getDeliveryServiceType(Sale\Delivery\Services\Base $deliveryService)
	{
		if ((int)$deliveryService->getId() === $this->getEmptyDeliveryId())
		{
			$result = Market\Data\Trading\Delivery::EMPTY_DELIVERY;
		}
		else
		{
			$result = null;
		}

		return $result;
	}

	/** @noinspection PhpInternalEntityUsedInspection */
	protected function filterBySite($deliveryServices, $siteId)
	{
		$result = [];

		if ($siteId === null)
		{
			$result = $deliveryServices;
		}
		else if (!empty($deliveryServices))
		{
			$deliveryIds = array_column($deliveryServices, 'ID');

			if (count($deliveryIds) === 1) // if only one then result boolean
			{
				$deliveryIds[] = -1;
			}

			$validServices = Sale\Delivery\Services\Manager::checkServiceRestriction(
				$deliveryIds,
				$siteId,
				'\Bitrix\Sale\Delivery\Restrictions\BySite'
			);

			if (is_array($validServices))
			{
				$validServicesMap = array_flip($validServices);
			}
			else // is older version
			{
				$validServicesMap = [];

				foreach ($deliveryServices as $delivery)
				{
					$isValid = Sale\Delivery\Services\Manager::checkServiceRestriction(
						$delivery['ID'],
						$siteId,
						'\Bitrix\Sale\Delivery\Restrictions\BySite'
					);

					if ($isValid)
					{
						$validServicesMap[$delivery['ID']] = true;
					}
				}
			}

			foreach ($deliveryServices as $deliveryService)
			{
				if (isset($validServicesMap[$deliveryService['ID']]))
				{
					$result[] = $deliveryService;
				}
			}
		}

		return $result;
	}

	public function filterServicesWithoutPeriod(array $deliveryIds)
	{
		if (empty($deliveryIds)) { return []; }

		$result = [];
		$query = Sale\Delivery\Services\Table::getList([
			'filter' => [ '=ID' => $deliveryIds ],
		]);

		while ($deliveryRow = $query->fetch())
		{
			if ($this->hasServicePeriod($deliveryRow)) { continue; }

			$result[] = $deliveryRow['ID'];
		}

		return $result;
	}

	protected function hasServicePeriod(array $deliveryRow)
	{
		if (!isset($deliveryRow['CLASS_NAME'])) { return false; }

		$deliveryClassName = ltrim($deliveryRow['CLASS_NAME'], '\\');
		$deliveryClassName = Market\Data\TextString::toLower($deliveryClassName);

		$result = false;
		/** @noinspection PhpUndefinedClassInspection */
		/** @noinspection PhpUndefinedNamespaceInspection */
		$types = [
			'configurable' => Sale\Delivery\Services\Configurable::class,
			'automatic' => Sale\Delivery\Services\AutomaticProfile::class,
			'additional' => \Sale\Handlers\Delivery\AdditionalProfile::class,
			'ruspost' => \Sale\Handlers\Delivery\RussianpostProfile::class,
			'dostavista' => \Sale\Handlers\Delivery\DostavistaHandler::class,
			'yandexTaxi' => \Sale\Handlers\Delivery\YandextaxiProfile::class,
			'ipolOzonCourier' => \Ipol\Ozon\Bitrix\Handler\DeliveryHandlerCourier::class,
			'ipolOzonPickup' => \Ipol\Ozon\Bitrix\Handler\DeliveryHandlerPickup::class,
			'ipolOzonPostamat' => \Ipol\Ozon\Bitrix\Handler\DeliveryHandlerPostamat::class,
		];

		foreach ($types as $type => $className)
		{
			$className = ltrim($className, '\\');
			$className = Market\Data\TextString::toLower($className);

			if ($className !== $deliveryClassName) { continue; }

			$method = 'has' . ucfirst($type) . 'ServicePeriod';

			if (method_exists($this, $method))
			{
				$result = $this->{$method}($deliveryRow);
			}
			else
			{
				$result = true;
			}

			break;
		}

		return $result;
	}

	/** @noinspection PhpUnused */
	protected function hasConfigurableServicePeriod(array $deliveryRow)
	{
		if (!isset($deliveryRow['CONFIG']['MAIN']['PERIOD'])) { return false; }

		$result = false;
		$configPeriod = $deliveryRow['CONFIG']['MAIN']['PERIOD'];
		$keys = [
			'FROM',
			'TO',
		];

		foreach ($keys as $key)
		{
			if (isset($configPeriod[$key]) && (string)$configPeriod[$key] !== '')
			{
				$result = true;
				break;
			}
		}

		return $result;
	}

	/** @noinspection PhpUnused */
	protected function hasAutomaticServicePeriod(array $deliveryRow)
	{
		if (empty($deliveryRow['CODE'])) { return false; }

		$result = false;
		$matched = [
			'rus_post',
			'ipolh_dpd',
			'boxberry',
			'sdek',
		];

		foreach ($matched as $code)
		{
			if (Market\Data\TextString::getPosition($deliveryRow['CODE'], $code) === 0)
			{
				$result = true;
				break;
			}
		}

		return $result;
	}

	public function getEmptyDeliveryId()
	{
		return (int)Sale\Delivery\Services\Manager::getEmptyDeliveryServiceId();
	}

	public function getRestricted(TradingEntity\Reference\Order $order)
	{
		$result = [];
		$calculatableOrder = $this->getOrderCalculatable($order);
		$shipment = $this->getCalculatableShipment($calculatableOrder);
		$services = Sale\Delivery\Services\Manager::getRestrictedList(
			$shipment,
			Sale\Delivery\Restrictions\Manager::MODE_CLIENT
		);

		foreach ($services as $serviceParameters)
		{
			try
			{
				/** @var class-string<Sale\Delivery\Services\Base> $serviceClassName */
				$serviceClassName = $serviceParameters['CLASS_NAME'];
				$serviceId = (int)$serviceParameters['ID'];

				if (
					$serviceId <= 0
					|| !class_exists($serviceClassName)
					|| $serviceClassName::canHasProfiles()
					|| (
						is_callable($serviceClassName . '::canHasChildren')
						&& $serviceClassName::canHasChildren()
					)
				)
				{
					continue;
				}

				$service = $this->getDeliveryService($serviceId);

				if (
					!$service
					|| $this->getDeliveryServiceType($service) === Market\Data\Trading\Delivery::EMPTY_DELIVERY
				)
				{
					continue;
				}

				if (
					!$this->isOrderLocationFilled($calculatableOrder)
					&& $this->hasDeliveryLocationRestriction($serviceId)
				)
				{
					continue;
				}

				$result[] = $serviceId;
			}
			catch (Main\SystemException $exception)
			{
				// silence
			}
		}

		return $result;
	}

	protected function isOrderLocationFilled(Sale\OrderBase $order)
	{
		$propertyCollection = $order->getPropertyCollection();

		if ($propertyCollection === null) { return false; }

		$locationProperty = $propertyCollection->getDeliveryLocation();

		if ($locationProperty === null) { return false; }

		return (string)$locationProperty->getValue() !== '';
	}

	protected function hasDeliveryLocationRestriction($serviceId)
	{
		$result = false;
		$restrictions = Sale\Delivery\Restrictions\Manager::getRestrictionsList($serviceId);

		foreach ($restrictions as $restriction)
		{
			if (
				$restriction['CLASS_NAME'] === '\Bitrix\Sale\Delivery\Restrictions\ByLocation'
				|| $restriction['CLASS_NAME'] === '\Bitrix\Sale\Delivery\Restrictions\ExcludeLocation'
			)
			{
				$result = true;
				break;
			}
		}

		return $result;
	}

	public function isCompatible($deliveryId, TradingEntity\Reference\Order $order)
	{
		try
		{
			$calculatableOrder = $this->getOrderCalculatable($order);
			$shipment = $this->getCalculatableShipment($calculatableOrder);
			$deliveryService = $this->getDeliveryService($deliveryId);

			$result = $deliveryService->isCompatible($shipment);
		}
		catch (Main\SystemException $exception)
		{
			$result = false;
		}

		return $result;
	}

	public function calculate($deliveryId, TradingEntity\Reference\Order $order)
	{
		$result = new TradingEntity\Reference\Delivery\CalculationResult();

		try
		{
			$calculatableOrder = $this->getOrderCalculatable($order);
			$shipment = $this->getCalculatableShipment($calculatableOrder);
			$deliveryService = $this->getDeliveryService($deliveryId);
			$currency = $shipment->getCurrency();

			$calculatableOrder->isStartField();

			$shipment->setDeliveryService($deliveryService);

			if ($currency !== $deliveryService->getCurrency())
			{
				$deliveryService->getExtraServices()->setOperationCurrency($currency);
			}

			$calculationResult = $shipment->calculateDelivery();

			if ($calculationResult->isSuccess())
			{
				$shipment->setField('BASE_PRICE_DELIVERY', $calculationResult->getPrice());
			}

			if ($this->hasDeliveryDiscount($calculatableOrder))
			{
				$calculatableOrder->doFinalAction(true);
			}

			Delivery\CalculationFacade::mergeCalculationResult($result, $calculationResult);
			Delivery\CalculationFacade::mergeDeliveryService($result, $deliveryService);
			Delivery\CalculationFacade::mergeOrderData($result, $calculatableOrder);
		}
		catch (Main\SystemException $exception)
		{
			$result->addError(new Market\Error\Base(
				$exception->getMessage(),
				$exception->getCode()
			));
		}

		return $result;
	}

	public function configureShipment(Order $order, $deliveryId)
	{
		$calculatableOrder = $this->getOrderCalculatable($order);
		$shipment = $this->getCalculatableShipment($calculatableOrder);
		$deliveryService = $this->getDeliveryService($deliveryId);

		$shipment->setDeliveryService($deliveryService);
	}

	public function getDeliveryService($deliveryId)
	{
		if (!isset($this->deliveryServices[$deliveryId]))
		{
			$this->deliveryServices[$deliveryId] = $this->loadDeliveryService($deliveryId);
		}

		return $this->deliveryServices[$deliveryId];
	}

	protected function loadDeliveryService($deliveryId)
	{
		$deliveryService = Sale\Delivery\Services\Manager::getObjectById($deliveryId);

		if ($deliveryService === null)
		{
			$message = static::getLang('TRADING_ENTITY_SALE_DELIVERY_SERVICE_NOT_FOUND', [
				'#ID#' => $deliveryId,
			]);
			throw new Main\SystemException($message);
		}

		return $deliveryService;
	}

	/**
	 * @param Order $order
	 *
	 * @return Sale\Order
	 */
	protected function getOrderCalculatable(TradingEntity\Reference\Order $order)
	{
		if (!($order instanceof Order))
		{
			throw new Main\NotSupportedException('only Sale\Order calculation supported');
		}

		return $order->getCalculatable();
	}

	protected function getCalculatableShipment(Sale\Order $order)
	{
		$result = null;

		/** @var Sale\Shipment $shipment */
		foreach ($order->getShipmentCollection() as $shipment)
		{
			if (!$shipment->isSystem())
			{
				$result = $shipment;
				break;
			}
		}

		if ($result === null)
		{
			$message = static::getLang('TRADING_ENTITY_SALE_DELIVERY_CALCULATED_SHIPMENT_NOT_FOUND');
			throw new Main\SystemException($message);
		}

		return $result;
	}

	protected function hasDeliveryDiscount(Sale\Order $order)
	{
		$siteId = $order->getSiteId();
		$userGroups = Market\Data\UserGroup::getUserGroups($order->getUserId());
		$cacheKey = $siteId . '|' . implode('.', $userGroups);

		if (!isset($this->existsDeliveryDiscount[$cacheKey]))
		{
			$this->existsDeliveryDiscount[$cacheKey] = $this->searchDeliveryDiscount($siteId, $userGroups);
		}

		return $this->existsDeliveryDiscount[$cacheKey];
	}

	protected function searchDeliveryDiscount($siteId, $userGroups)
	{
		if (!method_exists('CSaleActionCtrlDelivery', 'GetControlID')) { return false; }

		// query discounts

		$queryDiscounts = Sale\Internals\DiscountTable::getList([
			'filter' => [
				'=LID' => $siteId,
				'=ACTIVE' => 'Y',
				[
					'LOGIC' => 'OR',
					'ACTIVE_FROM' => null,
					'>=ACTIVE_FROM' => new Main\Type\DateTime(),
				],
				[
					'LOGIC' => 'OR',
					'ACTIVE_TO' => null,
					'<=ACTIVE_TO' => new Main\Type\DateTime(),
				],
				[
					'LOGIC' => 'OR',
					'%ACTIONS' => serialize(\CSaleActionCtrlDelivery::GetControlID()),
					'%APPLICATION' => '::applyToDelivery(',
				],
			],
			'select' => [ 'ID' ],
		]);

		$discounts = $queryDiscounts->fetchAll();

		if (empty($discounts)) { return false; }

		// test user group access

		$queryAccess = Sale\Internals\DiscountGroupTable::getList(array(
			'select' => ['DISCOUNT_ID'],
			'filter' => [
				'=DISCOUNT_ID' => array_column($discounts, 'ID'),
				'=GROUP_ID' => $userGroups,
				'=ACTIVE' => 'Y',
			],
			'limit' => 1,
		));

		return (bool)$queryAccess->fetch();
	}

	public function getStores($deliveryId)
	{
		$deliveryService = $this->getDeliveryService($deliveryId);

		if (!($deliveryService instanceof Sale\Delivery\Services\Configurable)) { return null; }

		return Sale\Delivery\ExtraServices\Manager::getStoresList($deliveryService->getId());
	}

	public function suggestDeliveryType($deliveryId, array $supportedTypes = null)
	{
		$implementedTypes = $this->getSuggestImplementedDeliveryTypes();
		$processTypes = ($supportedTypes === null)
			? $implementedTypes
			: array_intersect($supportedTypes, $implementedTypes);

		if (empty($processTypes)) { return null; }

		$deliveryService = $this->getDeliveryService($deliveryId);
		$result = null;

		foreach ($processTypes as $type)
		{
			if ($this->matchDeliveryType($deliveryService, $type))
			{
				$result = $type;
				break;
			}
		}

		return $result;
	}

	protected function matchDeliveryType(Sale\Delivery\Services\Base $deliveryService, $type)
	{
		$methodName = 'matchDeliveryType' . ucfirst($type);
		$result = false;

		if (method_exists($this, $methodName))
		{
			$result = (bool)$this->{$methodName}($deliveryService);
		}

		return $result;
	}

	/** @noinspection PhpUnused */
	protected function matchDeliveryTypeDelivery(Sale\Delivery\Services\Base $deliveryService)
	{
		if ($deliveryService instanceof SaleHandlers\Delivery\SimpleHandler)
		{
			$result = true;
		}
		else if ($deliveryService instanceof Sale\Delivery\Services\Configurable)
		{
			$stores = Sale\Delivery\ExtraServices\Manager::getStoresList($deliveryService->getId());
			$result = empty($stores);
		}
		else
		{
			$courier = $this->environment->getCourierRegistry()->resolveCourier($deliveryService->getId());
			$result = ($courier !== null);
		}

		return $result;
	}

	/** @noinspection PhpUnused */
	protected function matchDeliveryTypePickup(Sale\Delivery\Services\Base $deliveryService)
	{
		$deliveryId = $deliveryService->getId();
		$stores = Sale\Delivery\ExtraServices\Manager::getStoresList($deliveryId);

		if (!empty($stores)) { return true; }

		$outlet = $this->environment->getOutletRegistry()->resolveOutlet($deliveryId);

		return $outlet !== null;
	}

	/** @noinspection PhpUnused */
	protected function matchDeliveryTypePost(Sale\Delivery\Services\Base $deliveryService)
	{
		$result = false;
		$conditions = [
			'code',
			'serviceType',
		];

		foreach ($conditions as $condition)
		{
			$method = 'testDeliveryTypePostBy' . ucfirst($condition);

			if ($this->{$method}($deliveryService))
			{
				$result = true;
				break;
			}
		}

		return $result;
	}

	/** @noinspection PhpUnused */
	protected function testDeliveryTypePostByCode(Sale\Delivery\Services\Base $deliveryService)
	{
		if (!($deliveryService instanceof SaleHandlers\Delivery\AdditionalProfile)) { return false; }

		$parentService = $deliveryService->getParentService();
		$parentConfig = $parentService && method_exists($parentService, 'getConfigValues') ? $parentService->getConfigValues() : null;

		return (
			isset($parentConfig['MAIN']['SERVICE_TYPE'])
			&& Market\Data\TextString::getPositionCaseInsensitive($parentConfig['MAIN']['SERVICE_TYPE'], 'post') !== false
		);
	}

	/** @noinspection PhpUnused */
	protected function testDeliveryTypePostByServiceType(Sale\Delivery\Services\Base $deliveryService)
	{
		$serviceCode = $deliveryService->getCode();

		return (Market\Data\TextString::getPositionCaseInsensitive($serviceCode, 'post') !== false);
	}

	protected function getSuggestImplementedDeliveryTypes()
	{
		return [
			'DELIVERY',
			'PICKUP',
			'POST',
		];
	}

	public function debugData($deliveryId)
	{
		$result = [];

		try
		{
			$deliveryId = (int)$deliveryId;

			if ($deliveryId <= 0) { return []; }

			$service = $this->getDeliveryService($deliveryId);
			$result['name'] = $service::getClassTitle();
			$result['code'] = $service->getCode();

			if (
				$service instanceof Sale\Delivery\Services\Configurable
				&& method_exists($service, 'getConfigValues')
			)
			{
				$config = $service->getConfigValues();

				$result['period'] = [
					'from' => $config['MAIN']['PERIOD']['FROM'],
					'to' => $config['MAIN']['PERIOD']['TO'],
					'unit' => $config['MAIN']['PERIOD']['TYPE'],
				];
			}
		}
		catch (\Exception $exception)
		{
			trigger_error($exception->getMessage(), E_USER_WARNING);
		}
		/** @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection */
		catch (\Throwable $exception)
		{
			trigger_error($exception->getMessage(), E_USER_WARNING);
		}

		return $result;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit