Passed
Push — master ( 1f9686...6724e4 )
by Carsten
10:15
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) 2022 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 2022 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
     *
45
     * @param array $item
46
     */
47 26
    public function __construct(array $item)
48
    {
49 26
        foreach ($item as $key => $value) {
50 26
            $this->data[$key] = $value;
51
        }
52
53 26
        $item['tax'] = $item['tax'] ?? 0;
54
55 26
        $this->tax = new Tax($item['tax']);
56
    }
57
58
    /**
59
     * Set identifier.
60
     *
61
     * @param string $identifier
62
     */
63 18
    public function setIdentifier(string $identifier): void
64
    {
65 18
        $this->identifier = $identifier;
66
    }
67
68
    /**
69
     * Return the value of protected methods.
70
     *
71
     * @param string $param
72
     *
73
     * @return mixed
74
     */
75 18
    public function __get(string $param)
76
    {
77 18
        return 'identifier' === $param ? $this->identifier : $this->data[$param];
78
    }
79
80
    /**
81
     * Update data array using set magic method.
82
     *
83
     * @param mixed $param
84
     * @param mixed $value
85
     */
86 19
    public function __set(mixed $param, mixed $value): void
87
    {
88 19
        $this->data[$param] = $value;
89
90 19
        if ('tax' == $param) {
91 1
            $this->tax = new Tax(floatval($value));
92
        }
93
    }
94
95
    /**
96
     * Return the total tax for this item.
97
     *
98
     * @return float
99
     */
100 3
    public function tax(): float
101
    {
102 3
        return $this->tax->rate($this->totalPrice() * $this->getQuantity());
103
    }
104
105
    /**
106
     * Return the total price for this item.
107
     *
108
     * @return float
109
     */
110 11
    private function totalPrice(): float
111
    {
112 11
        $price = $this->data['price'];
113
114 11
        if ($this->hasOptions()) {
115 3
            foreach ($this->data['options'] as $item) {
116 3
                if (array_key_exists('price', $item)) {
117 3
                    $price += $item['price'];
118
                }
119
            }
120
        }
121
122 11
        return $price;
123
    }
124
125
    /**
126
     * Return the total of the item, with or without tax.
127
     *
128
     * @param bool $includeTax
129
     *
130
     * @return float
131
     */
132 7
    public function total(bool $includeTax = true): float
133
    {
134 7
        $price = $this->totalPrice();
135
136 7
        if ($includeTax) {
137 7
            $price = $this->tax->add($price);
138
        }
139
140 7
        return ($price * $this->getQuantity());
141
    }
142
143
    /**
144
     * Return the total weight of the item.
145
     *
146
     * @return float
147
     */
148 4
    public function weight(): float
149
    {
150 4
        $weight = $this->data['weight'];
151
152 4
        if ($this->hasOptions()) {
153 3
            foreach ($this->data['options'] as $item) {
154 3
                if (array_key_exists('weight', $item)) {
155 2
                    $weight += $item['weight'];
156
                }
157
            }
158
        }
159
160 4
        return (float) ($weight * $this->getQuantity());
161
    }
162
163
    /**
164
     * Return the total of the item, with or without tax.
165
     *
166
     * @param bool $includeTax
167
     *
168
     * @return float
169
     */
170 1
    public function single(bool $includeTax = true): float
171
    {
172 1
        $price = $this->totalPrice();
173
174 1
        if ($includeTax) {
175 1
            $price = $this->tax->add($price);
176
        }
177
178 1
        return $price;
179
    }
180
181
    /**
182
     * Update a single key for this item, or multiple.
183
     *
184
     * @param mixed $key
185
     * @param mixed|null $value
186
     */
187 4
    public function update(mixed $key, mixed $value = null): void
188
    {
189 4
        if ($key instanceof ItemInterface) {
190 1
            foreach ($key->toArray() as $updateKey => $updateValue) {
191 1
                $this->update($updateKey, $updateValue);
192
            }
193
        } else {
194 4
            if ('tax' == $key && is_numeric($value)) {
195 2
                $this->tax = new Tax((float)$value);
196
            } else {
197
                // update the item
198 2
                $this->data[$key] = $value;
199
            }
200
        }
201
    }
202
203
    /**
204
     * Check if this item has options.
205
     *
206
     * @return bool
207
     */
208 17
    public function hasOptions(): bool
209
    {
210 17
        return array_key_exists('options', $this->data) && ! empty($this->data['options']);
211
    }
212
213
    /**
214
     * Convert the item into an array.
215
     *
216
     * @return array
217
     */
218 18
    public function toArray(): array
219
    {
220 18
        return $this->data;
221
    }
222
223
    /**
224
     * Return quantity
225
     *
226
     * @return int
227
     */
228 16
    public function getQuantity(): int
229
    {
230 16
        return $this->data['quantity'];
231
    }
232
233
    /**
234
     * Set quantity
235
     *
236
     * @param int $quantity
237
     *
238
     * @return void
239
     */
240 2
    public function setQuantity(int $quantity): void
241
    {
242 2
        $this->data['quantity'] = $quantity;
243
    }
244
}
245