Completed
Push — master ( 26132b...c9e982 )
by Kamil
31:04 queued 12:47
created

itGivesPercentageOffCustomersNthOrder()   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
nc 1
cc 1
eloc 3
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Setup;
13
14
use Behat\Behat\Context\Context;
15
use Doctrine\Common\Persistence\ObjectManager;
16
use Sylius\Behat\Service\SharedStorageInterface;
17
use Sylius\Component\Core\Factory\PromotionActionFactoryInterface;
18
use Sylius\Component\Core\Factory\PromotionRuleFactoryInterface;
19
use Sylius\Component\Core\Model\ChannelInterface;
20
use Sylius\Component\Core\Model\ProductInterface;
21
use Sylius\Component\Core\Model\PromotionCouponInterface;
22
use Sylius\Component\Core\Model\PromotionInterface;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
25
use Sylius\Component\Promotion\Factory\PromotionCouponFactoryInterface;
26
use Sylius\Component\Promotion\Model\PromotionActionInterface;
27
use Sylius\Component\Promotion\Model\PromotionRuleInterface;
28
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
29
30
/**
31
 * @author Mateusz Zalewski <[email protected]>
32
 */
33
final class PromotionContext implements Context
34
{
35
    /**
36
     * @var SharedStorageInterface
37
     */
38
    private $sharedStorage;
39
40
    /**
41
     * @var PromotionActionFactoryInterface
42
     */
43
    private $actionFactory;
44
45
    /**
46
     * @var PromotionCouponFactoryInterface
47
     */
48
    private $couponFactory;
49
50
    /**
51
     * @var PromotionRuleFactoryInterface
52
     */
53
    private $ruleFactory;
54
55
    /**
56
     * @var TestPromotionFactoryInterface
57
     */
58
    private $testPromotionFactory;
59
60
    /**
61
     * @var PromotionRepositoryInterface
62
     */
63
    private $promotionRepository;
64
65
    /**
66
     * @var ObjectManager
67
     */
68
    private $objectManager;
69
70
    /**
71
     * @param SharedStorageInterface $sharedStorage
72
     * @param PromotionActionFactoryInterface $actionFactory
73
     * @param PromotionCouponFactoryInterface $couponFactory
74
     * @param PromotionRuleFactoryInterface $ruleFactory
75
     * @param TestPromotionFactoryInterface $testPromotionFactory
76
     * @param PromotionRepositoryInterface $promotionRepository
77
     * @param ObjectManager $objectManager
78
     */
79
    public function __construct(
80
        SharedStorageInterface $sharedStorage,
81
        PromotionActionFactoryInterface $actionFactory,
82
        PromotionCouponFactoryInterface $couponFactory,
83
        PromotionRuleFactoryInterface $ruleFactory,
84
        TestPromotionFactoryInterface $testPromotionFactory,
85
        PromotionRepositoryInterface $promotionRepository,
86
        ObjectManager $objectManager
87
    ) {
88
        $this->sharedStorage = $sharedStorage;
89
        $this->actionFactory = $actionFactory;
90
        $this->couponFactory = $couponFactory;
91
        $this->ruleFactory = $ruleFactory;
92
        $this->testPromotionFactory = $testPromotionFactory;
93
        $this->promotionRepository = $promotionRepository;
94
        $this->objectManager = $objectManager;
95
    }
96
97
    /**
98
     * @Given there is a promotion :promotionName
99
     * @Given there is a promotion :promotionName identified by :promotionCode code
100
     */
101
    public function thereIsPromotion($promotionName, $promotionCode = null)
102
    {
103
        $promotion = $this->testPromotionFactory
104
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
105
        ;
106
107
        if (null !== $promotionCode) {
108
            $promotion->setCode($promotionCode);
109
        }
110
111
        $this->promotionRepository->add($promotion);
112
        $this->sharedStorage->set('promotion', $promotion);
113
    }
114
115
    /**
116
     * @Given /^there is a promotion "([^"]+)" with priority ([^"]+)$/
117
     */
118
    public function thereIsAPromotionWithPriority($promotionName, $priority)
119
    {
120
        $promotion = $this->testPromotionFactory
121
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
122
        ;
123
124
        $promotion->setPriority($priority);
125
126
        $this->promotionRepository->add($promotion);
127
        $this->sharedStorage->set('promotion', $promotion);
128
    }
129
130
    /**
131
     * @Given /^there is an exclusive promotion "([^"]+)"(?:| with priority ([^"]+))$/
132
     */
133
    public function thereIsAnExclusivePromotionWithPriority($promotionName, $priority = 0)
134
    {
135
        $promotion = $this->testPromotionFactory
136
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
137
        ;
138
139
        $promotion->setExclusive(true);
140
        $promotion->setPriority($priority);
141
142
        $this->promotionRepository->add($promotion);
143
        $this->sharedStorage->set('promotion', $promotion);
144
    }
145
146
    /**
147
     * @Given there is a promotion :promotionName limited to :usageLimit usages
148
     */
149
    public function thereIsPromotionLimitedToUsages($promotionName, $usageLimit)
150
    {
151
        $promotion = $this->testPromotionFactory->createForChannel($promotionName, $this->sharedStorage->get('channel'));
152
153
        $promotion->setUsageLimit($usageLimit);
154
155
        $this->promotionRepository->add($promotion);
156
        $this->sharedStorage->set('promotion', $promotion);
157
    }
158
159
    /**
160
     * @Given the store has promotion :promotionName with coupon :couponCode
161
     * @Given the store has also 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($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 coupon) has already expired$/
195
     */
196
    public function thisCouponHasExpired(PromotionCouponInterface $coupon)
197
    {
198
        $coupon->setExpiresAt(new \DateTime('1 day ago'));
199
200
        $this->objectManager->flush();
201
    }
202
203
    /**
204
     * @Given /^(this coupon) expires tomorrow$/
205
     */
206
    public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon)
