Completed
Push — master ( b10958...e23a0f )
by Paweł
49:47 queued 34:50
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\Component\Core\Factory\ActionFactoryInterface;
17
use Sylius\Component\Core\Factory\RuleFactoryInterface;
18
use Sylius\Component\Core\Model\PromotionInterface;
19
use Sylius\Component\Core\Model\TaxonInterface;
20
use Sylius\Component\Core\Test\Factory\TestPromotionFactoryInterface;
21
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
22
use Sylius\Component\Promotion\Factory\CouponFactoryInterface;
23
use Sylius\Component\Promotion\Model\ActionInterface;
24
use Sylius\Component\Promotion\Model\CouponInterface;
25
use Sylius\Component\Promotion\Model\RuleInterface;
26
use Sylius\Component\Promotion\Repository\PromotionRepositoryInterface;
27
28
/**
29
 * @author Mateusz Zalewski <[email protected]>
30
 */
31
final class PromotionContext implements Context
32
{
33
    /**
34
     * @var SharedStorageInterface
35
     */
36
    private $sharedStorage;
37
38
    /**
39
     * @var ActionFactoryInterface
40
     */
41
    private $actionFactory;
42
43
    /**
44
     * @var CouponFactoryInterface
45
     */
46
    private $couponFactory;
47
48
    /**
49
     * @var RuleFactoryInterface
50
     */
51
    private $ruleFactory;
52
53
    /**
54
     * @var TestPromotionFactoryInterface
55
     */
56
    private $testPromotionFactory;
57
58
    /**
59
     * @var PromotionRepositoryInterface
60
     */
61
    private $promotionRepository;
62
63
    /**
64
     * @var ObjectManager
65
     */
66
    private $objectManager;
67
68
    /**
69
     * @param SharedStorageInterface $sharedStorage
70
     * @param ActionFactoryInterface $actionFactory
71
     * @param CouponFactoryInterface $couponFactory
72
     * @param RuleFactoryInterface $ruleFactory
73
     * @param TestPromotionFactoryInterface $testPromotionFactory
74
     * @param PromotionRepositoryInterface $promotionRepository
75
     * @param ObjectManager $objectManager
76
     */
77
    public function __construct(
78
        SharedStorageInterface $sharedStorage,
79
        ActionFactoryInterface $actionFactory,
80
        CouponFactoryInterface $couponFactory,
81
        RuleFactoryInterface $ruleFactory,
82
        TestPromotionFactoryInterface $testPromotionFactory,
83
        PromotionRepositoryInterface $promotionRepository,
84
        ObjectManager $objectManager
85
    ) {
86
        $this->sharedStorage = $sharedStorage;
87
        $this->actionFactory = $actionFactory;
88
        $this->couponFactory = $couponFactory;
89
        $this->ruleFactory = $ruleFactory;
90
        $this->testPromotionFactory = $testPromotionFactory;
91
        $this->promotionRepository = $promotionRepository;
92
        $this->objectManager = $objectManager;
93
    }
94
95
    /**
96
     * @Given there is a promotion :promotionName
97
     * @Given there is a promotion :promotionName identified by :promotionCode code
98
     */
99
    public function thereIsPromotion($promotionName, $promotionCode = null)
100
    {
101
        $promotion = $this->testPromotionFactory
102
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
103
        ;
104
105
        if (null !== $promotionCode) {
106
            $promotion->setCode($promotionCode);
107
        }
108
109
        $this->promotionRepository->add($promotion);
110
        $this->sharedStorage->set('promotion', $promotion);
111
    }
112
113
    /**
114
     * @Given the store has promotion :promotionName with coupon :couponCode
115
     * @Given the store has also promotion :promotionName with coupon :couponCode
116
     */
117
    public function thereIsPromotionWithCoupon($promotionName, $couponCode)
118
    {
119
        /** @var CouponInterface $coupon */
120
        $coupon = $this->couponFactory->createNew();
121
        $coupon->setCode($couponCode);
122
123
        $promotion = $this->testPromotionFactory
124
            ->createForChannel($promotionName, $this->sharedStorage->get('channel'))
125
        ;
126
        $promotion->addCoupon($coupon);
127
        $promotion->setCouponBased(true);
128
129
        $this->promotionRepository->add($promotion);
130
        $this->sharedStorage->set('promotion', $promotion);
131
        $this->sharedStorage->set('coupon', $coupon);
132
    }
133
134
    /**
135
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/
136
     */
137
    public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount)
