Passed
Push — master ( 54a344...83c53d )
by Mario
03:09
created

updateAction()   F

Complexity

Conditions 18
Paths 5370

Size

Total Lines 106
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
dl 0
loc 106
rs 2
c 0
b 0
f 0
eloc 75
nc 5370
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
use Shopware\Models\Order\Order;
3
use Shopware\Components\CSRFWhitelistAware;
4
5
/**
6
 * Klarna payment controller
7
 */
8
class Shopware_Controllers_Backend_PaymentKlarna extends Enlight_Controller_Action implements CSRFWhitelistAware
9
{
10
    /**
11
     * @var Shopware_Plugins_Frontend_SwagPaymentKlarna_Bootstrap
12
     */
13
    private $plugin;
14
15
    /**
16
     * @var Enlight_Config
17
     */
18
    private $config;
19
20
    /**
21
     * @var Shopware\Components\Model\ModelManager
22
     */
23
    private $modelManager;
24
25
    /**
26
     * @var Shopware\Models\Order\Repository
27
     */
28
    private $orderRepository;
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function preDispatch()
34
    {
35
        $this->plugin = $this->get('plugins')->Frontend()->SwagPaymentKlarna();
36
        $this->config = $this->plugin->Config();
37
        $this->modelManager = $this->get('models');
38
        $this->orderRepository = $this->modelManager->getRepository('Shopware\Models\Order\Order');
39
40
        $this->Front()->Plugins()->Json()->setRenderer();
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 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...
47
    {
48
        if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') {
49
            if ($name == 'pluginlogger') {
50
                $name = 'log';
51
            }
52
            $name = ucfirst($name);
53
            return Shopware()->Bootstrap()->getResource($name);
54
        }
55
        return parent::get($name);
56
    }
57
58
    /**
59
     * @return \Doctrine\ORM\Query
60
     */
61
    protected function getOrderByIdQuery()
62
    {
63
        $builder = $this->orderRepository->createQueryBuilder('o');
64
        $builder->addSelect(array(
65
            'details',
66
            'customer',
67
            'documents',
68
            'attribute',
69
            'detailsAttribute'
70
        ));
71
        $builder->leftJoin('o.details', 'details')
72
            ->leftJoin('details.attribute', 'detailsAttribute')
73
            ->leftJoin('o.customer', 'customer')
74
            ->leftJoin('o.documents', 'documents')
75
            ->leftJoin('o.attribute', 'attribute');
76
        $builder->where('o.id = :orderId');
77
        $query = $builder->getQuery();
78
        return $query;
79
    }
80
81
    /**
82
     * @param $orderId
83
     * @return Shopware\Models\Order\Order
84
     */
85
    protected function getOrderById($orderId)
86
    {
87
        $query = $this->getOrderByIdQuery();
88
        $query->setParameter('orderId', $orderId);
89
        return $query->getOneOrNullResult();
90
    }
91
92
    protected function registerShopByOrderId($orderId)
93
    {
94
        $repository = $this->modelManager->getRepository('Shopware\Models\Shop\Shop');
95
96
        $order = $this->orderRepository->find($orderId);
97
        if ($order === null) {
98
            throw new \Exception("Order {$orderId} not found");
99
        }
100
        $shopId = $order->getLanguageIso();
101
        if ($shopId === null) {
102
            $shop = $repository->getActiveDefault();
103
        } else {
104
            $shop = $repository->getActiveById($shopId);
105
        }
106
        if ($shop === null) {
107
            throw new \Exception("Shop {$shopId} not found");
108
        }
109
        $shop->registerResources(Shopware()->Bootstrap());
110
        $this->modelManager->clear();
111
        return $shop;
112
    }
113
114
    public function activateAction()
115
    {
116
        $orderId = $this->Request()->getParam('orderId');
117
        $positions = $this->Request()->getParam('positions', array());
118
        $this->registerShopByOrderId($orderId);
119
        $order = $this->getOrderById($orderId);
120
        $service = $this->getService($order);
121
        $detailStatus = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 3);
122
        $paymentStatus = $this->plugin->Config()->get('activateStatusId');
123 View Code Duplication
        if (!empty($paymentStatus)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
124
            $paymentStatus = $this->modelManager->find('\Shopware\Models\Order\Status', $paymentStatus);
125
        } else {
126
            $paymentStatus = null;
127
        }
128
129
        /** @var Shopware\Models\Order\Detail $position */
130
        foreach ($order->getDetails() as $position) {
131
            if (empty($positions)) {
132
                $selection = $position->getQuantity() - $position->getShipped();
133
                if (!empty($selection)) {
134
                    // $service->addArtNo($selection, $position->getArticleNumber());
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
135
                    $position->setShipped($position->getShipped() + $selection);
136
                    $position->setStatus($detailStatus);
137
                }
138
            } elseif (!empty($positions[$position->getId()])) {
139
                $quantity = $position->getQuantity() - $position->getShipped();
140
                $selection = min($positions[$position->getId()], $quantity);
141
                if (!empty($selection)) {
142
                    $service->addArtNo($selection, $position->getArticleNumber());
143
                    $position->setShipped($position->getShipped() + $selection);
144
                    if ($selection == $quantity) {
145
                        $position->setStatus($detailStatus);
146
                    }
147
                }
148
            }
149
        }
150
151
        try {
152
            $result = $service->activate($order->getTransactionId());
153
            if (!empty($result[1])) {
154
                $last = true;
155
                foreach ($order->getDetails() as $position) {
156
                    if ((empty($positions) || !empty($positions[$position->getId()]))) {
157
                        if ($position->getAttribute()->getSwagKlarnaInvoiceNumber() === null) {
158
                            $position->getAttribute()->setSwagKlarnaInvoiceNumber(
159
                                $result[1]
160
                            );
161
                        }
162
                    } elseif ($position->getStatus()->getId() == 0) {
163
                        $last = false;
164
                    }
165
                }
166
167
                $order->getAttribute()->setSwagKlarnaInvoiceNumber(
168
                    $result[1]
169
                );
170
171
                if (empty($positions) || $last) {
172
                    $order->setClearedDate(new DateTime());
173
                    $order->getAttribute()->setSwagKlarnaStatus(
174
                        'activate'
175
                    );
176
                    if ($paymentStatus !== null) {
177
                        $order->setPaymentStatus($paymentStatus);
178
                    }
179
                }
180
                $this->modelManager->flush();
181
                $this->View()->assign(array(
182
                    'success' => true,
183
                    'number' => $result[1]
184
                ));
185
            } else {
186
                $this->View()->assign(array(
187
                    'success' => false,
188
                    'status' => $result[0]
189
                ));
190
            }
191
        } catch (Exception $e) {
192
            $this->View()->assign(array(
193
                'success' => false,
194
                'message' => $e->getMessage()
195
            ));
196
        }
197
    }
