CalculationBusinessTester::isCanceledAmount()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
/**
4
 * This file is part of the Spryker Commerce OS.
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types = 1);
9
10
namespace PyzTest\Zed\Calculation;
11
12
use Codeception\Actor;
13
use DateTime;
14
use Generated\Shared\Transfer\AddressTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\AddressTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Generated\Shared\Transfer\CurrencyTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\CurrencyTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Generated\Shared\Transfer\DiscountTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\DiscountTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Generated\Shared\Transfer\ExpenseTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\ExpenseTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Generated\Shared\Transfer\ItemTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\ItemTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Generated\Shared\Transfer\ProductOptionTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\ProductOptionTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Generated\Shared\Transfer\QuoteTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\QuoteTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Generated\Shared\Transfer\StoreTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\StoreTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Orm\Zed\Country\Persistence\SpyCountryQuery;
23
use Orm\Zed\Currency\Persistence\SpyCurrency;
24
use Orm\Zed\Currency\Persistence\SpyCurrencyQuery;
25
use Orm\Zed\Discount\Persistence\SpyDiscount;
26
use Orm\Zed\Discount\Persistence\SpyDiscountAmount;
27
use Orm\Zed\Discount\Persistence\SpyDiscountQuery;
28
use Orm\Zed\Discount\Persistence\SpyDiscountStore;
29
use Orm\Zed\Discount\Persistence\SpyDiscountVoucher;
30
use Orm\Zed\Discount\Persistence\SpyDiscountVoucherPool;
31
use Orm\Zed\Product\Persistence\SpyProductAbstract;
32
use Orm\Zed\ProductOption\Persistence\SpyProductOptionGroup;
33
use Orm\Zed\ProductOption\Persistence\SpyProductOptionValue;
34
use Orm\Zed\Tax\Persistence\SpyTaxRate;
35
use Orm\Zed\Tax\Persistence\SpyTaxSet;
36
use Orm\Zed\Tax\Persistence\SpyTaxSetTax;
37
use Pyz\Zed\Calculation\CalculationDependencyProvider;
38
use Pyz\Zed\Discount\DiscountDependencyProvider;
39
use Spryker\Shared\Calculation\CalculationPriceMode;
40
use Spryker\Shared\Tax\TaxConstants;
41
use Spryker\Zed\Calculation\Business\CalculationBusinessFactory;
42
use Spryker\Zed\Calculation\Business\CalculationFacade;
43
use Spryker\Zed\Calculation\Communication\Plugin\Calculator\GrandTotalCalculatorPlugin;
44
use Spryker\Zed\Calculation\Communication\Plugin\Calculator\RefundableAmountCalculatorPlugin;
45
use Spryker\Zed\Calculation\Communication\Plugin\Calculator\RefundTotalCalculatorPlugin;
46
use Spryker\Zed\Calculation\Dependency\Service\CalculationToUtilTextBridge;
47
use Spryker\Zed\Kernel\Container;
48
49
/**
50
 * Inherited Methods
51
 *
52
 * @method void wantToTest($text)
53
 * @method void wantTo($text)
54
 * @method void execute($callable)
55
 * @method void expectTo($prediction)
56
 * @method void expect($prediction)
57
 * @method void amGoingTo($argumentation)
58
 * @method void am($role)
59
 * @method void lookForwardTo($achieveValue)
60
 * @method void comment($description)
61
 * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
62
 *
63
 * @SuppressWarnings(\PyzTest\Zed\Calculation\PHPMD)
64
 */
