Completed
Push — missing-product-variant-variab... ( a08960 )
by Kamil
22:45
created

itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 3
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\Behat\Service\SharedStorageInterface;
17
use Sylius\Component\Core\Factory\PromotionActionFactoryInterface;
18
use Sylius\Component\Core\Factory\PromotionRuleFactoryInterface;
19
use Sylius\Component\Core\Model\ChannelInterface;
20
use Sylius\Component\Core\Model\ProductInterface;
21
use Sylius\Component\Core\Model\PromotionCouponInterface;
22
use Sylius\Component\Core\Model\PromotionInterface;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Sylius\Component\Core\Promotion\Checker\Rule\CustomerGroupRuleChecker;
25
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
26
use Sylius\Component\Customer\Model\CustomerGroupInterface;
27
use Sylius\Component\Promotion\Factory\PromotionCouponFactoryInterface;
28
use Sylius\Component\Promotion\Model\PromotionActionInterface;
29
use Sylius\Component\Promotion\Model\PromotionRuleInterface;
30
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
31
32
/**
33
 * @author Mateusz Zalewski <[email protected]>
34
 */
35
final class PromotionContext implements Context
36
{
37
    /**
38
     * @var SharedStorageInterface
39
     */
40
    private $sharedStorage;
41
42
    /**
43
     * @var PromotionActionFactoryInterface
44
     */
45
    private $actionFactory;
46
47
    /**
48
     * @var PromotionCouponFactoryInterface
49
     */
50
    private $couponFactory;
51
52
    /**
53
     * @var PromotionRuleFactoryInterface
54
     */
55
    private $ruleFactory;
56
57
    /**
58
     * @var TestPromotionFactoryInterface
59
     */
60
    private $testPromotionFactory;
61
62
    /**
63
     * @var PromotionRepositoryInterface
64
     */
65
    private $promotionRepository;
66
67
    /**
68
     * @var ObjectManager
69
     */
70
    private $objectManager;
71
72
    /**
73
     * @param SharedStorageInterface $sharedStorage
74
     * @param PromotionActionFactoryInterface $actionFactory
75
     * @param PromotionCouponFactoryInterface $couponFactory
76
     * @param PromotionRuleFactoryInterface $ruleFactory
77
     * @param TestPromotionFactoryInterface $testPromotionFactory
78
     * @param PromotionRepositoryInterface $promotionRepository
79
     * @param ObjectManager $objectManager
80
     */
81
    public function __construct(
82
        SharedStorageInterface $sharedStorage,
83
        PromotionActionFactoryInterface $actionFactory,
84
        PromotionCouponFactoryInterface $couponFactory,
85
        PromotionRuleFactoryInterface $ruleFactory,
86
        TestPromotionFactoryInterface $testPromotionFactory,
87
        PromotionRepositoryInterface $promotionRepository,
88
        ObjectManager $objectManager
89
    ) {
90
        $this->sharedStorage = $sharedStorage;
91
        $this->actionFactory = $actionFactory;
92
        $this->couponFactory = $couponFactory;
93
        $this->ruleFactory = $ruleFactory;
94
        $this->testPromotionFactory = $testPromotionFactory;
95
        $this->promotionRepository = $promotionRepository;
96
        $this->objectManager = $objectManager;
97
    }
98
99
    /**
100
     * @Given there is a promotion :promotionName
101
     * @Given there is a promotion :promotionName identified by :promotionCode code
102
     */
103
    public function thereIsPromotion($promotionName, $promotionCode = null)
104
    {
105
        $promotion = $this->testPromotionFactory
106
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
107
        ;
108
109
        if (null !== $promotionCode) {
110
            $promotion->setCode($promotionCode);
111
        }
112
113
        $this->promotionRepository->add($promotion);
114
        $this->sharedStorage->set('promotion', $promotion);
115
    }
116
117
    /**
118
     * @Given /^there is a promotion "([^"]+)" with priority ([^"]+)$/
119
     */
120
    public function thereIsAPromotionWithPriority($promotionName, $priority)
121
    {
122
        $promotion = $this->testPromotionFactory
123
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
124
        ;
125
126
        $promotion->setPriority($priority);
127
128
        $this->promotionRepository->add($promotion);
129
        $this->sharedStorage->set('promotion', $promotion);
130
    }
131
132
    /**
133
     * @Given /^there is an exclusive promotion "([^"]+)"(?:| with priority ([^"]+))$/
134
     */
135
    public function thereIsAnExclusivePromotionWithPriority($promotionName, $priority = 0)
136
    {
137
        $promotion = $this->testPromotionFactory
138
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
139
        ;
140
141
        $promotion->setExclusive(true);
142
        $promotion->setPriority($priority);
143
144
        $this->promotionRepository->add($promotion);
145
        $this->sharedStorage->set('promotion', $promotion);
146
    }
147
148
    /**
149
     * @Given there is a promotion :promotionName limited to :usageLimit usages
150
     */
151
    public function thereIsPromotionLimitedToUsages($promotionName, $usageLimit)
152
    {
153
        $promotion = $this->testPromotionFactory->createForChannel($promotionName, $this->sharedStorage->get('channel'));
154
155
        $promotion->setUsageLimit($usageLimit);
156
157
        $this->promotionRepository->add($promotion);
158
        $this->sharedStorage->set('promotion', $promotion);
159
    }
160
161
    /**
162
     * @Given the store has promotion :promotionName with coupon :couponCode
163
     * @Given the store has a promotion :promotionName with a coupon :couponCode that is limited to :usageLimit usages
164
     */
165
    public function thereIsPromotionWithCoupon($promotionName, $couponCode, $usageLimit = null)
166
    {
167
        /** @var PromotionCouponInterface $coupon */
168
        $coupon = $this->couponFactory->createNew();
169
        $coupon->setCode($couponCode);
170
        $coupon->setUsageLimit($usageLimit);
171
172
        $promotion = $this->testPromotionFactory
173
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
174
        ;
175
        $promotion->addCoupon($coupon);
176
        $promotion->setCouponBased(true);
177
178
        $this->promotionRepository->add($promotion);
179
180
        $this->sharedStorage->set('promotion', $promotion);
181
        $this->sharedStorage->set('coupon', $coupon);
182
    }
183
184
    /**
185
     * @Given /^(this promotion) has already expired$/
186
     */
187
    public function thisPromotionHasExpired(PromotionInterface $promotion)
188
    {
189
        $promotion->setEndsAt(new \DateTime('1 day ago'));
190
191
        $this->objectManager->flush();
192
    }
193
194
    /**
195
     * @Given /^(this promotion) expires tomorrow$/
196
     */
197
    public function thisPromotionExpiresTomorrow(PromotionInterface $promotion)
198
    {
199
        $promotion->setEndsAt(new \DateTime('tomorrow'));
200
201
        $this->objectManager->flush();
202
    }
203
204
    /**
205
     * @Given /^(this promotion) has started yesterday$/
206
     */
207
    public function thisPromotionHasStartedYesterday(PromotionInterface $promotion)
208
    {
209
        $promotion->setStartsAt(new \DateTime('1 day ago'));
210
211
        $this->objectManager->flush();
212
    }
213
214
    /**
215
     * @Given /^(this promotion) starts tomorrow$/
216
     */
217
    public function thisPromotionStartsTomorrow(PromotionInterface $promotion)
218
    {
219
        $promotion->setStartsAt(new \DateTime('tomorrow'));
220
221
        $this->objectManager->flush();
222
    }
223
224
    /**
225
     * @Given /^(this coupon) has already expired$/
226
     */
227
    public function thisCouponHasExpired(PromotionCouponInterface $coupon)
228
    {
229
        $coupon->setExpiresAt(new \DateTime('1 day ago'));
230
231
        $this->objectManager->flush();
232
    }
233
234
    /**
235
     * @Given /^(this coupon) expires tomorrow$/
236
     */
237
    public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon)
