Completed
Push — 1.0-conflicts ( 05c08f )
by Kamil
54:56
created

PromotionContext::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
nc 1
cc 1
eloc 15
nop 7
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\Behat\Context\Setup;
15
16
use Behat\Behat\Context\Context;
17
use Doctrine\Common\Persistence\ObjectManager;
18
use Sylius\Behat\Service\SharedStorageInterface;
19
use Sylius\Component\Core\Factory\PromotionActionFactoryInterface;
20
use Sylius\Component\Core\Factory\PromotionRuleFactoryInterface;
21
use Sylius\Component\Core\Model\ChannelInterface;
22
use Sylius\Component\Core\Model\ProductInterface;
23
use Sylius\Component\Core\Model\PromotionCouponInterface;
24
use Sylius\Component\Core\Model\PromotionInterface;
25
use Sylius\Component\Core\Model\TaxonInterface;
26
use Sylius\Component\Core\Promotion\Checker\Rule\CustomerGroupRuleChecker;
27
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
28
use Sylius\Component\Customer\Model\CustomerGroupInterface;
29
use Sylius\Component\Promotion\Factory\PromotionCouponFactoryInterface;
30
use Sylius\Component\Promotion\Model\PromotionActionInterface;
31
use Sylius\Component\Promotion\Model\PromotionRuleInterface;
32
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
33
34
final class PromotionContext implements Context
35
{
36
    /**
37
     * @var SharedStorageInterface
38
     */
39
    private $sharedStorage;
40
41
    /**
42
     * @var PromotionActionFactoryInterface
43
     */
44
    private $actionFactory;
45
46
    /**
47
     * @var PromotionCouponFactoryInterface
48
     */
49
    private $couponFactory;
50
51
    /**
52
     * @var PromotionRuleFactoryInterface
53
     */
54
    private $ruleFactory;
55
56
    /**
57
     * @var TestPromotionFactoryInterface
58
     */
59
    private $testPromotionFactory;
60
61
    /**
62
     * @var PromotionRepositoryInterface
63
     */
64
    private $promotionRepository;
65
66
    /**
67
     * @var ObjectManager
68
     */
69
    private $objectManager;
70
71
    /**
72
     * @param SharedStorageInterface $sharedStorage
73
     * @param PromotionActionFactoryInterface $actionFactory
74
     * @param PromotionCouponFactoryInterface $couponFactory
75
     * @param PromotionRuleFactoryInterface $ruleFactory
76
     * @param TestPromotionFactoryInterface $testPromotionFactory
77
     * @param PromotionRepositoryInterface $promotionRepository
78
     * @param ObjectManager $objectManager
79
     */
80
    public function __construct(
81
        SharedStorageInterface $sharedStorage,
82
        PromotionActionFactoryInterface $actionFactory,
83
        PromotionCouponFactoryInterface $couponFactory,
84
        PromotionRuleFactoryInterface $ruleFactory,
85
        TestPromotionFactoryInterface $testPromotionFactory,
86
        PromotionRepositoryInterface $promotionRepository,
87
        ObjectManager $objectManager
88
    ) {
89
        $this->sharedStorage = $sharedStorage;
90
        $this->actionFactory = $actionFactory;
91
        $this->couponFactory = $couponFactory;
92
        $this->ruleFactory = $ruleFactory;
93
        $this->testPromotionFactory = $testPromotionFactory;
94
        $this->promotionRepository = $promotionRepository;
95
        $this->objectManager = $objectManager;
96
    }
97
98
    /**
99
     * @Given there is a promotion :promotionName
100
     * @Given there is a promotion :promotionName identified by :promotionCode code
101
     */
102
    public function thereIsPromotion($promotionName, $promotionCode = null)
103
    {
104
        $promotion = $this->testPromotionFactory
105
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
106
        ;
107
108
        if (null !== $promotionCode) {
109
            $promotion->setCode($promotionCode);
110
        }
111
112
        $this->promotionRepository->add($promotion);
113
        $this->sharedStorage->set('promotion', $promotion);
114
    }
115
116
    /**
117
     * @Given /^there is a promotion "([^"]+)" with priority ([^"]+)$/
118
     */
119
    public function thereIsAPromotionWithPriority($promotionName, $priority)
120
    {
121
        $promotion = $this->testPromotionFactory
122
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
123
        ;
124
125
        $promotion->setPriority((int) $priority);
126
127
        $this->promotionRepository->add($promotion);
128
        $this->sharedStorage->set('promotion', $promotion);
129
    }
130
131
    /**
132
     * @Given /^there is an exclusive promotion "([^"]+)"(?:| with priority ([^"]+))$/
133
     */
134
    public function thereIsAnExclusivePromotionWithPriority($promotionName, $priority = 0)
135
    {
136
        $promotion = $this->testPromotionFactory
137
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
138
        ;
139
140
        $promotion->setExclusive(true);
141
        $promotion->setPriority((int) $priority);
142
143
        $this->promotionRepository->add($promotion);
144
        $this->sharedStorage->set('promotion', $promotion);
145
    }
146
147
    /**
148
     * @Given there is a promotion :promotionName limited to :usageLimit usages
149
     */
150
    public function thereIsPromotionLimitedToUsages($promotionName, $usageLimit)
151
    {
152
        $promotion = $this->testPromotionFactory->createForChannel($promotionName, $this->sharedStorage->get('channel'));
153
154
        $promotion->setUsageLimit((int) $usageLimit);
155
156
        $this->promotionRepository->add($promotion);
157
        $this->sharedStorage->set('promotion', $promotion);
158
    }
159
160
    /**
161
     * @Given the store has promotion :promotionName with coupon :couponCode
162
     * @Given the store has a promotion :promotionName with a coupon :couponCode that is limited to :usageLimit usages
163
     */
164
    public function thereIsPromotionWithCoupon($promotionName, $couponCode, $usageLimit = null)
165
    {
166
        /** @var PromotionCouponInterface $coupon */
167
        $coupon = $this->couponFactory->createNew();
168
        $coupon->setCode($couponCode);
169
        $coupon->setUsageLimit((null === $usageLimit) ? null : (int) $usageLimit);
170
171
        $promotion = $this->testPromotionFactory
172
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
173
        ;
174
        $promotion->addCoupon($coupon);
175
        $promotion->setCouponBased(true);
176
177
        $this->promotionRepository->add($promotion);
178
179
        $this->sharedStorage->set('promotion', $promotion);
180
        $this->sharedStorage->set('coupon', $coupon);
181
    }
182
183
    /**
184
     * @Given /^(this promotion) has already expired$/
185
     */
186
    public function thisPromotionHasExpired(PromotionInterface $promotion)
187
    {
188
        $promotion->setEndsAt(new \DateTime('1 day ago'));
189
190
        $this->objectManager->flush();
191
    }
192
193
    /**
194
     * @Given /^(this promotion) expires tomorrow$/
195
     */
196
    public function thisPromotionExpiresTomorrow(PromotionInterface $promotion)
197
    {
198
        $promotion->setEndsAt(new \DateTime('tomorrow'));
199
200
        $this->objectManager->flush();
201
    }
202
203
    /**
204
     * @Given /^(this promotion) has started yesterday$/
205
     */
206
    public function thisPromotionHasStartedYesterday(PromotionInterface $promotion)
207
    {
208
        $promotion->setStartsAt(new \DateTime('1 day ago'));
209
210
        $this->objectManager->flush();
211
    }
212
213
    /**
214
     * @Given /^(this promotion) starts tomorrow$/
215
     */
216
    public function thisPromotionStartsTomorrow(PromotionInterface $promotion)
217
    {
218
        $promotion->setStartsAt(new \DateTime('tomorrow'));
219
220
        $this->objectManager->flush();
221
    }
222
223
    /**
224
     * @Given /^(this coupon) has already expired$/
225
     */
226
    public function thisCouponHasExpired(PromotionCouponInterface $coupon)
227
    {
228
        $coupon->setExpiresAt(new \DateTime('1 day ago'));
229
230
        $this->objectManager->flush();
231
    }
232
233
    /**
234
     * @Given /^(this coupon) expires tomorrow$/
235
     */
236
    public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon)
