Your IP : 18.220.89.112


Current Path : /home/bitrix/ext_www/dev.home-comfort.in.ua/bitrix/modules/sale/lib/
Upload File :
Current File : /home/bitrix/ext_www/dev.home-comfort.in.ua/bitrix/modules/sale/lib/paymentcollection.php

<?php
/**
 * Bitrix Framework
 * @package bitrix
 * @subpackage sale
 * @copyright 2001-2012 Bitrix
 */
namespace Bitrix\Sale;

use Bitrix\Main;
use Bitrix\Sale\Internals;
use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale\PaySystem\Manager;
use Bitrix\Sale\PaySystem\Service;

Loc::loadMessages(__FILE__);

class PaymentCollection
	extends Internals\EntityCollection
{
	/** @var OrderBase */
	protected $order;

	/**
	 * @return Order
	 */
	protected function getEntityParent()
	{
		return $this->getOrder();
	}

	public function createItem(Service $paySystemService = null)
	{
		$payment = Payment::create($this, $paySystemService);
		$this->addItem($payment);

		return $payment;
	}

	/**
	 * @param Internals\CollectableEntity $payment
	 * @return bool|void
	 */
	public function addItem(Internals\CollectableEntity $payment)
	{
		/** @var Payment $payment */
		$payment = parent::addItem($payment);

		$order = $this->getOrder();
		return $order->onPaymentCollectionModify(EventActions::ADD, $payment);
	}

	/**
	 * @internal
	 *
	 * @param $index
	 * @return bool
	 */
	public function deleteItem($index)
	{
		$oldItem = parent::deleteItem($index);

		/** @var Order $order */
		$order = $this->getOrder();
		return $order->onPaymentCollectionModify(EventActions::DELETE, $oldItem);
	}

	/**
	 * @param Internals\CollectableEntity $item
	 * @param null $name
	 * @param null $oldValue
	 * @param null $value
	 *
	 * @return Result
	 * @throws Main\NotImplementedException
	 * @throws Main\ObjectNotFoundException
	 */
	public function onItemModify(Internals\CollectableEntity $item, $name = null, $oldValue = null, $value = null)
	{
		/** @var Order $order */
		$order = $this->getOrder();
		return $order->onPaymentCollectionModify(EventActions::UPDATE, $item, $name, $oldValue, $value);
	}

	/**
	 * @return bool
	 */
	public function isPaid()
	{
		if (!empty($this->collection) && is_array($this->collection))
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if (!$payment->isPaid())
					return false;
			}

			return true;
		}

		return false;
	}

	/**
	 * @param $name
	 * @param $oldValue
	 * @param $value
	 * @return Result
	 */
	public function onOrderModify($name, $oldValue, $value)
	{
		$result = new Result();

		switch($name)
		{
			case "CANCELED":

				if ($value == "Y")
				{
					$isPaid = false;

					/** @var Payment $payment */
					foreach ($this->collection as $payment)
					{
						if ($payment->isPaid())
						{
							$isPaid = true;
							break;
						}
					}

					if ($isPaid)
					{
						$result->addError(new ResultError(Loc::getMessage('SALE_ORDER_CANCEL_PAYMENT_EXIST_ACTIVE'), 'SALE_ORDER_CANCEL_PAYMENT_EXIST_ACTIVE'));
					}
				}

			break;

			case "PRICE":
				if (($order = $this->getOrder()) && $order->getId() > 0 && !$order->isCanceled())
				{
					$currentPayment = false;
					$allowQuantityChange = false;
					if (count($this->collection) == 1)
					{
						/** @var Payment $currentPayment */
						if ($currentPayment = $this->rewind())
						{
							$allowQuantityChange = (bool)(!$currentPayment->isPaid() && !$currentPayment->isReturn() && ($currentPayment->getSum() == $oldValue));
							
							if ($allowQuantityChange)
							{
								if ($paySystemService = $currentPayment->getPaysystem())
								{
									$allowQuantityChange = $paySystemService->isAllowEditPayment();
								}
							}
						}
					}

					if ($allowQuantityChange && $currentPayment)
					{
						$r = $currentPayment->setField("SUM", $value);
						if (!$r->isSuccess())
						{
							$result->addErrors($r->getErrors());
						}
					}
				}
			break;
		}

		return $result;
	}

	/**
	 * @param OrderBase $order
	 */
	public function setOrder(OrderBase $order)
	{
		$this->order = $order;
	}

	/**
	 * @return Order
	 */
	public function getOrder()
	{
		return $this->order;
	}

	/**
	 * @return PaymentCollection
	 */
	protected static function createPaymentCollectionObject()
	{
		$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);
		$paymentCollectionClassName = $registry->getPaymentCollectionClassName();

		return new $paymentCollectionClassName();
	}

	/**
	 * @param OrderBase $order
	 * @return PaymentCollection
	 */
	public static function load(OrderBase $order)
	{
		/** @var PaymentCollection $paymentCollection */
		$paymentCollection = static::createPaymentCollectionObject();
		$paymentCollection->setOrder($order);

		if ($order->getId() > 0)
		{
			$paymentList = Payment::loadForOrder($order->getId());
			/** @var Payment $payment */
			foreach ($paymentList as $payment)
			{
				$payment->setCollection($paymentCollection);
				$paymentCollection->addItem($payment);
			}
		}

		return $paymentCollection;
	}


	/**
	 * @return float
	 */
	public function getPaidSum()
	{
		$sum = 0;
		if (!empty($this->collection) && is_array($this->collection))
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if ($payment->getField('PAID') == "Y")
				{
					$sum += $payment->getSum();
				}
			}
		}

		return $sum;
	}

	/**
	 * @return float
	 */
	public function getSum()
	{
		$sum = 0;
		if (!empty($this->collection) && is_array($this->collection))
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				$sum += $payment->getSum();
			}
		}

		return $sum;
	}

	/**
	 * @return bool
	 */
	public function hasPaidPayment()
	{
		if (!empty($this->collection) && is_array($this->collection))
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if ($payment->getField('PAID') == "Y")
					return true;
			}
		}

		return false;
	}

	/**
	 * @return Entity\Result
	 * @throws Main\ArgumentException
	 * @throws Main\ObjectNotFoundException
	 * @throws \Exception
	 */
	public function save()
	{
		$result = new Entity\Result();

		/** @var Order $order */
		if (!$order = $this->getOrder())
		{
			throw new Main\ObjectNotFoundException('Entity "Order" not found');
		}

		$itemsFromDb = array();
		if ($this->getOrder()->getId() > 0)
		{
			$itemsFromDbList = Internals\PaymentTable::getList(
				array(
					"filter" => array("ORDER_ID" => $this->getOrder()->getId()),
					"select" => array("ID", "PAY_SYSTEM_NAME", "PAY_SYSTEM_ID")
				)
			);
			while ($itemsFromDbItem = $itemsFromDbList->fetch())
				$itemsFromDb[$itemsFromDbItem["ID"]] = $itemsFromDbItem;
		}

		/** @var Payment $payment */
		foreach ($this->collection as $payment)
		{
			if ($payment->isInner() && $payment->getSum() == 0 && $payment->getId() == 0)
				$payment->delete();
		}

		$changeMeaningfulFields = array(
			"PAID",
			"PAY_SYSTEM_ID",
			"PAY_SYSTEM_NAME",
			"SUM",
			"IS_RETURN",
			"ACCOUNT_NUMBER",
			"EXTERNAL_PAYMENT",
		);

		/** @var Payment $payment */
		foreach ($this->collection as $payment)
		{
			$isNew = (bool)($payment->getId() <= 0);
			$isChanged = $payment->isChanged();

			if ($order->getId() > 0 && $isChanged)
			{
				$logFields = array();

				$fields = $payment->getFields();
				$originalValues = $fields->getOriginalValues();

				foreach($originalValues as $originalFieldName => $originalFieldValue)
				{
					if (in_array($originalFieldName, $changeMeaningfulFields) && $payment->getField($originalFieldName) != $originalFieldValue)
					{
						$logFields[$originalFieldName] = $payment->getField($originalFieldName);
						if (!$isNew)
							$logFields['OLD_'.$originalFieldName] = $originalFieldValue;
					}
				}
			}

			$r = $payment->save();
			if ($r->isSuccess())
			{
				if ($order->getId() > 0)
				{
					if ($isChanged)
					{
						OrderHistory::addLog('PAYMENT', $order->getId(), $isNew ? 'PAYMENT_ADD' : 'PAYMENT_UPDATE', $payment->getId(), $payment, $logFields, OrderHistory::SALE_ORDER_HISTORY_LOG_LEVEL_1);
						
						OrderHistory::addAction(
							'PAYMENT',
							$order->getId(),
							"PAYMENT_SAVED",
							$payment->getId(),
							$payment
						);
					}

				}
			}
			else
			{
				$result->addErrors($r->getErrors());
			}

			if (isset($itemsFromDb[$payment->getId()]))
				unset($itemsFromDb[$payment->getId()]);
		}

		$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);
		$paymentClassName = $registry->getPaymentClassName();
		$itemEventName = $paymentClassName::getEntityEventName();
		foreach ($itemsFromDb as $k => $v)
		{
			/** @var Main\Event $event */
			$event = new Main\Event('sale', "OnBefore".$itemEventName."Deleted", array(
					'VALUES' => $v,
			));
			$event->send();

			Internals\PaymentTable::delete($k);

			/** @var Main\Event $event */
			$event = new Main\Event('sale', "On".$itemEventName."Deleted", array(
					'VALUES' => $v,
			));
			$event->send();

			if ($order->getId() > 0)
			{
				OrderHistory::addAction('PAYMENT', $order->getId(), 'PAYMENT_REMOVE', $k, null, array(
					"PAY_SYSTEM_NAME" => $v["PAY_SYSTEM_NAME"],
					"PAY_SYSTEM_ID" => $v["PAY_SYSTEM_ID"],
				));

				EntityMarker::deleteByFilter(array(
					 '=ORDER_ID' => $order->getId(),
					 '=ENTITY_TYPE' => EntityMarker::ENTITY_TYPE_PAYMENT,
					 '=ENTITY_ID' => $k,
				 ));
			}

		}

		if ($order->getId() > 0)
		{
			OrderHistory::collectEntityFields('PAYMENT', $order->getId());
		}

		return $result;
	}

	/**
	 * @return Payment|bool
	 * @throws Main\ObjectNotFoundException
	 */
	public function getInnerPayment()
	{
		/** @var Order $order */
		if (!$order = $this->getOrder())
		{
			throw new Main\ObjectNotFoundException('Entity "Order" not found');
		}

		if ($paySystemId = PaySystem\Manager::getInnerPaySystemId())
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if ($payment->getPaymentSystemId() == $paySystemId)
					return $payment;
			}

			/** @var Service $paySystem */
			if ($paySystem = Manager::getObjectById($paySystemId))
			{
				return $this->createItem($paySystem);
			}

		}

		return false;
	}

	/**
	 * @return int
	 */
	public static function getInnerPaySystemId()
	{
		return PaySystem\Manager::getInnerPaySystemId();
	}

	/**
	 * @return bool
	 */
	public function isExistsInnerPayment()
	{
		if ($paySystemId = PaySystem\Manager::getInnerPaySystemId())
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if ($payment->getPaymentSystemId() == $paySystemId)
					return true;
			}
		}

		return false;
	}

	/**
	 * @return Result
	 * @throws Main\ObjectNotFoundException
	 */
	public function verify()
	{
		$result = new Result();

		/** @var Payment $payment */
		foreach ($this->collection as $payment)
		{
			$r = $payment->verify();
			if (!$r->isSuccess())
			{
				$result->addErrors($r->getErrors());
				
				/** @var Order $order */
				if (!$order = $this->getOrder())
				{
					throw new Main\ObjectNotFoundException('Entity "Order" not found');
				}

				EntityMarker::addMarker($order, $payment, $r);
				$order->setField('MARKED', 'Y');
			}
		}
		return $result;
	}

	/**
	 * @internal
	 * @param \SplObjectStorage $cloneEntity
	 *
	 * @return PaymentCollection
	 */
	public function createClone(\SplObjectStorage $cloneEntity)
	{
		if ($this->isClone() && $cloneEntity->contains($this))
		{
			return $cloneEntity[$this];
		}
		
		$paymentCollectionClone = clone $this;
		$paymentCollectionClone->isClone = true;

		if ($this->order)
		{
			if ($cloneEntity->contains($this->order))
			{
				$paymentCollectionClone->order = $cloneEntity[$this->order];
			}
		}

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

		/**
		 * @var int key
		 * @var Payment $payment
		 */
		foreach ($paymentCollectionClone->collection as $key => $payment)
		{
			if (!$cloneEntity->contains($payment))
			{
				$cloneEntity[$payment] = $payment->createClone($cloneEntity);
			}

			$paymentCollectionClone->collection[$key] = $cloneEntity[$payment];
		}

		return $paymentCollectionClone;
	}

	/**
	 * Is the entire collection of marked
	 *
	 * @return bool
	 */
	public function isMarked()
	{
		if (!empty($this->collection) && is_array($this->collection))
		{
			/** @var Payment $payment */
			foreach ($this->collection as $payment)
			{
				if ($payment->isMarked())
					return true;
			}
		}

		return false;
	}

}