Completed
Push — master ( 3c7667...799620 )
by Kamil
94:52 queued 57:43
created

Sylius/Behat/Context/Setup/PromotionContext.php (1 issue)

parameters are used.

Unused Code Minor

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 (also) a promotion :promotionName
100
     * @Given there is a promotion :promotionName identified by :promotionCode code
101
     */
102
    public function thereIsPromotion(string $promotionName, ?string $promotionCode = null): void
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(string $promotionName, string $couponCode, ?int $usageLimit = null): void
165
    {
166
        $coupon = $this->createCoupon($couponCode, $usageLimit);
167
168
        $promotion = $this->testPromotionFactory
169
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
170
        ;
171
        $promotion->addCoupon($coupon);
172
        $promotion->setCouponBased(true);
173
174
        $this->promotionRepository->add($promotion);
175
176
        $this->sharedStorage->set('promotion', $promotion);
177
        $this->sharedStorage->set('coupon', $coupon);
178
    }
179
180
    /**
181
     * @Given /^(this promotion) has "([^"]+)", "([^"]+)" and "([^"]+)" coupons/
182
     */
183
    public function thisPromotionHasCoupons(PromotionInterface $promotion, string ...$couponCodes): void
184
    {
185
        foreach ($couponCodes as $couponCode) {
186
            $coupon = $this->createCoupon($couponCode);
187
            $promotion->addCoupon($coupon);
188
        }
189
190
        $promotion->setCouponBased(true);
191
192
        $this->objectManager->flush();
193
    }
194
195
    /**
196
     * @Given /^(this promotion) has already expired$/
197
     */
198
    public function thisPromotionHasExpired(PromotionInterface $promotion)
199
    {
200
        $promotion->setEndsAt(new \DateTime('1 day ago'));
201
202
        $this->objectManager->flush();
203
    }
204
205
    /**
206
     * @Given /^(this promotion) expires tomorrow$/
207
     */
208
    public function thisPromotionExpiresTomorrow(PromotionInterface $promotion)
209
    {
210
        $promotion->setEndsAt(new \DateTime('tomorrow'));
211
212
        $this->objectManager->flush();
213
    }
214
215
    /**
216
     * @Given /^(this promotion) has started yesterday$/
217
     */
218
    public function thisPromotionHasStartedYesterday(PromotionInterface $promotion)
219
    {
220
        $promotion->setStartsAt(new \DateTime('1 day ago'));
221
222
        $this->objectManager->flush();
223
    }
224
225
    /**
226
     * @Given /^(this promotion) starts tomorrow$/
227
     */
228
    public function thisPromotionStartsTomorrow(PromotionInterface $promotion)
229
    {
230
        $promotion->setStartsAt(new \DateTime('tomorrow'));
231
232
        $this->objectManager->flush();
233
    }
234
235
    /**
236
     * @Given /^(this coupon) has already expired$/
237
     */
238
    public function thisCouponHasExpired(PromotionCouponInterface $coupon)
239
    {
240
        $coupon->setExpiresAt(new \DateTime('1 day ago'));
241
242
        $this->objectManager->flush();
243
    }
244
245
    /**
246
     * @Given /^(this coupon) expires tomorrow$/
247
     */
248
    public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon)
249
    {
250
        $coupon->setExpiresAt(new \DateTime('tomorrow'));
251
252
        $this->objectManager->flush();
253
    }
254
255
    /**
256
     * @Given /^(this coupon) has already reached its usage limit$/
257
     */
258
    public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon)
259
    {
260
        $coupon->setUsed(42);
261
        $coupon->setUsageLimit(42);
262
263
        $this->objectManager->flush();
264
    }
265
266
    /**
267
     * @Given /^(this coupon) can be used (\d+) times?$/
268
     */
269
    public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, $usageLimit)
270
    {
271
        $coupon->setUsageLimit((int) $usageLimit);
272
273
        $this->objectManager->flush();
274
    }
275
276
    /**
277
     * @Given /^(this coupon) can be used twice per customer$/
278
     */
279
    public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon)
