Completed
Push — master ( c9e675...0882fe )
by Paweł
02:38
created

CartController::pickupAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
namespace Sylius\ShopApiPlugin\Controller;
4
5
use Doctrine\Common\Persistence\ObjectManager;
6
use FOS\RestBundle\View\View;
7
use FOS\RestBundle\View\ViewHandlerInterface;
8
use Sylius\Component\Core\Factory\AddressFactoryInterface;
9
use Sylius\Component\Core\Factory\CartItemFactoryInterface;
10
use Sylius\Component\Core\Model\AddressInterface;
11
use Sylius\Component\Core\Model\OrderInterface;
12
use Sylius\Component\Core\Model\OrderItemInterface;
13
use Sylius\Component\Core\Model\ProductInterface;
14
use Sylius\Component\Core\Model\ProductVariantInterface;
15
use Sylius\Component\Core\Model\ShipmentInterface;
16
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
17
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
18
use Sylius\Component\Core\Repository\ProductVariantRepositoryInterface;
19
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
20
use Sylius\Component\Order\Processor\OrderProcessorInterface;
21
use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
22
use Sylius\Component\Registry\ServiceRegistryInterface;
23
use Sylius\Component\Resource\Factory\FactoryInterface;
24
use Sylius\Component\Shipping\Exception\UnresolvedDefaultShippingMethodException;
25
use Sylius\Component\Shipping\Resolver\ShippingMethodsResolverInterface;
26
use Sylius\ShopApiPlugin\Factory\PriceViewFactoryInterface;
27
use Sylius\ShopApiPlugin\View\EstimatedShippingCostView;
28
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
29
use Symfony\Component\HttpFoundation\Request;
30
use Symfony\Component\HttpFoundation\Response;
31
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
32
33
final class CartController extends Controller
34
{
35
    /**
36
     * @param Request $request
37
     *
38
     * @return Response
39
     */
40
    public function addAction(Request $request)
41
    {
42
        /** @var OrderRepositoryInterface $cartRepository */
43
        $cartRepository = $this->get('sylius.repository.order');
44
        /** @var ObjectManager $cartManager */
45
        $cartManager = $this->get('sylius.manager.order');
46
        /** @var ViewHandlerInterface $viewHandler */
47
        $viewHandler = $this->get('fos_rest.view_handler');
48
        /** @var CartItemFactoryInterface $cartItemFactory */
49
        $cartItemFactory = $this->get('sylius.factory.order_item');
50
        /** @var OrderItemQuantityModifierInterface $orderItemModifier */
51
        $orderItemModifier = $this->get('sylius.order_item_quantity_modifier');
52
        /** @var OrderProcessorInterface $orderProcessor */
53
        $orderProcessor = $this->get('sylius.order_processing.order_processor');
54
55
        /** @var OrderInterface $cart */
56
        $cart = $cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);
57
58
        if (null === $cart) {
59
            throw new NotFoundHttpException('Cart with given id does not exists');
60
        }
61
62
        $productVariant = $this->resolveVariant($request);
63
64
        if (null === $productVariant) {
65
            throw new NotFoundHttpException('Variant not found for given configuration');
66
        }
67
68
        /** @var OrderItemInterface $cartItem */
69
        $cartItem = $cartItemFactory->createForCart($cart);
70
        $cartItem->setVariant($productVariant);
71
        $orderItemModifier->modify($cartItem, $request->request->getInt('quantity'));
72
73
        $cart->addItem($cartItem);
74
75
        $orderProcessor->process($cart);
76
77
        $cartManager->flush();
78
79
        return $viewHandler->handle(View::create(null, Response::HTTP_CREATED));
80
    }
81
82
    /**
83
     * @param Request $request
84
     *
85
     * @return Response
86
     */
87
    public function dropAction(Request $request)
88
    {
89
        /** @var OrderRepositoryInterface $cartRepository */
90
        $cartRepository = $this->get('sylius.repository.order');
91
        /** @var ViewHandlerInterface $viewHandler */
92
        $viewHandler = $this->get('fos_rest.view_handler');
93
94
        $cart = $cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);
95
96
        if (null === $cart) {
97
            throw new NotFoundHttpException('Cart with given id does not exists');
98
        }
99
100
        $cartRepository->remove($cart);
101
102
        return $viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
103
    }
104
105
    /**
106
     * @param Request $request
107
     *
108
     * @return Response
109
     */
110
    public function changeItemQuantityAction(Request $request)
111
    {
112
        /** @var ObjectManager $cartManager */
113
        $cartManager = $this->get('sylius.manager.order');
114
        /** @var ViewHandlerInterface $viewHandler */
115
        $viewHandler = $this->get('fos_rest.view_handler');
116
        /** @var OrderItemRepositoryInterface $orderItemRepository */
117
        $cartItemRepository = $this->get('sylius.repository.order_item');
118
        /** @var OrderItemQuantityModifierInterface $orderItemModifier */
119
        $orderItemModifier = $this->get('sylius.order_item_quantity_modifier');
120
        /** @var OrderProcessorInterface $orderProcessor */
121
        $orderProcessor = $this->get('sylius.order_processing.order_processor');
122
        /** @var OrderRepositoryInterface $cartRepository */
123
        $cartRepository = $this->get('sylius.repository.order');
124
125
        $cart = $cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);
126
127
        if (null === $cart) {
128
            throw new NotFoundHttpException('Cart with given id does not exists');
129
        }
130
131
        /** @var OrderInterface $cart */
132
        $cartItem = $cartItemRepository->find($request->attributes->get('id'));
