Completed
Push — master ( 99572f...29604e )
by Mikołaj
12s queued 10s
created

HasPriceBetweenQueryBuilder::buildQuery()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 4
nop 1
dl 0
loc 18
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file has been created by developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * another great project.
7
 * You can find more information about us on https://bitbag.shop and write us
8
 * an email on [email protected].
9
 */
10
11
declare(strict_types=1);
12
13
namespace BitBag\SyliusElasticsearchPlugin\QueryBuilder;
14
15
use BitBag\SyliusElasticsearchPlugin\PropertyNameResolver\ConcatedNameResolverInterface;
16
use BitBag\SyliusElasticsearchPlugin\PropertyNameResolver\PriceNameResolverInterface;
17
use Elastica\Query\AbstractQuery;
18
use Elastica\Query\Range;
19
use Sylius\Component\Channel\Context\ChannelContextInterface;
20
use Sylius\Component\Core\Model\ChannelInterface;
21
use Sylius\Component\Currency\Context\CurrencyContextInterface;
22
use Sylius\Component\Currency\Converter\CurrencyConverterInterface;
23
24
final class HasPriceBetweenQueryBuilder implements QueryBuilderInterface
25
{
26
    /** @var ConcatedNameResolverInterface */
27
    private $channelPricingNameResolver;
28
29
    /** @var PriceNameResolverInterface */
30
    private $priceNameResolver;
31
32
    /** @var ChannelContextInterface */
33
    private $channelContext;
34
35
    /** @var CurrencyContextInterface */
36
    private $currencyContext;
37
38
    /** @var CurrencyConverterInterface */
39
    private $currencyConverter;
40
41
    public function __construct(
42
        PriceNameResolverInterface $priceNameResolver,
43
        ConcatedNameResolverInterface $channelPricingNameResolver,
44
        ChannelContextInterface $channelContext,
45
        CurrencyContextInterface $currencyContext,
46
        CurrencyConverterInterface $currencyConverter
47
    ) {
48
        $this->channelPricingNameResolver = $channelPricingNameResolver;
49
        $this->priceNameResolver = $priceNameResolver;
50
        $this->channelContext = $channelContext;
51
        $this->currencyContext = $currencyContext;
52
        $this->currencyConverter = $currencyConverter;
53
    }
54
55
    public function buildQuery(array $data): ?AbstractQuery
56
    {
57
        $dataMinPrice = $data[$this->priceNameResolver->resolveMinPriceName()];
58
        $dataMaxPrice = $data[$this->priceNameResolver->resolveMaxPriceName()];
59
60
        $minPrice = $dataMinPrice ? $this->resolveBasePrice($dataMinPrice) : 0;
61
        $maxPrice = $dataMaxPrice ? $this->resolveBasePrice($dataMaxPrice) : PHP_INT_MAX;
62
63
        $channelCode = $this->channelContext->getChannel()->getCode();
64
        $propertyName = $this->channelPricingNameResolver->resolvePropertyName($channelCode);
0 ignored issues
show
Bug introduced by
It seems like $channelCode can also be of type null; however, parameter $suffix of BitBag\SyliusElasticsear...::resolvePropertyName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
        $propertyName = $this->channelPricingNameResolver->resolvePropertyName(/** @scrutinizer ignore-type */ $channelCode);
Loading history...
65
        $rangeQuery = new Range();
66
67
        $rangeQuery->setParam($propertyName, [
68
            'gte' => $minPrice,
69
            'lte' => $maxPrice,
70
        ]);
71
72
        return $rangeQuery;
73
    }
74
75
    private function resolveBasePrice(string $price): int
76
    {
77
        $price = $this->convertFromString($price);
78
        /** @var ChannelInterface $channel */
79
        $channel = $this->channelContext->getChannel();
80
        $currentCurrencyCode = $this->currencyContext->getCurrencyCode();
81
        $channelBaseCurrencyCode = $channel->getBaseCurrency()->getCode();
82
83
        if ($currentCurrencyCode !== $channelBaseCurrencyCode) {
84
            $price = $this->currencyConverter->convert($price, $currentCurrencyCode, $channelBaseCurrencyCode);
0 ignored issues
show
Bug introduced by
It seems like $channelBaseCurrencyCode can also be of type null; however, parameter $targetCurrencyCode of Sylius\Component\Currenc...terInterface::convert() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
            $price = $this->currencyConverter->convert($price, $currentCurrencyCode, /** @scrutinizer ignore-type */ $channelBaseCurrencyCode);
Loading history...
85
        }
86
87
        return $price;
88
    }
89
90
    private function convertFromString(string $price): int
91
    {
92
        return (int) round($price * 100, 2);
93
    }
94
}
95