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

OrderContext::addSingleProductVariantToOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 17
rs 9.4285
nc 1
cc 1
eloc 9
nop 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A OrderContext::theCustomerBoughtProductAndProduct() 0 5 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\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