238
    {
239
        $coupon->setExpiresAt(new \DateTime('tomorrow'));
240
241
        $this->objectManager->flush();
242
    }
243
244
    /**
245
     * @Given /^(this coupon) has already reached its usage limit$/
246
     */
247
    public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon)
248
    {
249
        $coupon->setUsed(42);
250
        $coupon->setUsageLimit(42);
251
252
        $this->objectManager->flush();
253
    }
254
255
    /**
256
     * @Given /^(this coupon) can be used (\d+) times?$/
257
     */
258
    public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, $usageLimit)
259
    {
260
        $coupon->setUsageLimit($usageLimit);
261
262
        $this->objectManager->flush();
263
    }
264
265
    /**
266
     * @Given /^(this coupon) can be used twice per customer$/
267
     */
268
    public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon)
269
    {
270
        $coupon->setPerCustomerUsageLimit(2);
271
272
        $this->objectManager->flush();
273
    }
274
275
    /**
276
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/
277
     */
278
    public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount)
279
    {
280
        $this->createFixedPromotion($promotion, $discount);
281
    }
282
283
    /**
284
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/
285
     */
286
    public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel(
287
        PromotionInterface $promotion,
288
        $firstChannelDiscount,
289
        ChannelInterface $firstChannel,
290
        $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...
291
        ChannelInterface $secondChannel
292
    ) {
293
        /** @var PromotionActionInterface $action */
294
        $action = $this->actionFactory->createFixedDiscount($firstChannelDiscount, $firstChannel->getCode());
295
        $action->setConfiguration(array_merge($action->getConfiguration(), [$secondChannel->getCode() => ['amount' => $secondChannelDiscount]]));
296
297
        $promotion->addChannel($firstChannel);
298
        $promotion->addChannel($secondChannel);
299
        $promotion->addAction($action);
300
301
        $this->objectManager->flush();
302
    }