198
199
    public function creditAction()
200
    {
201
        $orderId = $this->Request()->getParam('orderId');
202
        $this->registerShopByOrderId($orderId);
203
        $order = $this->getOrderById($orderId);
204
205
        $service = $this->getService($order);
206
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
207
208
        try {
209
            $invoices = array(
210
                $order->getAttribute()->getSwagKlarnaInvoiceNumber()
211
            );
212
            /** @var Shopware\Models\Order\Detail $position */
213
            foreach ($order->getDetails() as $position) {
214
                if ($position->getAttribute()->getSwagKlarnaInvoiceNumber() !== null) {
215
                    $invoices[] = $position->getAttribute()->getSwagKlarnaInvoiceNumber();
216
                }
217
                $position->setStatus($status);
218
            }
219
            $result = array();
220
            foreach (array_unique($invoices) as $invoice) {
221
                $result[] = $service->creditInvoice($invoice);
222
            }
223
            $order->getAttribute()->setSwagKlarnaStatus(
224
                'credit'
225
            );
226
            $this->modelManager->flush();
227
            $this->View()->assign(array(
228
                'success' => !empty($result),
229
                'number' => $result
230
            ));
231
        } catch (Exception $e) {
232
            $this->View()->assign(array(
233
                'success' => false,
234
                'message' => $e->getMessage()
235
            ));
236
        }
237
    }
238
239
    public function cancelAction()