237
    {
238
        $coupon->setExpiresAt(new \DateTime('tomorrow'));
239
240
        $this->objectManager->flush();
241
    }
242
243
    /**
244
     * @Given /^(this coupon) has already reached its usage limit$/
245
     */
246
    public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon)
247
    {
248
        $coupon->setUsed(42);
249
        $coupon->setUsageLimit(42);
250
251
        $this->objectManager->flush();
252
    }
253
254
    /**
255
     * @Given /^(this coupon) can be used (\d+) times?$/
256
     */
257
    public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, $usageLimit)
258
    {
259
        $coupon->setUsageLimit((int) $usageLimit);
260
261
        $this->objectManager->flush();
262
    }
263
264
    /**
265
     * @Given /^(this coupon) can be used twice per customer$/
266
     */
267
    public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon)
268
    {
269
        $coupon->setPerCustomerUsageLimit(2);
270
271
        $this->objectManager->flush();
272
    }
273
274
    /**
275
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/
276
     */
277
    public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount)
278
    {
279
        $this->createFixedPromotion($promotion, $discount);
280
    }
281
282
    /**
283
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/
284
     */
285
    public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel(
286
        PromotionInterface $promotion,
287
        $firstChannelDiscount,
288
        ChannelInterface $firstChannel,
289
        $secondChannelDiscount,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $secondChannelDiscount exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
290
        ChannelInterface $secondChannel
291
    ) {
292
        /** @var PromotionActionInterface $action */
293
        $action = $this->actionFactory->createFixedDiscount($firstChannelDiscount, $firstChannel->getCode());
294
        $action->setConfiguration(array_merge($action->getConfiguration(), [$secondChannel->getCode() => ['amount' => $secondChannelDiscount]]));
295
296
        $promotion->addChannel($firstChannel);
297
        $promotion->addChannel($secondChannel);
298
        $promotion->addAction($action);
299
300
        $this->objectManager->flush();
301
    }