280
    {
281
        $coupon->setPerCustomerUsageLimit(2);
282
283
        $this->objectManager->flush();
284
    }
285
286
    /**
287
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/
288
     */
289
    public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount)
290
    {
291
        $this->createFixedPromotion($promotion, $discount);
292
    }
293
294
    /**
295
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/
296
     */
297
    public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel(
298
        PromotionInterface $promotion,
299
        $firstChannelDiscount,
300
        ChannelInterface $firstChannel,
301
        $secondChannelDiscount,
302
        ChannelInterface $secondChannel
303
    ) {
304
        /** @var PromotionActionInterface $action */
305
        $action = $this->actionFactory->createFixedDiscount($firstChannelDiscount, $firstChannel->getCode());
306
        $action->setConfiguration(array_merge($action->getConfiguration(), [$secondChannel->getCode() => ['amount' => $secondChannelDiscount]]));
307
308
        $promotion->addChannel($firstChannel);
309
        $promotion->addChannel($secondChannel);
310
        $promotion->addAction($action);
311
312
        $this->objectManager->flush();
313
    }
314
315
    /**
316
     * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/
317
     */
318
    public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount)
319
    {
320
        $this->createPercentagePromotion($promotion, $discount);
321
    }
322
323
    /**
324
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/
325
     */
326
    public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast(
327
        PromotionInterface $promotion,
328
        $discount,
329
        $quantity
330
    ) {
331
        $rule = $this->ruleFactory->createCartQuantity((int) $quantity);
332
333
        $this->createFixedPromotion($promotion, $discount, [], $rule);
334
    }
335
336
    /**
337
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/
338
     */
339
    public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast(
340
        PromotionInterface $promotion,
341
        $discount,
342
        $targetAmount
343
    ) {
344
        $channelCode = $this->sharedStorage->get('channel')->getCode();
345
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
346
347
        $this->createFixedPromotion($promotion, $discount, [], $rule);
348
    }
349
350
    /**
351
     * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/
352
     */
353
    public function itGivesOffOnEveryItemWhenItemTotalExceeds(
354
        PromotionInterface $promotion,
355
        $discount,
356
        $targetAmount
357
    ) {
358
        $channelCode = $this->sharedStorage->get('channel')->getCode();
359
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
360
361
        $this->createUnitPercentagePromotion($promotion, $discount, [], $rule);
362
    }
363
364
    /**
365
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/
366
     */
367
    public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount)
368
    {
369
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
370
        $promotion->addAction($action);
371
372
        $this->objectManager->flush();
373
    }
374
375
    /**
376
     * @Given /^([^"]+) gives free shipping to every order$/
377
     */
378
    public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion)
379
    {
380
        $this->itGivesPercentageDiscountOnShippingToEveryOrder($promotion, 1);
381
    }
382
383
    /**
384
     * @Given /^([^"]+) gives(?:| another) ("[^"]+%") off every product (classified as "[^"]+")$/
385
     */
386
    public function itGivesPercentageOffEveryProductClassifiedAs(
387
        PromotionInterface $promotion,
388
        $discount,
389
        TaxonInterface $taxon
390
    ) {
391
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
392
    }
393
394
    /**
395
     * @Given /^([^"]+) gives(?:| another) ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/
396
     */
397
    public function itGivesFixedOffEveryProductClassifiedAs(
398
        PromotionInterface $promotion,
399
        $discount,
400
        TaxonInterface $taxon
401
    ) {
402
        $this->createUnitFixedPromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
403
    }
404
405
    /**
406
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
407
     */
408
    public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt(
409
        PromotionInterface $promotion,
410
        $discount,
411
        $amount
412
    ) {
413
        $this->createUnitFixedPromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
414
    }
415
416
    /**
417
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
418
     */
419
    public function thisPromotionGivesOffOnEveryProductPricedBetween(
420
        PromotionInterface $promotion,
421
        $discount,
422
        $minAmount,
423
        $maxAmount
424
    ) {
425
        $this->createUnitFixedPromotion(
426
            $promotion,
427
            $discount,
428
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
429
        );
430
    }
431
432
    /**
433
     * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
434
     */
