Your IP : 18.226.94.242


Current Path : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/sale/lib/paysystem/
Upload File :
Current File : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/sale/lib/paysystem/service.php

<?php

namespace Bitrix\Sale\PaySystem;

use Bitrix\Crm\EntityRequisite;
use Bitrix\Crm\Requisite\EntityLink;
use Bitrix\Main\Entity\EntityError;
use Bitrix\Main\Error;
use Bitrix\Main\Event;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\NotSupportedException;
use Bitrix\Main\Request;
use Bitrix\Main\SystemException;
use Bitrix\Main\Type\DateTime;
use Bitrix\Sale\BusinessValue;
use Bitrix\Sale\Order;
use Bitrix\Sale\Payment;
use Bitrix\Sale\Result;
use Bitrix\Main\IO;
use Bitrix\Sale\ResultError;

Loc::loadMessages(__FILE__);

class Service
{
	const EVENT_ON_BEFORE_PAYMENT_PAID = 'OnSalePsServiceProcessRequestBeforePaid';
	const PAY_SYSTEM_PREFIX = 'PAYSYSTEM_';

	/** @var ServiceHandler|IHold|IRefund|IPrePayable|ICheckable|IPayable|IRequested $handler */
	private $handler = null;

	/**
	 * @var array
	 */
	private $fields = array();

	/** @var bool  */
	protected $isClone = false;

	/**
	 * @param $fields
	 */
	public function __construct($fields)
	{
		$handlerType = '';
		$className = '';

		$name = Manager::getFolderFromClassName($fields['ACTION_FILE']);

		foreach (Manager::getHandlerDirectories() as $type => $path)
		{
			if (IO\File::isFileExists($_SERVER['DOCUMENT_ROOT'].$path.$name.'/handler.php'))
			{
				$className = Manager::getClassNameFromPath($fields['ACTION_FILE']);
				if (!class_exists($className))
					require_once($_SERVER['DOCUMENT_ROOT'].$path.$name.'/handler.php');

				if (class_exists($className))
				{
					$handlerType = $type;
					break;
				}

				$className = '';
			}
		}

		if ($className === '')
		{
			if (Manager::isRestHandler($fields['ACTION_FILE']))
			{
				$className = '\Bitrix\Sale\PaySystem\RestHandler';
				if (!class_exists($fields['ACTION_FILE']))
				{
					class_alias($className, $fields['ACTION_FILE']);
				}
			}
			else
			{
				$className = '\Bitrix\Sale\PaySystem\CompatibilityHandler';
			}
		}

		$this->fields = $fields;
		$this->handler = new $className($handlerType, $this);
	}

	/**
	 * @param Payment $payment
	 * @param Request|null $request
	 * @param int $mode
	 * @return ServiceResult
	 */
	public function initiatePay(Payment $payment, Request $request = null, $mode = BaseServiceHandler::STREAM)
	{
		$this->handler->setInitiateMode($mode);
		$initResult = $this->handler->initiatePay($payment, $request);

		$psData = $initResult->getPsData();
		if ($psData)
		{
			$setResult = $payment->setFields($psData);
			if ($setResult->isSuccess())
			{
				/** @var \Bitrix\Sale\PaymentCollection $paymentCollection */
				$paymentCollection = $payment->getCollection();
				if ($paymentCollection)
				{
					$order = $paymentCollection->getOrder();
					if ($order)
					{
						$saveResult = $order->save();
						if (!$saveResult->isSuccess())
							$initResult->addErrors($saveResult->getErrors());
					}
				}
			}
			else
			{
				$initResult->addErrors($setResult->getErrors());
			}
		}

		if (!$initResult->isSuccess())
			ErrorLog::add(array('ACTION' => 'initiatePay', 'MESSAGE' => $initResult->getErrorMessages()));

		return $initResult;
	}

	/**
	 * @return bool
	 */
	public function isRefundable()
	{
		if ($this->handler instanceof IRefundExtended)
			return $this->handler->isRefundableExtended();

		return $this->handler instanceof IRefund;
	}

