Completed
Push — unused-definitions ( d9908f )
by Kamil
18:33
created

itGivesPercentageDiscountOnShippingToEveryOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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