Completed
Pull Request — master (#272)
by Felipe
38:19
created

getShipmentsAvailable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Sylius\ShopApiPlugin\Handler;
6
7
use Doctrine\Common\Collections\Collection;
8
use SM\Factory\FactoryInterface;
9
use Sylius\Component\Core\Model\OrderInterface;
10
use Sylius\Component\Core\Model\ShippingMethodInterface;
11
use Sylius\Component\Core\OrderCheckoutTransitions;
12
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
13
use Sylius\Component\Core\Repository\ShippingMethodRepositoryInterface;
14
use Sylius\Component\Shipping\Checker\ShippingMethodEligibilityCheckerInterface;
15
use Sylius\Component\Shipping\Resolver\ShippingMethodsResolverInterface;
16
use Sylius\ShopApiPlugin\Command\ChooseShippingMethod;
17
use Webmozart\Assert\Assert;
18
19
final class ChooseShippingMethodHandler
20
{
21
    /**
22
     * @var OrderRepositoryInterface
23
     */
24
    private $orderRepository;
25
26
    /**
27
     * @var ShippingMethodRepositoryInterface
28
     */
29
    private $shippingMethodRepository;
30
31
    /**
32
     * @var ShippingMethodEligibilityCheckerInterface
33
     */
34
    private $eligibilityChecker;
35
36
    /**
37
     * @var FactoryInterface
38
     */
39
    private $stateMachineFactory;
40
41
    /**
42
     * @var ShippingMethodsResolverInterface
43
     */
44
    private $shippingMethodsResolver;
45
46
    /**
47
     * @param OrderRepositoryInterface $orderRepository
48
     * @param ShippingMethodRepositoryInterface $shippingMethodRepository
49
     * @param ShippingMethodEligibilityCheckerInterface $eligibilityChecker
50
     * @param ShippingMethodsResolverInterface $shippingMethodsResolver
51
     * @param FactoryInterface $stateMachineFactory
52
     */
53
    public function __construct(
54
        OrderRepositoryInterface $orderRepository,
55
        ShippingMethodRepositoryInterface $shippingMethodRepository,
56
        ShippingMethodEligibilityCheckerInterface $eligibilityChecker,
57
        ShippingMethodsResolverInterface $shippingMethodsResolver,
58
        FactoryInterface $stateMachineFactory
59
    ) {
60
        $this->orderRepository = $orderRepository;
61
        $this->shippingMethodRepository = $shippingMethodRepository;
62
        $this->eligibilityChecker = $eligibilityChecker;
63
        $this->stateMachineFactory = $stateMachineFactory;
64
        $this->shippingMethodsResolver = $shippingMethodsResolver;
65
    }
66
67
    /**
68
     * @param ChooseShippingMethod $chooseShippingMethod
69
     */
70
    public function handle(ChooseShippingMethod $chooseShippingMethod)
71
    {
72
        /** @var OrderInterface $cart */
73
        $cart = $this->orderRepository->findOneBy(['tokenValue' => $chooseShippingMethod->orderToken()]);
74
75
        Assert::notNull($cart, 'Cart has not been found.');
76
77
        $stateMachine = $this->stateMachineFactory->get($cart, OrderCheckoutTransitions::GRAPH);
78
79
        Assert::true($stateMachine->can(OrderCheckoutTransitions::TRANSITION_SELECT_SHIPPING), 'Order cannot have shipment method assigned.');
80
81
        /** @var ShippingMethodInterface $shippingMethod */
82
        $shippingMethod = $this->shippingMethodRepository->findOneBy(['code' => $chooseShippingMethod->shippingMethod()]);
83
84
        Assert::notNull($shippingMethod, 'Shipping method has not been found');
85
86
        $shipmentsAvailable = $this->getShipmentsAvailable($cart->getShipments());
0 ignored issues
show
Bug introduced by
It seems like $cart->getShipments() targeting Sylius\Component\Core\Mo...terface::getShipments() can also be of type array<integer,object<Syl...del\ShipmentInterface>>; however, Sylius\ShopApiPlugin\Han...getShipmentsAvailable() does only seem to accept object<Doctrine\Common\Collections\Collection>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
87
88
        Assert::true(isset($shipmentsAvailable[$chooseShippingMethod->shipmentIdentifier()]), 'Can not find shipment with given identifier.');
89
90
        $shipment = $shipmentsAvailable[$chooseShippingMethod->shipmentIdentifier()];
91
92
        Assert::true($this->eligibilityChecker->isEligible($shipment, $shippingMethod), 'Given shipment is not eligible for provided shipping method.');
93
94
        $shipment->setMethod($shippingMethod);
95
        $stateMachine->apply(OrderCheckoutTransitions::TRANSITION_SELECT_SHIPPING);
96
    }
97
98
    /**
99
     * @param Collection $shipments
100
     *
101
     * @return array
102
     */
103
    private function getShipmentsAvailable(Collection $shipments): array
104
    {
105
        $shipmentsAvailable = [];
106
        foreach ($shipments as $shipment) {
107
            /** @var ShippingMethodInterface $shippingMethod */
108
            foreach ($this->shippingMethodsResolver->getSupportedMethods($shipment) as $shippingMethod) {
109
                $shipmentsAvailable[$shippingMethod->getCode()] = $shipment;
110
            }
111
        }
112
113
        return $shipmentsAvailable;
114
    }
115
}
116