Passed
Branch master (837a03)
by Tomáš
02:48
created

PackageTransportCostCollection::getBatchIds()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Inspirum\Balikobot\Model\Aggregates;
4
5
use ArrayAccess;
6
use ArrayIterator;
7
use Countable;
8
use Inspirum\Balikobot\Model\Values\PackageTransportCost;
9
use InvalidArgumentException;
10
use IteratorAggregate;
11
use RuntimeException;
12
13
/**
14
 * @implements \ArrayAccess<int,\Inspirum\Balikobot\Model\Values\PackageTransportCost>
15
 * @implements \IteratorAggregate<int,\Inspirum\Balikobot\Model\Values\PackageTransportCost>
16
 */
17
class PackageTransportCostCollection implements ArrayAccess, Countable, IteratorAggregate
18
{
19
    /**
20
     * Package costs
21
     *
22
     * @var array<int,\Inspirum\Balikobot\Model\Values\PackageTransportCost>|\Inspirum\Balikobot\Model\Values\PackageTransportCost[]
23
     */
24
    private $costs = [];
25
26
    /**
27
     * Shipper code
28
     *
29
     * @var string|null
30
     */
31
    private $shipper;
32
33
    /**
34
     * OrderedPackageCollection constructor
35
     *
36
     * @param string|null $shipper
37
     */
38 12
    public function __construct(string $shipper = null)
39
    {
40 12
        $this->shipper = $shipper;
41 12
    }
42
43
    /**
44
     * Add package cost
45
     *
46
     * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $package
47
     *
48
     * @return void
49
     *
50
     * @throws \InvalidArgumentException
51
     */
52 8
    public function add(PackageTransportCost $package): void
53
    {
54
        // validate package cost shipper
55 8
        $this->validateShipper($package);
56
57
        // add package cost to collection
58 8
        $this->costs[] = $package;
59 8
    }
60
61
    /**
62
     * Get shipper
63
     *
64
     * @return string
65
     */
66 4
    public function getShipper(): string
67
    {
68 4
        if ($this->shipper === null) {
69 1
            throw new RuntimeException('Collection is empty');
70
        }
71
72 3
        return $this->shipper;
73
    }
74
75
    /**
76
     * Get EIDs
77
     *
78
     * @return array<string>
79
     */
80 2
    public function getBatchIds(): array
81
    {
82 2
        return array_map(function (PackageTransportCost $transportCost) {
83 2
            return $transportCost->getBatchId();
84 2
        }, $this->costs);
85
    }
86
87
    /**
88
     * Get total cost for all packages
89
     *
90
     * @return float
91
     */
92 3
    public function getTotalCost(): float
93
    {
94 3
        $totalCost    = 0.0;
95 3
        $currencyCode = $this->getCurrencyCode();
96
97 3
        foreach ($this->costs as $cost) {
98 3
            if ($cost->getCurrencyCode() !== $currencyCode) {
99 1
                throw new RuntimeException('Package cost currency codes are not the same');
100
            }
101
102 3
            $totalCost += $cost->getTotalCost();
103
        }
104
105 2
        return $totalCost;
106
    }
107
108
    /**
109
     * Get currency code
110
     *
111
     * @return string
112
     */
113 4
    public function getCurrencyCode(): string
114
    {
115 4
        if (empty($this->costs)) {
116 1
            throw new RuntimeException('Collection is empty');
117
        }
118
119 3
        return $this->costs[0]->getCurrencyCode();
120
    }
121
122
    /**
123
     * Validate shipper
124
     *
125
     * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $package
126
     *
127
     * @return void
128
     *
129
     * @throws \InvalidArgumentException
130
     */
131 10
    private function validateShipper(PackageTransportCost $package): void
132
    {
133
        // set shipper if first package in collection
134 10
        if ($this->shipper === null) {
135 1
            $this->shipper = $package->getShipper();
136
        }
137
138
        // validate shipper
139 10
        if ($this->shipper !== $package->getShipper()) {
140 2
            throw new InvalidArgumentException(
141 2
                sprintf(
142 2
                    'Package is from different shipper ("%s" instead of "%s")',
143 2
                    $package->getShipper(),
144 2
                    $this->shipper
145
                )
146
            );
147
        }
148 10
    }
149
150
    /**
151
     * Determine if an item exists at an offset
152
     *
153
     * @param int $key
154
     *
155
     * @return bool
156
     */
157 1
    public function offsetExists($key)
158
    {
159 1
        return array_key_exists($key, $this->costs);
160
    }
161
162
    /**
163
     * Get an item at a given offset
164
     *
165
     * @param int $key
166
     *
167
     * @return \Inspirum\Balikobot\Model\Values\PackageTransportCost
168
     */
169 3
    public function offsetGet($key)
170
    {
171 3
        return $this->costs[$key];
172
    }
173
174
    /**
175
     * Set the item at a given offset
176
     *
177
     * @param int                                                   $key
178
     * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $value
179
     *
180
     * @return void
181
     */
182 2
    public function offsetSet($key, $value)
183
    {
184 2
        $this->validateShipper($value);
185
186 2
        $this->costs[$key] = $value;
187 2
    }
188
189
    /**
190
     * Unset the item at a given offset
191
     *
192
     * @param int $key
193
     *
194
     * @return void
195
     */
196 1
    public function offsetUnset($key)
197
    {
198 1
        unset($this->costs[$key]);
199 1
    }
200
201
    /**
202
     * Count elements of an object
203
     *
204
     * @return int
205
     */
206 4
    public function count(): int
207
    {
208 4
        return count($this->costs);
209
    }
210
211
    /**
212
     * Get an iterator for the items
213
     *
214
     * @return \ArrayIterator<int,\Inspirum\Balikobot\Model\Values\PackageTransportCost>
215
     */
216 1
    public function getIterator(): ArrayIterator
217
    {
218 1
        return new ArrayIterator($this->costs);
219
    }
220
}
221