435
    public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt(
436
        PromotionInterface $promotion,
437
        $discount,
438
        $amount
439
    ) {
440
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
441
    }
442
443
    /**
444
     * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
445
     */
446
    public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween(
447
        PromotionInterface $promotion,
448
        $discount,
449
        $minAmount,
450
        $maxAmount
451
    ) {
452
        $this->createUnitPercentagePromotion(
453
            $promotion,
454
            $discount,
455
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
456
        );
457
    }
458
459
    /**
460
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/
461
     */
462
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs(
463
        PromotionInterface $promotion,
464
        $discount,
465
        TaxonInterface $taxon
466
    ) {
467
        $rule = $this->ruleFactory->createHasTaxon([$taxon->getCode()]);
468
469
        $this->createFixedPromotion($promotion, $discount, [], $rule);
470
    }
471
472
    /**
473
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/
474
     */
475
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr(
476
        PromotionInterface $promotion,
477
        $discount,
478
        array $taxons
479
    ) {
480
        $rule = $this->ruleFactory->createHasTaxon([$taxons[0]->getCode(), $taxons[1]->getCode()]);
481
482
        $this->createFixedPromotion($promotion, $discount, [], $rule);
483
    }
484
485
    /**
486
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/
487
     */
488
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt(
489
        PromotionInterface $promotion,
490
        $discount,
491
        TaxonInterface $taxon,
492
        $amount
493
    ) {
494
        $channelCode = $this->sharedStorage->get('channel')->getCode();
495
        $rule = $this->ruleFactory->createItemsFromTaxonTotal($channelCode, $taxon->getCode(), $amount);
496
497
        $this->createFixedPromotion($promotion, $discount, [], $rule);
498
    }
499
500
    /**
501
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/
502
     */
503
    public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
504
    {
505
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
506
507
        $this->createFixedPromotion($promotion, $discount, [], $rule);
508
    }
509
510
    /**
511
     * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/
512
     */
513
    public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
514
    {
515
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
516
517
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
518
    }
519
520
    /**
521
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/
522
     */
523
    public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder(
524
        PromotionInterface $promotion,
525
        $productDiscount,
526
        TaxonInterface $discountTaxon,
527
        $orderDiscount
528
    ) {
529
        $this->createUnitPercentagePromotion($promotion, $productDiscount, $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]));
530
        $this->createFixedPromotion($promotion, $orderDiscount);
531
    }
532
533
    /**
534
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/
535
     */
536
    public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast(
537
        PromotionInterface $promotion,
538
        $discount,
539
        TaxonInterface $taxon,
0 ignored issues
show
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...
540
        $targetAmount
541
    ) {
542
        $freeShippingAction = $this->actionFactory->createShippingPercentageDiscount(1);
543
        $promotion->addAction($freeShippingAction);
544
545
        $channelCode = $this->sharedStorage->get('channel')->getCode();
546
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
547
548
        $this->createUnitFixedPromotion($promotion, $discount, [], $rule);
549
    }
550
551
    /**
552
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/
553
     */
554
    public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast(
555
        PromotionInterface $promotion,
556
        $taxonDiscount,
557
        TaxonInterface $taxon,
558
        $orderDiscount,
559
        $targetAmount
560
    ) {
561
        $orderDiscountAction = $this->actionFactory->createFixedDiscount($orderDiscount, $this->sharedStorage->get('channel')->getCode());
562
        $promotion->addAction($orderDiscountAction);
563
564
        $channelCode = $this->sharedStorage->get('channel')->getCode();
565
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
566
567
        $this->createUnitPercentagePromotion(
568
            $promotion,
569
            $taxonDiscount,
570
            $this->getTaxonFilterConfiguration([$taxon->getCode()]),
571
            $rule
572
        );
573
    }
574
575
    /**
576
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/
577
     */