302
303
    /**
304
     * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/
305
     */
306
    public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount)
307
    {
308
        $this->createPercentagePromotion($promotion, $discount);
309
    }
310
311
    /**
312
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/
313
     */
314
    public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast(
315
        PromotionInterface $promotion,
316
        $discount,
317
        $quantity
318
    ) {
319
        $rule = $this->ruleFactory->createCartQuantity((int) $quantity);
320
321
        $this->createFixedPromotion($promotion, $discount, [], $rule);
322
    }
323
324
    /**
325
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/
326
     */
327
    public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast(
328
        PromotionInterface $promotion,
329
        $discount,
330
        $targetAmount
331
    ) {
332
        $channelCode = $this->sharedStorage->get('channel')->getCode();
333
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
334
335
        $this->createFixedPromotion($promotion, $discount, [], $rule);
336
    }
337
338
    /**
339
     * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/
340
     */
341
    public function itGivesOffOnEveryItemWhenItemTotalExceeds(
342
        PromotionInterface $promotion,
343
        $discount,
344
        $targetAmount
345
    ) {
346
        $channelCode = $this->sharedStorage->get('channel')->getCode();
347
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
348
349
        $this->createUnitPercentagePromotion($promotion, $discount, [], $rule);
350
    }
351
352
    /**
353
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/
354
     */
355
    public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount)
356
    {
357
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
358
        $promotion->addAction($action);
359
360
        $this->objectManager->flush();
361
    }
362
363
    /**
364
     * @Given /^([^"]+) gives free shipping to every order$/
365
     */
366
    public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion)
367
    {
368
        $this->itGivesPercentageDiscountOnShippingToEveryOrder($promotion, 1);
369
    }
370
371
    /**
372
     * @Given /^([^"]+) gives(?:| another) ("[^"]+%") off every product (classified as "[^"]+")$/
373
     */
374
    public function itGivesPercentageOffEveryProductClassifiedAs(
375
        PromotionInterface $promotion,
376
        $discount,
377
        TaxonInterface $taxon
378
    ) {
379
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
380
    }
381
382
    /**
383
     * @Given /^([^"]+) gives(?:| another) ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/
384
     */
385
    public function itGivesFixedOffEveryProductClassifiedAs(
386
        PromotionInterface $promotion,
387
        $discount,
388
        TaxonInterface $taxon
389
    ) {
390
        $this->createUnitFixedPromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
391
    }
392
393
    /**
394
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
395
     */
