Completed
Push — master ( fcfa74...4ea0bb )
by Paweł
20s
created

Sylius/Behat/Context/Setup/PromotionContext.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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,
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
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
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
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
669
     *
670
     * @return array
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
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