Completed
Push — master ( b864d9...3fa98b )
by Dmitry
07:42 queued 03:17
created

CertificatePrice::getPeriods()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 7
loc 7
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace hipanel\modules\finance\models;
4
5
use Money\Currency;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, hipanel\modules\finance\models\Currency.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Money\Formatter\DecimalMoneyFormatter;
7
use Money\Money;
8
use Money\Currencies\ISOCurrencies;
9
use Money\Parser\DecimalMoneyParser;
10
use Yii;
11
use hipanel\base\ModelTrait;
12
use yii\behaviors\AttributeTypecastBehavior;
13
use yii\validators\NumberValidator;
14
15
/**
16
 * @property array $sums
17
 */
18
class CertificatePrice extends Price
19
{
20
    use ModelTrait;
21
22
    const TYPE_CERT_PURCHASE = 'certificate,certificate_purchase';
23
    const TYPE_CERT_RENEWAL = 'certificate,certificate_renewal';
24
25
    /**
26
     * @var DecimalMoneyFormatter
27
     */
28
    private $moneyFormatter;
29
30
    /**
31
     * @var DecimalMoneyParser
32
     */
33
    private $moneyParser;
34
35
    public function __construct(array $config = [])
36
    {
37
        parent::__construct($config);
38
        $this->moneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());
39
        $this->moneyParser = new DecimalMoneyParser(new ISOCurrencies());
40
    }
41
42
    public static function tableName()
43
    {
44
        return 'price';
45
    }
46
47
    public function behaviors()
48
    {
49
        return [
50
            'typecastAfterFind' => [
51
                'class' => AttributeTypecastBehavior::class,
52
                'attributeTypes' => [
53
                    'sums' => function ($sums) {
54
                        foreach ($sums as $key => $value) {
55
                            $sums[$key] = new Money($value, new Currency(strtoupper($this->currency)));
56
                        }
57
                        return $sums;
58
                    }],
59
                'typecastAfterFind' => true,
60
                'typecastAfterValidate' => false,
61
                'typecastBeforeSave' => false,
62
            ],
63
            'typecastBeforeSave' => [
64
                'class' => AttributeTypecastBehavior::class,
65
                'attributeTypes' => [
66
                    'sums' => function ($sums) {
67
                        foreach ($sums as $key => $value) {
68
                            $sums[$key] = $this->moneyParser
69
                                ->parse($value, strtoupper($this->currency))
70
                                ->getAmount();
71
                        }
72
                        return $sums;
73
                    }],
74
                'typecastAfterFind' => false,
75
                'typecastAfterValidate' => false,
76
                'typecastBeforeSave' => true,
77
            ],
78
        ];
79
    }
80
81
82
    public function rules()
83
    {
84
        $rules = parent::rules();
85
        $rules['create-required'] = [
86
            ['object_id'],
87
            'required',
88
            'on' => ['create', 'update'],
89
            'when' => function ($model) {
90
                /** @var self $model */
91
                return $model->isTypeCorrect();
0 ignored issues
show
Documentation Bug introduced by
The method isTypeCorrect does not exist on object<hipanel\modules\f...nce\models\Calculation>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
92
            },
93
        ];
94
        $rules[] = [['certificateType'], 'safe'];
95
        $rules[] = [['sums'], 'validatePrices', 'on' => ['create', 'update']];
96
        $rules[] = [['sums'], 'number', 'min' => 0, 'when' => function () {
97
            return false;
98
        }];
99
        $rules[] = [['sums'], 'each', 'rule' => ['number', 'min' => 0]];
100
101
        return $rules;
102
    }
103
104
    public function isTypeCorrect()
105
    {
106
        return isset($this->getTypes()[$this->type]);
107
    }
108
109
    /**
110
     * @return array
111
     */
112 View Code Duplication
    public static function getPeriods()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
    {
114
        return [
115
            1 => Yii::t('hipanel:finance:tariff', '{n, plural, one{# year} other{# years}}', ['n' => 1]),
116
            2 => Yii::t('hipanel:finance:tariff', '{n, plural, one{# year} other{# years}}', ['n' => 2]),
117
        ];
118
    }
119
120
    /**
121
     * @return array
122
     */
123 View Code Duplication
    public function getAvailablePeriods()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
    {
125
        $periods = [];
126
        foreach ([1, 2] as $period) {
127
            if ($this->hasPriceForPeriod($period)) {
128
                $periods[$period] = Yii::t('hipanel:finance:tariff', '{n, plural, one{# year} other{# years}}', ['n' => $period]);
129
            }
130
        }
131
132
        return $periods;
133
    }
134
135
    /**
136
     * @param int $period
137
     * @return null|string
138
     */
139 View Code Duplication
    public function getPriceForPeriod(int $period)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
140
    {
141
        if (!$this->hasPriceForPeriod($period)) {
142
            return null;
143
        }
144
145
        return $this->moneyFormatter->format($this->sums[$period]);
146
    }
147
148
    /**
149
     * @param int $period
150
     * @return bool
151
     */
152
    public function hasPriceForPeriod(int $period)
153
    {
154
        return !empty($this->sums[$period]);
155
    }
156
157
    public function validatePrices(): bool
158
    {
159
        $periods = $this->getPeriods();
160
        $validator = new NumberValidator();
161
162 View Code Duplication
        foreach (array_keys($periods) as $period) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
            $validation = $validator->validate($this->sums[$period]);
164
            if ($validation === false) {
165
                unset($this->sums[$period]);
166
            }
167
        }
168
169
        return true;
170
    }
171
172
    /**
173
     * @return array
174
     */
175
    public static function getTypes()
176
    {
177
        return [
178
            static::TYPE_CERT_PURCHASE => Yii::t('hipanel:finance:tariff', 'Purchase'),
179
            static::TYPE_CERT_RENEWAL => Yii::t('hipanel:finance:tariff', 'Renewal'),
180
        ];
181
    }
182
}
183