Completed
Push — master ( 308de5...6bfaa4 )
by Hannes
03:47 queued 02:10
created

ItemBasket::getTotalCost()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace byrokrat\billing;
6
7
use byrokrat\amount\Amount;
8
9
/**
10
 * Container for billable items
11
 */
12
class ItemBasket implements \IteratorAggregate
13
{
14
    /**
15
     * @var ItemEnvelope[] Contained items
16
     */
17
    private $items = [];
18
19
    /**
20
     * Optionally load items at construct
21
     */
22 24
    public function __construct(ItemEnvelope ...$items) {
23 24
        foreach ($items as $item) {
24 7
            $this->addItem($item);
25
        }
26 24
    }
27
28
    /**
29
     * Add item to basket
30
     */
31 8
    public function addItem(ItemEnvelope $item): self
32
    {
33 8
        $this->items[] = $item;
34 8
        return $this;
35
    }
36
37
    /**
38
     * Get contained items
39
     *
40
     * @return ItemEnvelope[]
41
     */
42 7
    public function getItems(): array
43
    {
44 7
        return $this->items;
45
    }
46
47
    /**
48
     * Implements the IteratorAggregate interface
49
     */
50 1
    public function getIterator(): \Traversable
51
    {
52 1
        foreach ($this->getItems() as $item) {
53 1
            yield $item;
54
        }
55 1
    }
56
57
    /**
58
     * Get number of items in basket
59
     */
60 1
    public function getNrOfItems(): int
61
    {
62 1
        return count($this->getItems());
63
    }
64
65
    /**
66
     * Get number of units in basket (each item may contain multiple units)
67
     */
68 1
    public function getNrOfUnits(): int
69
    {
70 1
        return array_reduce(
71 1
            $this->getItems(),
72
            function (int $carry, ItemEnvelope $item) {
73 1
                return $carry + $item->getNrOfUnits();
74 1
            },
75
            0
76
        );
77
    }
78
79
    /**
80
     * Get total cost of all items (VAT excluded)
81
     */
82 3 View Code Duplication
    public function getTotalUnitCost(): Amount
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...
83
    {
84 3
        return array_reduce(
85 3
            $this->getItems(),
86
            function (Amount $carry, ItemEnvelope $item) {
87 3
                return $carry->add($item->getTotalUnitCost());
88 3
            },
89 3
            new Amount('0')
90
        );
91
    }
92
93
    /**
94
     * Get total VAT cost for all items
95
     */
96 3 View Code Duplication
    public function getTotalVatCost(): Amount
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...
97
    {
98 3
        return array_reduce(
99 3
            $this->getItems(),
100 3
            function (Amount $carry, ItemEnvelope $item) {
101 3
                return $carry->add($item->getTotalVatCost());
102 3
            },
103 3
            new Amount('0')
104
        );
105
    }
106
107
    /**
108
     * Get total cost of all items (VAT included)
109
     */
110 2
    public function getTotalCost(): Amount
111
    {
112 2
        return $this->getTotalVatCost()->add($this->getTotalUnitCost());
113
    }
114
115
    /**
116
     * Get charged vat amounts for non-zero vat rates
117
     *
118
     * @return Billable[]
119
     */
120 1
    public function getVatRates(): array
121
    {
122 1
        $rates = [];
123
124 1
        foreach ($this as $item) {
125 1
            if ($item->getVatRate()->isPositive()) {
126 1
                $key = (string)$item->getVatRate();
127
128 1
                if (!array_key_exists($key, $rates)) {
129 1
                    $rates[$key] = new SimpleItem('', new Amount('0'), 1, $item->getVatRate());
130
                }
131
132 1
                $rates[$key] = new SimpleItem(
133 1
                    $rates[$key]->getBillingDescription(),
134 1
                    $rates[$key]->getCostPerUnit()->add($item->getTotalUnitCost()),
135 1
                    $rates[$key]->getNrOfUnits(),
136 1
                    $rates[$key]->getVatRate()
137
                );
138
            }
139
        }
140
141 1
        ksort($rates);
142
143 1
        return array_values($rates);
144
    }
145
}
146