Completed
Push — master ( 38e980...02483d )
by Joachim
02:23
created

PaymentHandler::bulkCapture()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
namespace Loevgaard\DandomainAltapayBundle\Handler;
4
5
use Loevgaard\AltaPay\Client\Client;
6
use Loevgaard\AltaPay\Entity\Transaction;
7
use Loevgaard\AltaPay\Payload\CaptureReservation as CaptureReservationPayload;
8
use Loevgaard\AltaPay\Payload\OrderLine;
9
use Loevgaard\AltaPay\Payload\RefundCapturedReservation as RefundCapturedReservationPayload;
10
use Loevgaard\AltaPay\Response\RefundCapturedReservation as RefundCapturedReservationResponse;
11
use Loevgaard\DandomainAltapayBundle\Entity\Payment;
12
use Loevgaard\DandomainAltapayBundle\Entity\PaymentLine;
13
use Loevgaard\DandomainAltapayBundle\Entity\PaymentRepository;
14
use Money\Currency;
15
use Money\Money;
16
17
class PaymentHandler
18
{
19
    /**
20
     * @var Client
21
     */
22
    private $altapayClient;
23
24
    /**
25
     * @var PaymentRepository
26
     */
27
    private $paymentRepository;
28
29
    public function __construct(Client $client, PaymentRepository $paymentRepository)
30
    {
31
        $this->altapayClient = $client;
32
        $this->paymentRepository = $paymentRepository;
33
    }
34
35
    public function capture(Payment $payment, Money $amount = null)
36
    {
37
        $payload = new CaptureReservationPayload($payment->getAltapayId());
38
        if ($amount) {
39
            $payload->setAmount($amount);
40
        }
41
42
        $res = $this->altapayClient->captureReservation($payload);
43
44
        if ($res->isSuccessful()) {
45
            $this->updatePaymentFromTransactions($payment, $res->getTransactions());
46
        }
47
48
        return $res;
49
    }
50
51
    /**
52
     * @param Payment[] $payments
53
     */
54
    public function bulkCapture(array $payments)
55
    {
56
        foreach ($payments as $payment) {
57
            $this->capture($payment);
58
        }
59
    }
60
61
    /**
62
     * @param Payment            $payment      The payment to refund
63
     * @param Money|null         $amount       The amount to refund
64
     * @param PaymentLine[]|null $paymentLines The payment lines to refund
65
     *
66
     * @return RefundCapturedReservationResponse
67
     */
68
    public function refund(Payment $payment, Money $amount = null, array $paymentLines = null)
69
    {
70
        $payload = new RefundCapturedReservationPayload($payment->getAltapayId());
71
72
        if ($amount) {
73
            $payload->setAmount($amount);
74
        }
75
76
        if ($paymentLines && count($paymentLines)) {
77
            $paymentLinesAmountInclVat = new Money(0, new Currency($amount->getCurrency()->getCode()));
0 ignored issues
show
Bug introduced by
It seems like $amount is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
78
79
            foreach ($paymentLines as $paymentLine) {
80
                $orderLine = new OrderLine(
81
                    $paymentLine->getName(),
82
                    $paymentLine->getProductNumber(),
83
                    $paymentLine->getQuantity(),
84
                    $paymentLine->getPriceInclVat()
85
                );
86
                $orderLine->setTaxPercent($paymentLine->getVat());
87
88
                $payload->addOrderLine($orderLine);
89
90
                $paymentLinesAmountInclVat = $paymentLinesAmountInclVat->add($paymentLine->getPriceInclVat());
91
            }
92
93
            /*
94
             * If the amount is set, but does not match the payment lines amount we have to
95
             * make a 'good will' refund which according to Altapay is made by adding an order line
96
             * with goods type equals 'refund' and the amount has to equal the refund amount including vat
97
             */
98
            if ($amount && !$amount->equals($paymentLinesAmountInclVat)) {
99
                $orderLine = new OrderLine('refund', 'refund', 1, $amount);
100
                $orderLine->setGoodsType(OrderLine::GOODS_TYPE_REFUND);
101
102
                // this effectively removes already added order lines and adds the 'refund' order line
103
                $payload->setOrderLines([$orderLine]);
104
            }
105
        }
106
107
        $res = $this->altapayClient->refundCapturedReservation($payload);
108
109
        if ($res->isSuccessful()) {
110
            $this->updatePaymentFromTransactions($payment, $res->getTransactions());
111
        }
112
113
        return $res;
114
    }
115
116
    /**
117
     * @param Payment       $payment
118
     * @param Transaction[] $transactions
119
     */
120
    private function updatePaymentFromTransactions(Payment $payment, array $transactions)
121
    {
122
        if (count($transactions)) {
123
            $transaction = $transactions[0];
124
125
            if ($transaction->getCapturedAmount()) {
126
                $payment->setCapturedAmount($transaction->getCapturedAmount());
127
            }
128
129
            if ($transaction->getRefundedAmount()) {
130
                $payment->setRefundedAmount($transaction->getRefundedAmount());
131
            }
132
133
            $this->paymentRepository->save($payment);
134
        }
135
    }
136
}
137