TransactionStatusUpdateManager::isPaymentOther()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 22
rs 9.8666
1
<?php
2
3
/**
4
 * MIT License
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\Payone\Business\TransactionStatus;
9
10
use Generated\Shared\Transfer\PayoneStandardParameterTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...andardParameterTransfer 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 Orm\Zed\Payone\Persistence\SpyPaymentPayone;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Payone\Persistence\SpyPaymentPayone 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 Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Payone\Persisten...oneTransactionStatusLog 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 Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLogOrderItem;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Payone\Persisten...ctionStatusLogOrderItem 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 SprykerEco\Shared\Payone\Dependency\TransactionStatusUpdateInterface;
15
use SprykerEco\Shared\Payone\PayoneTransactionStatusConstants;
16
use SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusResponse;
17
use SprykerEco\Zed\Payone\Business\Key\HashGeneratorInterface;
18
use SprykerEco\Zed\Payone\Persistence\PayoneQueryContainerInterface;
19
20
class TransactionStatusUpdateManager implements TransactionStatusUpdateManagerInterface
21
{
22
    /**
23
     * @var \SprykerEco\Zed\Payone\Persistence\PayoneQueryContainerInterface
24
     */
25
    protected $queryContainer;
26
27
    /**
28
     * @var \Generated\Shared\Transfer\PayoneStandardParameterTransfer
29
     */
30
    protected $standardParameter;
31
32
    /**
33
     * @var \SprykerEco\Zed\Payone\Business\Key\HashGeneratorInterface
34
     */
35
    protected $hashGenerator;
36
37
    /**
38
     * @param \SprykerEco\Zed\Payone\Persistence\PayoneQueryContainerInterface $queryContainer
39
     * @param \Generated\Shared\Transfer\PayoneStandardParameterTransfer $standardParameter
40
     * @param \SprykerEco\Zed\Payone\Business\Key\HashGeneratorInterface $hashGenerator
41
     */
42
    public function __construct(
43
        PayoneQueryContainerInterface $queryContainer,
44
        PayoneStandardParameterTransfer $standardParameter,
45
        HashGeneratorInterface $hashGenerator
46
    ) {
47
        $this->queryContainer = $queryContainer;
48
        $this->standardParameter = $standardParameter;
49
        $this->hashGenerator = $hashGenerator;
50
    }
51
52
    /**
53
     * @param \SprykerEco\Shared\Payone\Dependency\TransactionStatusUpdateInterface $request
54
     *
55
     * @return \SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusResponse
56
     */
57
    public function processTransactionStatusUpdate(TransactionStatusUpdateInterface $request): TransactionStatusResponse
58
    {
59
        $validationResult = $this->validate($request);
60
        if ($validationResult instanceof TransactionStatusResponse) {
61
            return $validationResult;
62
        }
63
        $this->transformCurrency($request);
64
65
        $paymentPayoneEntity = $this->findPaymentByTransactionId($request->getTxid());
66
67
        if (!$paymentPayoneEntity) {
68
            return $this->createErrorResponse('Payone transaction status update: Payment was not found!');
69
        }
70
71
        $this->persistRequest($request, $paymentPayoneEntity);
72
73
        return $this->createSuccessResponse();
74
    }
75
76
    /**
77
     * @param \SprykerEco\Shared\Payone\Dependency\TransactionStatusUpdateInterface $request
78
     * @param \Orm\Zed\Payone\Persistence\SpyPaymentPayone|null $paymentPayoneEntity
79
     *
80
     * @return void
81
     */
82
    protected function persistRequest(TransactionStatusUpdateInterface $request, ?SpyPaymentPayone $paymentPayoneEntity = null): void