207
    {
208
        $coupon->setExpiresAt(new \DateTime('tomorrow'));
209
210
        $this->objectManager->flush();
211
    }
212
213
    /**
214
     * @Given /^(this coupon) has already reached its usage limit$/
215
     */
216
    public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon)
217
    {
218
        $coupon->setUsed(42);
219
        $coupon->setUsageLimit(42);
220
221
        $this->objectManager->flush();
222
    }
223
224
    /**
225
     * @Given /^(this coupon) can be used (\d+) times?$/
226
     */
227
    public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, $usageLimit)
228
    {
229
        $coupon->setUsageLimit($usageLimit);
230
231
        $this->objectManager->flush();
232
    }
233
234
    /**
235
     * @Given /^(this coupon) can be used twice per customer$/
236
     */
237
    public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon)
238
    {
239
        $coupon->setPerCustomerUsageLimit(2);
240
241
        $this->objectManager->flush();
242
    }
243
244
    /**
245
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/
246
     */
247
    public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount)
248
    {
249
        $this->createFixedPromotion($promotion, $discount);
250
    }
251
252
    /**
253
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/
254
     */
255
    public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel(
256
        PromotionInterface $promotion,
257
        $firstChannelDiscount,
258
        ChannelInterface $firstChannel,
259
        $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...
260
        ChannelInterface $secondChannel
261
    ) {
262
        /** @var PromotionActionInterface $action */
263
        $action = $this->actionFactory->createFixedDiscount($firstChannelDiscount, $firstChannel->getCode());
264
        $action->setConfiguration(array_merge($action->getConfiguration(), [$secondChannel->getCode() => ['amount' => $secondChannelDiscount]]));
265
266
        $promotion->addChannel($firstChannel);
267
        $promotion->addChannel($secondChannel);
268
        $promotion->addAction($action);
269
270
        $this->objectManager->flush();
271
    }
272
273
    /**
274
     * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/
275
     */
276
    public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount)
277
    {
278
        $this->createPercentagePromotion($promotion, $discount);
279
    }
280
281
    /**
282
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/
283
     */
284
    public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast(
285
        PromotionInterface $promotion,
286
        $discount,
287
        $quantity
288
    ) {
289
        $rule = $this->ruleFactory->createCartQuantity((int) $quantity);
290
291
        $this->createFixedPromotion($promotion, $discount, [], $rule);
292
    }
293
294
    /**
295
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/
296
     */
297
    public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast(
298
        PromotionInterface $promotion,
299
        $discount,
300
        $targetAmount
301
    ) {
302
        $channelCode = $this->sharedStorage->get('channel')->getCode();
303
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
304
305
        $this->createFixedPromotion($promotion, $discount, [], $rule);
306
    }
307
308
    /**
309
     * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/
310
     */
311
    public function itGivesOffOnEveryItemWhenItemTotalExceeds(
312
        PromotionInterface $promotion,
313
        $discount,
314
        $targetAmount
315
    ) {
316
        $channelCode = $this->sharedStorage->get('channel')->getCode();
317
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
318
319
        $this->createUnitPercentagePromotion($promotion, $discount, [], $rule);
320
    }
321
322
    /**
323
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/
324
     */
325
    public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount)
326
    {
327
        $action = $this->actionFactory->createShippingPercentageDiscount($discount);
328
        $promotion->addAction($action);
329
330
        $this->objectManager->flush();
331
    }