138
    {
139
        $this->createFixedPromotion($promotion, $discount);
140
    }
141
142
    /**
143
     * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/
144
     */
145
    public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount)
146
    {
147
        $this->createPercentagePromotion($promotion, $discount);
148
    }
149
150
    /**
151
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/
152
     */
153
    public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast(
154
        PromotionInterface $promotion,
155
        $discount,
156
        $quantity
157
    ) {
158
        $rule = $this->ruleFactory->createCartQuantity((int) $quantity);
159
160
        $this->createFixedPromotion($promotion, $discount, [], $rule);
161
    }
162
163
    /**
164
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/
165
     */
166
    public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast(
167
        PromotionInterface $promotion,
168
        $discount,
169
        $targetAmount
170
    ) {
171
        $rule = $this->ruleFactory->createItemTotal($targetAmount);
172
173
        $this->createFixedPromotion($promotion, $discount, [], $rule);
174
    }
175
176
    /**
177
     * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/
178
     */
179
    public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount)
180
    {
181
        $action = $this->actionFactory->createPercentageShippingDiscount($discount);
182
        $promotion->addAction($action);
183
184
        $this->objectManager->flush();
185
    }
186
187
    /**
188
     * @Given /^([^"]+) gives free shipping to every order$/
189
     */
190
    public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion)
191
    {
192
        $this->itGivesPercentageDiscountOnShippingToEveryOrder($promotion, 1);
193
    }
194
195
    /**
196
     * @Given /^([^"]+) gives ("[^"]+%") off every product (classified as "[^"]+")$/
197
     */
198
    public function itGivesPercentageOffEveryProductClassifiedAs(
199
        PromotionInterface $promotion,
200
        $discount,
201
        TaxonInterface $taxon
202
    ) {
203
        $this->createItemPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
204
    }
205
206
    /**
207
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/
208
     */
209
    public function itGivesFixedOffEveryProductClassifiedAs(
210
        PromotionInterface $promotion,
211
        $discount,
212
        TaxonInterface $taxon
213
    ) {
214
        $this->createItemFixedPromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$taxon->getCode()]));
215
    }
216
217
    /**
218
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
219
     */
220
    public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt(
221
        PromotionInterface $promotion,
222
        $discount,
223
        $amount
224
    ) {
225
        $this->createItemFixedPromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
226
    }
227
228
    /**
229
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
230
     */
231
    public function thisPromotionGivesOffOnEveryProductPricedBetween(
232
        PromotionInterface $promotion,
233
        $discount,
234
        $minAmount,
235
        $maxAmount
236
    ) {
237
        $this->createItemFixedPromotion(
238
            $promotion,
239
            $discount,
240
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
241
        );
242
    }
243
244
    /**
245
     * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/
246
     */
247
    public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt(
248
        PromotionInterface $promotion,
249
        $discount,
250
        $amount
251
    ) {
252
        $this->createItemPercentagePromotion($promotion, $discount, $this->getPriceRangeFilterConfiguration($amount));
253
    }
254
255
    /**
256
     * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/
257
     */
258
    public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween(
259
        PromotionInterface $promotion,
260
        $discount,
261
        $minAmount,
262
        $maxAmount
263
    ) {
264
        $this->createItemPercentagePromotion(
265
            $promotion,
266
            $discount,
267
            $this->getPriceRangeFilterConfiguration($minAmount, $maxAmount)
268
        );
269
    }