240
    {
241
        $orderId = $this->Request()->getParam('orderId');
242
        $this->registerShopByOrderId($orderId);
243
        $order = $this->getOrderById($orderId);
244
        $service = $this->getService($order);
245
        $detailStatus = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
246
        $paymentStatus = $this->plugin->Config()->get('cancelStatusId');
247 View Code Duplication
        if (!empty($paymentStatus)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
248
            $paymentStatus = $this->modelManager->find('\Shopware\Models\Order\Status', $paymentStatus);
249
        } else {
250
            $paymentStatus = null;
251
        }
252
253
        try {
254
            /** @var Shopware\Models\Order\Detail $position */
255
            foreach ($order->getDetails() as $position) {
256
                if (!$position->getStatus()->getId()) {
257
                    $position->setStatus($detailStatus);
258
                }
259
            }
260
            $result = $service->cancelReservation(
261
                $order->getTransactionId()
262
            );
263
            if ($paymentStatus !== null) {
264
                $order->setPaymentStatus($paymentStatus);
265
            }
266
            $order->getAttribute()->setSwagKlarnaStatus(
267
                'cancel'
268
            );
269
            $this->modelManager->flush();
270
            $this->View()->assign(array(
271
                'success' => $result
272
            ));
273
        } catch (Exception $e) {
274
            $this->View()->assign(array(
275
                'success' => false,
276
                'message' => $e->getMessage()
277
            ));
278
        }
279
    }
280
281
    public function refundAction()
282
    {
283
        $orderId = $this->Request()->getParam('orderId');
284
        $this->registerShopByOrderId($orderId);
285
        $order = $this->getOrderById($orderId);
286
        $service = $this->getService($order);
287
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 2);
288
        $positions = $this->Request()->getParam('positions', array());
289
290
        try {
291
            $invoices = array();
292
            /** @var Shopware\Models\Order\Detail $position */
293
            foreach ($order->getDetails() as $position) {
294
                if (!empty($positions[$position->getId()])) {
295
                    $invoiceNumber = $position->getAttribute()->getSwagKlarnaInvoiceNumber();
296
                    $selection = min($positions[$position->getId()], $position->getShipped());
297
                    if ($invoiceNumber !== null && !empty($selection)) {
298
                        $invoices[$invoiceNumber][$position->getArticleNumber()] = $selection;
299
                        $position->setStatus($status);
300
                        $position->setShipped($position->getShipped() - $selection);
301
                    }
302
                }
303
            }
304
            $result = array();
305
            foreach ($invoices as $invoiceNumber => $articles) {
306
                foreach ($articles as $articleNumber => $quantity) {
307
                    $service->addArtNo($quantity, $articleNumber);
308
                }
309
                $result[] = $service->creditPart($invoiceNumber);
310
            }
311
            $this->modelManager->flush();
312
            $this->View()->assign(array(
313
                'success' => true,
314
                'number' => $result
315
            ));
316
        } catch (Exception $e) {
317
            $this->View()->assign(array(
318
                'success' => false,
319
                'message' => $e->getMessage()
320
            ));
321
        }
322
    }
323
324
    public function updateAction()
325
    {
326
        $orderId = $this->Request()->getParam('orderId');
327
        $this->registerShopByOrderId($orderId);
328
        $order = $this->getOrderById($orderId);
329
330
        $service = $this->getService($order);
331
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 0);
332
        $positions = $this->Request()->getParam('positions', array());
333
        if (is_string($positions)) {
334
            $positions = json_decode($positions, true);
335
        }
336
        $newPositions = array();