	/**
	 * @param Payment $payment
	 * @param int $refundableSum
	 * @return ServiceResult|Result
	 * @throws SystemException
	 * @throws \Bitrix\Main\ArgumentOutOfRangeException
	 */
	public function refund(Payment $payment, $refundableSum = 0)
	{
		if ($this->isRefundable())
		{
			$result = new Result();

			if (!$payment->isPaid())
			{
				$result->addError(new ResultError(Loc::getMessage('SALE_PS_SERVICE_PAYMENT_NOT_PAID')));
				return $result;
			}

			if ($refundableSum == 0)
				$refundableSum = $payment->getSum();

			/** @var ServiceResult $result */
			$result = $this->handler->refund($payment, $refundableSum);

			return $result;
		}

		throw new SystemException();
	}

	/**
	 * @param Request $request
	 * @return Result
	 * @throws \Bitrix\Main\ArgumentNullException
	 * @throws \Bitrix\Main\ArgumentOutOfRangeException
	 * @throws \Bitrix\Main\ObjectNotFoundException
	 */
	public function processRequest(Request $request)
	{
		$processResult = new Result();

		if (!($this->handler instanceof ServiceHandler))
			return $processResult;

		$paymentId = $this->handler->getPaymentIdFromRequest($request);

		if (empty($paymentId))
		{
			$errorMessage = str_replace('#PAYMENT_ID#', $paymentId, Loc::getMessage('SALE_PS_SERVICE_PAYMENT_ERROR'));
			$processResult->addError(new Error($errorMessage));
			ErrorLog::add(array(
				'ACTION' => 'processRequest',
				'MESSAGE' => $errorMessage
			));
			return $processResult;
		}

		list($orderId, $paymentId) = Manager::getIdsByPayment($paymentId);

		if (!$orderId)
		{
			$errorMessage = str_replace('#ORDER_ID#', $orderId, Loc::getMessage('SALE_PS_SERVICE_ORDER_ERROR'));
			$processResult->addError(new Error($errorMessage));
			ErrorLog::add(array(
				'ACTION' => 'processRequest',
				'MESSAGE' => $errorMessage
			));
			return $processResult;
		}

		/** @var \Bitrix\Sale\Order $order */
		$order = Order::load($orderId);

		if (!$order)
		{
			$errorMessage = str_replace('#ORDER_ID#', $orderId, Loc::getMessage('SALE_PS_SERVICE_ORDER_ERROR'));
			$processResult->addError(new Error($errorMessage));
			ErrorLog::add(array(
				'ACTION' => 'processRequest',
				'MESSAGE' => $errorMessage
			));
			return $processResult;
		}

		if ($order->isCanceled())
		{
			$errorMessage = str_replace('#ORDER_ID#', $orderId, Loc::getMessage('SALE_PS_SERVICE_ORDER_CANCELED'));
			$processResult->addError(new Error($errorMessage));
			ErrorLog::add(array(
				'ACTION' => 'processRequest',
				'MESSAGE' => $errorMessage
			));
			return $processResult;
		}
		/** @var \Bitrix\Sale\PaymentCollection $collection */
		$collection = $order->getPaymentCollection();

		/** @var \Bitrix\Sale\Payment $payment */
		$payment = $collection->getItemById($paymentId);

		if (!$payment)
		{
			$errorMessage = str_replace('#PAYMENT_ID#', $orderId, Loc::getMessage('SALE_PS_SERVICE_PAYMENT_ERROR'));
			$processResult->addError(new Error($errorMessage));
			ErrorLog::add(array(
				'ACTION' => 'processRequest',
				'MESSAGE' => $errorMessage
			));
			return $processResult;
		}

		if (ErrorLog::DEBUG_MODE)
		{
			ErrorLog::add(array(
				'ACTION' => 'RESPONSE',
				'MESSAGE' => print_r($request->toArray(), 1)
			));
		}

		/** @var \Bitrix\Sale\PaySystem\ServiceResult $serviceResult */
		$serviceResult = $this->handler->processRequest($payment, $request);

		if ($serviceResult->isSuccess())
		{
			$status = null;
			$operationType = $serviceResult->getOperationType();

			if ($operationType == ServiceResult::MONEY_COMING)
				$status = 'Y';
			else if ($operationType == ServiceResult::MONEY_LEAVING)
				$status = 'N';

			if ($status !== null)
			{
				$event = new Event('sale', self::EVENT_ON_BEFORE_PAYMENT_PAID,
					array(
						'payment' => $payment,
						'status' => $status,
						'pay_system_id' => $this->getField('ID')
					)
				);
				$event->send();

				$paidResult = $payment->setPaid($status);
				if (!$paidResult->isSuccess())
				{
					ErrorLog::add(array(
						'ACTION' => 'PAYMENT SET PAID',
						'MESSAGE' => join(' ', $paidResult->getErrorMessages())
					));
					$serviceResult->setResultApplied(false);
				}
			}

			$psData = $serviceResult->getPsData();
			if ($psData)
			{
				$res = $payment->setFields($psData);

				if (!$res->isSuccess())
				{
					ErrorLog::add(array(
						'ACTION' => 'PAYMENT SET DATA',
						'MESSAGE' => join(' ', $res->getErrorMessages())
					));
					$serviceResult->setResultApplied(false);
				}
			}

			$saveResult = $order->save();

			if (!$saveResult->isSuccess())
			{
				ErrorLog::add(array(
					'ACTION' => 'ORDER SAVE',
					'MESSAGE' => join(' ', $saveResult->getErrorMessages())
				));
				$serviceResult->setResultApplied(false);
			}
		}
		else
		{
			$serviceResult->setResultApplied(false);
			$processResult->addErrors($serviceResult->getErrors());
		}

		$this->handler->sendResponse($serviceResult, $request);

		return $processResult;
	}

