Completed
Push — master ( f9a038...cc9983 )
by Kamil
22:34
created

OrderContext::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 19

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 21
rs 9.3142
cc 1
eloc 19
nc 1
nop 9

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Behat\Context\Setup;
13
14
use Behat\Behat\Context\Context;
15
use Doctrine\Common\Persistence\ObjectManager;
16
use Sylius\Component\Core\Model\ChannelInterface;
17
use Sylius\Component\Core\Model\CouponInterface;
18
use Sylius\Component\Core\OrderProcessing\OrderRecalculatorInterface;
19
use Sylius\Component\Currency\Model\CurrencyInterface;
20
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
21
use Sylius\Component\Core\Model\AddressInterface;
22
use Sylius\Component\Core\Model\OrderInterface;
23
use Sylius\Component\Core\Model\OrderItemInterface;
24
use Sylius\Component\Core\Model\ProductInterface;
25
use Sylius\Component\Core\Model\ProductVariantInterface;
26
use Sylius\Component\Core\Model\ShippingMethodInterface;
27
use Sylius\Component\Core\OrderProcessing\OrderShipmentProcessorInterface;
28
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
29
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
30
use Sylius\Component\Payment\Factory\PaymentFactoryInterface;
31
use Sylius\Component\Payment\Model\PaymentInterface;
32
use Sylius\Component\Payment\Model\PaymentMethodInterface;
33
use Sylius\Component\Resource\Factory\FactoryInterface;
34
use Sylius\Component\User\Model\CustomerInterface;
35
use Sylius\Component\User\Model\UserInterface;
36
37
/**
38
 * @author Łukasz Chruściel <[email protected]>
39
 */
