Completed
Push — master ( ead026...e06fe9 )
by Michał
302:23 queued 302:00
created

StateResolver::resolvePaymentState()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 31
rs 5.3846
cc 8
eloc 16
nc 8
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Component\Core\OrderProcessing;
13
14
use SM\Factory\FactoryInterface;
15
use SM\StateMachine\StateMachineInterface;
16
use Sylius\Component\Core\Model\OrderInterface;
17
use Sylius\Component\Core\Model\OrderShippingStates;
18
use Sylius\Component\Core\Model\PaymentInterface;
19
use Sylius\Component\Core\Model\ShipmentInterface;
20
use Sylius\Component\Core\OrderPaymentStates;
21
use Sylius\Component\Core\OrderPaymentTransitions;
22
23
/**
24
 * @author Paweł Jędrzejewski <[email protected]>
25
 * @author Grzegorz Sadowski <[email protected]>
26
 */
27
class StateResolver implements StateResolverInterface
28
{
29
    /**
30
     * @var FactoryInterface
31
     */
32
    private $stateMachineFactory;
33
34
    /**
35
     * @param FactoryInterface $stateMachineFactory
36
     */
37
    public function __construct(FactoryInterface $stateMachineFactory)
38
    {
39
        $this->stateMachineFactory = $stateMachineFactory;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function resolvePaymentState(OrderInterface $order)
46
    {
47
        $stateMachine = $this->stateMachineFactory->get($order, OrderPaymentTransitions::GRAPH);
48
49
        if (OrderPaymentStates::STATE_PAID === $order->getPaymentState()) {
50
            return;
51
        }
52
53
        if ($order->hasPayments()) {
54
            $completedPaymentTotal = 0;
55
            $payments = $order->getPayments()->filter(function (PaymentInterface $payment) {
56
                return PaymentInterface::STATE_COMPLETED === $payment->getState();
57
            });
58
59
            foreach ($payments as $payment) {
60
                $completedPaymentTotal += $payment->getAmount();
61
            }
62
63
            if (0 < $payments->count() && $completedPaymentTotal >= $order->getTotal()) {
64
                $this->applyTransition($stateMachine, OrderPaymentTransitions::TRANSITION_PAY);
65
66
                return;
67
            }
68
69
            if ($completedPaymentTotal < $order->getTotal() && 0 < $completedPaymentTotal) {
70
                $this->applyTransition($stateMachine, OrderPaymentTransitions::TRANSITION_PARTIALLY_PAY);
71
72
                return;
73
            }
74
        }
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function resolveShippingState(OrderInterface $order)
81
    {
82
        if ($order->isBackorder()) {
83
            $order->setShippingState(OrderShippingStates::BACKORDER);
84
85
            return;
86
        }
87
88
        $order->setShippingState($this->getShippingState($order));
89
    }
90
91
    /**
92
     * @param OrderInterface $order
93
     *
94
     * @return string
95
     */
96
    protected function getShippingState(OrderInterface $order)
97
    {
98
        $states = [];
99
100
        foreach ($order->getShipments() as $shipment) {
101
            $states[] = $shipment->getState();
102
        }
103
104
        $states = array_unique($states);
105
106
        $acceptableStates = [
107
            ShipmentInterface::STATE_READY => OrderShippingStates::READY,
108
            ShipmentInterface::STATE_SHIPPED => OrderShippingStates::SHIPPED,
109
            ShipmentInterface::STATE_CANCELLED => OrderShippingStates::CANCELLED,
110
        ];
111
112
        foreach ($acceptableStates as $shipmentState => $orderState) {
113
            if ([$shipmentState] == $states) {
114
                return $orderState;
115
            }
116
        }
117
118
        return OrderShippingStates::PARTIALLY_SHIPPED;
119
    }
120
121
    /**
122
     * @param StateMachineInterface $stateMachine
123
     * @param string $transition
124
     */
125
    private function applyTransition(StateMachineInterface $stateMachine, $transition)
126
    {
127
        if ($stateMachine->can($transition)) {
128
            $stateMachine->apply($transition);
129
        }
130
    }
131
}
132