578
    public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr(
579
        PromotionInterface $promotion,
580
        $discount,
581
        array $discountTaxons,
582
        array $targetTaxons
583
    ) {
584
        $discountTaxonsCodes = [$discountTaxons[0]->getCode(), $discountTaxons[1]->getCode()];
585
        $targetTaxonsCodes = [$targetTaxons[0]->getCode(), $targetTaxons[1]->getCode()];
586
587
        $rule = $this->ruleFactory->createHasTaxon($targetTaxonsCodes);
588
589
        $this->createUnitPercentagePromotion(
590
            $promotion,
591
            $discount,
592
            $this->getTaxonFilterConfiguration($discountTaxonsCodes),
593
            $rule
594
        );
595
    }
596
597
    /**
598
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/
599
     */
600
    public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs(
601
        PromotionInterface $promotion,
602
        $discount,
603
        $discountTaxon,
604
        $targetTaxon
605
    ) {
606
        $rule = $this->ruleFactory->createHasTaxon([$targetTaxon->getCode()]);
607
608
        $this->createUnitPercentagePromotion(
609
            $promotion,
610
            $discount,
611
            $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]),
612
            $rule
613
        );
614
    }
615
616
    /**
617
     * @Given /^(it) is coupon based promotion$/
618
     */
619
    public function itIsCouponBasedPromotion(PromotionInterface $promotion)
620
    {
621
        $promotion->setCouponBased(true);
622
623
        $this->objectManager->flush();
624
    }
625
626
    /**
627
     * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/
628
     */
629
    public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel)
630
    {
631
        $promotion->removeChannel($channel);
632
633
        $this->objectManager->flush();
634
    }
635
636
    /**
637
     * @Given /^the (coupon "[^"]+") was used up to its usage limit$/
638
     */
639
    public function theCouponWasUsed(PromotionCouponInterface $coupon)
640
    {
641
        $coupon->setUsed($coupon->getUsageLimit());
642
643
        $this->objectManager->flush();
644
    }
645
646
    /**
647
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/
648
     */
649
    public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product)
650
    {
651
        $rule = $this->ruleFactory->createContainsProduct($product->getCode());
652
653
        $this->createFixedPromotion($promotion, $discount, [], $rule);
654
    }
655
656
    /**
657
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/
658
     */
659
    public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
660
    {
661
        $this->createUnitFixedPromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
662
    }
663
664
    /**
665
     * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/
666
     */
667
    public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
668
    {
669
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
670
    }
671
672
    /**
673
     * @Given /^([^"]+) gives ("[^"]+%") off the order for customers from ("[^"]*" group)$/
674
     */
675
    public function thePromotionGivesOffTheOrderForCustomersFromGroup(
676
        PromotionInterface $promotion,
677
        $discount,
678
        CustomerGroupInterface $customerGroup
679
    ) {
680
        $rule = $this->ruleFactory->createNew();
681
        $rule->setType(CustomerGroupRuleChecker::TYPE);
682
        $rule->setConfiguration(['group_code' => $customerGroup->getCode()]);
683
684
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
685
    }
686
687
    /**
688
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order over ("(?:€|£|\$)[^"]+")$/
689
     */
690
    public function itGivesDiscountOnShippingToEveryOrderOver(
691
        PromotionInterface $promotion,
692
        $discount,
693
        $itemTotal
694
    ) {
695
        $channelCode = $this->sharedStorage->get('channel')->getCode();
696
        $rule = $this->ruleFactory->createItemTotal($channelCode, $itemTotal);
697
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
698
699
        $this->persistPromotion($promotion, $action, [], $rule);
700
    }
701
702
    /**
703
     * @Given /^([^"]+) gives free shipping to every order over ("(?:€|£|\$)[^"]+")$/
704
     */
705
    public function itGivesFreeShippingToEveryOrderOver(PromotionInterface $promotion, $itemTotal)
706
    {
707
        $this->itGivesDiscountOnShippingToEveryOrderOver($promotion, 1, $itemTotal);
708
    }
709
710
    /**
711
     * @param array $taxonCodes
712
     *
713
     * @return array
714
     */
715
    private function getTaxonFilterConfiguration(array $taxonCodes)
716
    {
717
        return ['filters' => ['taxons_filter' => ['taxons' => $taxonCodes]]];
718
    }
719
720
    /**
721
     * @param array $productCodes
722
     *
723
     * @return array
724
     */
