Completed
Push — master ( eccdf7...a581ed )
by Mario
03:04
created

getOrderPaymentStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
use Shopware\Bundle\AttributeBundle\Service\DataLoader;
3
use Shopware\Models\Order\Order;
4
use Shopware\Components\CSRFWhitelistAware;
5
6
/**
7
 * Klarna payment controller
8
 */
9
class Shopware_Controllers_Backend_PaymentKlarna extends Enlight_Controller_Action implements CSRFWhitelistAware
10
{
11
    /**
12
     * @var Shopware_Plugins_Frontend_SwagPaymentKlarna_Bootstrap
13
     */
14
    private $plugin;
15
16
    /**
17
     * @var Enlight_Config
18
     */
19
    private $config;
20
21
    /**
22
     * @var Shopware\Components\Model\ModelManager
23
     */
24
    private $modelManager;
25
26
    /**
27
     * @var Shopware\Models\Order\Repository
28
     */
29
    private $orderRepository;
30
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function preDispatch()
35
    {
36
        $this->plugin = $this->get('plugins')->Frontend()->SwagPaymentKlarna();
37
        $this->config = $this->plugin->Config();
38
        $this->modelManager = $this->get('models');
39
        $this->orderRepository = $this->modelManager->getRepository('Shopware\Models\Order\Order');
40
41
        $this->Front()->Plugins()->Json()->setRenderer();
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 View Code Duplication
    public function get($name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
48
    {
49
        if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') {
50
            if ($name == 'pluginlogger') {
51
                $name = 'log';
52
            }
53
            $name = ucfirst($name);
54
            return Shopware()->Bootstrap()->getResource($name);
55
        }
56
        return parent::get($name);
57
    }
58
59
    /**
60
     * @return \Doctrine\ORM\Query
61
     */
62
    protected function getOrderByIdQuery()
63
    {
64
        $builder = $this->orderRepository->createQueryBuilder('o');
65
        $builder->addSelect([
66
            'details',
67
            'customer',
68
            'documents',
69
            'attribute',
70
            'detailsAttribute'
71
        ]);
72
        $builder->leftJoin('o.details', 'details')
73
            ->leftJoin('details.attribute', 'detailsAttribute')
74
            ->leftJoin('o.customer', 'customer')
75
            ->leftJoin('o.documents', 'documents')
76
            ->leftJoin('o.attribute', 'attribute');
77
        $builder->where('o.id = :orderId');
78
        $query = $builder->getQuery();
79
        return $query;
80
    }
81
82
    /**
83
     * @param $orderId
84
     * @return Shopware\Models\Order\Order
85
     */
86
    protected function getOrderById($orderId)
87
    {
88
        $query = $this->getOrderByIdQuery();
89
        $query->setParameter('orderId', $orderId);
90
        return $query->getOneOrNullResult();
91
    }
92
93
    /**
94
     * @param $orderId
95
     * @return \Shopware\Models\Shop\DetachedShop
96
     * @throws Exception
97
     */
98
    protected function registerShopByOrderId($orderId)
99
    {
100
        $repository = $this->modelManager->getRepository('Shopware\Models\Shop\Shop');
101
102
        $order = $this->orderRepository->find($orderId);
103
        if ($order === null) {
104
            throw new \Exception("Order {$orderId} not found");
105
        }
106
        $shopId = $order->getLanguageIso();
107
        if ($shopId === null) {
108
            $shop = $repository->getActiveDefault();
109
        } else {
110
            $shop = $repository->getActiveById($shopId);
111
        }
112
        if ($shop === null) {
113
            throw new \Exception("Shop {$shopId} not found");
114
        }
115
        $shop->registerResources(Shopware()->Bootstrap());
116
        $this->modelManager->clear();
117
        return $shop;
118
    }
119
120
    private function getOrderPaymentStatus($statusType)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
121
    {
122
        $paymentStatus = $this->plugin->Config()->get($statusType);
123
        if (!empty($paymentStatus)) {
124
            return $this->modelManager->find('\Shopware\Models\Order\Status', $paymentStatus);
125
        } else {
126
            return null;
127
        }
128
    }
129
130
    public function activateAction()
131
    {
132
        $orderId = $this->Request()->getParam('orderId');
133
        $positions = $this->Request()->getParam('positions', []);
134
        $this->registerShopByOrderId($orderId);
135
        $order = $this->getOrderById($orderId);
136
        $service = $this->getService($order);
137
        $detailStatus = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 3);
138
        $paymentStatus = $this->getOrderPaymentStatus('activateStatusId');
139
140
        /** @var Shopware\Models\Order\Detail $position */
141
        foreach ($order->getDetails() as $position) {
142
            if (empty($positions)) {
143
                $selection = $position->getQuantity() - $position->getShipped();
144
                if (!empty($selection)) {
145
                    $position->setShipped($position->getShipped() + $selection);
146
                    $position->setStatus($detailStatus);
147
                }
148
            } elseif (!empty($positions[$position->getId()])) {
149
                $quantity = $position->getQuantity() - $position->getShipped();
150
                $selection = min($positions[$position->getId()], $quantity);
151
                if (!empty($selection)) {
152
                    $service->addArtNo($selection, $position->getArticleNumber());
153
                    $position->setShipped($position->getShipped() + $selection);
154
                    if ($selection == $quantity) {
155
                        $position->setStatus($detailStatus);
156
                    }
157
                }
158
            }
159
        }
160
161
        try {
162
            $result = $service->activate($order->getTransactionId());
163
            if (!empty($result[1])) {
164
                $last = true;
165
                foreach ($order->getDetails() as $position) {
166
                    if ((empty($positions) || !empty($positions[$position->getId()]))) {
167
                        /** @noinspection PhpUndefinedMethodInspection */
168
                        if ($position->getAttribute()->getSwagKlarnaInvoiceNumber() === null) {
169
                            /** @noinspection PhpUndefinedMethodInspection */
170
                            $position->getAttribute()->setSwagKlarnaInvoiceNumber(
171
                                $result[1]
172
                            );
173
                        }
174
                    } elseif ($position->getStatus()->getId() == 0) {
175
                        $last = false;
176
                    }
177
                }
178
                /** @noinspection PhpUndefinedMethodInspection */
179
                $order->getAttribute()->setSwagKlarnaInvoiceNumber(
180
                    $result[1]
181
                );
182
183
                if (empty($positions) || $last) {
184
                    $order->setClearedDate(new DateTime());
185
                    /** @noinspection PhpUndefinedMethodInspection */
186
                    $order->getAttribute()->setSwagKlarnaStatus(
187
                        'activate'
188
                    );
189
                    if ($paymentStatus !== null) {
190
                        $order->setPaymentStatus($paymentStatus);
191
                    }
192
                }
193
                $this->modelManager->flush();
194
                $this->View()->assign([
195
                    'success' => true,
196
                    'number' => $result[1]
197
                ]);
198
            } else {
199
                $this->View()->assign([
200
                    'success' => false,
201
                    'status' => $result[0]
202
                ]);
203
            }
204
        } catch (Exception $e) {
205
            $this->View()->assign([
206
                'success' => false,
207
                'message' => $e->getMessage()
208
            ]);
209
        }
210
    }
211
212
    public function creditAction()
213
    {
214
        $orderId = $this->Request()->getParam('orderId');
215
        $this->registerShopByOrderId($orderId);
216
        $order = $this->getOrderById($orderId);
217
218
        $service = $this->getService($order);
219
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
220
221
        try {
222
            /** @noinspection PhpUndefinedMethodInspection */
223
            $invoices = [
224
                $order->getAttribute()->getSwagKlarnaInvoiceNumber()
225
            ];
226
            /** @var Shopware\Models\Order\Detail $position */
227
            foreach ($order->getDetails() as $position) {
228
                /** @noinspection PhpUndefinedMethodInspection */
229
                if ($position->getAttribute()->getSwagKlarnaInvoiceNumber() !== null) {
230
                    /** @noinspection PhpUndefinedMethodInspection */
231
                    $invoices[] = $position->getAttribute()->getSwagKlarnaInvoiceNumber();
232
                }
233
                $position->setStatus($status);
234
            }
235
            $result = [];
236
            foreach (array_unique($invoices) as $invoice) {
237
                $result[] = $service->creditInvoice($invoice);
238
            }
239
            /** @noinspection PhpUndefinedMethodInspection */
240
            $order->getAttribute()->setSwagKlarnaStatus(
241
                'credit'
242
            );
243
            $this->modelManager->flush();
244
            $this->View()->assign([
245
                'success' => !empty($result),
246
                'number' => $result
247
            ]);
248
        } catch (Exception $e) {
249
            $this->View()->assign([
250
                'success' => false,
251
                'message' => $e->getMessage()
252
            ]);
253
        }
254
    }
255
256
    public function cancelAction()
257
    {
258
        $orderId = $this->Request()->getParam('orderId');
259
        $this->registerShopByOrderId($orderId);
260
        $order = $this->getOrderById($orderId);
261
        $service = $this->getService($order);
262
        $detailStatus = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
263
        $paymentStatus = $this->getOrderPaymentStatus('cancelStatusId');
264
265
        try {
266
            /** @var Shopware\Models\Order\Detail $position */
267
            foreach ($order->getDetails() as $position) {
268
                if (!$position->getStatus()->getId()) {
269
                    $position->setStatus($detailStatus);
270
                }
271
            }
272
            $result = $service->cancelReservation(
273
                $order->getTransactionId()
274
            );
275
            if ($paymentStatus !== null) {
276
                $order->setPaymentStatus($paymentStatus);
277
            }
278
            /** @noinspection PhpUndefinedMethodInspection */
279
            $order->getAttribute()->setSwagKlarnaStatus(
280
                'cancel'
281
            );
282
            $this->modelManager->flush();
283
            $this->View()->assign([
284
                'success' => $result
285
            ]);
286
        } catch (Exception $e) {
287
            $this->View()->assign([
288
                'success' => false,
289
                'message' => $e->getMessage()
290
            ]);
291
        }
292
    }
293
294
    public function refundAction()
295
    {
296
        $orderId = $this->Request()->getParam('orderId');
297
        $this->registerShopByOrderId($orderId);
298
        $order = $this->getOrderById($orderId);
299
        $service = $this->getService($order);
300
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
301
        $positions = $this->Request()->getParam('positions', []);
302
303
        try {
304
            $invoices = [];
305
            /** @var Shopware\Models\Order\Detail $position */
306
            foreach ($order->getDetails() as $position) {
307
                if (!empty($positions[$position->getId()])) {
308
                    /** @noinspection PhpUndefinedMethodInspection */
309
                    $invoiceNumber = $position->getAttribute()->getSwagKlarnaInvoiceNumber();
310
                    $selection = min($positions[$position->getId()], $position->getShipped());
311
                    if ($invoiceNumber !== null && !empty($selection)) {
312
                        $invoices[$invoiceNumber][$position->getArticleNumber()] = $selection;
313
                        $position->setStatus($status);
314
                        $position->setShipped($position->getShipped() - $selection);
315
                    }
316
                }
317
            }
318
            $result = [];
319
            foreach ($invoices as $invoiceNumber => $articles) {
320
                foreach ($articles as $articleNumber => $quantity) {
321
                    $service->addArtNo($quantity, $articleNumber);
322
                }
323
                $result[] = $service->creditPart($invoiceNumber);
324
            }
325
            $this->modelManager->flush();
326
            $this->View()->assign([
327
                'success' => true,
328
                'number' => $result
329
            ]);
330
        } catch (Exception $e) {
331
            $this->View()->assign([
332
                'success' => false,
333
                'message' => $e->getMessage()
334
            ]);
335
        }
336
    }
337
338
    public function updateAction()
339
    {
340
        $orderId = $this->Request()->getParam('orderId');
341
        $this->registerShopByOrderId($orderId);
342
        $order = $this->getOrderById($orderId);
343
344
        $service = $this->getService($order);
345
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 0);
346
        $positions = $this->Request()->getParam('positions', []);
347
        if (is_string($positions)) {
348
            $positions = json_decode($positions, true);
349
        }
350
        $newPositions = [];
351
352
        try {
353
            if ($order->getInvoiceShipping() > 0) {
354
                $invoiceShippingNet = $order->getInvoiceShippingNet();
355
                $taxRate = round(($order->getInvoiceShipping() - $invoiceShippingNet) / $invoiceShippingNet * 100, 2);
356
                $service->addArticle(
357
                    1,
358
                    'SHIPPING',
359
                    'Shipping Fee',
360
                    $order->getInvoiceShipping(),
361
                    $taxRate,
362
                    0,
363
                    KlarnaFlags::INC_VAT | KlarnaFlags::IS_SHIPMENT
364
                );
365
            }
366
367
            if (!empty($positions)) {
368
                foreach ($positions as $positionData) {
369
                    if (empty($positionData['price'])) {
370
                        $positionData = $this->getPriceData($positionData);
371
                    }
372
                    $position = null;
373
                    if (!empty($positionData['id'])) {
374
                        /** @var \Shopware\Models\Order\Detail $testPosition */
375
                        foreach ($order->getDetails() as $testPosition) {
376
                            if ($testPosition->getId() == $positionData['id']) {
377
                                $position = $testPosition;
378
                                break;
379
                            }
380
                        }
381
                    }
382
                    if ($position === null) {
383
                        $position = new Shopware\Models\Order\Detail();
384
                        $position->fromArray([
385
                            'order' => $order,
386
                            'number' => $order->getNumber(),
387
                            'status' => $status,
388
                            'attribute' => ['attribute1' => '']
389
                        ]);
390
                    }
391
                    if (!empty($positionData['taxId'])
392
                        && ($position->getTax() === null || $position->getTax()->getId() != $positionData['taxId'])
393
                    ) {
394
                        /** @var \Shopware\Models\Tax\Tax $tax */
395
                        $tax = $this->modelManager->find('\Shopware\Models\Tax\Tax', $positionData['taxId']);
396
                        $position->setTax($tax);
397
                        $positionData['taxRate'] = $tax->getTax();
398
                    }
399
                    $position->fromArray([
400
                        'taxRate' => $positionData['taxRate'],
401
                        'articleId' => $positionData['articleId'],
402
                        'articleNumber' => $positionData['articleNumber'],
403
                        'articleName' => $positionData['articleName'],
404
                        'price' => $positionData['price'],
405
                        'quantity' => $positionData['quantity']
406
                    ]);
407
                    $newPositions[] = $position;
408
                }
409
                $order->setDetails($newPositions);
410
            }
411
412
            /** @var Shopware\Models\Order\Detail $position */
413
            foreach ($order->getDetails() as $position) {
414
                $flags = KlarnaFlags::INC_VAT;
415
                if ($position->getMode() != 0 && $position->getPrice() > 0) {
416
                    $flags |= KlarnaFlags::IS_HANDLING;
417
                } elseif ($position->getArticleNumber() == 'SHIPPING') {
418
                    $flags |= KlarnaFlags::IS_SHIPMENT;
419
                }
420
                $articleName = utf8_decode($position->getArticleName());
421
422
                $service->addArticle(
423
                    $position->getQuantity(),
424
                    $position->getArticleNumber(),
425
                    $articleName,
426
                    $position->getPrice(),
427
                    $position->getTaxRate(),
428
                    0,
429
                    $flags
430
                );
431
            }
432
433
            $service->update($order->getTransactionId());
434
            $this->modelManager->flush();
435
            $this->View()->assign([
436
                'success' => true
437
            ]);
438
        } catch (Exception $e) {
439
            $this->View()->assign([
440
                'success' => false,
441
                'message' => $e->getMessage()
442
            ]);
443
        }
444
    }