337
338
        try {
339
            if ($order->getInvoiceShipping() > 0) {
340
                $taxRate = round(($order->getInvoiceShipping() - $order->getInvoiceShippingNet()) / $order->getInvoiceShippingNet() * 100, 2);
341
                $service->addArticle(
342
                    1,
343
                    'SHIPPING',
344
                    'Shipping Fee',
345
                    $order->getInvoiceShipping(),
346
                    $taxRate,
347
                    0,
348
                    KlarnaFlags::INC_VAT | KlarnaFlags::IS_SHIPMENT
349
                );
350
            }
351
352
            if (!empty($positions)) {
353
                foreach ($positions as $positionData) {
354
                    if (empty($positionData['price'])) {
355
                        $positionData = $this->getPriceData($positionData);
356
                    }
357
                    $position = null;
358
                    if (!empty($positionData['id'])) {
359
                        /** @var \Shopware\Models\Order\Detail $testPosition */
360
                        foreach ($order->getDetails() as $testPosition) {
361
                            if ($testPosition->getId() == $positionData['id']) {
362
                                $position = $testPosition;
363
                                break;
364
                            }
365
                        }
366
                    }
367
                    if ($position === null) {
368
                        $position = new Shopware\Models\Order\Detail();
369
                        $position->fromArray(array(
370
                            'order' => $order,
371
                            'number' => $order->getNumber(),
372
                            'status' => $status,
373
                            'attribute' => array('attribute1' => '')
374
                        ));
375
                    }
376
                    if (!empty($positionData['taxId'])
377
                        && ($position->getTax() === null || $position->getTax()->getId() != $positionData['taxId'])
378
                    ) {
379
                        /** @var \Shopware\Models\Tax\Tax $tax */
380
                        $tax = $this->modelManager->find('\Shopware\Models\Tax\Tax', $positionData['taxId']);
381
                        $position->setTax($tax);
382
                        $positionData['taxRate'] = $tax->getTax();
383
                    }
384
                    $position->fromArray(array(
385
                        'taxRate' => $positionData['taxRate'],
386
                        'articleId' => $positionData['articleId'],
387
                        'articleNumber' => $positionData['articleNumber'],
388
                        'articleName' => $positionData['articleName'],
389
                        'price' => $positionData['price'],
390
                        'quantity' => $positionData['quantity']
391
                    ));
392
                    $newPositions[] = $position;
393
                }
394
                $order->setDetails($newPositions);
395
            }
396
397
            /** @var Shopware\Models\Order\Detail $position */
398
            foreach ($order->getDetails() as $position) {
399
                $flags = KlarnaFlags::INC_VAT;
400
                if ($position->getMode() != 0 && $position->getPrice() > 0) {
401
                    $flags |= KlarnaFlags::IS_HANDLING;
402
                } elseif ($position->getArticleNumber() == 'SHIPPING') {
403
                    $flags |= KlarnaFlags::IS_SHIPMENT;
404
                }
405
                $articleName = utf8_decode($position->getArticleName());
406
407
                $service->addArticle(
408
                    $position->getQuantity(),
409
                    $position->getArticleNumber(),
410
                    $articleName,
411
                    $position->getPrice(),
412
                    $position->getTaxRate(),
413
                    0,
414
                    $flags
415
                );
416
            }
417
418
            $service->update($order->getTransactionId());
419
            $this->modelManager->flush();
420
            $this->View()->assign(array(
421
                'success' => true
422
            ));
423
        } catch (Exception $e) {
424
            $this->View()->assign(array(
425
                'success' => false,
426
                'message' => $e->getMessage()
427
            ));
428
        }
429
    }
430
431
    public function discountAction()
432
    {
433
        $orderId = $this->Request()->getParam('orderId');
434
        $this->registerShopByOrderId($orderId);
435
        $order = $this->getOrderById($orderId);
436
        $value = (float)str_replace(',', '.', $this->Request()->getParam('value'));
437
        $service = $this->getService($order);
438
439
        $invoiceNumber = $order->getAttribute()->getSwagKlarnaInvoiceNumber();
440
        $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 3);
441
        $tax = null;
442
        /** @var Shopware\Models\Order\Detail $detail */
443
        foreach ($order->getDetails() as $detail) {
444
            if ($detail->getTax() !== null && $detail->getTax()->getId() != 0) {
445
                $tax = $detail->getTax();
446
            }
447
        }