396
    public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt(
397
        PromotionInterface $promotion,
398
        $discount,
399
        $amount
400
    ) {
401
        $this->createUnitFixedPromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
402
    }
403
404
    /**
405
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
406
     */
407
    public function thisPromotionGivesOffOnEveryProductPricedBetween(
408
        PromotionInterface $promotion,
409
        $discount,
410
        $minAmount,
411
        $maxAmount
412
    ) {
413
        $this->createUnitFixedPromotion(
414
            $promotion,
415
            $discount,
416
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
417
        );
418
    }
419
420
    /**
421
     * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
422
     */
423
    public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt(
424
        PromotionInterface $promotion,
425
        $discount,
426
        $amount
427
    ) {
428
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
429
    }
430
431
    /**
432
     * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
433
     */
434
    public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween(
435
        PromotionInterface $promotion,
436
        $discount,
437
        $minAmount,
438
        $maxAmount
439
    ) {
440
        $this->createUnitPercentagePromotion(
441
            $promotion,
442
            $discount,
443
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
444
        );
445
    }
446
447
    /**
448
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/
449
     */
450
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs(
451
        PromotionInterface $promotion,
452
        $discount,
453
        TaxonInterface $taxon
454
    ) {
455
        $rule = $this->ruleFactory->createHasTaxon([$taxon->getCode()]);
456
457
        $this->createFixedPromotion($promotion, $discount, [], $rule);
458
    }
459
460
    /**
461
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/
462
     */
463
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr(
464
        PromotionInterface $promotion,
465
        $discount,
466
        array $taxons
467
    ) {
468
        $rule = $this->ruleFactory->createHasTaxon([$taxons[0]->getCode(), $taxons[1]->getCode()]);
469
470
        $this->createFixedPromotion($promotion, $discount, [], $rule);
471
    }
472
473
    /**
474
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/
475
     */
476
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt(
477
        PromotionInterface $promotion,
478
        $discount,
479
        TaxonInterface $taxon,
480
        $amount
481
    ) {
482
        $channelCode = $this->sharedStorage->get('channel')->getCode();
483
        $rule = $this->ruleFactory->createItemsFromTaxonTotal($channelCode, $taxon->getCode(), $amount);
484
485
        $this->createFixedPromotion($promotion, $discount, [], $rule);
486
    }
487
488
    /**
489
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/
490
     */
491
    public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
492
    {
493
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
494
495
        $this->createFixedPromotion($promotion, $discount, [], $rule);
496
    }
497
498
    /**
499
     * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/
500
     */
501
    public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
502
    {
503
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
504
505
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
506
    }
507
508
    /**
509
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/
510
     */
511
    public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder(
512
        PromotionInterface $promotion,
513
        $productDiscount,
514
        TaxonInterface $discountTaxon,
515
        $orderDiscount
516
    ) {
517
        $this->createUnitPercentagePromotion($promotion, $productDiscount, $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]));
518
        $this->createFixedPromotion($promotion, $orderDiscount);
519
    }
520
521
    /**
522
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/
523
     */
524
    public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast(
525
        PromotionInterface $promotion,
526
        $discount,
527
        TaxonInterface $taxon,
0 ignored issues
show
Unused Code introduced by
The parameter $taxon is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
528
        $targetAmount
529
    ) {
530
        $freeShippingAction = $this->actionFactory->createShippingPercentageDiscount(1);
531
        $promotion->addAction($freeShippingAction);
532
533
        $channelCode = $this->sharedStorage->get('channel')->getCode();
534
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
535
536
        $this->createUnitFixedPromotion($promotion, $discount, [], $rule);
537
    }
538
539
    /**
540
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/
541
     */
542
    public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast(
543
        PromotionInterface $promotion,
544
        $taxonDiscount,
545
        TaxonInterface $taxon,
546
        $orderDiscount,
547
        $targetAmount
548
    ) {
549
        $orderDiscountAction = $this->actionFactory->createFixedDiscount($orderDiscount, $this->sharedStorage->get('channel')->getCode());
550
        $promotion->addAction($orderDiscountAction);
551
552
        $channelCode = $this->sharedStorage->get('channel')->getCode();
553
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
554
555
        $this->createUnitPercentagePromotion(
556
            $promotion,
557
            $taxonDiscount,
558
            $this->getTaxonFilterConfiguration([$taxon->getCode()]),
559
            $rule
560
        );
561
    }
