• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/order/builder/orderbuilder.php
  • Класс: BitrixSaleHelpersOrderBuilderOrderBuilder
  • Вызов: OrderBuilder::buildPayments
public function buildPayments()
{
	global $USER;

	$isEmptyPaymentData = $this->isEmptyPaymentData();
	if ($isEmptyPaymentData)
	{
		$this->formData['PAYMENT'] = [];
	}

	if ($isEmptyPaymentData && !$this->needCreateDefaultPayment())
	{
		return $this;
	}

	if($isEmptyPaymentData && $this->getOrder()->isNew())
	{
		$this->createEmptyPayment();
		return $this;
	}

	if(!$this->removePayments())
	{
		$this->errorsContainer->addError(new Error('Payments remove - error'));
		throw new BuildingException();
	}

	$paymentCollection = $this->order->getPaymentCollection();

	foreach($this->formData["PAYMENT"] as $paymentData)
	{
		$paymentId = (int)($paymentData['ID'] ?? 0);
		$isNew = ($paymentId <= 0);
		$hasError = false;
		$products = $paymentData['PRODUCT'] ?? [];

		$settablePaymentFields = $this->getSettablePaymentFields();

		if(count($settablePaymentFields)>0)//for backward compatibility
			$paymentData = array_intersect_key($paymentData, array_flip($settablePaymentFields));

		/** @var BitrixSalePayment $paymentItem */
		if($isNew)
		{
			$paymentItem = $paymentCollection->createItem();
			if (isset($paymentData['CURRENCY']) && !empty($paymentData['CURRENCY']) && $paymentData['CURRENCY'] !== $this->order->getCurrency())
			{
				$paymentData["SUM"] = CCurrencyRates::ConvertCurrency($paymentData["SUM"], $paymentData["CURRENCY"], $this->order->getCurrency());
				$paymentData['CURRENCY'] = $this->order->getCurrency();
			}
		}
		else
		{
			$paymentItem = $paymentCollection->getItemById($paymentId);

			if(!$paymentItem)
			{
				$this->errorsContainer->addError(new Error(Loc::getMessage("SALE_HLP_ORDERBUILDER_PAYMENT_NOT_FOUND")." - ".$paymentId));
				continue;
			}
		}

		$isReturn = (isset($paymentData['IS_RETURN']) && ($paymentData['IS_RETURN'] == 'Y' || $paymentData['IS_RETURN'] == 'P'));
		$psService = null;

		if((int)$paymentData['PAY_SYSTEM_ID'] > 0)
		{
			$psService = PaySystemManager::getObjectById((int)$paymentData['PAY_SYSTEM_ID']);
		}

		$paymentData['COMPANY_ID'] = (isset($paymentData['COMPANY_ID']) && intval($paymentData['COMPANY_ID']) > 0) ? intval($paymentData['COMPANY_ID']) : 0;
		$paymentData['PAY_SYSTEM_NAME'] = ($psService) ? $psService->getField('NAME') : '';

		if (isset($paymentData['PAID']))
		{
			$paymentFields['PAID'] = ($paymentData['PAID'] === 'Y') ? 'Y' : 'N';
			unset($paymentData['PAID']);
		}

		if ($isNew)
		{
			if(empty($paymentData['COMPANY_ID']))
			{
				$paymentData['COMPANY_ID'] = $this->order->getField('COMPANY_ID');
			}

			if(empty($paymentData['RESPONSIBLE_ID']))
			{
				$paymentData['RESPONSIBLE_ID'] = $this->order->getField('RESPONSIBLE_ID');
				$paymentData['EMP_RESPONSIBLE_ID'] = $USER->GetID();
			}
		}

		$dateFields = ['DATE_PAID', 'DATE_PAY_BEFORE', 'DATE_BILL', 'PAY_RETURN_DATE', 'PAY_VOUCHER_DATE'];

		foreach($dateFields as $fieldName)
		{
			if(isset($paymentData[$fieldName]) && is_string($paymentData[$fieldName]))
			{
				try
				{
					$paymentData[$fieldName] = new Date($paymentData[$fieldName]);
				}
				catch (ObjectException $exception)
				{
					$this->errorsContainer->addError(new Error('Wrong field "'.$fieldName.'"'));
					$hasError = true;
				}
			}
		}

		if($paymentItem->isPaid()
			&& isset($paymentData['SUM'])
			&& abs(floatval($paymentData['SUM']) - floatval($paymentItem->getSum())) > 0.001)
		{
			$this->errorsContainer->addError(new Error(Loc::getMessage("SALE_HLP_ORDERBUILDER_ERROR_PAYMENT_SUM")));
			$hasError = true;
		}

		/*
		 * We are editing an order. We have only one payment. So the payment fields are mostly in view mode.
		 * If we have changed the price of the order then the sum of the payment must be changed automaticaly by payment api earlier.
		 * But if the payment sum was received from the form we will erase the previous changes.
		 */
		if(isset($paymentData['SUM']))
		{
			$paymentData['SUM'] = (float)str_replace(',', '.', $paymentData['SUM']);
		}

		if(isset($paymentData['RESPONSIBLE_ID']))
		{
			$paymentData['RESPONSIBLE_ID'] = !empty($paymentData['RESPONSIBLE_ID']) ? $paymentData['RESPONSIBLE_ID'] : $USER->GetID();

			if($paymentData['RESPONSIBLE_ID'] != $paymentItem->getField('RESPONSIBLE_ID'))
			{
				if(!$isNew)
				{
					$paymentData['EMP_RESPONSIBLE_ID'] = $USER->GetID();
				}
			}
		}

		if(!$hasError)
		{
			if($paymentItem->isInner() && isset($paymentData['SUM']) && $paymentData['SUM'] === 0)
			{
				unset($paymentData['SUM']);
			}

			$setResult = $paymentItem->setFields($paymentData);

			if(!$setResult->isSuccess())
			{
				$this->errorsContainer->addErrors($setResult->getErrors());
			}

			if ($products)
			{
				$this->buildPayableItems($paymentItem, $products);
			}

			if($isReturn && $paymentData['IS_RETURN'])
			{
				$setResult = $paymentItem->setReturn($paymentData['IS_RETURN']);

				if(!$setResult->isSuccess())
				{
					$this->errorsContainer->addErrors($setResult->getErrors());
				}
			}

			if(!empty($paymentFields['PAID']))
			{
				$setResult = $paymentItem->setPaid($paymentFields['PAID']);

				if(!$setResult->isSuccess())
				{
					$this->errorsContainer->addErrors($setResult->getErrors());
				}
			}
		}
	}

	return $this;
}