83
    {
84
        if (!$paymentPayoneEntity) {
85
            return;
86
        }
87
88
        $paymentPayoneTransactionStatusLogEntity = new SpyPaymentPayoneTransactionStatusLog();
89
        $paymentPayoneTransactionStatusLogEntity->setFkPaymentPayone($paymentPayoneEntity->getIdPaymentPayone());
90
        $paymentPayoneTransactionStatusLogEntity->setTransactionId($request->getTxid());
91
        $paymentPayoneTransactionStatusLogEntity->setReferenceId($request->getReference());
92
        $paymentPayoneTransactionStatusLogEntity->setMode($request->getMode());
93
        $paymentPayoneTransactionStatusLogEntity->setStatus($request->getTxaction());
94
        $paymentPayoneTransactionStatusLogEntity->setTransactionTime($request->getTxtime());
95
        $paymentPayoneTransactionStatusLogEntity->setSequenceNumber($request->getSequencenumber());
96
        $paymentPayoneTransactionStatusLogEntity->setClearingType($request->getClearingtype());
97
        $paymentPayoneTransactionStatusLogEntity->setPortalId($request->getPortalid());
98
        $paymentPayoneTransactionStatusLogEntity->setPrice($request->getPrice());
99
        $paymentPayoneTransactionStatusLogEntity->setBalance($request->getBalance());
100
        $paymentPayoneTransactionStatusLogEntity->setReceivable($request->getReceivable());
101
        $paymentPayoneTransactionStatusLogEntity->setReminderLevel($request->getReminderlevel());
102
        $paymentPayoneTransactionStatusLogEntity->setRawRequest($request);
103
104
        $paymentPayoneTransactionStatusLogEntity->save();
105
    }
106
107
    /**
108
     * @param int $idSalesOrder
109
     * @param int $idSalesOrderItem
110
     *
111
     * @return bool
112
     */
113
    public function isPaymentNotificationAvailable(int $idSalesOrder, int $idSalesOrderItem): bool
114
    {
115
        return $this->hasUnprocessedTransactionStatusLogs($idSalesOrder, $idSalesOrderItem);
116
    }
117
118
    /**
119
     * @param \SprykerEco\Shared\Payone\Dependency\TransactionStatusUpdateInterface $request
120
     *
121
     * @return void
122
     */
123
    protected function transformCurrency(TransactionStatusUpdateInterface $request): void
124
    {
125
        /** @var \SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusRequest $request */
126
        $balance = $request->getBalance();
127
        $balanceAmountInCents = round((float)$balance * 100);
128
        $request->setBalance($balanceAmountInCents);
129
130
        $receivable = $request->getReceivable();
131
        $receivableAmountInCents = round((float)$receivable * 100);
132
        $request->setReceivable($receivableAmountInCents);
133
134
        $price = $request->getPrice();
135
        $priceAmountInCents = round((float)$price * 100);
136
        $request->setPrice($priceAmountInCents);
137
    }
138
139
    /**
140
     * @param \SprykerEco\Shared\Payone\Dependency\TransactionStatusUpdateInterface $request
141
     *
142
     * @return bool|\SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusResponse
143
     */
144
    protected function validate(TransactionStatusUpdateInterface $request)
145
    {
146
        $systemHashedKey = $this->hashGenerator->hash($this->standardParameter->getKey());
147
        if ($request->getKey() !== $systemHashedKey) {
148
            return $this->createErrorResponse('Payone transaction status update: Given and internal key do not match!');
149
        }
150
151
        if ((int)$request->getAid() !== (int)$this->standardParameter->getAid()) {
152
            return $this->createErrorResponse('Payone transaction status update: Invalid Aid! System: ' . $this->standardParameter->getAid() . ' Request: ' . $request->getAid());
153
        }
154
155
        if ((int)$request->getPortalid() !== (int)$this->standardParameter->getPortalId()) {
156
            return $this->createErrorResponse('Payone transaction status update: Invalid Portalid! System: ' . $this->standardParameter->getPortalId() . ' Request: ' . $request->getPortalid());
157
        }
158
159
        return true;
160
    }
161
162
    /**
163
     * @param string $errorMessage
164
     *
165
     * @return \SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusResponse
166
     */
167
    protected function createErrorResponse(string $errorMessage): TransactionStatusResponse
168
    {
169
        $response = new TransactionStatusResponse(false);
170
        $response->setErrorMessage($errorMessage);
171
172
        return $response;
173
    }
174
175
    /**
176
     * @return \SprykerEco\Zed\Payone\Business\Api\TransactionStatus\TransactionStatusResponse
177
     */
178
    protected function createSuccessResponse(): TransactionStatusResponse
179
    {
180
        return new TransactionStatusResponse(true);
181
    }
182
183
    /**
184
     * @param int $transactionId
185
     *
186
     * @return \Orm\Zed\Payone\Persistence\SpyPaymentPayone|null
187
     */
188
    protected function findPaymentByTransactionId(int $transactionId): ?SpyPaymentPayone
189
    {
190
        return $this->queryContainer->createPaymentByTransactionIdQuery($transactionId)->findOne();
191
    }