562
563
    /**
564
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/
565
     */
566
    public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr(
567
        PromotionInterface $promotion,
568
        $discount,
569
        array $discountTaxons,
570
        array $targetTaxons
571
    ) {
572
        $discountTaxonsCodes = [$discountTaxons[0]->getCode(), $discountTaxons[1]->getCode()];
573
        $targetTaxonsCodes = [$targetTaxons[0]->getCode(), $targetTaxons[1]->getCode()];
574
575
        $rule = $this->ruleFactory->createHasTaxon($targetTaxonsCodes);
576
577
        $this->createUnitPercentagePromotion(
578
            $promotion,
579
            $discount,
580
            $this->getTaxonFilterConfiguration($discountTaxonsCodes),
581
            $rule
582
        );
583
    }
584
585
    /**
586
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/
587
     */
588
    public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs(
589
        PromotionInterface $promotion,
590
        $discount,
591
        $discountTaxon,
592
        $targetTaxon
593
    ) {
594
        $rule = $this->ruleFactory->createHasTaxon([$targetTaxon->getCode()]);
595
596
        $this->createUnitPercentagePromotion(
597
            $promotion,
598
            $discount,
599
            $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]),
600
            $rule
601
        );
602
    }
603
604
    /**
605
     * @Given /^(it) is coupon based promotion$/
606
     */
607
    public function itIsCouponBasedPromotion(PromotionInterface $promotion)
608
    {
609
        $promotion->setCouponBased(true);
610
611
        $this->objectManager->flush();
612
    }
613
614
    /**
615
     * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/
616
     */
617
    public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel)
618
    {
619
        $promotion->removeChannel($channel);
620
621
        $this->objectManager->flush();
622
    }
623
624
    /**
625
     * @Given /^the (coupon "[^"]+") was used up to its usage limit$/
626
     */
627
    public function theCouponWasUsed(PromotionCouponInterface $coupon)
628
    {
629
        $coupon->setUsed($coupon->getUsageLimit());
630
631
        $this->objectManager->flush();
632
    }
633
634
    /**
635
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/
636
     */
637
    public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product)
638
    {
639
        $rule = $this->ruleFactory->createContainsProduct($product->getCode());
640
641
        $this->createFixedPromotion($promotion, $discount, [], $rule);
642
    }
643
644
    /**
645
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/
646
     */
647
    public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
648
    {
649
        $this->createUnitFixedPromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
650
    }
651
652
    /**
653
     * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/
654
     */
655
    public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
656
    {
657
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
658
    }
659
660
    /**
661
     * @Given /^([^"]+) gives ("[^"]+%") off the order for customers from ("[^"]*" group)$/
662
     */
663
    public function thePromotionGivesOffTheOrderForCustomersFromGroup(
664
        PromotionInterface $promotion,
665
        $discount,
666
        CustomerGroupInterface $customerGroup
667
    ) {
668
        $rule = $this->ruleFactory->createNew();
669
        $rule->setType(CustomerGroupRuleChecker::TYPE);
670
        $rule->setConfiguration(['group_code' => $customerGroup->getCode()]);
671
672
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
673
    }
674
675
    /**
676
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order over ("(?:€|£|\$)[^"]+")$/
677
     */
678
    public function itGivesDiscountOnShippingToEveryOrderOver(
679
        PromotionInterface $promotion,
680
        $discount,
681
        $itemTotal
682
    ) {
683
        $channelCode = $this->sharedStorage->get('channel')->getCode();
684
        $rule = $this->ruleFactory->createItemTotal($channelCode, $itemTotal);
685
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
686
687
        $this->persistPromotion($promotion, $action, [], $rule);
688
    }
689
690
    /**
691
     * @Given /^([^"]+) gives free shipping to every order over ("(?:€|£|\$)[^"]+")$/
692
     */
693
    public function itGivesFreeShippingToEveryOrderOver(PromotionInterface $promotion, $itemTotal)
694
    {
695
        $this->itGivesDiscountOnShippingToEveryOrderOver($promotion, 1, $itemTotal);
696
    }