332
333
    /**
334
     * @Given /^([^"]+) gives free shipping to every order$/
335
     */
336
    public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion)
337
    {
338
        $this->itGivesPercentageDiscountOnShippingToEveryOrder($promotion, 1);
339
    }
340
341
    /**
342
     * @Given /^([^"]+) gives ("[^"]+%") off every product (classified as "[^"]+")$/
343
     */
344
    public function itGivesPercentageOffEveryProductClassifiedAs(
345
        PromotionInterface $promotion,
346
        $discount,
347
        TaxonInterface $taxon
348
    ) {
349
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
350
    }
351
352
    /**
353
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/
354
     */
355
    public function itGivesFixedOffEveryProductClassifiedAs(
356
        PromotionInterface $promotion,
357
        $discount,
358
        TaxonInterface $taxon
359
    ) {
360
        $this->createUnitFixedPromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
361
    }
362
363
    /**
364
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
365
     */
366
    public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt(
367
        PromotionInterface $promotion,
368
        $discount,
369
        $amount
370
    ) {
371
        $this->createUnitFixedPromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
372
    }
373
374
    /**
375
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") in base currency or ("(?:€|£|\$)[^"]+") in "([^"]+)" off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
376
     */
377
    public function thisPromotionGivesInDifferentCurrenciesOffOnEveryProductWithMinimumPriceAt(
378
        PromotionInterface $promotion,
379
        $baseDiscount,
380
        $currencyDiscount,
381
        $currencyCode,
382
        $minimumPrice
383
    ) {
384
        $configuration = $this->getPriceRangeFilterConfiguration($minimumPrice);
385
        $configuration['amounts'] = [$currencyCode => $currencyDiscount];
386
387
        $this->createUnitFixedPromotion($promotion, $baseDiscount, $configuration);
388
    }
389
390
    /**
391
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
392
     */
393
    public function thisPromotionGivesOffOnEveryProductPricedBetween(
394
        PromotionInterface $promotion,
395
        $discount,
396
        $minAmount,
397
        $maxAmount
398
    ) {
399
        $this->createUnitFixedPromotion(
400
            $promotion,
401
            $discount,
402
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
403
        );
404
    }
405
406
    /**
407
     * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
408
     */
409
    public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt(
410
        PromotionInterface $promotion,
411
        $discount,
412
        $amount
413
    ) {
414
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
415
    }
416
417
    /**
418
     * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
419
     */
420
    public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween(
421
        PromotionInterface $promotion,
422
        $discount,
423
        $minAmount,
424
        $maxAmount
425
    ) {
426
        $this->createUnitPercentagePromotion(
427
            $promotion,
428
            $discount,
429
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
430
        );
431
    }
432
433
    /**
434
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/
435
     */
436
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs(
437
        PromotionInterface $promotion,
438
        $discount,
439
        TaxonInterface $taxon
440
    ) {
441
        $rule = $this->ruleFactory->createHasTaxon([$taxon->getCode()]);
442
443
        $this->createFixedPromotion($promotion, $discount, [], $rule);
444
    }
445
446
    /**
447
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/
448
     */
449
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr(
450
        PromotionInterface $promotion,
451
        $discount,
452
        array $taxons
453
    ) {
454
        $rule = $this->ruleFactory->createHasTaxon([$taxons[0]->getCode(), $taxons[1]->getCode()]);
455
456
        $this->createFixedPromotion($promotion, $discount, [], $rule);
457
    }
458
459
    /**
460
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/
461
     */
462
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt(
463
        PromotionInterface $promotion,
464
        $discount,
465
        TaxonInterface $taxon,
466
        $amount
467
    ) {
468
        $channelCode = $this->sharedStorage->get('channel')->getCode();
469
        $rule = $this->ruleFactory->createItemsFromTaxonTotal($channelCode, $taxon->getCode(), $amount);
470
471
        $this->createFixedPromotion($promotion, $discount, [], $rule);
472
    }
473
474
    /**
475
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/
476
     */
477
    public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
478
    {
479
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
480
481
        $this->createFixedPromotion($promotion, $discount, [], $rule);
482
    }
483
484
    /**
485
     * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/
486
     */
487
    public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
488
    {
489
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
490
491
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
492
    }
493
494
    /**
495
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/
496
     */
497
    public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder(
498
        PromotionInterface $promotion,
499
        $productDiscount,
500
        TaxonInterface $discountTaxon,
501
        $orderDiscount
502
    ) {
503
        $this->createUnitPercentagePromotion($promotion, $productDiscount, $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]));
504
        $this->createFixedPromotion($promotion, $orderDiscount);
505
    }
506
507
    /**
508
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/
509
     */