192
193
    /**
194
     * @param int $idSalesOrder
195
     * @param int $idSalesOrderItem
196
     *
197
     * @return bool
198
     */
199
    public function isPaymentPaid(int $idSalesOrder, int $idSalesOrderItem): bool
200
    {
201
        $status = PayoneTransactionStatusConstants::TXACTION_PAID;
202
        $statusLog = $this->getFirstUnprocessedTransactionStatusLog($idSalesOrder, $idSalesOrderItem, $status);
203
        if ($statusLog === null) {
204
            return false;
205
        }
206
        if ($statusLog->getBalance() > 0) {
207
            return false;
208
        }
209
210
        $this->saveSpyPaymentPayoneTransactionStatusLogOrderItem($idSalesOrderItem, $statusLog);
211
212
        return true;
213
    }
214
215
    /**
216
     * @param int $idSalesOrder
217
     * @param int $idSalesOrderItem
218
     *
219
     * @return bool
220
     */
221
    public function isPaymentCapture(int $idSalesOrder, int $idSalesOrderItem): bool
222
    {
223
        $status = PayoneTransactionStatusConstants::TXACTION_CAPTURE;
224
225
        return $this->isPayment($idSalesOrder, $idSalesOrderItem, $status);
226
    }
227
228
    /**
229
     * @param int $idSalesOrder
230
     * @param int $idSalesOrderItem
231
     *
232
     * @return bool
233
     */
234
    public function isPaymentOverpaid(int $idSalesOrder, int $idSalesOrderItem): bool
235
    {
236
        $status = PayoneTransactionStatusConstants::TXACTION_PAID;
237
        $statusLog = $this->getFirstUnprocessedTransactionStatusLog($idSalesOrder, $idSalesOrderItem, $status);
238
        if ($statusLog === null) {
239
            return false;
240
        }
241
        if ($statusLog->getBalance() >= 0) {
242
            return false;
243
        }
244
245
        $this->saveSpyPaymentPayoneTransactionStatusLogOrderItem($idSalesOrderItem, $statusLog);
246
247
        return true;
248
    }
249
250
    /**
251
     * @param int $idSalesOrder
252
     * @param int $idSalesOrderItem
253
     *
254
     * @return bool
255
     */
256
    public function isPaymentUnderpaid(int $idSalesOrder, int $idSalesOrderItem): bool
257
    {
258
        $status = PayoneTransactionStatusConstants::TXACTION_UNDERPAID;
259
260
        return $this->isPayment($idSalesOrder, $idSalesOrderItem, $status);
261
    }
262
263
    /**
264
     * @param int $idSalesOrder
265
     * @param int $idSalesOrderItem
266
     *
267
     * @return bool
268
     */
269
    public function isPaymentRefund(int $idSalesOrder, int $idSalesOrderItem): bool
270
    {
271
        $status = PayoneTransactionStatusConstants::TXACTION_REFUND;
272
273
        return $this->isPayment($idSalesOrder, $idSalesOrderItem, $status);
274
    }
275
276
    /**
277
     * @param int $idSalesOrder
278
     * @param int $idSalesOrderItem
279
     *
280
     * @return bool
281
     */
282
    public function isPaymentAppointed(int $idSalesOrder, int $idSalesOrderItem): bool
283
    {
284
        $status = PayoneTransactionStatusConstants::TXACTION_APPOINTED;
285
286
        return $this->isPayment($idSalesOrder, $idSalesOrderItem, $status);
287
    }
288
289
    /**
290
     * @param int $idSalesOrder
291
     * @param int $idSalesOrderItem
292
     *
293
     * @return bool
294
     */
295
    public function isPaymentOther(int $idSalesOrder, int $idSalesOrderItem): bool
296
    {
297
        $statusLogs = $this->getUnprocessedTransactionStatusLogs($idSalesOrder, $idSalesOrderItem);
298
        if (empty($statusLogs)) {
299
            return false;
300
        }
301
302
        /** @var \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog $statusLog */
303
        $statusLog = array_shift($statusLogs);
304
305
        $statuses = [
306
            PayoneTransactionStatusConstants::TXACTION_PAID,
307
            PayoneTransactionStatusConstants::TXACTION_APPOINTED,
308
            PayoneTransactionStatusConstants::TXACTION_UNDERPAID,
309
        ];
310
        if (in_array($statusLog->getStatus(), $statuses)) {
311
            return false;
312
        }
313
314
        $this->saveSpyPaymentPayoneTransactionStatusLogOrderItem($idSalesOrderItem, $statusLog);
315
316
        return true;
317
    }