	/**
	 * @return string
	 */
	public function getConsumerName()
	{
		return static::PAY_SYSTEM_PREFIX.$this->fields['ID'];
	}

	/**
	 * @return array
	 */
	public function getHandlerDescription()
	{
		return $this->handler->getDescription();
	}

	/**
	 * @return bool
	 */
	public function isBlockable()
	{
		return $this->handler instanceof IHold;
	}

	/**
	 * @param Payment $payment
	 * @return mixed
	 * @throws SystemException
	 */
	public function cancel(Payment $payment)
	{
		if ($this->isBlockable())
			return $this->handler->cancel($payment);

		throw new SystemException();
	}

	/**
	 * @param Payment $payment
	 * @return mixed
	 * @throws SystemException
	 */
	public function confirm(Payment $payment)
	{
		if ($this->isBlockable())
			return  $this->handler->confirm($payment);

		throw new SystemException();
	}

	/**
	 * @param $name
	 * @return mixed
	 */
	public function getField($name)
	{
		return $this->fields[$name];
	}

	/**
	 * @return array
	 */
	public function getCurrency()
	{
		return $this->handler->getCurrencyList();
	}

	/**
	 * @return bool
	 */
	public function isCash()
	{
		return $this->fields['IS_CASH'] == 'Y';
	}

	/**
	 * @param Payment $payment
	 * @return ServiceResult
	 */
	public function creditNoDemand(Payment $payment)
	{
		return $this->handler->creditNoDemand($payment);
	}

	/**
	 * @param Payment $payment
	 * @return ServiceResult
	 */
	public function debitNoDemand(Payment $payment)
	{
		return $this->handler->debitNoDemand($payment);
	}

	/**
	 * @return bool
	 */
	public function isPayable()
	{
		if ($this->handler instanceof IPayable)
			return true;

		if (method_exists($this->handler, 'isPayableCompatibility'))
			return $this->handler->isPayableCompatibility();

		return false;
	}

	/**
	 * @return bool
	 */
	public function isAffordPdf()
	{
		return $this->handler->isAffordPdf();
	}

	/**
	 * @param Payment $payment
	 * @return mixed
	 */
	public function getPaymentPrice(Payment $payment)
	{
		if ($this->isPayable())
			return $this->handler->getPrice($payment);

		return 0;
	}

	/**
	 * @param array $params
	 */
	public function setTemplateParams(array $params)
	{
		$this->handler->setExtraParams($params);
	}

	/**
	 * @param Payment|null $payment
	 * @param $templateName
	 * @return ServiceResult
	 */
	public function showTemplate(Payment $payment = null, $templateName)
	{
		return $this->handler->showTemplate($payment, $templateName);
	}

	/**
	 * @return bool
	 */
	public function isPrePayable()
	{
		return $this->handler instanceof IPrePayable;
	}

	/**
	 * @param Payment|null $payment
	 * @param Request $request
	 * @throws NotSupportedException
	 */
	public function initPrePayment(Payment $payment = null, Request $request)
	{
		if ($this->isPrePayable())
			return $this->handler->initPrePayment($payment, $request);

		throw new NotSupportedException;
	}

