TicketPurchase::applyTicketReserved()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ConferenceTools\Tickets\Domain\Model\Ticket;
4
5
use Carnage\Cqrs\Aggregate\AbstractAggregate;
6
use ConferenceTools\Tickets\Domain\Event\Ticket\DiscountCodeApplied;
7
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketAssigned;
8
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketCancelled;
9
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketPurchaseCreated;
10
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketPurchaseTimedout;
11
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketPurchaseTotalPriceCalculated;
12
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketPurchasePaid;
13
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketReleased;
14
use ConferenceTools\Tickets\Domain\Event\Ticket\TicketReserved;
15
use ConferenceTools\Tickets\Domain\ValueObject\Basket;
16
use ConferenceTools\Tickets\Domain\ValueObject\Delegate;
17
use ConferenceTools\Tickets\Domain\ValueObject\Money;
18
19
class TicketPurchase extends AbstractAggregate
20
{
21
    /**
22
     * @var string
23
     */
24
    private $id;
25
26
    /**
27
     * @var Money
28
     */
29
    private $total;
30
31
    /**
32
     * @var bool
33
     */
34
    private $isPaid = false;
35
36
    /**
37
     * @var bool
38
     */
39
    private $isTimedout = false;
40
    
41
    /**
42
     * @var BookedTicket[]
43
     */
44
    private $tickets = [];
45
46
    public function getId()
47
    {
48
        return $this->id;
49
    }
50
51
    public static function create(string $id, Basket $basket)
52
    {
53
        $instance = new static();
54
        $event = new TicketPurchaseCreated($id);
55
        $instance->apply($event);
56
57
        foreach ($basket->getTickets() as $ticket) {
58
            $event = new TicketReserved($ticket->getReservationId(), $ticket->getTicketType(), $id);
59
            $instance->apply($event);
60
        }
61
62
        if ($basket->hasDiscountCode()) {
63
            $event = new TicketPurchaseTotalPriceCalculated($id, $basket->getPreDiscountTotal());
64
            $instance->apply($event);
65
66
            $event = new DiscountCodeApplied($id, $basket->getDiscountCode());
67
            $instance->apply($event);
68
        }
69
70
        $event = new TicketPurchaseTotalPriceCalculated($id, $basket->getTotal());
71
        $instance->apply($event);
72
73
        return $instance;
74
    }
75
76
    public function completePurchase(string $email, Delegate ...$delegateInformation)
77
    {
78
        if (count($delegateInformation) !== count($this->tickets)) {
79
            throw new \DomainException('Number of delegates\' information supplied doesn\'t match number of tickets');
80
        }
81
82
        $iterator = new \MultipleIterator(\MultipleIterator::MIT_KEYS_NUMERIC|\MultipleIterator::MIT_NEED_ALL);
83
        $iterator->attachIterator(new \ArrayIterator($delegateInformation), 'delegate');
84
        $iterator->attachIterator(new \ArrayIterator($this->tickets), 'ticketId');
85
86
        foreach ($iterator as $data) {
87
            $this->assignTicketToDelegate($data[1]->getId(), $data[0]);
88
        }
89
90
        $this->markAsPaid($email);
91
    }
92
93
    public function cancelTicket(string $ticketId)
94
    {
95
        if (!$this->isPaid) {
96
            throw new \DomainException('Cannot cancel a ticket which hasn\'t been paid for');
97
        }
98
99
        $this->apply(new TicketCancelled($this->id, $ticketId));
100
    }
101
102
    protected function applyTicketCancelled(TicketCancelled $event)
103
    {
104
        unset($this->tickets[$event->getTicketId()]);
105
    }
106
107
    protected function applyTicketReserved(TicketReserved $event)
108
    {
109
        $this->tickets[$event->getId()] = BookedTicket::reserve($event);
110
    }
111
112
    protected function applyTicketPurchaseCreated(TicketPurchaseCreated $event)
113
    {
114
        $this->id = $event->getId();
115
    }
116
117
    protected function applyTicketPurchaseTotalPriceCalculated(TicketPurchaseTotalPriceCalculated $event)
118
    {
119
        $this->total = $event->getTotal();
0 ignored issues
show
Documentation Bug introduced by
It seems like $event->getTotal() of type ConferenceTools\Tickets\Domain\ValueObject\Price is incompatible with the declared type ConferenceTools\Tickets\Domain\ValueObject\Money of property $total.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
120
    }
121
122
    public function assignTicketToDelegate(string $id, Delegate $delegate)
123
    {
124
        $event = new TicketAssigned($id, $this->id, $delegate);
125
        $this->apply($event);
126
    }
127
128
    protected function applyTicketAssigned(TicketAssigned $event)
129
    {
130
        $this->tickets[$event->getTicketId()]->assignToDelegate($event);
131
    }
132
133
    public function timeoutPurchase()
134
    {
135
        if ($this->isPaid) {
136
            throw new \DomainException('Booking cannot timeout once it has been paid for');
137
        }
138
        
139
        $event = new TicketPurchaseTimedout($this->id);
140
        $this->apply($event);
141
        
142
        foreach ($this->tickets as $ticket) {
143
            $this->apply(new TicketReleased($ticket->getId(), $this->id, $ticket->getTicketType()));
144
        }
145
    }
146
147
    protected function applyTicketPurchaseTimedout(TicketPurchaseTimedout $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

147
    protected function applyTicketPurchaseTimedout(/** @scrutinizer ignore-unused */ TicketPurchaseTimedout $event)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
148
    {
149
        $this->isTimedout = true;
150
    }
151
152
    public function markAsPaid(string $email)
153
    {
154
        $event = new TicketPurchasePaid($this->id, $email);
155
        $this->apply($event);
156
    }
157
158
    protected function applyTicketPurchasePaid(TicketPurchasePaid $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

158
    protected function applyTicketPurchasePaid(/** @scrutinizer ignore-unused */ TicketPurchasePaid $event)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
159
    {
160
        $this->isPaid = true;
161
    }
162
}