303
304
    /**
305
     * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/
306
     */
307
    public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount)
308
    {
309
        $this->createPercentagePromotion($promotion, $discount);
310
    }
311
312
    /**
313
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/
314
     */
315
    public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast(
316
        PromotionInterface $promotion,
317
        $discount,
318
        $quantity
319
    ) {
320
        $rule = $this->ruleFactory->createCartQuantity((int) $quantity);
321
322
        $this->createFixedPromotion($promotion, $discount, [], $rule);
323
    }
324
325
    /**
326
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/
327
     */
328
    public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast(
329
        PromotionInterface $promotion,
330
        $discount,
331
        $targetAmount
332
    ) {
333
        $channelCode = $this->sharedStorage->get('channel')->getCode();
334
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
335
336
        $this->createFixedPromotion($promotion, $discount, [], $rule);
337
    }
338
339
    /**
340
     * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/
341
     */
342
    public function itGivesOffOnEveryItemWhenItemTotalExceeds(
343
        PromotionInterface $promotion,
344
        $discount,
345
        $targetAmount
346
    ) {
347
        $channelCode = $this->sharedStorage->get('channel')->getCode();
348
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
349
350
        $this->createUnitPercentagePromotion($promotion, $discount, [], $rule);
351
    }
352
353
    /**
354
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/
355
     */
356
    public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount)
357
    {
358
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
359
        $promotion->addAction($action);
360
361
        $this->objectManager->flush();
362
    }
363
364
    /**
365
     * @Given /^([^"]+) gives free shipping to every order$/
366
     */
367
    public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion)
368
    {
369
        $this->itGivesPercentageDiscountOnShippingToEveryOrder($promotion, 1);
370
    }
371
372
    /**
373
     * @Given /^([^"]+) gives(?:| another) ("[^"]+%") off every product (classified as "[^"]+")$/
374
     */
375
    public function itGivesPercentageOffEveryProductClassifiedAs(
376
        PromotionInterface $promotion,
377
        $discount,
378
        TaxonInterface $taxon
379
    ) {
380
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
381
    }
382
383
    /**
384
     * @Given /^([^"]+) gives(?:| another) ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/
385
     */
386
    public function itGivesFixedOffEveryProductClassifiedAs(
387
        PromotionInterface $promotion,
388
        $discount,
389
        TaxonInterface $taxon
390
    ) {
391
        $this->createUnitFixedPromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
392
    }
