Completed
Push — master ( 04b9b6...0cee6b )
by Andrii
04:13
created

Discount::ensureValidValue()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 8.0291

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 12
cts 13
cp 0.9231
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 13
nc 6
nop 1
crap 8.0291
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\charge\modifiers\addons;
12
13
use hiqdev\php\billing\charge\ChargeInterface;
14
use hiqdev\php\billing\charge\modifiers\AddonInterface;
15
use Money\Currencies\ISOCurrencies;
16
use Money\Currency;
17
use Money\Money;
18
use Money\Parser\DecimalMoneyParser;
19
20
/**
21
 * Discount addon.
22
 *
23
 * @author Andrii Vasyliev <[email protected]>
24
 */
25
class Discount implements AddonInterface
26
{
27
    protected static $name = 'discount';
28
29
    /**
30
     * @var string|Money
31
     */
32
    protected $value;
33
34
    protected $moneyParser;
35
36 24
    public function __construct($value)
37
    {
38 24
        $this->moneyParser = new DecimalMoneyParser(new ISOCurrencies());
39 24
        $this->value = $this->ensureValidValue($value);
40 24
    }
41
42 11
    public function getValue()
43
    {
44 11
        return $this->value;
45
    }
46
47 14
    public function isAbsolute()
48
    {
49 14
        return $this->value instanceof Money;
50
    }
51
52 8
    public function isRelative()
53
    {
54 8
        return !$this->isAbsolute();
55
    }
56
57 24
    public function ensureValidValue($value)
58
    {
59 24
        if ($value instanceof static) {
60
            return $value->getValue();
61
        }
62
63 24
        if ($value instanceof Money) {
64 8
            return $value;
65
        }
66
67 22
        if (is_numeric($value)) {
68 10
            return (string) $value;
69
        }
70
71 18
        if (is_string($value) && preg_match('/^(\d{1,5}(\.\d+)?)%$/', $value, $ms)) {
72 16
            return $ms[1];
73
        }
74
75 15
        if (is_string($value) && preg_match('/^(\d{1,5}(\.\d+)?) ([A-Z]{3})$/', $value, $ms)) {
76 15
            return $this->moneyParser->parse($ms[1], new Currency($ms[3]));
77
        }
78
79
        /// var_dump($value);
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
80
81
        /// TODO: add special exception
82 4
        $name = static::$name;
83 4
        throw new \Exception("invalid $name value: $value");
84
    }
85
86 8
    public function multiply($multiplier)
87
    {
88 8
        if (!is_numeric($multiplier)) {
89 3
            throw new \Exception('multiplier for discount myst be numeric');
90
        }
91
92 5
        return new static($this->isAbsolute() ? $this->value->multiply($multiplier) : $this->value*$multiplier);
93
    }
94
95 11
    public function add($addend)
96
    {
97 11
        if (!$addend instanceof self) {
98 7
            $addend = new self($addend);
99
        }
100 7
        $this->ensureSameType($addend, 'addend');
0 ignored issues
show
Documentation introduced by
$addend is of type object<hiqdev\php\billin...ifiers\addons\Discount>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
101
102 5
        if ($this->isAbsolute()) {
103 3
            $sum = $this->value->add($addend->getValue());
104
        } else {
105 3
            $sum = $this->value + $addend->getValue();
106
        }
107
108 5
        return new static($sum);
109
    }
110
111 1
    public function compare($other)
112
    {
113 1
        if (!$other instanceof self) {
114 1
            $other = new self($other);
115
        }
116 1
        $this->ensureSameType($other, 'comparison argument');
0 ignored issues
show
Documentation introduced by
$other is of type object<hiqdev\php\billin...ifiers\addons\Discount>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
117
118 1
        if ($this->isAbsolute()) {
119 1
            return $this->value->compare($other->getValue());
120
        } else {
121 1
            return $this->value - $other->getValue();
122
        }
123
    }
124
125 8
    public function ensureSameType(self $other, $name)
126
    {
127 8
        if ($this->isRelative() && !$other->isRelative()) {
128 1
            throw new \Exception("$name must be relative");
129
        }
130 7
        if ($this->isAbsolute() && !$other->isAbsolute()) {
131 1
            throw new \Exception("$name must be absolute");
132
        }
133 6
    }
134
135 4
    public function calculateSum(ChargeInterface $charge): Money
136
    {
137 4
        return $this->isAbsolute() ? $this->value : $charge->getSum()->multiply($this->value*0.01);
138
    }
139
}
140