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;
}