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