445
446
    public function discountAction()
447
    {
448
        $orderId = $this->Request()->getParam('orderId');
449
        $this->registerShopByOrderId($orderId);
450
        $order = $this->getOrderById($orderId);
451
        $value = (float)str_replace(',', '.', $this->Request()->getParam('value'));
452
        $service = $this->getService($order);
453
454
        /** @noinspection PhpUndefinedMethodInspection */
455
        $invoiceNumber = $order->getAttribute()->getSwagKlarnaInvoiceNumber();
456
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 3);
457
        $tax = null;
458
        /** @var Shopware\Models\Order\Detail $detail */
459
        foreach ($order->getDetails() as $detail) {
460
            if ($detail->getTax() !== null && $detail->getTax()->getId() != 0) {
461
                $tax = $detail->getTax();
462
            }
463
        }
464
465
        try {
466
            $result = $service->returnAmount(
467
                $invoiceNumber,
468
                $value,
469
                $detail->getTaxRate(),
0 ignored issues
show
Bug introduced by
The variable $detail seems to be defined by a foreach iteration on line 459. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
470
                KlarnaFlags::INC_VAT,
471
                'discount'
472
            );
473
474
            $value = $value > 0 ? $value * -1 : $value;
475
            $detail = new Shopware\Models\Order\Detail();
476
            $detail->fromArray([
477
                'order' => $order,
478
                'number' => $order->getNumber(),
479
                'tax' => $tax,
480
                'status' => $status,
481
                'taxRate' => $tax !== null ? $tax->getTax() : 0,
482
                'articleId' => 0,
483
                'articleNumber' => 'DISCOUNT',
484
                'articleName' => 'Discount',
485
                'price' => $value,
486
                'quantity' => 1,
487
                'attribute' => [
488
                    'swagKlarnaInvoiceNumber' => $result
489
                ]
490
            ]);
491
            $order->getDetails()->add($detail);
492
            $this->modelManager->flush();
493
            $this->View()->assign([
494
                'success' => true,
495
                'number' => $result
496
            ]);
497
        } catch (Exception $e) {
498
            $this->View()->assign([
499
                'success' => false,
500
                'message' => $e->getMessage()
501
            ]);
502
        }
