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()); |
|
|
|
|
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
|
|
|
|
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.