270
271
    /**
272
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/
273
     */
274
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs(
275
        PromotionInterface $promotion,
276
        $discount,
277
        TaxonInterface $taxon
278
    ) {
279
        $rule = $this->ruleFactory->createTaxon([$taxon->getCode()]);
280
281
        $this->createFixedPromotion($promotion, $discount, [], $rule);
282
    }
283
284
    /**
285
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/
286
     */
287
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr(
288
        PromotionInterface $promotion,
289
        $discount,
290
        array $taxons
291
    ) {
292
        $rule = $this->ruleFactory->createTaxon([$taxons[0]->getCode(), $taxons[1]->getCode()]);
293
294
        $this->createFixedPromotion($promotion, $discount, [], $rule);
295
    }
296
297
    /**
298
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/
299
     */
300
    public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt(
301
        PromotionInterface $promotion,
302
        $discount,
303
        TaxonInterface $taxon,
304
        $amount
305
    ) {
306
        $rule = $this->ruleFactory->createItemsFromTaxonTotal($taxon->getCode(), $amount);
307
308
        $this->createFixedPromotion($promotion, $discount, [], $rule);
309
    }
310
311
    /**
312
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (\d+) products (classified as "[^"]+")$/
313
     */
314
    public function thePromotionGivesOffIfOrderContainsNumberOfProductsClassifiedAs(
315
        PromotionInterface $promotion,
316
        $discount,
317
        $count,
318
        TaxonInterface $taxon
319
    ) {
320
        $rule = $this->ruleFactory->createContainsTaxon($taxon->getCode(), $count);
321
322
        $this->createFixedPromotion($promotion, $discount, [], $rule);
323
    }
324
325
    /**
326
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/
327
     */
328
    public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
329
    {
330
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
331
332
        $this->createFixedPromotion($promotion, $discount, [], $rule);
333
    }
334
335
    /**
336
     * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/
337
     */
338
    public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth)
339
    {
340
        $rule = $this->ruleFactory->createNthOrder((int) $nth);
341
342
        $this->createPercentagePromotion($promotion, $discount, [], $rule);
343
    }
344
345
    /**
346
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if an order contains any product (classified as "[^"]+")$/
347
     */
348
    public function itGivesPercentageOffOnEveryProductClassifiedAsIfAnOrderContainsAnyProductClassifiedAs(
349
        PromotionInterface $promotion,
350
        $discount,
351
        TaxonInterface $discountTaxon,
352
        TaxonInterface $targetTaxon
353
    ) {
354
        $rule = $this->ruleFactory->createContainsTaxon($targetTaxon->getCode(), 1);
355
356
        $this->createItemPercentagePromotion($promotion, $discount, $this->getTaxonFilterConfiguration([$discountTaxon->getCode()]), $rule);
357
    }
358
359
    /**
360
     * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/
361
     */
362
    public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast(
363
        PromotionInterface $promotion,
364
        $discount,
365
        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...
366
        $targetAmount
367
    ) {
368
        $freeShippingAction = $this->actionFactory->createPercentageShippingDiscount(1);
369
        $promotion->addAction($freeShippingAction);
370
371
        $rule = $this->ruleFactory->createItemTotal($targetAmount);
372
373
        $this->createItemFixedPromotion($promotion, $discount, [], $rule);
374
    }
375
376
    /**
377
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/
378
     */
379
    public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast(
380
        PromotionInterface $promotion,
381
        $taxonDiscount,
382
        TaxonInterface $taxon,
383
        $orderDiscount,
384
        $targetAmount
385
    ) {
386
        $orderDiscountAction = $this->actionFactory->createFixedDiscount($orderDiscount);
387
        $promotion->addAction($orderDiscountAction);
388
389
        $rule = $this->ruleFactory->createItemTotal($targetAmount);
390
391
        $this->createItemPercentagePromotion(
392
            $promotion,
393
            $taxonDiscount,
394
            $this->getTaxonFilterConfiguration([$taxon->getCode()]),
395
            $rule
396
        );
397
    }
