paymentRepository = $paymentRepository; $this->orderRepository = $orderRepository; } /** * @inheritdoc */ public function validate($entity) { if ($entity->getState() == Invoice::STATE_PAID && $this->isGrandTotalEnoughToRefund($entity) && $this->isPaymentAllowRefund($entity) ) { return []; } return [__('We can\'t create creditmemo for the invoice.')]; } /** * @param InvoiceInterface $invoice * @return bool */ private function isPaymentAllowRefund(InvoiceInterface $invoice) { $order = $this->orderRepository->get($invoice->getOrderId()); $payment = $order->getPayment(); if (!$payment instanceof InfoInterface) { return false; } $method = $payment->getMethodInstance(); return $this->canPartialRefund($method, $payment) || $this->canFullRefund($invoice, $method); } /** * @param InvoiceInterface $entity * @return bool */ private function isGrandTotalEnoughToRefund(InvoiceInterface $entity) { return abs($entity->getBaseGrandTotal() - $entity->getBaseTotalRefunded()) >= .0001; } /** * @param MethodInterface $method * @param InfoInterface $payment * @return bool */ private function canPartialRefund(MethodInterface $method, InfoInterface $payment) { return $method->canRefund() && $method->canRefundPartialPerInvoice() && $payment->getAmountPaid() > $payment->getAmountRefunded(); } /** * @param InvoiceInterface $invoice * @param MethodInterface $method * @return bool */ private function canFullRefund(InvoiceInterface $invoice, MethodInterface $method) { return $method->canRefund() && !$invoice->getIsUsedForRefund(); } }