Completed
Push — scalar-types/taxonomy ( 4d330b )
by Kamil
23:21
created

thePromotionGivesOffTheOrderForCustomersFromGroup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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