CalculationBusinessTester::createItemTransfer()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 20
rs 9.8666
cc 3
nc 4
nop 4
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;
15
use Generated\Shared\Transfer\CurrencyTransfer;
16
use Generated\Shared\Transfer\DiscountTransfer;
17
use Generated\Shared\Transfer\ExpenseTransfer;
18
use Generated\Shared\Transfer\ItemTransfer;
19
use Generated\Shared\Transfer\ProductOptionTransfer;
20
use Generated\Shared\Transfer\QuoteTransfer;
21
use Generated\Shared\Transfer\StoreTransfer;
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;
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\CurrencyTransfer
253
     */
254
    public function createCurrencyTransfer(): CurrencyTransfer
255
    {
256
        return (new CurrencyTransfer())
257
            ->setCode('EUR');
258
    }
259
260
    /**
261
     * @param int $price
262
     * @param string $priceMode
263
     * @param float $taxRate
264
     * @param int $quantity
265
     *
266
     * @return \Generated\Shared\Transfer\ItemTransfer
267
     */
268
    public function createItemTransfer(int $price, string $priceMode, float $taxRate, int $quantity): ItemTransfer
269
    {
270
        $abstractProductEntity = $this->createAbstractProductWithTaxSet($taxRate);
271
272
        $itemTransfer = (new ItemTransfer())
273
            ->setName('test' . $this->getIncrementNumber())
274
            ->setIdProductAbstract($abstractProductEntity->getIdProductAbstract())
275
            ->setSku('test' . $this->getIncrementNumber())
276
            ->setQuantity($quantity)
277
            ->setTaxRate($taxRate);
278
279
        if ($priceMode === CalculationPriceMode::PRICE_MODE_GROSS) {
280
            $itemTransfer->setUnitGrossPrice($price);
281
        }
282
283
        if ($priceMode === CalculationPriceMode::PRICE_MODE_NET) {
284
            $itemTransfer->setUnitNetPrice($price);
285
        }
286
287
        return $itemTransfer;
288
    }
289
290
    /**
291
     * @param int $price
292
     * @param string $priceMode
293
     * @param float $taxRate
294
     * @param int $quantity
295
     *
296
     * @return \Generated\Shared\Transfer\ProductOptionTransfer
297
     */
298
    public function createProductOptionTransfer(int $price, string $priceMode, float $taxRate, int $quantity): ProductOptionTransfer
299
    {
300
        $productOptionValueEntity = $this->createProductOptionValue($taxRate);
301
302
        $productOptionTransfer = (new ProductOptionTransfer())
303
            ->setTaxRate($taxRate)
304
            ->setQuantity($quantity)
305
            ->setIdProductOptionValue($productOptionValueEntity->getIdProductOptionValue());
306
307
        if ($priceMode === CalculationPriceMode::PRICE_MODE_GROSS) {
308
            $productOptionTransfer->setUnitGrossPrice($price);
309
        }
310
311
        if ($priceMode === CalculationPriceMode::PRICE_MODE_NET) {
312
            $productOptionTransfer->setUnitNetPrice($price);
313
        }
314
315
        return $productOptionTransfer;
316
    }
317
318
    /**
319
     * @param float $taxRate
320
     *
321
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
322
     */
323
    public function createAbstractProductWithTaxSet(float $taxRate): SpyProductAbstract
324
    {
325
        $countryEntity = SpyCountryQuery::create()->findOneByIso2Code(static::COUNTRY_DE);
326
327
        $taxRateEntity = new SpyTaxRate();
328
        $taxRateEntity->setRate($taxRate);
329
        $taxRateEntity->setName('test rate');
330
        $taxRateEntity->setFkCountry($countryEntity->getIdCountry());
331
        $taxRateEntity->save();
332
333
        $taxSetEntity = $this->createTaxSet();
334
335
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
336
337
        return $this->createAbstractProduct($taxSetEntity);
338
    }
339
340
    /**
341
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
342
     */
343
    public function createAbstractProductWithTaxExemption(): SpyProductAbstract
344
    {
345
        $taxRateEntity = new SpyTaxRate();
346
        $taxRateEntity->setRate(0);
347
        $taxRateEntity->setName(TaxConstants::TAX_EXEMPT_PLACEHOLDER);
348
        $taxRateEntity->save();
349
350
        $taxSetEntity = $this->createTaxSet();
351
352
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
353
354
        return $this->createAbstractProduct($taxSetEntity);
355
    }