65
class CalculationBusinessTester extends Actor
66
{
67
    use _generated\CalculationBusinessTesterActions;
0 ignored issues
show
Bug introduced by
The type PyzTest\Zed\Calculation\...onBusinessTesterActions was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
68
69
    /**
70
     * @var int
71
     */
72
    protected $incrementNumber = 0;
73
74
    /**
75
     * @var string
76
     */
77
    protected const COUNTRY_DE = 'DE';
78
79
    /**
80
     * @param int $discountAmount
81
     * @param string $calculatorType
82
     * @param string $sku
83
     *
84
     * @return \Orm\Zed\Discount\Persistence\SpyDiscountVoucher
85
     */
86
    public function createDiscounts(int $discountAmount, string $calculatorType, string $sku = '*'): SpyDiscountVoucher
87
    {
88
        $discountVoucherPoolEntity = new SpyDiscountVoucherPool();
89
        $discountVoucherPoolEntity->setName('test-pool' . $this->getIncrementNumber());
90
        $discountVoucherPoolEntity->setIsActive(true);
91
        $discountVoucherPoolEntity->save();
92
93
        $discountVoucherEntity = new SpyDiscountVoucher();
94
        $discountVoucherEntity->setCode('spryker-test' . $this->getIncrementNumber());
95
        $discountVoucherEntity->setIsActive(true);
96
        $discountVoucherEntity->setFkDiscountVoucherPool($discountVoucherPoolEntity->getIdDiscountVoucherPool());
97
        $discountVoucherEntity->save();
98
99
        $discountEntity = new SpyDiscount();
100
        $discountEntity->setAmount($discountAmount);
101
        $discountEntity->setDisplayName('test1' . $this->getIncrementNumber());
102
        $discountEntity->setIsActive(1);
103
        $discountEntity->setValidFrom(new DateTime('1985-07-01'));
104
        $discountEntity->setValidTo(new DateTime('2030-07-01'));
105
        $discountEntity->setCalculatorPlugin($calculatorType);
106
        $discountEntity->setCollectorQueryString('sku = "' . $sku . '"');
107
108
        $discountEntity->setFkDiscountVoucherPool($discountVoucherPoolEntity->getIdDiscountVoucherPool());
109
        $discountEntity->save();
110
111
        (new SpyDiscountStore())
112
            ->setFkDiscount($discountEntity->getIdDiscount())
113
            ->setFkStore($this->getCurrentStoreTransfer()->getIdStore())
114
            ->save();
115
116
        $discountAmountEntity = new SpyDiscountAmount();
117
        $currencyEntity = $this->getCurrency();
118
        $discountAmountEntity->setFkCurrency($currencyEntity->getIdCurrency());
119
        $discountAmountEntity->setNetAmount($discountAmount);
120
        $discountAmountEntity->setGrossAmount($discountAmount);
121
        $discountAmountEntity->setFkDiscount($discountEntity->getIdDiscount());
122
        $discountAmountEntity->save();
123
124
        $discountEntity->reload(true);
125
        $pool = $discountEntity->getVoucherPool();
126
        $pool->getDiscountVouchers();
127
128
        return $discountVoucherEntity;
129
    }
130
131
    /**
132
     * @param int $price
133
     * @param string $priceMode
134
     * @param float $taxRate
135
     * @param int $quantity
136
     *
137
     * @return \Generated\Shared\Transfer\ExpenseTransfer
138
     */
139
    public function createExpenseTransfer(int $price, string $priceMode, float $taxRate, int $quantity): ExpenseTransfer
140
    {
141
        $expenseTransfer = new ExpenseTransfer();
142
        $expenseTransfer->setTaxRate($taxRate);
143
        $expenseTransfer->setQuantity($quantity);
144
145
        if ($priceMode === CalculationPriceMode::PRICE_MODE_GROSS) {
146
            $expenseTransfer->setUnitGrossPrice($price);
147
        }
148
149
        if ($priceMode === CalculationPriceMode::PRICE_MODE_NET) {
150
            $expenseTransfer->setUnitNetPrice($price);
151
        }
152
153
        return $expenseTransfer;
154
    }
155
156
    /**
157
     * @param array $calculatorPlugins
158
     *
159
     * @return \Spryker\Zed\Calculation\Business\CalculationFacade
160
     */
161
    public function createCalculationFacade(array $calculatorPlugins = []): CalculationFacade
162
    {
163
        if (!$calculatorPlugins) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $calculatorPlugins of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
164
            return new CalculationFacade();
165
        }
166
167
        $calculationFacade = new CalculationFacade();
168
169
        $calculationBusinessFactory = new CalculationBusinessFactory();
170
171
        $container = new Container();
172
        $container[CalculationDependencyProvider::QUOTE_CALCULATOR_PLUGIN_STACK] = $calculatorPlugins;
173
        $container[CalculationDependencyProvider::PLUGINS_QUOTE_POST_RECALCULATE] = [];
174
175
        $container->set(CalculationDependencyProvider::SERVICE_UTIL_TEXT, function (Container $container) {
176
            return new CalculationToUtilTextBridge($container->getLocator()->utilText()->service());
177
        });
178
179
        $calculationBusinessFactory->setContainer($container);
180
        $calculationFacade->setFactory($calculationBusinessFactory);
181
182
        return $calculationFacade;
183
    }
184
185
    /**
186
     * @return void
187
     */
188
    public function resetCurrentDiscounts(): void
189
    {
190
        $discounts = SpyDiscountQuery::create()->find();
191
192
        foreach ($discounts as $discountEntity) {
193
            $discountEntity->setIsActive(false);
194
195
            $discountEntity->save();
196
        }
197
    }
198
199
    /**
200
     * @param array<\Generated\Shared\Transfer\ItemTransfer> $items
201
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
202
     *
203
     * @return \Generated\Shared\Transfer\QuoteTransfer
204
     */
205
    public function recalculateCanceledAmount(array $items, QuoteTransfer $quoteTransfer): QuoteTransfer
