Completed
Push — 1.2-commands ( 515a1b )
by Kamil
131:33 queued 110:12
created

OrderFixture::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 30
nc 1
nop 14

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
declare(strict_types=1);
13
14
namespace Sylius\Bundle\CoreBundle\Fixture;
15
16
use Doctrine\Common\Persistence\ObjectManager;
17
use SM\Factory\FactoryInterface as StateMachineFactoryInterface;
18
use Sylius\Bundle\FixturesBundle\Fixture\AbstractFixture;
19
use Sylius\Component\Core\Checker\OrderPaymentMethodSelectionRequirementCheckerInterface;
20
use Sylius\Component\Core\Checker\OrderShippingMethodSelectionRequirementCheckerInterface;
21
use Sylius\Component\Core\Model\AddressInterface;
22
use Sylius\Component\Core\Model\OrderInterface;
23
use Sylius\Component\Core\OrderCheckoutTransitions;
24
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
25
use Sylius\Component\Core\Repository\ShippingMethodRepositoryInterface;
26
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
27
use Sylius\Component\Resource\Factory\FactoryInterface;
28
use Sylius\Component\Resource\Repository\RepositoryInterface;
29
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
30
use Webmozart\Assert\Assert;
31
32
class OrderFixture extends AbstractFixture
33
{
34
    /**
35
     * @var FactoryInterface
36
     */
37
    private $orderFactory;
38
39
    /**
40
     * @var FactoryInterface
41
     */
42
    private $orderItemFactory;
43
44
    /**
45
     * @var OrderItemQuantityModifierInterface
46
     */
47
    private $orderItemQuantityModifier;
48
49
    /**
50
     * @var ObjectManager
51
     */
52
    private $orderManager;
53
54
    /**
55
     * @var RepositoryInterface
56
     */
57
    private $channelRepository;
58
59
    /**
60
     * @var RepositoryInterface
61
     */
62
    private $customerRepository;
63
64
    /**
65
     * @var RepositoryInterface
66
     */
67
    private $productRepository;
68
69
    /**
70
     * @var RepositoryInterface
71
     */
72
    private $countryRepository;
73
74
    /**
75
     * @var PaymentMethodRepositoryInterface
76
     */
77
    private $paymentMethodRepository;
78
79
    /**
80
     * @var ShippingMethodRepositoryInterface
81
     */
82
    private $shippingMethodRepository;
83
84
    /**
85
     * @var FactoryInterface
86
     */
87
    private $addressFactory;
88
89
    /**
90
     * @var StateMachineFactoryInterface
91
     */
92
    private $stateMachineFactory;
93
94
    /**
95
     * @var OrderShippingMethodSelectionRequirementCheckerInterface
96
     */
97
    private $orderShippingMethodSelectionRequirementChecker;
98
99
    /**
100
     * @var OrderPaymentMethodSelectionRequirementCheckerInterface
101
     */
102
    private $orderPaymentMethodSelectionRequirementChecker;
103
104
    /**
105
     * @var \Faker\Generator
106
     */
107
    private $faker;
108
109
    /**
110
     * @param FactoryInterface $orderFactory
111
     * @param FactoryInterface $orderItemFactory
112
     * @param OrderItemQuantityModifierInterface $orderItemQuantityModifier
113
     * @param ObjectManager $orderManager
114
     * @param RepositoryInterface $channelRepository
115
     * @param RepositoryInterface $customerRepository
116
     * @param RepositoryInterface $productRepository
117
     * @param RepositoryInterface $countryRepository
118
     * @param PaymentMethodRepositoryInterface $paymentMethodRepository
119
     * @param ShippingMethodRepositoryInterface $shippingMethodRepository
120
     * @param FactoryInterface $addressFactory
121
     * @param StateMachineFactoryInterface $stateMachineFactory
122
     * @param OrderShippingMethodSelectionRequirementCheckerInterface $orderShippingMethodSelectionRequirementChecker
123
     * @param OrderPaymentMethodSelectionRequirementCheckerInterface $orderPaymentMethodSelectionRequirementChecker
124
     */
125
    public function __construct(
126
        FactoryInterface $orderFactory,
127
        FactoryInterface $orderItemFactory,
128
        OrderItemQuantityModifierInterface $orderItemQuantityModifier,
129
        ObjectManager $orderManager,
130
        RepositoryInterface $channelRepository,
131
        RepositoryInterface $customerRepository,
132
        RepositoryInterface $productRepository,
133
        RepositoryInterface $countryRepository,
134
        PaymentMethodRepositoryInterface $paymentMethodRepository,
135
        ShippingMethodRepositoryInterface $shippingMethodRepository,
136
        FactoryInterface $addressFactory,
137
        StateMachineFactoryInterface $stateMachineFactory,
138
        OrderShippingMethodSelectionRequirementCheckerInterface $orderShippingMethodSelectionRequirementChecker,
139
        OrderPaymentMethodSelectionRequirementCheckerInterface $orderPaymentMethodSelectionRequirementChecker
140
    ) {
141
        $this->orderFactory = $orderFactory;
142
        $this->orderItemFactory = $orderItemFactory;
143
        $this->orderItemQuantityModifier = $orderItemQuantityModifier;
144
        $this->orderManager = $orderManager;
145
        $this->channelRepository = $channelRepository;
146
        $this->customerRepository = $customerRepository;
147
        $this->productRepository = $productRepository;
148
        $this->countryRepository = $countryRepository;
149
        $this->paymentMethodRepository = $paymentMethodRepository;
150
        $this->shippingMethodRepository = $shippingMethodRepository;
151
        $this->addressFactory = $addressFactory;
152
        $this->stateMachineFactory = $stateMachineFactory;
153
        $this->orderShippingMethodSelectionRequirementChecker = $orderShippingMethodSelectionRequirementChecker;
154
        $this->orderPaymentMethodSelectionRequirementChecker = $orderPaymentMethodSelectionRequirementChecker;
155
156
        $this->faker = \Faker\Factory::create();
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162
    public function load(array $options): void
163
    {
164
        $channels = $this->channelRepository->findAll();
165
        $customers = $this->customerRepository->findAll();
166
        $countries = $this->countryRepository->findAll();
167
168
        for ($i = 0; $i < $options['amount']; ++$i) {
169
            $channel = $this->faker->randomElement($channels);
170
            $customer = $this->faker->randomElement($customers);
171
            $countryCode = $this->faker->randomElement($countries)->getCode();
172
173
            $currencyCode = $channel->getBaseCurrency()->getCode();
174
            $localeCode = $this->faker->randomElement($channel->getLocales()->toArray())->getCode();
175
176
            $order = $this->orderFactory->createNew();
177
            $order->setChannel($channel);
178
            $order->setCustomer($customer);
179
            $order->setCurrencyCode($currencyCode);
180
            $order->setLocaleCode($localeCode);
181
182
            $this->generateItems($order);
183
184
            $this->address($order, $countryCode);
185
            $this->selectShipping($order);
186
            $this->selectPayment($order);
187
            $this->completeCheckout($order);
188
189
            $this->orderManager->persist($order);
190
191
            if (0 === ($i % 50)) {
192
                $this->orderManager->flush();
193
            }
194
        }
195
196
        $this->orderManager->flush();
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function getName(): string
203
    {
204
        return 'order';
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210
    protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void
211
    {
212
        $optionsNode
213
            ->children()
214
                ->integerNode('amount')->isRequired()->min(0)->end()
215
        ;
216
    }
217
218
    /**
219
     * @param OrderInterface $order
220
     */
221
    private function generateItems(OrderInterface $order): void
222
    {
223
        $numberOfItems = random_int(1, 5);
224
        $products = $this->productRepository->findAll();
225
226
        for ($i = 0; $i < $numberOfItems; ++$i) {
227
            $item = $this->orderItemFactory->createNew();
228
229
            $product = $this->faker->randomElement($products);
230
            $variant = $this->faker->randomElement($product->getVariants()->toArray());
231
232
            $item->setVariant($variant);
233
            $this->orderItemQuantityModifier->modify($item, random_int(1, 5));
234
235
            $order->addItem($item);
236
        }
237
    }
238
239
    /**
240
     * @param OrderInterface $order
241
     * @param string $countryCode
242
     */
243
    private function address(OrderInterface $order, string $countryCode): void
244
    {
245
        /** @var AddressInterface $address */
246
        $address = $this->addressFactory->createNew();
247
        $address->setFirstName($this->faker->firstName);
248
        $address->setLastName($this->faker->lastName);
249
        $address->setStreet($this->faker->streetName);
250
        $address->setCountryCode($countryCode);
251
        $address->setCity($this->faker->city);
252
        $address->setPostcode($this->faker->postcode);
253
254
        $order->setShippingAddress($address);
255
        $order->setBillingAddress(clone $address);
256
257
        $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_ADDRESS);
258
    }
259
260
    /**
261
     * @param OrderInterface $order
262
     */
263
    private function selectShipping(OrderInterface $order): void
264
    {
265
        $shippingMethod = $this
266
            ->faker
267
            ->randomElement($this->shippingMethodRepository->findEnabledForChannel($order->getChannel()))
268
        ;
269
        Assert::notNull($shippingMethod, 'Shipping method should not be null.');
270
271
        foreach ($order->getShipments() as $shipment) {
272
            $shipment->setMethod($shippingMethod);
273
        }
274
275
        if ($this->orderShippingMethodSelectionRequirementChecker->isShippingMethodSelectionRequired($order)) {
276
            $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_SELECT_SHIPPING);
277
        }
278
    }
279
280
    /**
281
     * @param OrderInterface $order
282
     */
283
    private function selectPayment(OrderInterface $order): void
284
    {
285
        $paymentMethod = $this
286
            ->faker
287
            ->randomElement($this->paymentMethodRepository->findEnabledForChannel($order->getChannel()))
288
        ;
289
        Assert::notNull($paymentMethod, 'Payment method should not be null.');
290
291
        foreach ($order->getPayments() as $payment) {
292
            $payment->setMethod($paymentMethod);
293
        }
294
295
        if ($this->orderPaymentMethodSelectionRequirementChecker->isPaymentMethodSelectionRequired($order)) {
296
            $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT);
297
        }
298
    }
299
300
    /**
301
     * @param OrderInterface $order
302
     */
303
    private function completeCheckout(OrderInterface $order): void
304
    {
305
        if ($this->faker->boolean(25)) {
306
            $order->setNotes($this->faker->sentence);
307
        }
308
309
        $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_COMPLETE);
310
    }
311
312
    /**
313
     * @param OrderInterface $order
314
     * @param string $transition
315
     */
316
    private function applyCheckoutStateTransition(OrderInterface $order, string $transition): void
317
    {
318
        $this->stateMachineFactory->get($order, OrderCheckoutTransitions::GRAPH)->apply($transition);
319
    }
320
}
321