697
698
    /**
699
     * @param array $taxonCodes
700
     *
701
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string,array<string,array>>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
702
     */
703
    private function getTaxonFilterConfiguration(array $taxonCodes)
704
    {
705
        return ['filters' => ['taxons_filter' => ['taxons' => $taxonCodes]]];
706
    }
707
708
    /**
709
     * @param array $productCodes
710
     *
711
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string,array<string,array>>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
712
     */
713
    private function getProductsFilterConfiguration(array $productCodes)
714
    {
715
        return ['filters' => ['products_filter' => ['products' => $productCodes]]];
716
    }
717
718
    /**
719
     * @param int $minAmount
720
     * @param int $maxAmount
0 ignored issues
show
Documentation introduced by
Should the type for parameter $maxAmount not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
721
     *
722
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string,array<string,integer>>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
723
     */
724
    private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null)
725
    {
726
        $configuration = ['filters' => ['price_range_filter' => ['min' => $minAmount]]];
727
        if (null !== $maxAmount) {
728
            $configuration['filters']['price_range_filter']['max'] = $maxAmount;
729
        }
730
731
        return $configuration;
732
    }
733
734
    /**
735
     * @param PromotionInterface $promotion
736
     * @param int $discount
737
     * @param array $configuration
738
     * @param PromotionRuleInterface|null $rule
739
     */
740
    private function createUnitFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
741
    {
742
        $channelCode = $this->sharedStorage->get('channel')->getCode();
743
744
        $this->persistPromotion(
745
            $promotion,
746
            $this->actionFactory->createUnitFixedDiscount($discount, $channelCode),
747
            [$channelCode => $configuration],
748
            $rule
749
        );
750
    }
751
752
    /**
753
     * @param PromotionInterface $promotion
754
     * @param int $discount
755
     * @param array $configuration
756
     * @param PromotionRuleInterface|null $rule
757
     */
758
    private function createUnitPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
759
    {
760
        $channelCode = $this->sharedStorage->get('channel')->getCode();
761
762
        $this->persistPromotion(
763
            $promotion,
764
            $this->actionFactory->createUnitPercentageDiscount($discount, $channelCode),
765
            [$channelCode => $configuration],
766
            $rule
767
        );
768
    }
769
770
    /**
771
     * @param PromotionInterface $promotion
772
     * @param int $discount
773
     * @param array $configuration
774
     * @param PromotionRuleInterface|null $rule
775
     * @param ChannelInterface|null $channel
776
     */
777
    private function createFixedPromotion(
778
        PromotionInterface $promotion,
779
        $discount,
780
        array $configuration = [],
781
        PromotionRuleInterface $rule = null,
782
        ChannelInterface $channel = null
783
    ) {
784
        $channelCode = (null !== $channel) ? $channel->getCode() : $this->sharedStorage->get('channel')->getCode();
785
786
        $this->persistPromotion($promotion, $this->actionFactory->createFixedDiscount($discount, $channelCode), $configuration, $rule);
787
    }
788
789
    /**
790
     * @param PromotionInterface $promotion
791
     * @param float $discount
792
     * @param array $configuration
793
     * @param PromotionRuleInterface $rule
0 ignored issues
show
Documentation introduced by
Should the type for parameter $rule not be null|PromotionRuleInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
794
     */
795
    private function createPercentagePromotion(
796
        PromotionInterface $promotion,
797
        $discount,
798
        array $configuration = [],
799
        PromotionRuleInterface $rule = null
800
    ) {
801
        $this->persistPromotion($promotion, $this->actionFactory->createPercentageDiscount($discount), $configuration, $rule);
802
    }
803
804
    /**
805
     * @param PromotionInterface $promotion
806
     * @param PromotionActionInterface $action
807
     * @param array $configuration
808
     * @param PromotionRuleInterface|null $rule
809
     */
810
    private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null)
811
    {
812
        $configuration = array_merge_recursive($action->getConfiguration(), $configuration);
813
        $action->setConfiguration($configuration);
814
815
        $promotion->addAction($action);
816
        if (null !== $rule) {
817
            $promotion->addRule($rule);
818
        }
819
820
        $this->objectManager->flush();
821
    }
822
}
823