buildRefundRequestForOrderItem()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * MIT License
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
namespace SprykerEco\Zed\AfterPay\Business\Payment\Transaction\Handler;
9
10
use Generated\Shared\Transfer\AfterPayPaymentOrderItemTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...aymentOrderItemTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Generated\Shared\Transfer\AfterPayPaymentTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\AfterPayPaymentTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Generated\Shared\Transfer\AfterPayRefundRequestTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...ayRefundRequestTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Generated\Shared\Transfer\AfterPayRefundResponseTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...yRefundResponseTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Generated\Shared\Transfer\ItemTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\ItemTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Generated\Shared\Transfer\OrderTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\OrderTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use SprykerEco\Zed\AfterPay\Business\Payment\PaymentReaderInterface;
17
use SprykerEco\Zed\AfterPay\Business\Payment\PaymentWriterInterface;
18
use SprykerEco\Zed\AfterPay\Business\Payment\Transaction\Refund\RefundRequestBuilderInterface;
19
use SprykerEco\Zed\AfterPay\Business\Payment\Transaction\RefundTransactionInterface;
20
use SprykerEco\Zed\AfterPay\Dependency\Facade\AfterPayToMoneyFacadeInterface;
21
22
class RefundTransactionHandler implements RefundTransactionHandlerInterface
23
{
24
    /**
25
     * @var \SprykerEco\Zed\AfterPay\Business\Payment\Transaction\RefundTransactionInterface
26
     */
27
    protected $transaction;
28
29
    /**
30
     * @var \SprykerEco\Zed\AfterPay\Business\Payment\PaymentReaderInterface
31
     */
32
    protected $paymentReader;
33
34
    /**
35
     * @var \SprykerEco\Zed\AfterPay\Business\Payment\Transaction\Refund\RefundRequestBuilderInterface
36
     */
37
    protected $refundRequestBuilder;
38
39
    /**
40
     * @var \SprykerEco\Zed\AfterPay\Business\Payment\PaymentWriterInterface
41
     */
42
    protected $paymentWriter;
43
44
    /**
45
     * @var \SprykerEco\Zed\AfterPay\Dependency\Facade\AfterPayToMoneyFacadeInterface
46
     */
47
    protected $moneyFacade;
48
49
    /**
50
     * @param \SprykerEco\Zed\AfterPay\Business\Payment\Transaction\RefundTransactionInterface $transaction
51
     * @param \SprykerEco\Zed\AfterPay\Business\Payment\PaymentReaderInterface $paymentReader
52
     * @param \SprykerEco\Zed\AfterPay\Business\Payment\PaymentWriterInterface $paymentWriter
53
     * @param \SprykerEco\Zed\AfterPay\Dependency\Facade\AfterPayToMoneyFacadeInterface $moneyFacade
54
     * @param \SprykerEco\Zed\AfterPay\Business\Payment\Transaction\Refund\RefundRequestBuilderInterface $refundRequestBuilder
55
     */
56
    public function __construct(
57
        RefundTransactionInterface $transaction,
58
        PaymentReaderInterface $paymentReader,
59
        PaymentWriterInterface $paymentWriter,
60
        AfterPayToMoneyFacadeInterface $moneyFacade,
61
        RefundRequestBuilderInterface $refundRequestBuilder
62
    ) {
63
        $this->transaction = $transaction;
64
        $this->paymentReader = $paymentReader;
65
        $this->refundRequestBuilder = $refundRequestBuilder;
66
        $this->moneyFacade = $moneyFacade;
67
        $this->paymentWriter = $paymentWriter;
68
    }
69
70
    /**
71
     * @param array<\Generated\Shared\Transfer\ItemTransfer> $items
72
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
73
     *
74
     * @return void
75
     */
76
    public function refund(array $items, OrderTransfer $orderTransfer): void
77
    {
78
        $refundRequestTransfer = $this->buildRefundRequestForOrderItem($items, $orderTransfer);
79
        $paymentTransfer = $this->getPaymentTransferForItem($refundRequestTransfer);
80
81
        if ($paymentTransfer->getExpenseTotal()) {
82
            $this->processExpensesRefund($items, $paymentTransfer, $orderTransfer);
83
        }
84
85
        $refundResponseTransfer = $this->transaction->executeTransaction($refundRequestTransfer);
86
87
        $this->updateOrderPayment($refundResponseTransfer, $refundRequestTransfer);
88
    }
89
90
    /**
91
     * @param array<\Generated\Shared\Transfer\ItemTransfer> $items
92
     * @param \Generated\Shared\Transfer\AfterPayPaymentTransfer $paymentTransfer
93
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
94
     *
95
     * @return void
96
     */
97
    protected function processExpensesRefund(
98
        array $items,
99
        AfterPayPaymentTransfer $paymentTransfer,
100
        OrderTransfer $orderTransfer
101
    ): void {
102
        if (!$this->isLastItemToRefund($items, $paymentTransfer)) {
103
            return;
104
        }
105
106
        $expensesRefundRequest = $this->refundRequestBuilder
107
            ->buildBaseRefundRequestForOrder($orderTransfer);
108
        $this->addExpensesToRefundRequest($paymentTransfer->getExpenseTotal(), $expensesRefundRequest);
109
        $expensesRefundRequest->setCaptureNumber($paymentTransfer->getExpensesCaptureNumber());
110
        $expensesRefundResponse = $this->transaction->executeTransaction($expensesRefundRequest);
111
        $this->updateOrderPayment($expensesRefundResponse, $expensesRefundRequest);
112
    }
113
114
    /**
115
     * @param array<\Generated\Shared\Transfer\ItemTransfer> $items
116
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
117
     *
118
     * @return \Generated\Shared\Transfer\AfterPayRefundRequestTransfer
119
     */
120
    protected function buildRefundRequestForOrderItem(
121
        array $items,
122
        OrderTransfer $orderTransfer
123
    ): AfterPayRefundRequestTransfer {
124
        $refundRequestTransfer = $this->refundRequestBuilder->buildBaseRefundRequestForOrder($orderTransfer);
125
126
        foreach ($items as $itemTransfer) {
127
            $this->refundRequestBuilder->addOrderItemToRefundRequest($itemTransfer, $refundRequestTransfer);
128
            $this->addCaptureNumberToRefundRequest($refundRequestTransfer, $itemTransfer);
129
        }
130
131
        return $refundRequestTransfer;
132
    }
133
134
    /**
135
     * @param int $expenseTotal
136
     * @param \Generated\Shared\Transfer\AfterPayRefundRequestTransfer $refundRequestTransfer
137
     *
138
     * @return void
139
     */
140
    protected function addExpensesToRefundRequest(
141
        int $expenseTotal,
142
        AfterPayRefundRequestTransfer $refundRequestTransfer
143
    ): void {
144
        $this->refundRequestBuilder->addOrderExpenseToRefundRequest($expenseTotal, $refundRequestTransfer);
145
    }
146
147
    /**
148
     * @param \Generated\Shared\Transfer\AfterPayRefundRequestTransfer $refundRequestTransfer
149
     *
150
     * @return \Generated\Shared\Transfer\AfterPayPaymentTransfer
151
     */
152
    protected function getPaymentTransferForItem(AfterPayRefundRequestTransfer $refundRequestTransfer): AfterPayPaymentTransfer
153
    {
154
        return $this->paymentReader->getPaymentByIdSalesOrder($refundRequestTransfer->getIdSalesOrder());
155
    }
156
157
    /**
158
     * @param \Generated\Shared\Transfer\AfterPayRefundRequestTransfer $refundRequestTransfer
159
     * @param \Generated\Shared\Transfer\ItemTransfer $itemTransfer
160
     *
161
     * @return \Generated\Shared\Transfer\AfterPayPaymentOrderItemTransfer
162
     */
163
    protected function getPaymentOrderItemTransferForItem(
164
        AfterPayRefundRequestTransfer $refundRequestTransfer,
165
        ItemTransfer $itemTransfer
166
    ): AfterPayPaymentOrderItemTransfer {
167
        $paymentTransfer = $this->getPaymentTransferForItem($refundRequestTransfer);
168
169
        return $this->paymentReader
170
            ->getPaymentOrderItemByIdSalesOrderItemAndIdPayment(
171
                $itemTransfer->getIdSalesOrderItem(),
172
                $paymentTransfer->getIdPaymentAfterPay(),
173
            );
174
    }
175
176
    /**
177
     * @param \Generated\Shared\Transfer\AfterPayRefundResponseTransfer $refundResponseTransfer
178
     * @param \Generated\Shared\Transfer\AfterPayRefundRequestTransfer $refundRequestTransfer
179
     *
180
     * @return void
181
     */
182
    protected function updateOrderPayment(
183
        AfterPayRefundResponseTransfer $refundResponseTransfer,
184
        AfterPayRefundRequestTransfer $refundRequestTransfer
185
    ): void {
186
        if (!$refundResponseTransfer->getTotalCapturedAmount()) {
187
            return;
188
        }
189
190
        $refundedAmountDecimal = (float)0;
191
        $refundedAmountInt = $this->moneyFacade->convertDecimalToInteger($refundedAmountDecimal);
192
193
        foreach ($refundRequestTransfer->getOrderItems() as $item) {
194
            $itemGrossPriceDecimal = (float)$item->getGrossUnitPrice();
195
            $refundedAmountInt += $this->moneyFacade->convertDecimalToInteger($itemGrossPriceDecimal);
196
        }
197
198
        $this->paymentWriter->increaseRefundedTotalByIdSalesOrder(
199
            $refundedAmountInt,
200
            $refundRequestTransfer->getIdSalesOrder(),
201
        );
202
    }
203
204
    /**
205
     * @param array<\Generated\Shared\Transfer\ItemTransfer> $items
206
     * @param \Generated\Shared\Transfer\AfterPayPaymentTransfer $paymentTransfer
207
     *
208
     * @return bool
209
     */
210
    protected function isLastItemToRefund(array $items, AfterPayPaymentTransfer $paymentTransfer): bool
211
    {
212
        $refundable = $paymentTransfer->getAuthorizedTotal() -
213
            $paymentTransfer->getCancelledTotal() -
214
            $paymentTransfer->getRefundedTotal() -
215
            $paymentTransfer->getExpenseTotal();
216
217
        $amountToRefund = 0;
218
        foreach ($items as $itemTransfer) {
219
            $amountToRefund += $itemTransfer->getRefundableAmount();
220
        }
221
222
        return $refundable === $amountToRefund;
223
    }
224
225
    /**
226
     * @param \Generated\Shared\Transfer\AfterPayRefundRequestTransfer $refundRequestTransfer
227
     * @param \Generated\Shared\Transfer\ItemTransfer $itemTransfer
228
     *
229
     * @return void
230
     */
231
    protected function addCaptureNumberToRefundRequest(
232
        AfterPayRefundRequestTransfer $refundRequestTransfer,
233
        ItemTransfer $itemTransfer
234
    ): void {
235
        $paymentOrderItemTransfer = $this->getPaymentOrderItemTransferForItem($refundRequestTransfer, $itemTransfer);
236
        $refundRequestTransfer->setCaptureNumber($paymentOrderItemTransfer->getCaptureNumber());
237
    }
238
}
239