	/**
	 * @return mixed
	 * @throws NotSupportedException
	 */
	public function getPrePaymentProps()
	{
		if ($this->isPrePayable())
			return $this->handler->getProps();

		throw new NotSupportedException;
	}

	/**
	 * @param array $orderData
	 * @return mixed
	 * @throws NotSupportedException
	 */
	public function basketButtonAction(array $orderData = array())
	{
		if ($this->isPrePayable())
			return $this->handler->basketButtonAction($orderData);

		throw new NotSupportedException;
	}

	/**
	 * @param array $orderData
	 * @return mixed
	 * @throws NotSupportedException
	 */
	public function setOrderDataForPrePayment($orderData = array())
	{
		if ($this->isPrePayable())
			return $this->handler->setOrderConfig($orderData);

		throw new NotSupportedException;
	}

	/**
	 * @param $orderData
	 * @return mixed
	 * @throws NotSupportedException
	 */
	public function payOrderByPrePayment($orderData)
	{
		if ($this->isPrePayable())
			return $this->handler->payOrder($orderData);

		throw new NotSupportedException;
	}

	/**
	 * @return array
	 */
	public function getFieldsValues()
	{
		return $this->fields;
	}

	/**
	 * @return bool
	 */
	public function isAllowEditPayment()
	{
		return $this->fields['ALLOW_EDIT_PAYMENT'] == 'Y';
	}

	/**
	 * @return bool
	 */
	public function isCheckable()
	{
		if ($this->handler instanceof ICheckable)
			return true;

		if (method_exists($this->handler, 'isCheckableCompatibility'))
			return $this->handler->isCheckableCompatibility();

		return false;
	}

	/**
	 * @param Payment $payment
	 * @return ServiceResult
	 */
	public function check(Payment $payment)
	{
		$result = new ServiceResult();

		if ($this->isCheckable())
		{
			/** @var \Bitrix\Sale\PaymentCollection $paymentCollection */
			$paymentCollection = $payment->getCollection();

			/** @var \Bitrix\Sale\Order $order */
			$order = $paymentCollection->getOrder();

			if (!$order->isCanceled())
			{
				/** @var ServiceResult $result */
				$checkResult = $this->handler->check($payment);
				if ($checkResult instanceof ServiceResult && $checkResult->isSuccess())
				{
					$psData = $checkResult->getPsData();
					if ($psData)
					{
						$res = $payment->setFields($psData);
						if (!$res->isSuccess())
							$result->addErrors($res->getErrors());
					}

					if ($checkResult->getOperationType() == ServiceResult::MONEY_COMING)
					{
						$res = $payment->setPaid('Y');
						if (!$res->isSuccess())
							$result->addErrors($res->getErrors());
					}

					$res = $order->save();
					if (!$res->isSuccess())
						$result->addErrors($res->getErrors());
				}
				elseif (!$checkResult)
				{
					$result->addError(new Error(Loc::getMessage('SALE_PS_SERVICE_ERROR_CONNECT_PS')));
				}
			}
			else
			{
				$result->addError(new EntityError(Loc::getMessage('SALE_PS_SERVICE_ORDER_CANCELED', array('#ORDER_ID#' => $order->getId()))));
			}
		}

		return $result;
	}

	/**
	 * @param \SplObjectStorage $cloneEntity
	 *
	 * @return Service
	 */
	public function createClone(\SplObjectStorage $cloneEntity)
	{
		if ($this->isClone() && $cloneEntity->contains($this))
		{
			return $cloneEntity[$this];
		}

		$paySystemServiceClone = clone $this;
		$paySystemServiceClone->isClone = true;

		if (!$cloneEntity->contains($this))
		{
			$cloneEntity[$this] = $paySystemServiceClone;
		}

		if ($handler = $this->handler)
		{
			if (!$cloneEntity->contains($handler))
			{
				$cloneEntity[$handler] = $handler->createClone($cloneEntity);
			}

			if ($cloneEntity->contains($handler))
			{
				$paySystemServiceClone->handler = $cloneEntity[$handler];
			}
		}

		return $paySystemServiceClone;
	}

	/**
	 * @return bool
	 */
	public function isClone()
	{
		return $this->isClone;
	}

	/**
	 * @return bool
	 */
	public function isCustom()
	{
		return in_array($this->handler->getHandlerType(), array('CUSTOM', 'USER'));
	}