393
394
    /**
395
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
396
     */
397
    public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt(
398
        PromotionInterface $promotion,
399
        $discount,
400
        $amount
401
    ) {
402
        $this->createUnitFixedPromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
403
    }
404
405
    /**
406
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
407
     */
408
    public function thisPromotionGivesOffOnEveryProductPricedBetween(
409
        PromotionInterface $promotion,
410
        $discount,
411
        $minAmount,
412
        $maxAmount
413
    ) {
414
        $this->createUnitFixedPromotion(
415
            $promotion,
416
            $discount,
417
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
418
        );
419
    }
420
421
    /**
422
     * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
423
     */
424
    public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt(
425
        PromotionInterface $promotion,
426
        $discount,
427
        $amount
428
    ) {
429
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
430
    }
431
432
    /**
433
     * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
434
     */
435
    public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween(
436
        PromotionInterface $promotion,
437
        $discount,
438
        $minAmount,
439
        $maxAmount
440
    ) {
441
        $this->createUnitPercentagePromotion(
442
            $promotion,
443
            $discount,
444
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
445
        );
446
    }
447
448
    /**
449
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/
450
     */
451
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs(
452
        PromotionInterface $promotion,
453
        $discount,
454
        TaxonInterface $taxon
455
    ) {
456
        $rule = $this->ruleFactory->createHasTaxon([$taxon->getCode()]);
457
458
        $this->createFixedPromotion($promotion, $discount, [], $rule);
459
    }
460
461
    /**
462
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/
463
     */
464
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr(
465
        PromotionInterface $promotion,
466
        $discount,
467
        array $taxons
468
    ) {
469
        $rule = $this->ruleFactory->createHasTaxon([$taxons[0]->getCode(), $taxons[1]->getCode()]);
470
471
        $this->createFixedPromotion($promotion, $discount, [], $rule);
472
    }
473
474
    /**
475
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/
476
     */
477
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt(
478
        PromotionInterface $promotion,
479
        $discount,
480
        TaxonInterface $taxon,
481
        $amount
482
    ) {
483
        $channelCode = $this->sharedStorage->get('channel')->getCode();
484
        $rule = $this->ruleFactory->createItemsFromTaxonTotal($channelCode, $taxon->getCode(), $amount);
485
486
        $this->createFixedPromotion($promotion, $discount, [], $rule);
487
    }
488
489
    /**
490
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/
491
     */
492
    public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
493
    {
494
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
495
496
        $this->createFixedPromotion($promotion, $discount, [], $rule);
497
    }
498
499
    /**
500
     * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/
501
     */
502
    public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
503
    {
504
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
505
506
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
507
    }
508
509
    /**
510
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/
511
     */
512
    public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder(
513
        PromotionInterface $promotion,
514
        $productDiscount,
515
        TaxonInterface $discountTaxon,
516
        $orderDiscount
517
    ) {
518
        $this->createUnitPercentagePromotion($promotion, $productDiscount, $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]));
519
        $this->createFixedPromotion($promotion, $orderDiscount);
520
    }
521
522
    /**
523
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/
524
     */
525
    public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast(
526
        PromotionInterface $promotion,
527
        $discount,
528
        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...
529
        $targetAmount
530
    ) {
531
        $freeShippingAction = $this->actionFactory->createShippingPercentageDiscount(1);
532
        $promotion->addAction($freeShippingAction);
533
534
        $channelCode = $this->sharedStorage->get('channel')->getCode();
535
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
536
537
        $this->createUnitFixedPromotion($promotion, $discount, [], $rule);
538
    }
539
540
    /**
541
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/
542
     */
543
    public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast(
544
        PromotionInterface $promotion,
545
        $taxonDiscount,
546
        TaxonInterface $taxon,
547
        $orderDiscount,
548
        $targetAmount
549
    ) {
550
        $orderDiscountAction = $this->actionFactory->createFixedDiscount($orderDiscount, $this->sharedStorage->get('channel')->getCode());
551
        $promotion->addAction($orderDiscountAction);
552
553
        $channelCode = $this->sharedStorage->get('channel')->getCode();
554
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
555
556
        $this->createUnitPercentagePromotion(
557
            $promotion,
558
            $taxonDiscount,
559
            $this->getTaxonFilterConfiguration([$taxon->getCode()]),
560
            $rule
561
        );
562
    }