40
final class OrderContext implements Context
41
{
42
    /**
43
     * @var SharedStorageInterface
44
     */
45
    private $sharedStorage;
46
47
    /**
48
     * @var OrderRepositoryInterface
49
     */
50
    private $orderRepository;
51
52
    /**
53
     * @var FactoryInterface
54
     */
55
    private $orderFactory;
56
57
    /**
58
     * @var OrderShipmentProcessorInterface
59
     */
60
    private $orderShipmentFactory;
61
62
    /**
63
     * @var PaymentFactoryInterface
64
     */
65
    private $paymentFactory;
66
67
    /**
68
     * @var FactoryInterface
69
     */
70
    private $orderItemFactory;
71
72
    /**
73
     * @var OrderItemQuantityModifierInterface
74
     */
75
    private $itemQuantityModifier;
76
77
    /**
78
     * @var OrderRecalculatorInterface
79
     */
80
    private $orderRecalculator;
81
82
    /**
83
     * @var ObjectManager
84
     */
85
    private $objectManager;
86
87
    /**
88
     * @param SharedStorageInterface $sharedStorage
89
     * @param OrderRepositoryInterface $orderRepository
90
     * @param FactoryInterface $orderFactory
91
     * @param OrderShipmentProcessorInterface $orderShipmentFactory
92
     * @param PaymentFactoryInterface $paymentFactory
93
     * @param FactoryInterface $orderItemFactory
94
     * @param OrderItemQuantityModifierInterface $itemQuantityModifier
95
     * @param SharedStorageInterface $sharedStorage
96
     * @param OrderRecalculatorInterface $orderRecalculator
97
     * @param ObjectManager $objectManager
98
     */
99
    public function __construct(
100
        SharedStorageInterface $sharedStorage,
101
        OrderRepositoryInterface $orderRepository,
102
        FactoryInterface $orderFactory,
103
        OrderShipmentProcessorInterface $orderShipmentFactory,
104
        PaymentFactoryInterface $paymentFactory,
105
        FactoryInterface $orderItemFactory,
106
        OrderItemQuantityModifierInterface $itemQuantityModifier,
107
        OrderRecalculatorInterface $orderRecalculator,
108
        ObjectManager $objectManager
109
    ) {
110
        $this->sharedStorage = $sharedStorage;
111
        $this->orderRepository = $orderRepository;
112
        $this->orderFactory = $orderFactory;
113
        $this->orderShipmentFactory = $orderShipmentFactory;
114
        $this->paymentFactory = $paymentFactory;
115
        $this->orderItemFactory = $orderItemFactory;
116
        $this->itemQuantityModifier = $itemQuantityModifier;
117
        $this->orderRecalculator = $orderRecalculator;
118
        $this->objectManager = $objectManager;
119
    }
120
121
    /**
122
     * @Given there is a customer :customer that placed an order :orderNumber
123
     */
124
    public function thereIsCustomerThatPlacedOrder(CustomerInterface $customer, $orderNumber)
125
    {
126
        $order = $this->createOrder($customer, $orderNumber);
127
128
        $this->sharedStorage->set('order', $order);
129
130
        $this->orderRepository->add($order);
131
    }
132
133
    /**
134
     * @Given /^the customer ("[^"]+" addressed it to "[^"]+", "[^"]+" "[^"]+" in the "[^"]+")$/
135
     */
136
    public function theCustomerAddressedItTo(AddressInterface $address)
137
    {
138
        /** @var OrderInterface $order */
139
        $order = $this->sharedStorage->get('order');
140
        $order->setShippingAddress($address);
141
142
        $this->objectManager->flush();
143
    }
144
145
    /**
146
     * @Given /^for the billing address (of "[^"]+" in the "[^"]+", "[^"]+" "[^"]+", "[^"]+")$/
147
     */
148
    public function forTheBillingAddressOf(AddressInterface $address)
149
    {
150
        /** @var OrderInterface $order */
151
        $order = $this->sharedStorage->get('order');
152
153
        $order->setBillingAddress($address);
154
155
        $this->objectManager->flush();
156
    }
157
158
    /**
159
     * @Given /^the customer chose ("[^"]+" shipping method) (to "[^"]+") with ("[^"]+" payment)$/
160
     */
161
    public function theCustomerChoseShippingToWithPayment(
162
        ShippingMethodInterface $shippingMethod,
163
        AddressInterface $address,
164
        PaymentMethodInterface $paymentMethod
165
    ) {
166
        /** @var OrderInterface $order */
167
        $order = $this->sharedStorage->get('order');
168
169
        $this->orderShipmentFactory->processOrderShipment($order);
170
        $order->getShipments()->first()->setMethod($shippingMethod);
171
172
        $payment = $this->paymentFactory->createWithAmountAndCurrency($order->getTotal(), $order->getCurrency());
173
        $payment->setMethod($paymentMethod);
174
175
        $order->addPayment($payment);
176
177
        $order->setShippingAddress($address);
178
        $order->setBillingAddress($address);
179
180
        $this->orderRecalculator->recalculate($order);
181
182
        $this->objectManager->flush();
183
    }
184
185
    /**
186
     * @Given /^the customer chose ("[^"]+" shipping method) with ("[^"]+" payment)$/
187
     */
188
    public function theCustomerChoseShippingWithPayment(
189
        ShippingMethodInterface $shippingMethod,
190
        PaymentMethodInterface $paymentMethod
191
    ) {
192
        /** @var OrderInterface $order */
193
        $order = $this->sharedStorage->get('order');
194
195
        $this->orderShipmentFactory->processOrderShipment($order);
196
        $order->getShipments()->first()->setMethod($shippingMethod);
197
198
        $this->orderRecalculator->recalculate($order);
199
200
        $payment = $this->paymentFactory->createWithAmountAndCurrency($order->getTotal(), $order->getCurrency());
201
        $payment->setMethod($paymentMethod);
202
203
        $order->addPayment($payment);
204
205
        $this->objectManager->flush();
206
    }
207
208
    /**
209
     * @Given the customer bought a single :product
210
     */
211
    public function theCustomerBoughtSingleProduct(ProductInterface $product)
212
    {
213
        $this->addProductVariantToOrder($product->getMasterVariant(), $product->getPrice(), 1);
214
215
        $this->objectManager->flush();
216
    }
217
218
    /**
219
     * @Given /^the customer bought ((?:a|an) "[^"]+") and ((?:a|an) "[^"]+")$/
220
     */
221
    public function theCustomerBoughtProductAndProduct(ProductInterface $product, ProductInterface $secondProduct)
222
    {
223
        $this->theCustomerBoughtSingleProduct($product);
224
        $this->theCustomerBoughtSingleProduct($secondProduct);
225
    }
226
227
228
    /**
229
     * @Given /^the customer bought (\d+) ("[^"]+" products)/
230
     */
231
    public function theCustomerBoughtSeveralProducts($quantity, ProductInterface $product)
232
    {
233
        $this->addProductVariantToOrder($product->getMasterVariant(), $product->getPrice(), $quantity);
234
235
        $this->objectManager->flush();
236
    }
237
238
    /**
239
     * @Given /^the customer bought a single ("[^"]+" variant of product "[^"]+")$/
240
     */
241
    public function theCustomerBoughtSingleProductVariant(ProductVariantInterface $productVariant)
242
    {
243
        $this->addProductVariantToOrder($productVariant, $productVariant->getPrice());
244
245
        $this->objectManager->flush();
246
    }
247
248
    /**
249
     * @Given the customer bought a single :product using :coupon coupon
250
     */
251
    public function theCustomerBoughtSingleUsing(ProductInterface $product, CouponInterface $coupon)
252
    {
253
        $order = $this->addProductVariantToOrder($product->getMasterVariant(), $product->getPrice());
254
        $order->setPromotionCoupon($coupon);
255
256
        $this->orderRecalculator->recalculate($order);
257
258
        $this->objectManager->flush();
259
    }
260
261
    /**
262
     * @Given /^(I) have already placed an order (\d+) times$/
263
     */
264
    public function iHaveAlreadyPlacedOrderNthTimes(UserInterface $user, $numberOfOrders)
265
    {
266
        $customer = $user->getCustomer();
267
        for ($i = 0; $i < $numberOfOrders; $i++) {
268
            $order = $this->createOrder($customer, '#00000'.$i);
269
            $order->setPaymentState(PaymentInterface::STATE_COMPLETED);
270
            $order->setCompletedAt(new \DateTime());
271
272
            $this->orderRepository->add($order);
273
        }
274
    }
275
276
    /**
277
     * @param ProductVariantInterface $productVariant
278
     * @param int $price
279
     * @param int $quantity
280
     *
281
     * @return OrderInterface
282
     */
283
    private function addProductVariantToOrder(ProductVariantInterface $productVariant, $price, $quantity = 1)
284
    {
285
        $order = $this->sharedStorage->get('order');
286
287
        /** @var OrderItemInterface $item */
288
        $item = $this->orderItemFactory->createNew();
289
        $item->setVariant($productVariant);
290
        $item->setUnitPrice($price);
291
292
        $this->itemQuantityModifier->modify($item, $quantity);
293
294
        $order->addItem($item);
295
296
        $this->orderRecalculator->recalculate($order);
297
298
        return $order;
299
    }
300
301
    /**
302
     * @param CustomerInterface $customer
303
     * @param string $number
304
     * @param ChannelInterface|null $channel
305
     * @param CurrencyInterface|null $currency
306
     *
307
     * @return OrderInterface
308
     */
309
    private function createOrder(
310
        CustomerInterface $customer,
311
        $number,
312
        ChannelInterface $channel = null,
313
        CurrencyInterface $currency = null
314
    ) {
315
        $order = $this->orderFactory->createNew();
316
317
        $order->setCustomer($customer);
318
        $order->setNumber($number);
319
        $order->setChannel((null !== $channel) ? $channel : $this->sharedStorage->get('channel'));
320
        $order->setCurrency((null !== $currency) ? $currency : $this->sharedStorage->get('currency'));
321
        $order->complete();
322
323
        return $order;
324
    }
325
}
326