	/**
	 * @param Payment $payment
	 * @return array
	 */
	public function getParamsBusValue(Payment $payment)
	{
		return $this->handler->getParamsBusValue($payment);
	}

	/**
	 * @return bool
	 */
	public function isRequested()
	{
		return $this->handler instanceof IRequested;
	}

	/**
	 * @param $requestId
	 * @return ServiceResult
	 * @throws NotSupportedException
	 */
	public function checkMovementListStatus($requestId)
	{
		if ($this->isRequested())
			return $this->handler->getMovementListStatus($requestId);

		throw new NotSupportedException;
	}

	/**
	 * @param $requestId
	 * @return ServiceResult
	 * @throws NotSupportedException
	 */
	public function getMovementList($requestId)
	{
		if ($this->isRequested())
			return $this->handler->getMovementList($requestId);

		throw new NotSupportedException;
	}

	/**
	 * @param Request $request
	 * @return ServiceResult
	 */
	public function processAccountMovementList(Request $request)
	{
		$serviceResult = new ServiceResult();

		if ($this->isRequested())
		{
			$requestId = $request->get('requestId');
			if ($requestId === null)
			{
				$result = $this->handler->createMovementListRequest($request);
				if ($result->isSuccess())
				{
					$data = $result->getData();
					$requestId = $data['requestId'];
				}
				else
				{
					ErrorLog::add(array('ACTION' => 'createMovementListRequest', 'MESSAGE' => implode("\n", $result->getErrorMessages())));
					$serviceResult->addErrors($result->getErrors());
					return $serviceResult;
				}
			}

			if ($requestId)
			{
				$result = $this->handler->getMovementListStatus($requestId);
				if (!$result->isSuccess())
				{
					$serviceResult->addErrors($result->getErrors());
					return $serviceResult;
				}

				$data = $result->getData();
				if ($data['status'] === false)
				{
					$timeSleep = 2;
					$estimatedTime = $data['estimatedTime'] ?: '';
					if ($estimatedTime)
					{
						$dateTime = new DateTime($estimatedTime);
						$timeSleep = $dateTime->getTimestamp() - time();
					}

					$serviceResult->setData(array('timeSleep' => $timeSleep, 'requestId' => $requestId));
				}
				else
				{
					$result = $this->handler->getMovementList($requestId);
					if ($result->isSuccess())
					{
						$data = $result->getData();
						if ($data['ITEMS'])
						{
							$result = $this->applyAccountMovementList($data['ITEMS']);
							if (!$result->isSuccess())
								ErrorLog::add(array('ACTION' => 'getMovementList', 'MESSAGE' => implode("\n", $result->getErrorMessages())));

							return $result;
						}
					}
					else
					{
						ErrorLog::add(array('ACTION' => 'getMovementList', 'MESSAGE' => implode("\n", $result->getErrorMessages())));
						$serviceResult->addErrors($result->getErrors());
					}
				}
			}
			else
			{
				$serviceResult->addError(new Error(Loc::getMessage('SALE_PS_SERVICE_REQUEST_ERROR')));
			}
		}

		return $serviceResult;
	}

