/** * Modify payment collection. * * @param string $action Action. * @param Payment $payment Payment. * @param null|string $name Field name. * @param null|string|int|float $oldValue Old value. * @param null|string|int|float $value New value. * @return Result * @throws Main\ArgumentOutOfRangeException * @throws Main\NotImplementedException * @throws Main\ObjectNotFoundException */ public function onPaymentCollectionModify($action, Payment $payment, $name = null, $oldValue = null, $value = null) { $result = new Result(); if ($action == EventActions::DELETE) { if ($this->getField('PAY_SYSTEM_ID') == $payment->getPaymentSystemId()) { /** @var PaymentCollection $paymentCollection */ if (!($paymentCollection = $payment->getCollection())) { throw new Main\ObjectNotFoundException('Entity "PaymentCollection" not found'); } /** @var Payment $entityPayment */ foreach ($paymentCollection as $entityPayment) { if (intval($entityPayment->getField('PAY_SYSTEM_ID')) > 0 && intval($entityPayment->getField('PAY_SYSTEM_ID')) != $payment->getPaymentSystemId()) { $this->setFieldNoDemand('PAY_SYSTEM_ID', $entityPayment->getField('PAY_SYSTEM_ID')); break; } } } } if ($action != EventActions::UPDATE) { return $result; } if ($name == "CURRENCY" && $value != $this->getField("CURRENCY")) { throw new Main\NotImplementedException(); } if ($name == "SUM" || $name == "PAID") { if ($this->isCanceled()) { $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PAID_ORDER_CANCELED'), 'SALE_ORDER_PAID_ORDER_CANCELED')); return $result; } if ($name == "SUM" && !$payment->isPaid()) { if ($value == 0 && $payment->isInner()) { $payment->delete(); } return $result; } $r = $this->syncOrderAndPayments($payment); if (!$r->isSuccess()) { $result->addErrors($r->getErrors()); } } elseif ($name == "IS_RETURN") { if ($this->isCanceled()) { $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_RETURN_ORDER_CANCELED'), 'SALE_ORDER_RETURN_ORDER_CANCELED')); return $result; } if ($value != Payment::RETURN_NONE) { if (!$payment->isPaid()) { $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PAYMENT_RETURN_NOT_PAID'), 'SALE_ORDER_PAYMENT_RETURN_NOT_PAID')); return $result; } $oldPaid = $this->isPaid() ? "Y" : "N"; /** @var PaymentCollection $paymentCollection */ if (!($paymentCollection = $this->getPaymentCollection())) { throw new Main\ObjectNotFoundException('Entity "PaymentCollection" not found'); } $creditSum = 0; $overPaid = $paymentCollection->getPaidSum() - $this->getPrice(); if ($overPaid <= 0) { $creditSum = $payment->getSum(); $overPaid = 0; } elseif ($payment->getSum() - $overPaid > 0) { $creditSum = $payment->getSum() - $overPaid; } if ($value == Payment::RETURN_PS) { $psId = $payment->getPaymentSystemId(); } elseif ($value == Payment::RETURN_INNER) { $psId = Manager::getInnerPaySystemId(); } else { $result->addError(new Entity\EntityError('unsupported operation')); return $result; } $service = Manager::getObjectById($psId); if ($service && $service->isRefundable()) { if ($creditSum) { if ($value == Payment::RETURN_PS) { if ($overPaid > 0) { $userBudget = Internals\UserBudgetPool::getUserBudgetByOrder($this); if (PriceMaths::roundByFormatCurrency($overPaid, $this->getCurrency()) > PriceMaths::roundByFormatCurrency($userBudget, $this->getCurrency())) { $result->addError(new Entity\EntityError(Loc::getMessage('SALE_ORDER_PAYMENT_RETURN_PAID'))); return $result; } } } $refResult = $service->refund($payment); if ($refResult->isSuccess()) { if ($overPaid > 0) { Internals\UserBudgetPool::addPoolItem($this, -$overPaid, Internals\UserBudgetPool::BUDGET_TYPE_ORDER_PAY, $payment); } } else { $result->addErrors($refResult->getErrors()); return $result; } } } else { $result->addError(new Entity\EntityError(Loc::getMessage('SALE_ORDER_PAYMENT_RETURN_NO_SUPPORTED'))); return $result; } $payment->setFieldNoDemand('PAID', 'N'); $finalSumPaid = $this->getSumPaid() - $creditSum; if ($finalSumPaid != $this->getSumPaid()) { $this->setFieldNoDemand('SUM_PAID', $finalSumPaid); $this->setFieldNoDemand('PAYED', $this->getPrice() <= $finalSumPaid ? "Y" : "N"); } /** @var Result $r */ $r = $this->onAfterSyncPaid($oldPaid); if (!$r->isSuccess()) { $result->addErrors($r->getErrors()); } } else { if ($payment->isPaid()) { $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PAYMENT_RETURN_PAID'), 'SALE_ORDER_PAYMENT_RETURN_PAID')); return $result; } $userBudget = Internals\UserBudgetPool::getUserBudgetByOrder($this); if (PriceMaths::roundByFormatCurrency($userBudget, $this->getCurrency()) < PriceMaths::roundByFormatCurrency($payment->getSum(), $this->getCurrency())) { $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PAYMENT_NOT_ENOUGH_USER_BUDGET'), "SALE_ORDER_PAYMENT_NOT_ENOUGH_USER_BUDGET")); return $result; } Internals\UserBudgetPool::addPoolItem($this, $payment->getSum() * -1, Internals\UserBudgetPool::BUDGET_TYPE_ORDER_PAY, $payment); $r = $payment->setField('PAID', "Y"); if (!$r->isSuccess()) { $result->addErrors($r->getErrors()); return $result; } } } elseif ($name == "PAY_SYSTEM_ID") { if ($payment->getField('PAY_SYSTEM_ID') != $this->getField('PAY_SYSTEM_ID')) { $this->setFieldNoDemand('PAY_SYSTEM_ID', $payment->getField('PAY_SYSTEM_ID')); } } elseif ($name == "DATE_PAID") { if ($payment->getField('DATE_PAID') != $this->getField('DATE_PAID')) { $this->setFieldNoDemand('DATE_PAYED', $payment->getField('DATE_PAID')); } } if ($value != $oldValue) { $fields = $this->fields->getChangedValues(); if (!array_key_exists("UPDATED_1C", $fields)) { parent::setField("UPDATED_1C", "N"); } } return $result; }