Passed
Push — master ( 9be0c8...8c1bed )
by Chris
02:56
created

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