563
564
    /**
565
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/
566
     */
567
    public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr(
568
        PromotionInterface $promotion,
569
        $discount,
570
        array $discountTaxons,
571
        array $targetTaxons
572
    ) {
573
        $discountTaxonsCodes = [$discountTaxons[0]->getCode(), $discountTaxons[1]->getCode()];
574
        $targetTaxonsCodes = [$targetTaxons[0]->getCode(), $targetTaxons[1]->getCode()];
575
576
        $rule = $this->ruleFactory->createHasTaxon($targetTaxonsCodes);
577
578
        $this->createUnitPercentagePromotion(
579
            $promotion,
580
            $discount,
581
            $this->getTaxonFilterConfiguration($discountTaxonsCodes),
582
            $rule
583
        );
584
    }
585
586
    /**
587
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/
588
     */
589
    public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs(
590
        PromotionInterface $promotion,
591
        $discount,
592
        $discountTaxon,
593
        $targetTaxon
594
    ) {
595
        $rule = $this->ruleFactory->createHasTaxon([$targetTaxon->getCode()]);
596
597
        $this->createUnitPercentagePromotion(
598
            $promotion,
599
            $discount,
600
            $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]),
601
            $rule
602
        );
603
    }
604
605
    /**
606
     * @Given /^(it) is coupon based promotion$/
607
     */
608
    public function itIsCouponBasedPromotion(PromotionInterface $promotion)
609
    {
610
        $promotion->setCouponBased(true);
611
612
        $this->objectManager->flush();
613
    }
614
615
    /**
616
     * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/
617
     */
618
    public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel)
619
    {
620
        $promotion->removeChannel($channel);
621
622
        $this->objectManager->flush();
623
    }
624
625
    /**
626
     * @Given /^the (coupon "[^"]+") was used up to its usage limit$/
627
     */
628
    public function theCouponWasUsed(PromotionCouponInterface $coupon)
629
    {
630
        $coupon->setUsed($coupon->getUsageLimit());
631
632
        $this->objectManager->flush();
633
    }
634
635
    /**
636
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/
637
     */
638
    public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product)
639
    {
640
        $rule = $this->ruleFactory->createContainsProduct($product->getCode());
641
642
        $this->createFixedPromotion($promotion, $discount, [], $rule);
643
    }
644
645
    /**
646
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/
647
     */
648
    public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
649
    {
650
        $this->createUnitFixedPromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
651
    }
652
653
    /**
654
     * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/
655
     */
656
    public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
657
    {
658
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
659
    }
660
661
    /**
662
     * @Given /^([^"]+) gives ("[^"]+%") off the order for customers from ("[^"]*" group)$/
663
     */
664
    public function thePromotionGivesOffTheOrderForCustomersFromGroup(
665
        PromotionInterface $promotion,
666
        $discount,
667
        CustomerGroupInterface $customerGroup
668
    ) {
669
        $rule = $this->ruleFactory->createNew();
670
        $rule->setType(CustomerGroupRuleChecker::TYPE);
671
        $rule->setConfiguration(['group_code' => $customerGroup->getCode()]);
672
673
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
674
    }
675
676
    /**
677
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order over ("(?:€|£|\$)[^"]+")$/
678
     */
679
    public function itGivesDiscountOnShippingToEveryOrderOver(
680
        PromotionInterface $promotion,
681
        $discount,
682
        $itemTotal
683
    ) {
684
        $channelCode = $this->sharedStorage->get('channel')->getCode();
685
        $rule = $this->ruleFactory->createItemTotal($channelCode, $itemTotal);
686
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
687
688
        $this->persistPromotion($promotion, $action, [], $rule);
689
    }
690
691
    /**
692
     * @Given /^([^"]+) gives free shipping to every order over ("(?:€|£|\$)[^"]+")$/
693
     */
