Completed
Push — 1.0 ( 00b01c...96a461 )
by Kamil
19s
created

thePromotionGivesOffIfOrderContainsProducts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
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
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,
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
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
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
721
     *
722
     * @return array
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
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