Passed
Push — master ( cb50cd...7264d5 )
by Chris
37s
created

Basket::calculateTotal()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace ConferenceTools\Tickets\Domain\ValueObject;
4
5
use ConferenceTools\Tickets\Domain\Service\Configuration;
6
7
class Basket
8
{
9
    /**
10
     * @var TicketReservation[]
11
     */
12
    private $tickets;
13
14
    /**
15
     * @var Price
16
     */
17
    private $preDiscountTotal;
18
19
    /**
20
     * @var Price
21
     */
22
    private $total;
23
24
    /**
25
     * @var DiscountCode
26
     */
27
    private $discountCode;
28
29 13
    private function __construct(TicketReservation ...$tickets)
30
    {
31 13
        if (count($tickets) === 0) {
32 1
            throw new \InvalidArgumentException('Must put at least one Ticket reservation into a basket');
33
        }
34
35 12
        $this->tickets = $tickets;
36
37 12
    }
38
39 7
    public static function fromReservations(Configuration $config, TicketReservation ...$tickets)
40
    {
41 7
        $instance = new self(
42 7
            ...$tickets
43
        );
44
45 7
        $zero = Price::fromNetCost(new Money(0, $config->getCurrency()), $config->getTaxRate());
46 7
        $instance->preDiscountTotal = $instance->calculateTotal($zero);
47
48 7
        $instance->total = $instance->preDiscountTotal;
49 7
        return $instance;
50
    }
51
52 3
    public static function fromReservationsWithDiscount(
53
        Configuration $config,
54
        DiscountCode $discountCode,
55
        TicketReservation ...$tickets)
56
    {
57 3
        $instance = new self(
58 3
            ...$tickets
59
        );
60
61 3
        $zero = Price::fromNetCost(new Money(0, $config->getCurrency()), $config->getTaxRate());
62 3
        $instance->preDiscountTotal = $instance->calculateTotal($zero);
63
64 3
        $instance->total = $instance->preDiscountTotal->subtract($discountCode->apply($instance));
65 3
        $instance->discountCode = $discountCode;
66
67 3
        return $instance;
68
    }
69
70
    /**
71
     * @return TicketReservation[]
72
     */
73 8
    public function getTickets(): array
74
    {
75 8
        return $this->tickets;
76
    }
77
78 6
    public function getTotal(): Price
79
    {
80 6
        return $this->total;
81
    }
82
83
    public function hasDiscountCode(): bool
84
    {
85
        return !($this->discountCode === null);
86
    }
87
88
    /**
89
     * @TODO make nullable (PHP 7.1)
90
     * @return DiscountCode
91
     */
92
    public function getDiscountCode(): DiscountCode
93
    {
94
        return $this->discountCode;
95
    }
96
97 12
    private function calculateTotal(Price $total): Price
98
    {
99 12
        foreach ($this->tickets as $ticket) {
100 12
            $total = $total->add($ticket->getTicketType()->getPrice());
101
        }
102
103 12
        return $total;
104
    }
105
106 6
    public function getPreDiscountTotal(): Price
107
    {
108 6
        return $this->preDiscountTotal;
109
    }
110
111 7
    public function containingOnly(TicketType ...$ticketTypes)
112
    {
113 7
        $filteredReservations = [];
114 7
        foreach($this->tickets as $ticketReservation) {
115 7
            if (in_array($ticketReservation->getTicketType(), $ticketTypes, false)) {
116 6
                $filteredReservations[] = $ticketReservation;
117
            }
118
        }
119
120 7
        $instance = new self(
121 7
            ...$filteredReservations
122
        );
123
124 6
        $zero = Price::fromNetCost(
125 6
            new Money(0, $this->preDiscountTotal->getNet()->getCurrency()),
126 6
            $this->preDiscountTotal->getTaxRate()
127
        );
128
129 6
        $instance->preDiscountTotal = $instance->calculateTotal($zero);
130 6
        $instance->total = $instance->preDiscountTotal;
131
132 6
        return $instance;
133
    }
134
}
135