694
    public function itGivesFreeShippingToEveryOrderOver(PromotionInterface $promotion, $itemTotal)
695
    {
696
        $this->itGivesDiscountOnShippingToEveryOrderOver($promotion, 1, $itemTotal);
697
    }
698
699
    /**
700
     * @param array $taxonCodes
701
     *
702
     * @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...
703
     */
704
    private function getTaxonFilterConfiguration(array $taxonCodes)
705
    {
706
        return ['filters' => ['taxons_filter' => ['taxons' => $taxonCodes]]];
707
    }
708
709
    /**
710
     * @param array $productCodes
711
     *
712
     * @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...
713
     */
714
    private function getProductsFilterConfiguration(array $productCodes)
715
    {
716
        return ['filters' => ['products_filter' => ['products' => $productCodes]]];
717
    }
718
719
    /**
720
     * @param int $minAmount
721
     * @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...
722
     *
723
     * @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...
724
     */
725
    private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null)
726
    {
727
        $configuration = ['filters' => ['price_range_filter' => ['min' => $minAmount]]];
728
        if (null !== $maxAmount) {
729
            $configuration['filters']['price_range_filter']['max'] = $maxAmount;
730
        }
731
732
        return $configuration;
733
    }
734
735
    /**
736
     * @param PromotionInterface $promotion
737
     * @param int $discount
738
     * @param array $configuration
739
     * @param PromotionRuleInterface|null $rule
740
     */
741
    private function createUnitFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
742
    {
743
        $channelCode = $this->sharedStorage->get('channel')->getCode();
744
745
        $this->persistPromotion(
746
            $promotion,
747
            $this->actionFactory->createUnitFixedDiscount($discount, $channelCode),
748
            [$channelCode => $configuration],
749
            $rule
750
        );
751
    }
752
753
    /**
754
     * @param PromotionInterface $promotion
755
     * @param int $discount
756
     * @param array $configuration
757
     * @param PromotionRuleInterface|null $rule
758
     */
759
    private function createUnitPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
760
    {
761
        $channelCode = $this->sharedStorage->get('channel')->getCode();
762
763
        $this->persistPromotion(
764
            $promotion,
765
            $this->actionFactory->createUnitPercentageDiscount($discount, $channelCode),
766
            [$channelCode => $configuration],
767
            $rule
768
        );
769
    }
770
771
    /**
772
     * @param PromotionInterface $promotion
773
     * @param int $discount
774
     * @param array $configuration
775
     * @param PromotionRuleInterface|null $rule
776
     * @param ChannelInterface|null $channel
777
     */
778
    private function createFixedPromotion(
779
        PromotionInterface $promotion,
780
        $discount,
781
        array $configuration = [],
782
        PromotionRuleInterface $rule = null,
783
        ChannelInterface $channel = null
784
    ) {
785
        $channelCode = (null !== $channel) ? $channel->getCode() : $this->sharedStorage->get('channel')->getCode();
786
787
        $this->persistPromotion($promotion, $this->actionFactory->createFixedDiscount($discount, $channelCode), $configuration, $rule);
788
    }
789
790
    /**
791
     * @param PromotionInterface $promotion
792
     * @param float $discount
793
     * @param array $configuration
794
     * @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...
795
     */
796
    private function createPercentagePromotion(
797
        PromotionInterface $promotion,
798
        $discount,
799
        array $configuration = [],
800
        PromotionRuleInterface $rule = null
801
    ) {
802
        $this->persistPromotion($promotion, $this->actionFactory->createPercentageDiscount($discount), $configuration, $rule);
803
    }
804
805
    /**
806
     * @param PromotionInterface $promotion
807
     * @param PromotionActionInterface $action
808
     * @param array $configuration
809
     * @param PromotionRuleInterface|null $rule
810
     */
811
    private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null)
812
    {
813
        $configuration = array_merge_recursive($action->getConfiguration(), $configuration);
814
        $action->setConfiguration($configuration);
815
816
        $promotion->addAction($action);
817
        if (null !== $rule) {
818
            $promotion->addRule($rule);
819
        }
820
821
        $this->objectManager->flush();
822
    }
823
}
824