SetStatusOrderAction   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 93
rs 10
c 0
b 0
f 0
wmc 21

6 Methods

Rating   Name   Duplication   Size   Complexity  
A applyStateMachineOrderTransition() 0 9 2
A isShippingAllItems() 0 3 1
C execute() 0 31 12
A __construct() 0 8 1
A isConfirmNotify() 0 11 3
A applyStateMachineShipmentsTransition() 0 9 2
1
<?php
2
3
/*
4
 * This file has been created by developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * You can find more information about us on https://bitbag.io and write us
7
 * an email on [email protected].
8
 */
9
10
declare(strict_types=1);
11
12
namespace BitBag\SyliusMolliePlugin\Action\StateMachine;
13
14
use BitBag\SyliusMolliePlugin\PartialShip\CreatePartialShipFromMollieInterface;
15
use BitBag\SyliusMolliePlugin\Transitions\PartialShip\ShipmentTransitions as ShipmentTransitionsPartial;
16
use Mollie\Api\Resources\Order;
17
use SM\Factory\FactoryInterface;
18
use Sylius\Component\Core\Model\OrderInterface;
19
use Sylius\Component\Core\Model\ShipmentInterface;
20
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
21
use Sylius\Component\Order\OrderTransitions;
22
use Sylius\Component\Shipping\ShipmentTransitions;
23
24
final class SetStatusOrderAction
25
{
26
    /** @var FactoryInterface */
27
    private $factory;
28
29
    /** @var OrderRepositoryInterface */
30
    private $orderRepository;
31
32
    /** @var CreatePartialShipFromMollieInterface */
33
    private $createPartialShipFromMollie;
34
35
    public function __construct(
36
        FactoryInterface $factory,
37
        OrderRepositoryInterface $orderRepository,
38
        CreatePartialShipFromMollieInterface $createPartialShipFromMollie
39
    ) {
40
        $this->factory = $factory;
41
        $this->orderRepository = $orderRepository;
42
        $this->createPartialShipFromMollie = $createPartialShipFromMollie;
43
    }
44
45
    public function execute(Order $order): void
46
    {
47
        if (!$order->orderNumber) {
48
            return;
49
        }
50
        /** @var OrderInterface $orderSylius */
51
        $orderSylius = $this->orderRepository->findOneBy(['id' => $order->orderNumber]);
52
53
        /** @var ShipmentInterface $firstShipment */
54
        $firstShipment = $orderSylius->getShipments()->first();
55
56
        /** @var ShipmentInterface $lastShipment */
57
        $lastShipment = $orderSylius->getShipments()->last();
58
59
        if ($order->isCompleted()) {
60
            $this->applyStateMachineOrderTransition($orderSylius, OrderTransitions::TRANSITION_FULFILL);
61
            $this->applyStateMachineShipmentsTransition($firstShipment, ShipmentTransitions::TRANSITION_SHIP);
62
        }
63
        if ($order->isCanceled() || $order->isExpired()) {
64
            $this->applyStateMachineOrderTransition($orderSylius, OrderTransitions::TRANSITION_CANCEL);
65
        }
66
67
        if ($order->isShipping() && $this->isConfirmNotify($order, $firstShipment) && false === $this->isShippingAllItems($firstShipment)) {
68
            return;
69
        }
70
        if ($order->isShipping() && false === $this->isShippingAllItems($firstShipment)) {
71
            $this->createPartialShipFromMollie->create($orderSylius, $order);
72
            $this->applyStateMachineShipmentsTransition($lastShipment, ShipmentTransitionsPartial::TRANSITION_CREATE_AND_SHIP);
73
        }
74
        if ($order->isShipping() && true === $this->isShippingAllItems($firstShipment)) {
75
            $this->applyStateMachineShipmentsTransition($lastShipment, ShipmentTransitions::TRANSITION_SHIP);
76
        }
77
    }
78
79
    private function applyStateMachineOrderTransition(OrderInterface $orderSylius, string $transitions): void
80
    {
81
        $stateMachine = $this->factory->get($orderSylius, OrderTransitions::GRAPH);
82
83
        if (!$stateMachine->can($transitions)) {
84
            return;
85
        }
86
87
        $stateMachine->apply($transitions);
88
    }
89
90
    private function applyStateMachineShipmentsTransition(ShipmentInterface $orderSylius, string $transitions): void
91
    {
92
        $stateMachine = $this->factory->get($orderSylius, ShipmentTransitions::GRAPH);
93
94
        if (!$stateMachine->can($transitions)) {
95
            return;
96
        }
97
98
        $stateMachine->apply($transitions);
99
    }
100
101
    private function isShippingAllItems(ShipmentInterface $shipment): bool
102
    {
103
        return $shipment->getUnits()->isEmpty();
104
    }
105
106
    private function isConfirmNotify(Order $order, ShipmentInterface $shipment): bool
107
    {
108
        // check if in mollie and sylius is the same shipped items
109
        $shippableQuantity = 0;
110
        foreach ($order->lines as $line) {
111
            if ($line->type === 'physical') {
112
                $shippableQuantity += $line->shippableQuantity;
113
            }
114
        }
115
116
        return $shippableQuantity === count($shipment->getUnits()->toArray());
117
    }
118
}
119