• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/compatible/ordercompatibility.php
  • Класс: BitrixSaleCompatibleOrderCompatibility
  • Вызов: OrderCompatibility::fillPaymentCollectionFromRequest
public function fillPaymentCollectionFromRequest(array $fields)
{
	/** @var SaleOrder $order */
	if (!$order = $this->getOrder())
	{
		throw new MainObjectNotFoundException('Entity "Order" not found');
	}

	/** @var SalePaymentCollection $paymentCollection */
	if (!$paymentCollection = $order->getPaymentCollection())
	{
		throw new MainObjectNotFoundException('Entity "PaymentCollection" not found');
	}

	$result = new SaleResult();
	$sum = floatval($fields['PRICE']);

	if (isset($fields['SUM_PAID'])
		&& floatval($fields['SUM_PAID']) >= floatval($fields['PRICE']))
	{
		$sum = floatval($fields['SUM_PAID']);
	}

	$isPayFromUserBudget = null;
	$backToUserBudget = null;

	if (array_key_exists('ONLY_FULL_PAY_FROM_ACCOUNT', $fields))
	{
		$isPayFromUserBudget = $fields['ONLY_FULL_PAY_FROM_ACCOUNT'];
	}

	if ($isPayFromUserBudget === null && array_key_exists('PAY_CURRENT_ACCOUNT', $fields) && $fields['PAY_CURRENT_ACCOUNT'] !== null)
	{
		$isPayFromUserBudget = ($fields['PAY_CURRENT_ACCOUNT'] != "Y");
	}

	if (array_key_exists('PAY_FROM_ACCOUNT_BACK', $fields))
	{
		$backToUserBudget = ($fields['PAY_FROM_ACCOUNT_BACK'] == "Y");
	}

	$paySystemId = null;
	$paySystemName = null;

	$userId = $order->getUserId();
	$currency = $order->getCurrency();

	$rawFields = array();
	$paymentInner = null;
	$paymentOuter = null;
	$countPayments = count($paymentCollection);

	$orderPaid = false;

	if ((($countPayments == 0 && $order->getId() == 0)
		|| ($countPayments == 2 && $paymentCollection->isExistsInnerPayment())
		|| ($countPayments == 1 && !$paymentCollection->isExistsInnerPayment())))
	{

		$needSum = $order->getPrice() - $order->getSumPaid();

		if ($countPayments <= 1)
		{

			if ($order->getId() == 0)
			{
				if (!isset($fields["PAY_SYSTEM_ID"]))
					$fields["PAY_SYSTEM_ID"] = static::getDefaultPaySystemId($order->getPersonTypeId());


				/** @var SalePaySystemService $service */
				if ($service = SalePaySystemManager::getObjectById($fields["PAY_SYSTEM_ID"]))
				{
					/** @var SalePayment $paymentOuter */
					$paymentOuter = $paymentCollection->createItem($service);
					$paymentOuter->setField('DATE_BILL', new MainTypeDateTime());
					$paymentOuter->setField('SUM', $needSum);
					$paymentOuter->setField('PAY_SYSTEM_NAME', $service->getField('NAME'));
					$order->setFieldNoDemand('PAY_SYSTEM_ID', $fields["PAY_SYSTEM_ID"]);
					$countPayments = 1;
				}
			}
			else
			{
				$paymentOuter = null;

				/** @var SalePayment $payment */
				foreach ($paymentCollection as $payment)
				{
					if ($payment->isInner())
						continue;

					$paymentOuter = $payment;
				}

				if ($paymentOuter !== null
					&& ($paymentOuter->getPaymentSystemId() != intval($fields["PAY_SYSTEM_ID"]))
				)
				{
					/** @var SalePaySystemService $service */
					if ($service = SalePaySystemManager::getObjectById($fields["PAY_SYSTEM_ID"]))
					{
						/** @var SalePayment $paymentOuter */
						$paymentOuter->setField('PAY_SYSTEM_NAME', $service->getField('NAME'));
						$paymentOuter->setField('PAY_SYSTEM_ID', intval($fields["PAY_SYSTEM_ID"]));
						$order->setFieldNoDemand('PAY_SYSTEM_ID', intval($fields["PAY_SYSTEM_ID"]));
					}
				}

			}


		}

		if (isset($fields['PAYED']))
		{
			$paidFlag = null;


			if ($countPayments > 0)
			{
				/** @var SalePayment $payment */
				foreach($paymentCollection as $payment)
				{
					if ($paidFlag === null && $payment->isPaid() && $needSum == 0)
					{
						$paidFlag = 'Y';
					}

					if ($payment->isInner())
						continue;

					$paymentOuter = $payment;
				}
			}

			if ($paidFlag === null)
			{
				$paidFlag = 'N';
			}


			if ($paidFlag != $fields['PAYED'])
			{
				if ($fields['PAYED'] == "Y")
				{
					$pay = true;
					$orderPaid = true;

					if ($isPayFromUserBudget !== null)
					{
						if (static::canPayWithUserBudget($needSum, $userId, $currency, $isPayFromUserBudget))
						{
							$userBudget = SaleInternalsUserBudgetPool::getUserBudget($userId, $currency);

							if ($userBudget >= $needSum)
							{
								$pay = false;
							}
						}
					}

					/** @var SaleResult $r */
					$r = static::payFromBudget($order, $pay, $isPayFromUserBudget);
					if ($r->isSuccess())
					{
						$needSum = $order->getPrice() - $order->getSumPaid();

						if (!$pay)
						{
							/** @var SaleResult $r */
							$r = $paymentOuter->setField('SUM', $needSum);
						}

						if (!$r->isSuccess())
						{
							$result->addErrors($r->getErrors());
						}
					}
					else
					{
						$result->addErrors($r->getErrors());
					}
				}
				else
				{
					//
					/** @var SalePayment $payment */
					foreach($paymentCollection as $payment)
					{
						if ($payment->isPaid())
						{
							if ($backToUserBudget && $payment->isInner())
							{
								$payment->setReturn('Y');
							}
							else
							{
								$payment->setPaid('N');
							}
						}

						if ($payment->isInner())
						{
							$payment->delete();
						}
						else
						{
							$payment->setField('SUM', $order->getPrice());
						}
					}


				}

				unset($fields['PAYED']);
			}
			elseif ($order->getId() == 0)
			{
				if ($isPayFromUserBudget !== null)
				{
					if (static::canPayWithUserBudget($needSum, $userId, $currency, $isPayFromUserBudget))
					{
						$userBudget = SaleInternalsUserBudgetPool::getUserBudget($userId, $currency);

						$setSum = $userBudget;

						/** @var SaleResult $r */
						$r = static::payFromBudget($order, false);
						if ($r->isSuccess())
						{
							$sum -= $setSum;
						}
						else
						{
							$result->addErrors($r->getErrors());
						}
					}
				}
			}

			if ($order->getId() > 0)
			{
				$payment = null;

				/** @var SalePayment $paymentItem */
				foreach($paymentCollection as $paymentItem)
				{
					if ($paymentItem->isInner())
					{
						$paymentInner = $paymentItem;
						if ($payment === null && $paymentItem->isPaid())
						{
							$payment = $paymentItem;
						}
					}
					else
					{
						$paymentOuter = $paymentItem;
						if ($payment === null && $paymentItem->isPaid())
						{
							$payment = $paymentItem;
						}
					}
				}

				if ($payment === null)
				{
					if ($paymentOuter !== null)
						$payment = $paymentOuter;
					else
						$payment = $paymentInner;
				}

				if ($payment === null)
				{
					return $result;
				}

				$paymentFields = static::convertDateFields($fields, static::getPaymentDateFields());


				if (!empty($paymentFields['PAY_SYSTEM_ID']) && $paymentFields['PAY_SYSTEM_ID'] != $payment->getPaymentSystemId())
				{
					if ($payment->isInner())
					{
						unset($paymentFields['PAY_SYSTEM_ID']);
					}
					else
					{
						$paySystemId = (int)$paymentFields['PAY_SYSTEM_ID'];

						/** @var SalePaySystemService $paysystem */
						if ($paysystem = SalePaySystemManager::getObjectById($paySystemId))
						{
							$paymentFields['PAY_SYSTEM_NAME'] = $paysystem->getField('NAME');
						}
					}
				}


				$paymentFields = static::replaceFields($paymentFields, static::getPaymentReplaceFields());
				$paymentFields = static::clearFields($paymentFields, static::getPaymentAvailableFields());

				/** @var SaleResult $r */
				$r = $payment->setFields($paymentFields);
				if ($r->isSuccess())
				{

					static::fillOrderFieldsFromEntity($order, $payment, $fields, static::getPaymentFieldsToConvert());
				}
				else
				{
					$result->addErrors($r->getErrors());
				}


				if ($result->isSuccess() && intval($paySystemId) > 0)
				{
					$order->setFieldNoDemand('PAY_SYSTEM_ID', $paySystemId);
				}
			}
		}

		$paymentOuter = null;
		$calcSum = 0;
		/** @var SalePayment $payment */
		foreach($paymentCollection as $payment)
		{
			$calcSum += $payment->getSum();
			if ($payment->isInner())
				continue;

			$paymentOuter = $payment;
		}

		if ($paymentOuter && !$paymentOuter->isPaid())
		{
			if ($order->getPrice() != $calcSum)
			{
				$paymentOuter->setField('SUM', $paymentOuter->getSum() + ($order->getPrice() - $calcSum));
			}
		}

		if (!$paymentOuter)
			return $result;

		$fieldsFromOrder = array(
			'PS_STATUS', 'PS_STATUS_CODE', 'PS_STATUS_DESCRIPTION',
			'PS_STATUS_MESSAGE', 'PS_SUM', 'PS_CURRENCY', 'PS_RESPONSE_DATE',
			'PAY_VOUCHER_NUM', 'PAY_VOUCHER_DATE', 'DATE_PAY_BEFORE',
			'DATE_BILL', 'PAY_SYSTEM_NAME', 'PAY_SYSTEM_ID',
			'DATE_PAYED', 'EMP_PAYED_ID', 'CURRENCY'
		);

		foreach ($fieldsFromOrder as $fieldName)
		{
			if (isset($fields[$fieldName]))
			{
				switch ($fieldName)
				{
					case 'DATE_BILL':
					case 'DATE_PAY_BEFORE':
					case 'PS_RESPONSE_DATE':
					if (!isset($fields[$fieldName]) || strval($fields[$fieldName]) == '')
						continue 2;
						$value = new MainTypeDateTime($fields[$fieldName]);
					break;
					case 'PAY_VOUCHER_DATE':
						if (!isset($fields[$fieldName]) ||  strval($fields[$fieldName]) == '')
							continue 2;
						$value = new MainTypeDate($fields[$fieldName]);
						break;
					case 'DATE_PAYED':
						if (!isset($fields[$fieldName]) || strval($fields[$fieldName]) == '')
							continue 2;
						$fieldName = 'DATE_PAID';
						$value = new MainTypeDateTime($fields['DATE_PAYED']);
						break;
					case 'EMP_PAYED_ID':
						$fieldName = 'EMP_PAID_ID';
						$value = $fields['EMP_PAYED_ID'];
						break;
					default:
						$value = $fields[$fieldName];
					break;
				}
				$paymentOuter->setFieldNoDemand($fieldName, $value);
				if ($fieldName === 'PAY_SYSTEM_ID')
				{
					$order->setFieldNoDemand('PAY_SYSTEM_ID', $value);

					/** @var SalePaySystemService $paysystem */
					if ($paysystem = SalePaySystemManager::getObjectById($value))
						$paymentOuter->setFieldNoDemand('PAY_SYSTEM_NAME', $paysystem->getField('NAME'));
				}

				if ($fieldName == "DATE_PAID")
					$fieldName = 'DATE_PAYED';

				if (in_array($fieldName, $this->getAvailableFields()))
				{
					$order->setFieldNoDemand($fieldName, $value);
				};
			}
			elseif (isset($fields['~'.$fieldName]))
			{
				$rawFields['~'.$fieldName] = $fields['~'.$fieldName];
			}
		}

		if (isset($fields['PAY_SYSTEM_PRICE']))
			$paymentOuter->setField('PRICE_COD', $fields['PAY_SYSTEM_PRICE']);

		if (!empty($rawFields))
		{
			$this->parseRawFields(static::ENTITY_PAYMENT, $rawFields);
		}
	}


	if (array_key_exists('SUM_PAID', $fields))
	{
		if ($orderPaid)
		{
			if ($fields['SUM_PAID'] == 0)
			{
				$fields['SUM_PAID'] = $order->getPrice();
			}
		}

		if ($fields['SUM_PAID'] >= 0)
		{
			$oldSumPaid = $order->getSumPaid();

			$deltaSumPaid = floatval($fields['SUM_PAID']) - $oldSumPaid;

			if ($deltaSumPaid > 0)
			{
				$paidPayment = false;

				/** @var SalePayment $payment */
				foreach ($paymentCollection as $payment)
				{
					if ($payment->isPaid() || $payment->isInner())
						continue;

					if (SalePriceMaths::roundPrecision($payment->getSum()) === SalePriceMaths::roundPrecision($deltaSumPaid))
					{
						$paidPayment = true;
						/** @var SaleResult $r */
						$r = $payment->setPaid("Y");
						if (!$r->isSuccess())
						{
							$result->addErrors($r->getErrors());
						}
						break;
					}
				}

				if (!$paidPayment)
				{
					$service = null;
					$paymentSystemId = null;

					if (count($paymentCollection) > 0)
					{
						/** @var SalePayment $firstPayment */
						if ($firstPayment = $paymentCollection->rewind())
						{
							$paymentSystemId = $firstPayment->getPaymentSystemId();
							if ($paymentSystemId > 0)
							{
								$service = SalePaySystemManager::getObjectById($paymentSystemId);
							}
						}
					}

					if (!$service)
					{
						$paymentSystemId = static::getDefaultPaySystemId($order->getPersonTypeId());
						$service = SalePaySystemManager::getObjectById($paymentSystemId);
					}

					/** @var SalePaySystemService $service */
					if ($service)
					{
						/** @var SalePayment $paymentOuter */
						$payment = $paymentCollection->createItem($service);
						$payment->setField('DATE_BILL', new MainTypeDateTime());
						$payment->setField('SUM', $deltaSumPaid);
						$payment->setField('PAY_SYSTEM_NAME', $service->getField('NAME'));
						$order->setFieldNoDemand('PAY_SYSTEM_ID', $paymentSystemId);

						/** @var SaleResult $r */
						$r = $payment->setPaid("Y");
						if (!$r->isSuccess())
						{
							$result->addErrors($r->getErrors());
						}
					}
				}
			}
		}
	}

	return $result;
}