503
    }
504
505
    public function autoUpdateAction()
506
    {
507
        $orderId = $this->Request()->getParam('orderId');
508
        $this->registerShopByOrderId($orderId);
509
        $order = $this->getOrderById($orderId);
510
511
        if ($order === null) {
512
            return;
513
        }
514
515
        if ($order->getInvoiceShipping() > 0 && $this->config->get('convertShippingFee')) {
516
            $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 0);
517
            $invoiceShippingNet = $order->getInvoiceShippingNet();
518
            $taxRate = round(($order->getInvoiceShipping() - $invoiceShippingNet) / $invoiceShippingNet * 100, 2);
519
            $detail = new Shopware\Models\Order\Detail();
520
            $detail->fromArray([
521
                'order' => $order,
522
                'number' => $order->getNumber(),
523
                'status' => $status,
524
                'taxRate' => $taxRate,
525
                'articleId' => 0,
526
                'articleNumber' => 'SHIPPING',
527
                'articleName' => 'Shipping Fee',
528
                'price' => $order->getInvoiceShipping(),
529
                'quantity' => 1,
530
                'attribute' => ['attribute1' => '']
531
            ]);
532
            $order->getDetails()->add($detail);
533
            $order->setInvoiceShipping(0);
534
            $order->setInvoiceShippingNet(0);
535
            $this->modelManager->flush();
536
        }