318
319
    /**
320
     * @param int $idSalesOrder
321
     * @param int $idSalesOrderItem
322
     * @param string $status
323
     *
324
     * @return bool
325
     */
326
    protected function isPayment(int $idSalesOrder, int $idSalesOrderItem, string $status): bool
327
    {
328
        $statusLog = $this->getFirstUnprocessedTransactionStatusLog($idSalesOrder, $idSalesOrderItem, $status);
329
        if ($statusLog === null) {
330
            return false;
331
        }
332
333
        $this->saveSpyPaymentPayoneTransactionStatusLogOrderItem($idSalesOrderItem, $statusLog);
334
335
        return true;
336
    }
337
338
    /**
339
     * @param int $idSalesOrder
340
     * @param int $idSalesOrderItem
341
     *
342
     * @return bool
343
     */
344
    protected function hasUnprocessedTransactionStatusLogs(int $idSalesOrder, int $idSalesOrderItem): bool
345
    {
346
        $records = $this->getUnprocessedTransactionStatusLogs($idSalesOrder, $idSalesOrderItem);
0 ignored issues
show
Unused Code introduced by
The assignment to $records is dead and can be removed.
Loading history...
347
348
        return !empty($transactionStatusLogs);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $transactionStatusLogs seems to never exist and therefore empty should always be true.
Loading history...
349
    }
350
351
    /**
352
     * @param int $idSalesOrder
353
     * @param int $idSalesOrderItem
354
     * @param string $status
355
     *
356
     * @return \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog|null
357
     */
358
    protected function getFirstUnprocessedTransactionStatusLog(int $idSalesOrder, int $idSalesOrderItem, string $status): ?SpyPaymentPayoneTransactionStatusLog
359
    {
360
        $transactionStatusLogs = $this->getUnprocessedTransactionStatusLogs($idSalesOrder, $idSalesOrderItem);
361
362
        if (empty($transactionStatusLogs)) {
363
            return null;
364
        }
365
366
        while (count($transactionStatusLogs)) {
367
            /** @var \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog $transactionStatusLog */
368
            $transactionStatusLog = array_shift($transactionStatusLogs);
369
370
            if ($transactionStatusLog->getStatus() == $status) {
371
                return $transactionStatusLog;
372
            }
373
        }
374
375
        return null;
376
    }
377
378
    /**
379
     * @param int $idSalesOrder
380
     * @param int $idSalesOrderItem
381
     *
382
     * @return \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog[]
383
     */
384
    protected function getUnprocessedTransactionStatusLogs(int $idSalesOrder, int $idSalesOrderItem): array
385
    {
386
        $transactionStatusLogs = $this->queryContainer->createTransactionStatusLogsBySalesOrder($idSalesOrder)->find();
387
388
        $ids = [];
389
390
        /** @var \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog $transactionStatusLog */
391
        foreach ($transactionStatusLogs as $transactionStatusLog) {
392
            $ids[$transactionStatusLog->getIdPaymentPayoneTransactionStatusLog()] = $transactionStatusLog;
393
        }
394
395
        $relations = $this->queryContainer
396
            ->createTransactionStatusLogOrderItemsByLogIds($idSalesOrderItem, array_keys($ids))
397
            ->find();
398
399
        /** @var \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLogOrderItem $relation */
400
        foreach ($relations as $relation) {
401
            unset($ids[$relation->getIdPaymentPayoneTransactionStatusLog()]);
402
        }
403
404
        return $ids;
405
    }
406
407
    /**
408
     * @param int $idSalesOrderItem
409
     * @param \Orm\Zed\Payone\Persistence\SpyPaymentPayoneTransactionStatusLog $statusLog
410
     *
411
     * @return void
412
     */
413
    protected function saveSpyPaymentPayoneTransactionStatusLogOrderItem(int $idSalesOrderItem, SpyPaymentPayoneTransactionStatusLog $statusLog): void
414
    {
415
        $entity = new SpyPaymentPayoneTransactionStatusLogOrderItem();
416
        $entity->setSpyPaymentPayoneTransactionStatusLog($statusLog);
417
        $entity->setIdSalesOrderItem($idSalesOrderItem);
418
        $entity->save();
419
    }
420
}
421