398
399
    /**
400
     * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/
401
     */
402
    public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr(
403
        PromotionInterface $promotion,
404
        $discount,
405
        array $discountTaxons,
406
        array $targetTaxons
407
    ) {
408
        $discountTaxonsCodes = [$discountTaxons[0]->getCode(), $discountTaxons[1]->getCode()];
409
        $targetTaxonsCodes = [$targetTaxons[0]->getCode(), $targetTaxons[1]->getCode()];
410
411
        $rule = $this->ruleFactory->createTaxon($targetTaxonsCodes);
412
413
        $this->createItemPercentagePromotion(
414
            $promotion,
415
            $discount,
416
            $this->getTaxonFilterConfiguration($discountTaxonsCodes),
417
            $rule
418
        );
419
    }
420
421
    /**
422
     * @Given /^(it) is coupon based promotion$/
423
     */
424
    public function itIsCouponBasedPromotion(PromotionInterface $promotion)
425
    {
426
        $promotion->setCouponBased(true);
427
428
        $this->objectManager->flush();
429
    }
430
431
    /**
432
     * @param array $taxonCodes
433
     *
434
     * @return array
435
     */
436
    private function getTaxonFilterConfiguration(array $taxonCodes)
437
    {
438
        return ['filters' => ['taxons' => $taxonCodes]];
439
    }
440
441
    /**
442
     * @param int $minAmount
443
     * @param int $maxAmount
444
     *
445
     * @return array
446
     */
447
    private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null)
448
    {
449
        $configuration = ['filters' => ['price_range' => ['min' => $minAmount]]];
450
        if (null !== $maxAmount) {
451
            $configuration['filters']['price_range']['max'] = $maxAmount;
452
        }
453
454
        return $configuration;
455
    }
456
457
    /**
458
     * @param PromotionInterface $promotion
459
     * @param int $discount
460
     * @param array $configuration
461
     */
462
    private function createItemFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], $rule = null)
463
    {
464
        $this->persistPromotion($promotion, $this->actionFactory->createItemFixedDiscount($discount), $configuration, $rule);
465
    }
466
467
    /**
468
     * @param PromotionInterface $promotion
469
     * @param int $discount
470
     * @param array $configuration
471
     */
472
    private function createItemPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], $rule = null)
473
    {
474
        $this->persistPromotion($promotion, $this->actionFactory->createItemPercentageDiscount($discount), $configuration, $rule);
475
    }
476
477
    /**
478
     * @param PromotionInterface $promotion
479
     * @param int $discount
480
     * @param array $configuration
481
     * @param RuleInterface $rule
482
     */
483
    private function createFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], RuleInterface $rule = null)
484
    {
485
        $this->persistPromotion($promotion, $this->actionFactory->createFixedDiscount($discount), $configuration, $rule);
486
    }
487
488
    /**
489
     * @param PromotionInterface $promotion
490
     * @param float $discount
491
     * @param array $configuration
492
     * @param RuleInterface $rule
493
     */
494
    private function createPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], RuleInterface $rule = null)
495
    {
496
        $this->persistPromotion($promotion, $this->actionFactory->createPercentageDiscount($discount), $configuration, $rule);
497
    }
498
499
    /**
500
     * @param PromotionInterface $promotion
501
     * @param ActionInterface $action
502
     * @param array $configuration
503
     * @param RuleInterface|null $rule
504
     */
505
    private function persistPromotion(PromotionInterface $promotion, ActionInterface $action, array $configuration, RuleInterface $rule = null)
506
    {
507
        $configuration = array_merge($configuration, $action->getConfiguration());
508
        $action->setConfiguration($configuration);
509
510
        $promotion->addAction($action);
511
        if (null !== $rule) {
512
            $promotion->addRule($rule);
513
        }
514
515
        $this->objectManager->flush();
516
    }
517
}
518