206
    {
207
        if (!$this->isCanceledAmount($items)) {
208
            return $quoteTransfer;
209
        }
210
211
        foreach ($quoteTransfer->getItems() as $itemTransferIndex => $itemTransfer) {
212
            $itemTransfer->setCanceledAmount($items[$itemTransferIndex][5]);
213
            $itemTransfer->setRefundableAmount($items[$itemTransferIndex][5]);
214
        }
215
216
        $calculationFacade = $this->createCalculationFacade(
217
            [
218
                new RefundableAmountCalculatorPlugin(),
219
                new RefundTotalCalculatorPlugin(),
220
                new GrandTotalCalculatorPlugin(),
221
            ],
222
        );
223
224
        return $calculationFacade->recalculateQuote($quoteTransfer);
225
    }
226
227
    /**
228
     * @param int $discountAmount
229
     * @param string $sku
230
     *
231
     * @return \Generated\Shared\Transfer\DiscountTransfer
232
     */
233
    public function createDiscountTransfer(int $discountAmount, string $sku): DiscountTransfer
234
    {
235
        $voucherEntity = $this->createDiscounts($discountAmount, DiscountDependencyProvider::PLUGIN_CALCULATOR_FIXED, $sku);
236
237
        return (new DiscountTransfer())
238
            ->setVoucherCode($voucherEntity->getCode());
239
    }
240
241
    /**
242
     * @return \Generated\Shared\Transfer\StoreTransfer
243
     */
244
    public function getCurrentStoreTransfer(): StoreTransfer
245
    {
246
        return (new StoreTransfer())
247
            ->setIdStore(1)
248
            ->setName(static::COUNTRY_DE);
249
    }
250
251
    /**
252
     * @return \Generated\Shared\Transfer\AddressTransfer
253
     */
254
    public function getCurrentShippingAddress(): AddressTransfer
255
    {
256
        return (new AddressTransfer())->setIso2Code(static::COUNTRY_DE);
257
    }
258
259
    /**
260
     * @return \Generated\Shared\Transfer\CurrencyTransfer
261
     */
262
    public function createCurrencyTransfer(): CurrencyTransfer
263
    {
264
        return (new CurrencyTransfer())
265
            ->setCode('EUR');
266
    }
267
268
    /**
269
     * @param int $price
270
     * @param string $priceMode
271
     * @param float $taxRate
272
     * @param int $quantity
273
     *
274
     * @return \Generated\Shared\Transfer\ItemTransfer
275
     */
276
    public function createItemTransfer(int $price, string $priceMode, float $taxRate, int $quantity): ItemTransfer
277
    {
278
        $abstractProductEntity = $this->createAbstractProductWithTaxSet($taxRate);
279
280
        $itemTransfer = (new ItemTransfer())
281
            ->setName('test' . $this->getIncrementNumber())
282
            ->setIdProductAbstract($abstractProductEntity->getIdProductAbstract())
283
            ->setSku('test' . $this->getIncrementNumber())
284
            ->setQuantity($quantity)
285
            ->setTaxRate($taxRate);
286
287
        if ($priceMode === CalculationPriceMode::PRICE_MODE_GROSS) {
288
            $itemTransfer->setUnitGrossPrice($price);
289
        }
290
291
        if ($priceMode === CalculationPriceMode::PRICE_MODE_NET) {
292
            $itemTransfer->setUnitNetPrice($price);
293
        }
294
295
        return $itemTransfer;
296
    }
297
298
    /**
299
     * @param int $price
300
     * @param string $priceMode
301
     * @param float $taxRate
302
     * @param int $quantity
303
     *
304
     * @return \Generated\Shared\Transfer\ProductOptionTransfer
305
     */
306
    public function createProductOptionTransfer(int $price, string $priceMode, float $taxRate, int $quantity): ProductOptionTransfer
307
    {
308
        $productOptionValueEntity = $this->createProductOptionValue($taxRate);
309
310
        $productOptionTransfer = (new ProductOptionTransfer())
311
            ->setTaxRate($taxRate)
312
            ->setQuantity($quantity)
313
            ->setIdProductOptionValue($productOptionValueEntity->getIdProductOptionValue());
314
315
        if ($priceMode === CalculationPriceMode::PRICE_MODE_GROSS) {
316
            $productOptionTransfer->setUnitGrossPrice($price);
317
        }
318
319
        if ($priceMode === CalculationPriceMode::PRICE_MODE_NET) {
320
            $productOptionTransfer->setUnitNetPrice($price);
321
        }
322
323
        return $productOptionTransfer;
324
    }
325
326
    /**
327
     * @param float $taxRate
328
     *
329
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
330
     */
331
    public function createAbstractProductWithTaxSet(float $taxRate): SpyProductAbstract
