Completed
Push — remove-specs ( 8265db )
by Kamil
18:10
created

itGivesFixedDiscountInDifferentCurrencyToEveryOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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