510
    public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast(
511
        PromotionInterface $promotion,
512
        $discount,
513
        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...
514
        $targetAmount
515
    ) {
516
        $freeShippingAction = $this->actionFactory->createShippingPercentageDiscount(1);
517
        $promotion->addAction($freeShippingAction);
518
519
        $channelCode = $this->sharedStorage->get('channel')->getCode();
520
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
521
522
        $this->createUnitFixedPromotion($promotion, $discount, [], $rule);
523
    }
524
525
    /**
526
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/
527
     */
528
    public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast(
529
        PromotionInterface $promotion,
530
        $taxonDiscount,
531
        TaxonInterface $taxon,
532
        $orderDiscount,
533
        $targetAmount
534
    ) {
535
        $orderDiscountAction = $this->actionFactory->createFixedDiscount($orderDiscount, $this->sharedStorage->get('channel')->getCode());
536
        $promotion->addAction($orderDiscountAction);
537
538
        $channelCode = $this->sharedStorage->get('channel')->getCode();
539
        $rule = $this->ruleFactory->createItemTotal($channelCode, $targetAmount);
540
541
        $this->createUnitPercentagePromotion(
542
            $promotion,
543
            $taxonDiscount,
544
            $this->getTaxonFilterConfiguration([$taxon->getCode()]),
545
            $rule
546
        );
547
    }
548
549
    /**
550
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/
551
     */
552
    public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr(
553
        PromotionInterface $promotion,
554
        $discount,
555
        array $discountTaxons,
556
        array $targetTaxons
557
    ) {
558
        $discountTaxonsCodes = [$discountTaxons[0]->getCode(), $discountTaxons[1]->getCode()];
559
        $targetTaxonsCodes = [$targetTaxons[0]->getCode(), $targetTaxons[1]->getCode()];
560
561
        $rule = $this->ruleFactory->createHasTaxon($targetTaxonsCodes);
562
563
        $this->createUnitPercentagePromotion(
564
            $promotion,
565
            $discount,
566
            $this->getTaxonFilterConfiguration($discountTaxonsCodes),
567
            $rule
568
        );
569
    }
570
571
    /**
572
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/
573
     */
574
    public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs(
575
        PromotionInterface $promotion,
576
        $discount,
577
        $discountTaxon,
578
        $targetTaxon
579
    ) {
580
        $rule = $this->ruleFactory->createHasTaxon([$targetTaxon->getCode()]);
581
582
        $this->createUnitPercentagePromotion(
583
            $promotion,
584
            $discount,
585
            $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]),
586
            $rule
587
        );
588
    }
589
590
    /**
591
     * @Given /^(it) is coupon based promotion$/
592
     */
593
    public function itIsCouponBasedPromotion(PromotionInterface $promotion)
594
    {
595
        $promotion->setCouponBased(true);
596
597
        $this->objectManager->flush();
598
    }
599
600
    /**
601
     * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/
602
     */
603
    public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel)
604
    {
605
        $promotion->removeChannel($channel);
606
607
        $this->objectManager->flush();
608
    }
609
610
    /**
611
     * @Given /^the (coupon "[^"]+") was used up to its usage limit$/
612
     */
613
    public function theCouponWasUsed(PromotionCouponInterface $coupon)
614
    {
615
        $coupon->setUsed($coupon->getUsageLimit());
616
617
        $this->objectManager->flush();
618
    }
619
620
    /**
621
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/
622
     */
623
    public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product)
624
    {
625
        $rule = $this->ruleFactory->createContainsProduct($product->getCode());
626
627
        $this->createFixedPromotion($promotion, $discount, [], $rule);
628
    }
629
630
    /**
631
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/
632
     */
633
    public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
634
    {
635
        $this->createUnitFixedPromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
636
    }
637
638
    /**
639
     * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/
640
     */
641
    public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product)
642
    {
643
        $this->createUnitPercentagePromotion($promotion, $discount, $this->getProductsFilterConfiguration([$product->getCode()]));
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(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null)
744
    {
745
        $this->persistPromotion($promotion, $this->actionFactory->createPercentageDiscount($discount), $configuration, $rule);
746
    }
747
748
    /**
749
     * @param PromotionInterface $promotion
750
     * @param PromotionActionInterface $action
751
     * @param array $configuration
752
     * @param PromotionRuleInterface|null $rule
753
     */
754
    private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null)
755
    {
756
        $configuration = array_merge_recursive($action->getConfiguration(), $configuration);
757
        $action->setConfiguration($configuration);
758
759
        $promotion->addAction($action);
760
        if (null !== $rule) {
761
            $promotion->addRule($rule);
762
        }
763
764
        $this->objectManager->flush();
765
    }
766
}
767