332
    {
333
        $countryEntity = SpyCountryQuery::create()->findOneByIso2Code(static::COUNTRY_DE);
334
335
        $taxRateEntity = new SpyTaxRate();
336
        $taxRateEntity->setRate($taxRate);
337
        $taxRateEntity->setName('test rate');
338
        $taxRateEntity->setFkCountry($countryEntity->getIdCountry());
339
        $taxRateEntity->save();
340
341
        $taxSetEntity = $this->createTaxSet();
342
343
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
344
345
        return $this->createAbstractProduct($taxSetEntity);
346
    }
347
348
    /**
349
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
350
     */
351
    public function createAbstractProductWithTaxExemption(): SpyProductAbstract
352
    {
353
        $taxRateEntity = new SpyTaxRate();
354
        $taxRateEntity->setRate(0);
355
        $taxRateEntity->setName(TaxConstants::TAX_EXEMPT_PLACEHOLDER);
356
        $taxRateEntity->save();
357
358
        $taxSetEntity = $this->createTaxSet();
359
360
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
361
362
        return $this->createAbstractProduct($taxSetEntity);
363
    }
364
365
    /**
366
     * @return int
367
     */
368
    protected function getIncrementNumber(): int
369
    {
370
        return ++$this->incrementNumber;
371
    }
372
373
    /**
374
     * @return \Orm\Zed\Currency\Persistence\SpyCurrency
375
     */
376
    protected function getCurrency(): SpyCurrency
377
    {
378
        return SpyCurrencyQuery::create()->findOneByCode('EUR');
379
    }
380
381
    /**
382
     * @param float $taxRate
383
     *
384
     * @return \Orm\Zed\ProductOption\Persistence\SpyProductOptionValue
385
     */
386
    protected function createProductOptionValue(float $taxRate): SpyProductOptionValue
387
    {
388
        $countryEntity = SpyCountryQuery::create()->findOneByIso2Code('DE');
389
390
        $taxRateEntity = new SpyTaxRate();
391
        $taxRateEntity->setRate($taxRate);
392
        $taxRateEntity->setName('test rate');
393
        $taxRateEntity->setFkCountry($countryEntity->getIdCountry());
394
        $taxRateEntity->save();
395
396
        $taxSetEntity = $this->createTaxSet();
397
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
398
399
        $productOptionGroupEntity = new SpyProductOptionGroup();
400
        $productOptionGroupEntity->setName('group.name.translation.key.edit');
401
        $productOptionGroupEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
402
        $productOptionGroupEntity->save();
403
404
        $productOptionValueEntity = new SpyProductOptionValue();
405
        $productOptionValueEntity->setSku('product-' . $this->getIncrementNumber());
406
        $productOptionValueEntity->setFkProductOptionGroup($productOptionGroupEntity->getIdProductOptionGroup());
407
        $productOptionValueEntity->setValue('product.option.test');
408
        $productOptionValueEntity->save();
409
410
        return $productOptionValueEntity;
411
    }
412
413
    /**
414
     * @return \Orm\Zed\Tax\Persistence\SpyTaxSet
415
     */
416
    protected function createTaxSet(): SpyTaxSet
417
    {
418
        $taxSetEntity = new SpyTaxSet();
419
        $taxSetEntity->setName('name of tax set');
420
        $taxSetEntity->save();
421
422
        return $taxSetEntity;
423
    }
424
425
    /**
426
     * @param \Orm\Zed\Tax\Persistence\SpyTaxSet $taxSetEntity
427
     * @param \Orm\Zed\Tax\Persistence\SpyTaxRate $taxRateEntity
428
     *
429
     * @return void
430
     */
431
    protected function createTaxSetTax(SpyTaxSet $taxSetEntity, SpyTaxRate $taxRateEntity): void
432
    {
433
        $taxSetTaxRateEntity = new SpyTaxSetTax();
434
        $taxSetTaxRateEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
435
        $taxSetTaxRateEntity->setFkTaxRate($taxRateEntity->getIdTaxRate());
436
437
        $taxSetTaxRateEntity->save();
438
    }
439
440
    /**
441
     * @param \Orm\Zed\Tax\Persistence\SpyTaxSet $taxSetEntity
442
     *
443
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
444
     */
445
    protected function createAbstractProduct(SpyTaxSet $taxSetEntity): SpyProductAbstract
446
    {
447
        $abstractProductEntity = new SpyProductAbstract();
448
        $abstractProductEntity->setSku('test-abstract-sku_' . $this->getIncrementNumber());
449
        $abstractProductEntity->setAttributes('');
450
        $abstractProductEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
451
        $abstractProductEntity->save();
452
453
        return $abstractProductEntity;
454
    }
455
456
    /**
457
     * @param array $items
458
     *
459
     * @return bool
460
     */
461
    protected function isCanceledAmount(array $items): bool
462
    {
463
        foreach ($items as $item) {
464
            if ($item[5]) {
465
                return true;
466
            }
467
        }
468
469
        return false;
470
    }
471
}
472