448
449
        try {
450
            $result = $service->returnAmount(
451
                $invoiceNumber,
452
                $value,
453
                $detail->getTaxRate(),
0 ignored issues
show
Bug introduced by
The variable $detail seems to be defined by a foreach iteration on line 443. 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...
454
                KlarnaFlags::INC_VAT,
455
                'discount'
456
            );
457
458
            $value = $value > 0 ? $value * -1 : $value;
459
            $detail = new Shopware\Models\Order\Detail();
460
            $detail->fromArray(array(
461
                'order' => $order,
462
                'number' => $order->getNumber(),
463
                'tax' => $tax,
464
                'status' => $status,
465
                'taxRate' => $tax !== null ? $tax->getTax() : 0,
466
                'articleId' => 0,
467
                'articleNumber' => 'DISCOUNT',
468
                'articleName' => 'Discount',
469
                'price' => $value,
470
                'quantity' => 1,
471
                'attribute' => array(
472
                    'swagKlarnaInvoiceNumber' => $result
473
                )
474
            ));
475
            $order->getDetails()->add($detail);
476
            $this->modelManager->flush();
477
            $this->View()->assign(array(
478
                'success' => true,
479
                'number' => $result
480
            ));
481
        } catch (Exception $e) {
482
            $this->View()->assign(array(
483
                'success' => false,
484
                'message' => $e->getMessage()
485
            ));
486
        }
487
    }
488
489
    public function autoUpdateAction()
490
    {
491
        $orderId = $this->Request()->getParam('orderId');
492
        $this->registerShopByOrderId($orderId);
493
        $order = $this->getOrderById($orderId);
494
495
        if ($order === null) {
496
            return;
497
        }
498
499
        if ($order->getInvoiceShipping() > 0 && $this->config->get('convertShippingFee')) {
500
            $status = $this->modelManager->find('\Shopware\Models\Order\DetailStatus', 0);
501
            $taxRate = round(($order->getInvoiceShipping() - $order->getInvoiceShippingNet()) / $order->getInvoiceShippingNet() * 100, 2);
502
503
            $detail = new Shopware\Models\Order\Detail();
504
            $detail->fromArray(array(
505
                'order' => $order,
506
                'number' => $order->getNumber(),
507
                'status' => $status,
508
                'taxRate' => $taxRate,
509
                'articleId' => 0,
510
                'articleNumber' => 'SHIPPING',
511
                'articleName' => 'Shipping Fee',
512
                'price' => $order->getInvoiceShipping(),
513
                'quantity' => 1,
514
                'attribute' => array('attribute1' => '')
515
            ));
516
            $order->getDetails()->add($detail);
517
            $order->setInvoiceShipping(0);
518
            $order->setInvoiceShippingNet(0);
519
            $this->modelManager->flush();
520
        }
521
522
        $this->View()->assign(array(
523
            'success' => true,
524
        ));
525
    }
526
527
    /**
528
     * Helper method to get the default price for an article
529
     * @param $positionData
530
     */
531
    private function getPriceData($positionData)
532
    {
533
        /** @var Shopware\Models\Article\Detail $articleDetail */
534
        $articleDetail = Shopware()->Models()->getRepository('Shopware\Models\Article\Detail')->findOneBy(array(
535
            'number' => $positionData['articleNumber']
536
        ));
537
        $article = $articleDetail->getArticle();
538
        $tax = intval($article->getTax()->getTax());
539
        $price = Shopware()->Models()->getRepository('Shopware\Models\Article\Price')->findOneBy(array(
540
            'articleDetailsId' => $articleDetail->getId(),
541
            'from' => 1
542
        ))->getPrice();
543
544
        $price = round($price * (100 + $tax) / 100, 3);
545
546
        $positionData['taxRate'] = $tax;
547
        $positionData['price'] = $price;
548
549
        return $positionData;
550
    }
551
552
    /**
553
     * Helper method to get the proper service with the correct EID
554
     *
555
     * @param Order $order
556
     * @return Klarna
557
     */
558
    private function getService($order)
559
    {
560
        $plugin = $this->plugin;
561
562
        if ($order->getPayment()->getName() !== 'klarna_checkout'
563
            && $this->plugin->isKpmActive()) {
564
            $plugin = Shopware()->Plugins()->Frontend()->SwagPaymentKlarnaKpm();
565
        }
566
567
        if (!method_exists($plugin, 'getService')) {
568
            //Older KPM version
569
            return $plugin->getKlarnaServiceByConfig($plugin->Config());
570
        }
571
        return $plugin->getService();
572
    }
573
574
575
    public function getWhitelistedCSRFActions()
576
    {
577
        $csrfActions = array(
578
            'activate',
579
            'autoUpdate',
580
            'cancel',
581
            'credit',
582
            'discount',
583
            'refund',
584
            'update'            
585
        );
586
        
587
        return $csrfActions;
588
    }
589
}
590