725
    private function getProductsFilterConfiguration(array $productCodes)
726
    {
727
        return ['filters' => ['products_filter' => ['products' => $productCodes]]];
728
    }
729
730
    /**
731
     * @param int $minAmount
732
     * @param int $maxAmount
733
     *
734
     * @return array
735
     */
736
    private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null)
737
    {
738
        $configuration = ['filters' => ['price_range_filter' => ['min' => $minAmount]]];
739
        if (null !== $maxAmount) {
740
            $configuration['filters']['price_range_filter']['max'] = $maxAmount;
741
        }
742
743
        return $configuration;
744
    }
745
746
    /**
747
     * @param PromotionInterface $promotion
748
     * @param int $discount
749
     * @param array $configuration
750
     * @param PromotionRuleInterface|null $rule
751
     */
752
    private function createUnitFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
753
    {
754
        $channelCode = $this->sharedStorage->get('channel')->getCode();
755
756
        $this->persistPromotion(
757
            $promotion,
758
            $this->actionFactory->createUnitFixedDiscount($discount, $channelCode),
759
            [$channelCode => $configuration],
760
            $rule
761
        );
762
    }
763
764
    /**
765
     * @param PromotionInterface $promotion
766
     * @param int $discount
767
     * @param array $configuration
768
     * @param PromotionRuleInterface|null $rule
769
     */
770
    private function createUnitPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
771
    {
772
        $channelCode = $this->sharedStorage->get('channel')->getCode();
773
774
        $this->persistPromotion(
775
            $promotion,
776
            $this->actionFactory->createUnitPercentageDiscount($discount, $channelCode),
777
            [$channelCode => $configuration],
778
            $rule
779
        );
780
    }
781
782
    /**
783
     * @param PromotionInterface $promotion
784
     * @param int $discount
785
     * @param array $configuration
786
     * @param PromotionRuleInterface|null $rule
787
     * @param ChannelInterface|null $channel
788
     */
789
    private function createFixedPromotion(
790
        PromotionInterface $promotion,
791
        $discount,
792
        array $configuration = [],
793
        PromotionRuleInterface $rule = null,
794
        ChannelInterface $channel = null
795
    ) {
796
        $channelCode = (null !== $channel) ? $channel->getCode() : $this->sharedStorage->get('channel')->getCode();
797
798
        $this->persistPromotion($promotion, $this->actionFactory->createFixedDiscount($discount, $channelCode), $configuration, $rule);
799
    }
800
801
    /**
802
     * @param PromotionInterface $promotion
803
     * @param float $discount
804
     * @param array $configuration
805
     * @param PromotionRuleInterface $rule
806
     */
807
    private function createPercentagePromotion(
808
        PromotionInterface $promotion,
809
        $discount,
810
        array $configuration = [],
811
        PromotionRuleInterface $rule = null
812
    ) {
813
        $this->persistPromotion($promotion, $this->actionFactory->createPercentageDiscount($discount), $configuration, $rule);
814
    }
815
816
    /**
817
     * @param PromotionInterface $promotion
818
     * @param PromotionActionInterface $action
819
     * @param array $configuration
820
     * @param PromotionRuleInterface|null $rule
821
     */
822
    private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null)
823
    {
824
        $configuration = array_merge_recursive($action->getConfiguration(), $configuration);
825
        $action->setConfiguration($configuration);
826
827
        $promotion->addAction($action);
828
        if (null !== $rule) {
829
            $promotion->addRule($rule);
830
        }
831
832
        $this->objectManager->flush();
833
    }
834
835
    /**
836
     * @param string $couponCode
837
     * @param int|null $usageLimit
838
     *
839
     * @return PromotionCouponInterface
840
     */
841
    private function createCoupon(string $couponCode, ?int $usageLimit = null): PromotionCouponInterface
842
    {
843
        /** @var PromotionCouponInterface $coupon */
844
        $coupon = $this->couponFactory->createNew();
845
        $coupon->setCode($couponCode);
846
        $coupon->setUsageLimit($usageLimit);
847
848
        return $coupon;
849
    }
850
}
851