133
134
        if (null === $cartItem || !$cart->hasItem($cartItem)) {
135
            throw new NotFoundHttpException('Cart item with given id does not exists');
136
        }
137
138
        $orderItemModifier->modify($cartItem, $request->request->getInt('quantity'));
139
140
        $orderProcessor->process($cart);
141
142
        $cartManager->flush();
143
144
        return $viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
145
    }
146
147
    /**
148
     * @param Request $request
149
     *
150
     * @return Response
151
     */
152
    public function removeItemAction(Request $request)
153
    {
154
        /** @var OrderRepositoryInterface $cartRepository */
155
        $cartRepository = $this->get('sylius.repository.order');
156
        /** @var ViewHandlerInterface $viewHandler */
157
        $viewHandler = $this->get('fos_rest.view_handler');
158
        /** @var OrderItemRepositoryInterface $orderItemRepository */
159
        $cartItemRepository = $this->get('sylius.repository.order_item');
160
161
        $cart = $cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);
162
163
        if (null === $cart) {
164
            throw new NotFoundHttpException('Cart with given id does not exists');
165
        }
166
167
        /** @var OrderInterface $cart */
168
        $cartItem = $cartItemRepository->find($request->attributes->get('id'));
169
170
        if (null === $cartItem || !$cart->hasItem($cartItem)) {
171
            throw new NotFoundHttpException('Cart item with given id does not exists');
172
        }
173
174
        $cart->removeItem($cartItem);
175
        $cartItemRepository->remove($cartItem);
176
177
        return $viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
178
    }
179
180
    /**
181
     * @param Request $request
182
     *
183
     * @return Response
184
     */
185
    public function estimateShippingCostAction(Request $request)
186
    {
187
        /** @var OrderRepositoryInterface $cartRepository */
188
        $cartRepository = $this->get('sylius.repository.order');
189
        /** @var ViewHandlerInterface $viewHandler */
190
        $viewHandler = $this->get('fos_rest.view_handler');
191
        /** @var ShippingMethodsResolverInterface $shippingMethodResolver */
192
        $shippingMethodResolver = $this->get('sylius.shipping_methods_resolver');
193
        /** @var AddressFactoryInterface $addressFactory */
194
        $addressFactory = $this->get('sylius.factory.address');
195
        /** @var FactoryInterface $shipmentFactory */
196
        $shipmentFactory = $this->get('sylius.factory.shipment');
197
        /** @var ServiceRegistryInterface $calculators */
198
        $calculators = $this->get('sylius.registry.shipping_calculator');
199
        /** @var PriceViewFactoryInterface $priceViewFactory */
200
        $priceViewFactory = $this->get('sylius.shop_api_plugin.factory.price_view_factory');
201
202
        /** @var OrderInterface $cart */
203
        $cart = $cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);
204
205
        if (null === $cart) {
206
            throw new NotFoundHttpException('Cart with given id does not exists');
207
        }
208
209
        /** @var AddressInterface $address */
210
        $address = $addressFactory->createNew();
211
        $address->setCountryCode($request->query->get('countryCode'));
212
        $address->setProvinceCode($request->query->get('provinceCode'));
213
        $cart->setShippingAddress($address);
214
215
        /** @var ShipmentInterface $shipment */
216
        $shipment = $shipmentFactory->createNew();
217
        $shipment->setOrder($cart);
218
219
        $shippingMethods = $shippingMethodResolver->getSupportedMethods($shipment);
220
221
        if (empty($shippingMethods)) {
222
            throw new UnresolvedDefaultShippingMethodException();
223
        }
224
225
        $shippingMethod = $shippingMethods[0];
226
227
        $estimatedShippingCostView = new EstimatedShippingCostView();
228
        $calculator = $calculators->get($shippingMethod->getCalculator());
229
230
        $estimatedShippingCostView->price = $priceViewFactory->create($calculator->calculate($shipment, $shippingMethod->getConfiguration()));
231
232
        return $viewHandler->handle(View::create($estimatedShippingCostView, Response::HTTP_OK));
233
    }
234
235
    /**
236
     * @param Request $request
237
     *
238
     * @return null|ProductVariantInterface
239
     */
240
    private function resolveVariant(Request $request)
241
    {
242
        /** @var ProductRepositoryInterface $productRepository */
243
        $productRepository = $this->get('sylius.repository.product');
244
245
        /** @var ProductInterface $product */
246
        $product = $productRepository->findOneBy(['code' => $request->request->get('productCode')]);
247
248
        if ($product->isSimple()) {
249
            return $product->getVariants()[0];
250
        }
251
252
        if ($product->hasOptions()){
253
            return $this->getVariant($request->request->get('options'), $product);
254
        }
255
256
        /** @var ProductVariantRepositoryInterface $productVariantRepository */
257
        $productVariantRepository = $this->get('sylius.repository.product_variant');
258
259
        return $productVariantRepository->findOneByCodeAndProductCode($request->request->get('variantCode'), $request->request->get('productCode'));
260
    }
261
262
    /**
263
     * @param array $options
264
     * @param ProductInterface $product
265
     *
266
     * @return null|ProductVariantInterface
267
     */
268
    private function getVariant(array $options, ProductInterface $product)
269
    {
270
        foreach ($product->getVariants() as $variant) {
271
            foreach ($variant->getOptionValues() as $optionValue) {
272
                if (!isset($options[$optionValue->getOptionCode()]) || $optionValue->getCode() !== $options[$optionValue->getOptionCode()]) {
273
                    continue 2;
274
                }
275
            }
276
277
            return $variant;
278
        }
279
280
        return null;
281
    }
282
}
283