Completed
Pull Request — master (#8491)
by Stefan
18:30 queued 07:04
created

TaxationContext::theStoreHasTaxCategories()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Setup;
15
16
use Behat\Behat\Context\Context;
17
use Doctrine\Common\Persistence\ObjectManager;
18
use Sylius\Behat\Service\SharedStorageInterface;
19
use Sylius\Component\Addressing\Model\ZoneInterface;
20
use Sylius\Component\Core\Formatter\StringInflector;
21
use Sylius\Component\Core\Model\TaxRateInterface;
22
use Sylius\Component\Resource\Factory\FactoryInterface;
23
use Sylius\Component\Resource\Repository\RepositoryInterface;
24
use Sylius\Component\Taxation\Model\TaxCategoryInterface;
25
use Sylius\Component\Taxation\Repository\TaxCategoryRepositoryInterface;
26
use Webmozart\Assert\Assert;
27
28
final class TaxationContext implements Context
29
{
30
    /**
31
     * @var SharedStorageInterface
32
     */
33
    private $sharedStorage;
34
35
    /**
36
     * @var FactoryInterface
37
     */
38
    private $taxRateFactory;
39
40
    /**
41
     * @var FactoryInterface
42
     */
43
    private $taxCategoryFactory;
44
45
    /**
46
     * @var RepositoryInterface
47
     */
48
    private $taxRateRepository;
49
50
    /**
51
     * @var TaxCategoryRepositoryInterface
52
     */
53
    private $taxCategoryRepository;
54
55
    /**
56
     * @var ObjectManager
57
     */
58
    private $objectManager;
59
60
    /**
61
     * @param SharedStorageInterface $sharedStorage
62
     * @param FactoryInterface $taxRateFactory
63
     * @param FactoryInterface $taxCategoryFactory
64
     * @param RepositoryInterface $taxRateRepository
65
     * @param TaxCategoryRepositoryInterface $taxCategoryRepository
66
     * @param ObjectManager $objectManager
67
     */
68
    public function __construct(
69
        SharedStorageInterface $sharedStorage,
70
        FactoryInterface $taxRateFactory,
71
        FactoryInterface $taxCategoryFactory,
72
        RepositoryInterface $taxRateRepository,
73
        TaxCategoryRepositoryInterface $taxCategoryRepository,
74
        ObjectManager $objectManager
75
    ) {
76
        $this->sharedStorage = $sharedStorage;
77
        $this->taxRateFactory = $taxRateFactory;
78
        $this->taxCategoryFactory = $taxCategoryFactory;
79
        $this->taxRateRepository = $taxRateRepository;
80
        $this->taxCategoryRepository = $taxCategoryRepository;
81
        $this->objectManager = $objectManager;
82
    }
83
84
    /**
85
     * @Given the store has :taxRateName tax rate of :taxRateAmount% for :taxCategoryName within the :zone zone
86
     * @Given the store has :taxRateName tax rate of :taxRateAmount% for :taxCategoryName within the :zone zone identified by the :taxRateCode code
87
     * @Given /^the store has(?:| also) "([^"]+)" tax rate of ([^"]+)% for "([^"]+)" for the (rest of the world)$/
88
     */
89
    public function storeHasTaxRateWithinZone(
90
        $taxRateName,
91
        $taxRateAmount,
92
        $taxCategoryName,
93
        ZoneInterface $zone,
94
        $taxRateCode = null,
95
        $includedInPrice = false
96
    ) {
97
        $taxCategory = $this->getOrCreateTaxCategory($taxCategoryName);
98
99
        if (null === $taxRateCode) {
100
            $taxRateCode = $this->getCodeFromNameAndZoneCode($taxRateName, $zone->getCode());
101
        }
102
103
        /** @var TaxRateInterface $taxRate */
104
        $taxRate = $this->taxRateFactory->createNew();
105
        $taxRate->setName($taxRateName);
106
        $taxRate->setCode($taxRateCode);
107
        $taxRate->setZone($zone);
108
        $taxRate->setAmount((float) $this->getAmountFromString($taxRateAmount));
109
        $taxRate->setCategory($taxCategory);
110
        $taxRate->setCalculator('default');
111
        $taxRate->setIncludedInPrice($includedInPrice);
112
113
        $this->taxRateRepository->add($taxRate);
114
115
        $this->sharedStorage->set('tax_rate', $taxRate);
116
    }
117
118
    /**
119
     * @Given the store has included in price :taxRateName tax rate of :taxRateAmount% for :taxCategoryName within the :zone zone
120
     */
121
    public function storeHasIncludedInPriceTaxRateWithinZone($taxRateName, $taxRateAmount, $taxCategoryName, ZoneInterface $zone)
122
    {
123
        $this->storeHasTaxRateWithinZone($taxRateName, $taxRateAmount, $taxCategoryName, $zone, null, true);
124
    }
125
126
    /**
127
     * @Given the store has a tax category :name with a code :code
128
     * @Given the store has a tax category :name
129
     * @Given the store has a tax category :name also
130
     */
131
    public function theStoreHasTaxCategoryWithCode($name, $code = null)
132
    {
133
        $taxCategory = $this->createTaxCategory($name, $code);
134
135
        $this->sharedStorage->set('tax_category', $taxCategory);
136
    }
137
138
    /**
139
     * @Given the store has tax categories :firstName, :secondName and :thirdName
140
     */
141
    public function theStoreHasTaxCategories(string ...$names): void
142
    {
143
        foreach ($names as $name) {
144
            $this->theStoreHasTaxCategoryWithCode($name);
145
        }
146
    }
147
148
    /**
149
     * @Given the store does not have any categories defined
150
     */
151
    public function theStoreDoesNotHaveAnyCategoriesDefined()
152
    {
153
        $taxCategories = $this->taxCategoryRepository->findAll();
154
155
        foreach ($taxCategories as $taxCategory) {
156
            $this->taxCategoryRepository->remove($taxCategory);
157
        }
158
    }
159
160
    /**
161
     * @Given /^the ("[^"]+" tax rate) has changed to ([^"]+)%$/
162
     */
163
    public function theTaxRateIsOfAmount(TaxRateInterface $taxRate, $amount)
164
    {
165
        $taxRate->setAmount((float) $this->getAmountFromString($amount));
166
167
        $this->objectManager->flush();
168
    }
169
170
    /**
171
     * @param string $taxCategoryName
172
     *
173
     * @return TaxCategoryInterface
174
     */
175
    private function getOrCreateTaxCategory($taxCategoryName)
176
    {
177
        $taxCategories = $this->taxCategoryRepository->findByName($taxCategoryName);
178
        if (empty($taxCategories)) {
179
            return $this->createTaxCategory($taxCategoryName);
180
        }
181
182
        Assert::eq(
183
            count($taxCategories),
184
            1,
185
            sprintf('%d tax categories has been found with name "%s".', count($taxCategories), $taxCategoryName)
186
        );
187
188
        return $taxCategories[0];
189
    }
190
191
    /**
192
     * @param string $taxCategoryName
193
     * @param string|null $taxCategoryCode
194
     *
195
     * @return TaxCategoryInterface
196
     */
197
    private function createTaxCategory($taxCategoryName, $taxCategoryCode = null)
198
    {
199
        /** @var TaxCategoryInterface $taxCategory */
200
        $taxCategory = $this->taxCategoryFactory->createNew();
201
        if (null === $taxCategoryCode) {
202
            $taxCategoryCode = $this->getCodeFromName($taxCategoryName);
203
        }
204
205
        $taxCategory->setName($taxCategoryName);
206
        $taxCategory->setCode($taxCategoryCode);
207
208
        $this->taxCategoryRepository->add($taxCategory);
209
210
        return $taxCategory;
211
    }
212
213
    /**
214
     * @param string $taxRateAmount
215
     *
216
     * @return string
217
     */
218
    private function getAmountFromString($taxRateAmount)
219
    {
220
        return ((int) $taxRateAmount) / 100;
221
    }
222
223
    /**
224
     * @param string $taxRateName
225
     *
226
     * @return string
227
     */
228
    private function getCodeFromName($taxRateName)
229
    {
230
        return StringInflector::nameToLowercaseCode($taxRateName);
231
    }
232
233
    /**
234
     * @param string $taxRateName
235
     * @param string $zoneCode
236
     *
237
     * @return string
238
     */
239
    private function getCodeFromNameAndZoneCode($taxRateName, $zoneCode)
240
    {
241
        return $this->getCodeFromName($taxRateName) . '_' . strtolower($zoneCode);
242
    }
243
}
244