537
538
        $this->View()->assign([
539
            'success' => true,
540
        ]);
541
    }
542
543
    public function getInvoiceSecretAction()
544
    {
545
        $orderId = $this->Request()->getParam('orderId');
546
        $invoiceNo = $this->Request()->getParam('invoiceNo');
547
548
        if (empty($invoiceNo)) {
549
            /** @var DataLoader $dataLoader */
550
            $dataLoader = $this->get('shopware_attribute.data_loader');
551
552
            try {
553
                $data = $dataLoader->load('s_order_details_attributes', $orderId);
554
            } catch (Exception $e) {
555
                $this->View()->assign(['success' => false, 'message' => $e->getMessage()]);
556
                return;
557
            }
558
559
            if (empty($data)) {
560
                $this->View()->assign(['success' => false, 'message' => 'Dataset was empty!']);
561
                return;
562
            }
563
564
            $invoiceNo = $data['swag_klarna_invoice_number'];
565
        }
566
567
        $eid = $this->config->get('merchantId');
568
        $sharedSecret = $this->config->get('sharedSecret');
569
        $testDrive = $this->config->get('testDrive');
570
571
        $secretParts = [$eid, $invoiceNo, $sharedSecret];
572
        $secret = urlencode(
573
            base64_encode(
574
                hash('sha512', implode(':', $secretParts), true)
575
            )
576
        );
577
578
        $this->View()->assign([
579
            'success' => true,
580
            'invoiceNo' => $invoiceNo,
581
            'secret' => $secret,
582
            'testDrive' => $testDrive
583
        ]);
584
    }