	/**
	 * @param $movementList
	 * @return ServiceResult
	 * @throws \Bitrix\Main\ArgumentNullException
	 * @throws \Bitrix\Main\ArgumentOutOfRangeException
	 */
	private function applyAccountMovementList($movementList)
	{
		$serviceResult = new ServiceResult();
		$paymentList = array();
		$usedOrders = array();

		if ($this->isRequested())
		{
			foreach ($movementList as $item)
			{
				if ($item['OPERATION'] !== 'C')
					continue;

				$info = array(
					'ACCOUNT_NUMBER' => '',
					'PRICE' => $item['SUM'],
					'CONTRACTOR_INN' => $item['CONTRACTOR_INN'],
					'CONTRACTOR_KPP' => $item['CONTRACTOR_KPP'],
					'DOC_NUMBER' => $item['DOC_NUMBER'],
					'CHARGE_DATE' => $item['CHARGE_DATE'],
					'PAID_BEFORE' => 'N'
				);

				$entityIds = array();
				if (!empty($item['PAYMENT_ID']))
					$entityIds[] = Manager::getIdsByPayment($item['PAYMENT_ID']);
				else
					$entityIds = $this->findEntityIds($item);

				if ($entityIds)
				{
					foreach ($entityIds as $entityId)
					{
						list($orderId, $paymentId) = $entityId;
						if ($orderId > 0)
						{
							$hash = md5($orderId);
							if (isset($usedOrders[$hash]))
								continue;

							$order = Order::load($orderId);
							if ($order)
							{
								$paymentCollection = $order->getPaymentCollection();
								if ($paymentCollection && $paymentId > 0)
								{
									/** @var \Bitrix\Sale\Payment $payment */
									$payment = $paymentCollection->getItemById($paymentId);
									if ($payment)
									{
										if (roundEx($payment->getSum(), 2) === roundEx($item['SUM'], 2))
										{
											$info['ACCOUNT_NUMBER'] = $order->getField('ACCOUNT_NUMBER');
											$info['ORDER_ID'] = $order->getId();

											$usedOrders[$hash] = $orderId;
											if ($payment->isPaid())
											{
												$info['PAID_BEFORE'] = 'Y';
											}
											else
											{
												$result = $payment->setPaid('Y');
												if ($result->isSuccess())
													$result = $order->save();

												if (!$result->isSuccess())
													$serviceResult->addErrors($result->getErrors());
												else
													break;
											}
										}
									}
								}
							}
						}
					}
				}

				$paymentList[] = $info;
			}
		}

		$serviceResult->setData(array('PAYMENT_LIST' => $paymentList));
		return $serviceResult;
	}

	/**
	 * @param $item
	 * @return array
	 * @throws \Bitrix\Main\LoaderException
	 */
	private function findEntityIds($item)
	{
		$result = array();

		$personTypeList = Manager::getPersonTypeIdList($this->getField('ID'));

		$map = BusinessValue::getMapping('BUYER_PERSON_COMPANY_INN', $this->getConsumerName(), array_shift($personTypeList));
		if ($map)
		{
			$filter = array();
			$runtimeFields = array();

			$type = $map['PROVIDER_KEY'];
			$value = $map['PROVIDER_VALUE'];

			if ($type == 'PROPERTY')
			{
				$runtimeFields['PROP'] = array(
					'data_type' => 'Bitrix\Sale\Internals\OrderPropsValueTable',
					'reference' => array('ref.ORDER_ID' => 'this.ORDER_ID'),
					'join_type' => 'inner'
				);

				$filter = array('PROP.CODE' => $value, 'PROP.VALUE' => $item['CONTRACTOR_INN']);
			}
			elseif ($type == 'REQUISITE')
			{
				if (!Loader::includeModule('crm'))
					return $result;

				$orderIds = array();

				$requisite = new EntityRequisite();
				$res = $requisite->getList(
					array(
						'select' => array('ID'),
						'filter' => array(
							'=ENTITY_TYPE_ID' => array(\CCrmOwnerType::Company, \CCrmOwnerType::Contact),
							'=RQ_INN' => $item['CONTRACTOR_INN']
						)
					)
				);

				$rqIds = array();
				while ($row = $res->fetch())
					$rqIds[] = $row['ID'];

				if ($rqIds)
				{
					$res = EntityLink::getList(
						array(
							'select' => array('ENTITY_ID'),
							'filter' => array('=ENTITY_TYPE_ID' => \CCrmOwnerType::Invoice, '=REQUISITE_ID' => $rqIds)
						)
					);

					while ($row = $res->fetch())
						$orderIds[] = $row['ENTITY_ID'];
				}

				if ($orderIds)
					$filter = array('ORDER_ID' => $orderIds);
			}

			if ($filter)
			{
				$dbRes = Payment::getList(array('select' => array('ID', 'ORDER_ID', 'SUM', 'CURRENCY'), 'filter' => $filter, 'order' => array('ID' => 'ASC'), 'runtime' => $runtimeFields));
				while ($data = $dbRes->fetch())
				{
					if (roundEx($data['SUM'], 2) === roundEx($item['SUM'], 2))
						$result[] = array($data['ORDER_ID'], $data['ID']);
				}
			}
		}

		return $result;
	}

	/**
	 * @return bool
	 */
	public function isTuned()
	{
		return $this->handler->isTuned();
	}

	/**
	 * @return array
	 */
	public function getDemoParams()
	{
		return $this->handler->getDemoParams();
	}

	/**
	 * @param $mode
	 */
	public function setTemplateMode($mode)
	{
		$this->handler->setInitiateMode($mode);
	}
}