356
357
    /**
358
     * @return int
359
     */
360
    protected function getIncrementNumber(): int
361
    {
362
        return ++$this->incrementNumber;
363
    }
364
365
    /**
366
     * @return \Orm\Zed\Currency\Persistence\SpyCurrency
367
     */
368
    protected function getCurrency(): SpyCurrency
369
    {
370
        return SpyCurrencyQuery::create()->findOneByCode('EUR');
371
    }
372
373
    /**
374
     * @param float $taxRate
375
     *
376
     * @return \Orm\Zed\ProductOption\Persistence\SpyProductOptionValue
377
     */
378
    protected function createProductOptionValue(float $taxRate): SpyProductOptionValue
379
    {
380
        $countryEntity = SpyCountryQuery::create()->findOneByIso2Code('DE');
381
382
        $taxRateEntity = new SpyTaxRate();
383
        $taxRateEntity->setRate($taxRate);
384
        $taxRateEntity->setName('test rate');
385
        $taxRateEntity->setFkCountry($countryEntity->getIdCountry());
386
        $taxRateEntity->save();
387
388
        $taxSetEntity = $this->createTaxSet();
389
        $this->createTaxSetTax($taxSetEntity, $taxRateEntity);
390
391
        $productOptionGroupEntity = new SpyProductOptionGroup();
392
        $productOptionGroupEntity->setName('group.name.translation.key.edit');
393
        $productOptionGroupEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
394
        $productOptionGroupEntity->save();
395
396
        $productOptionValueEntity = new SpyProductOptionValue();
397
        $productOptionValueEntity->setSku('product-' . $this->getIncrementNumber());
398
        $productOptionValueEntity->setFkProductOptionGroup($productOptionGroupEntity->getIdProductOptionGroup());
399
        $productOptionValueEntity->setValue('product.option.test');
400
        $productOptionValueEntity->save();
401
402
        return $productOptionValueEntity;
403
    }
404
405
    /**
406
     * @return \Orm\Zed\Tax\Persistence\SpyTaxSet
407
     */
408
    protected function createTaxSet(): SpyTaxSet
409
    {
410
        $taxSetEntity = new SpyTaxSet();
411
        $taxSetEntity->setName('name of tax set');
412
        $taxSetEntity->save();
413
414
        return $taxSetEntity;
415
    }
416
417
    /**
418
     * @param \Orm\Zed\Tax\Persistence\SpyTaxSet $taxSetEntity
419
     * @param \Orm\Zed\Tax\Persistence\SpyTaxRate $taxRateEntity
420
     *
421
     * @return void
422
     */
423
    protected function createTaxSetTax(SpyTaxSet $taxSetEntity, SpyTaxRate $taxRateEntity): void
424
    {
425
        $taxSetTaxRateEntity = new SpyTaxSetTax();
426
        $taxSetTaxRateEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
427
        $taxSetTaxRateEntity->setFkTaxRate($taxRateEntity->getIdTaxRate());
428
429
        $taxSetTaxRateEntity->save();
430
    }
431
432
    /**
433
     * @param \Orm\Zed\Tax\Persistence\SpyTaxSet $taxSetEntity
434
     *
435
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstract
436
     */
437
    protected function createAbstractProduct(SpyTaxSet $taxSetEntity): SpyProductAbstract
438
    {
439
        $abstractProductEntity = new SpyProductAbstract();
440
        $abstractProductEntity->setSku('test-abstract-sku_' . $this->getIncrementNumber());
441
        $abstractProductEntity->setAttributes('');
442
        $abstractProductEntity->setFkTaxSet($taxSetEntity->getIdTaxSet());
443
        $abstractProductEntity->save();
444
445
        return $abstractProductEntity;
446
    }
447
448
    /**
449
     * @param array $items
450
     *
451
     * @return bool
452
     */
453
    protected function isCanceledAmount(array $items): bool
454
    {
455
        foreach ($items as $item) {
456
            if ($item[5]) {
457
                return true;
458
            }
459
        }
460
461
        return false;
462
    }
463
464
    /**
465
     * @return \Generated\Shared\Transfer\AddressTransfer
466
     */
467
    public function getCurrentShippingAddress(): AddressTransfer
468
    {
469
        return (new AddressTransfer())->setIso2Code(static::COUNTRY_DE);
470
    }
471
}
472