585
586
    /**
587
     * Helper method to get the default price for an article
588
     * @param $positionData
589
     */
590
    private function getPriceData($positionData)
591
    {
592
        /** @var Shopware\Models\Article\Detail $articleDetail */
593
        $articleDetail = Shopware()->Models()->getRepository('Shopware\Models\Article\Detail')->findOneBy([
594
            'number' => $positionData['articleNumber']
595
        ]);
596
        $article = $articleDetail->getArticle();
597
        $tax = intval($article->getTax()->getTax());
598
        $price = Shopware()->Models()->getRepository('Shopware\Models\Article\Price')->findOneBy([
599
            'articleDetailsId' => $articleDetail->getId(),
600
            'from' => 1
601
        ])->getPrice();
602
603
        $price = round($price * (100 + $tax) / 100, 3);
604
605
        $positionData['taxRate'] = $tax;
606
        $positionData['price'] = $price;
607
608
        return $positionData;
609
    }
610
611
    /**
612
     * Helper method to get the proper service with the correct EID
613
     *
614
     * @param Order $order
615
     * @return Klarna
616
     */
617
    private function getService($order)
618
    {
619
        $plugin = $this->plugin;
620
621
        if ($order->getPayment()->getName() !== 'klarna_checkout'
622
            && $this->plugin->isKpmActive()) {
623
            $plugin = Shopware()->Plugins()->Frontend()->SwagPaymentKlarnaKpm();
624
        }
625
626
        if (!method_exists($plugin, 'getService')) {
627
            // Older KPM version
628
            /** @noinspection PhpUndefinedMethodInspection */
629
            return $plugin->getKlarnaServiceByConfig($plugin->Config());
630
        }
631
        return $plugin->getService();
632
    }
633
634
635
    /**
636
     * @return array
637
     */
638
    public function getWhitelistedCSRFActions()
639
    {
640
        $csrfActions = [
641
            'activate',
642
            'autoUpdate',
643
            'cancel',
644
            'credit',
645
            'discount',
646
            'refund',
647
            'update'
648
        ];
649
        
650
        return $csrfActions;
651
    }
652
}
653