Passed
Pull Request — master (#15)
by Carsten
11:50
created

Item::getQuantity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of Lenius Basket, a PHP package to handle
5
 * your shopping basket.
6
 *
7
 * Copyright (c) 2017 Lenius.
8
 * https://github.com/lenius/basket
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 *
13
 * @author Carsten Jonstrup<[email protected]>
14
 * @copyright 2017 Lenius.
15
 *
16
 * @version production
17
 *
18
 * @see https://github.com/lenius/basket
19
 */
20
21
namespace Lenius\Basket;
22
23
/**
24
 * Class Item.
25
 *
26
 * @property string $identifier
27
 * @property float  $price
28
 * @property int    $quantity
29
 * @property float  $weight
30
 */
31
class Item implements ItemInterface
32
{
33
    /** @var string */
34
    protected string $identifier;
35
36
    /** @var Tax */
37
    protected Tax $tax;
38
39
    /** @var array */
40
    protected array $data = [];
41
42
    /**
43
     * Construct the item.
44
     * @param array $item
45
     */
46 25
    public function __construct(array $item)
47
    {
48 25
        foreach ($item as $key => $value) {
49 25
            $this->data[$key] = $value;
50
        }
51
52 25
        $item['tax'] = $item['tax'] ?? 0;
53
54 25
        $this->tax = new Tax($item['tax']);
55
    }
56
57
    /**
58
     * Set identifier.
59
     *
60
     * @param string $identifier
61
     */
62 18
    public function setIdentifier(string $identifier): void
63
    {
64 18
        $this->identifier = $identifier;
65
    }
66
67
    /**
68
     * Return the value of protected methods.
69
     *
70
     * @param string $param
71
     *
72
     * @return mixed
73
     */
74 23
    public function __get(string $param)
75
    {
76 23
        return 'identifier' === $param ? $this->identifier : $this->data[$param];
77
    }
78
79
    /**
80
     * Update data array using set magic method.
81
     *
82
     * @param mixed $param The key to set
83
     * @param mixed $value The value to set $param to
84
     */
85 19
    public function __set($param, $value): void
86
    {
87 19
        $this->data[$param] = $value;
88
89 19
        if ('tax' == $param) {
90 1
            $this->tax = new Tax(floatval($value));
91
        }
92
    }
93
94
    /**
95
     * Return the total tax for this item.
96
     *
97
     * @return float
98
     */
99 3
    public function tax(): float
100
    {
101 3
        return $this->tax->rate($this->totalPrice() * $this->getQuantity());
102
    }
103
104
    /**
105
     * Return the total price for this item.
106
     *
107
     * @return float
108
     */
109 11
    private function totalPrice(): float
110
    {
111 11
        $price = $this->price;
112
113 11
        if ($this->hasOptions()) {
114 3
            foreach ($this->data['options'] as $item) {
115 3
                if (array_key_exists('price', $item)) {
116 3
                    $price += $item['price'];
117
                }
118
            }
119
        }
120
121 11
        return $price;
122
    }
123
124
    /**
125
     * Return the total of the item, with or without tax.
126
     *
127
     * @param bool $includeTax Whether or not to include tax
128
     *
129
     * @return float The total, as a float
130
     */
131 7
    public function total(bool $includeTax = true): float
132
    {
133 7
        $price = $this->totalPrice();
134
135 7
        if ($includeTax) {
136 7
            $price = $this->tax->add($price);
137
        }
138
139 7
        return ($price * $this->getQuantity());
140
    }
141
142
    /**
143
     * Return the total weight of the item.
144
     *
145
     * @return float The weight, as a float
146
     */
147 4
    public function weight(): float
148
    {
149 4
        $weight = $this->weight;
150
151 4
        if ($this->hasOptions()) {
152 3
            foreach ($this->data['options'] as $item) {
153 3
                if (array_key_exists('weight', $item)) {
154 2
                    $weight += $item['weight'];
155
                }
156
            }
157
        }
158
159 4
        return (float) ($weight * $this->getQuantity());
160
    }
161
162
    /**
163
     * Return the total of the item, with or without tax.
164
     *
165
     * @param bool $includeTax Whether or not to include tax
166
     *
167
     * @return float The total, as a float
168
     */
169 1
    public function single(bool $includeTax = true): float
170
    {
171 1
        $price = $this->totalPrice();
172
173 1
        if ($includeTax) {
174 1
            $price = $this->tax->add($price);
175
        }
176
177 1
        return $price;
178
    }
179
180
    /**
181
     * Update a single key for this item, or multiple.
182
     *
183
     * @param mixed $key   The array key to update, or an array of key-value pairs to update
184
     * @param mixed $value
185
     */
186 4
    public function update($key, $value = null): void
187
    {
188 4
        if ($key instanceof ItemInterface) {
189 1
            foreach ($key->toArray() as $updateKey => $updateValue) {
190 1
                $this->update($updateKey, $updateValue);
191
            }
192
        } else {
193 4
            if ('tax' == $key && is_numeric($value)) {
194 2
                $this->tax = new Tax((float)$value);
195
            } else {
196
                // update the item
197 2
                $this->data[$key] = $value;
198
            }
199
        }
200
    }
201
202
    /**
203
     * Check if this item has options.
204
     *
205
     * @return bool Yes or no?
206
     */
207 17
    public function hasOptions(): bool
208
    {
209 17
        return array_key_exists('options', $this->data) && ! empty($this->data['options']);
210
    }
211
212
    /**
213
     * Convert the item into an array.
214
     *
215
     * @return array The item data
216
     */
217 18
    public function toArray(): array
218
    {
219 18
        return $this->data;
220
    }
221
222
    /**
223
     * Return quantity
224
     *
225
     * @return int
226
     */
227 15
    public function getQuantity(): int
228
    {
229 15
        return $this->quantity;
230
    }
231
232
    /**
233
     * Set quantity
234
     *
235
     * @param int $quantity
236
     *
237
     * @return void
238
     */
239 1
    public function setQuantity(int $quantity): void
240
    {
241 1
        $this->quantity = $quantity;
242
    }
243
}
244