Bill   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Test Coverage

Coverage 55.22%

Importance

Changes 11
Bugs 1 Features 2
Metric Value
eloc 60
c 11
b 1
f 2
dl 0
loc 207
ccs 37
cts 67
cp 0.5522
rs 10
wmc 29

23 Methods

Rating   Name   Duplication   Size   Complexity  
A getCustomer() 0 3 1
A getType() 0 3 1
A getTarget() 0 3 1
A getPlan() 0 3 1
A calculatePrice() 0 5 2
A getUniqueString() 0 11 2
A hasCharges() 0 3 1
A getQuantity() 0 3 1
A getSum() 0 3 1
A getComment() 0 3 1
A setComment() 0 3 1
A jsonSerialize() 0 3 1
A getRequisite() 0 3 1
A getTime() 0 3 1
A getState() 0 3 1
A isFinished() 0 3 2
A __construct() 0 22 1
A setQuantity() 0 5 1
A setCharges() 0 8 2
A getCharges() 0 3 1
A setId() 0 9 3
A getId() 0 3 1
A setFinished() 0 3 1
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\bill;
12
13
use DateTimeImmutable;
14
use hiqdev\php\billing\charge\ChargeInterface;
15
use hiqdev\php\billing\customer\CustomerInterface;
16
use hiqdev\php\billing\Exception\CannotReassignException;
17
use hiqdev\php\billing\plan\PlanInterface;
18
use hiqdev\php\billing\target\TargetInterface;
19
use hiqdev\php\billing\type\TypeInterface;
20
use hiqdev\php\units\QuantityInterface;
21
use Money\Money;
22
23
/**
24
 * Bill.
25
 *
26
 * @author Andrii Vasyliev <[email protected]>
27
 */
28
class Bill implements BillInterface
29
{
30
    /** @var int|string */
31
    protected $id;
32
33
    /** @var TypeInterface */
34
    protected $type;
35
36
    /** @var DateTimeImmutable */
37
    protected $time;
38
39
    /** @var Money */
40
    protected $sum;
41
42
    /** @var QuantityInterface */
43
    protected $quantity;
44
45
    /** @var CustomerInterface */
46
    protected $customer;
47
48
    /** @var TargetInterface */
49
    protected $target;
50
51
    /** @var BillRequisite */
52
    protected $requisite;
53
54
    /** @var PlanInterface */
55
    protected $plan;
56
57
    /** @var ChargeInterface[] */
58
    protected $charges = [];
59
60
    /** @var BillState */
61
    protected $state;
62
63 3
    /** @var string */
64
    protected $comment;
65
66
    public function __construct(
67
                            $id,
68
        TypeInterface $type,
69
        DateTimeImmutable $time,
70
        Money $sum,
71
        QuantityInterface $quantity,
72
        CustomerInterface $customer,
73
        TargetInterface $target = null,
74
        PlanInterface $plan = null,
75 3
        array $charges = [],
76 3
        BillState $state = null
77 3
    ) {
78 3
        $this->id           = $id;
79 3
        $this->type         = $type;
80 3
        $this->time         = $time;
81 3
        $this->sum          = $sum;
82 3
        $this->quantity     = $quantity;
83 3
        $this->customer     = $customer;
84 3
        $this->target       = $target;
85 3
        $this->plan         = $plan;
86
        $this->charges      = $charges;
87
        $this->state        = $state;
88
    }
89
90
    /**
91 1
     * Provides unique string.
92
     * Can be used to compare or aggregate bills.
93
     */
94 1
    public function getUniqueString(): string
95 1
    {
96 1
        $parts = [
97 1
            'currency'  => $this->sum->getCurrency()->getCode(),
98 1
            'buyer'     => $this->customer->getUniqueId(),
99
            'target'    => $this->target ? $this->target->getUniqueId() : null,
100
            'type'      => $this->type->getUniqueId(),
101 1
            'time'      => $this->time->format('c'),
102
        ];
103
104
        return implode('-', $parts);
105
    }
106
107
    public function calculatePrice()
108
    {
109
        $quantity = $this->quantity->getQuantity();
110
111
        return $quantity ? $this->sum->divide(sprintf('%.14F', $quantity)) : $this->sum;
112
    }
113
114 3
    /**
115
     * @return int|string
116 3
     */
117
    public function getId()
118
    {
119
        return $this->id;
120
    }
121
122
    public function setId($id)
123
    {
124
        if ($this->id === $id) {
125
            return;
126
        }
127
        if ($this->id !== null) {
128
            throw new CannotReassignException('bill id');
129
        }
130 1
        $this->id = $id;
131
    }
132 1
133
    public function getType(): TypeInterface
134
    {
135 3
        return $this->type;
136
    }
137 3
138
    public function getTime(): DateTimeImmutable
139
    {
140
        return $this->time;
141
    }
142
143 3
    public function getTarget(): ?TargetInterface
144
    {
145 3
        return $this->target;
146
    }
147
148
    public function getRequisite(): ?BillRequisite
149
    {
150
        return $this->requisite;
151 3
    }
152
153 3
    public function getCustomer(): CustomerInterface
154
    {
155
        return $this->customer;
156
    }
157
158
    public function getQuantity(): QuantityInterface
159 3
    {
160
        return $this->quantity;
161 3
    }
162
163
    public function setQuantity(QuantityInterface $quantity): BillInterface
164
    {
165
        $this->quantity = $quantity;
166
167
        return $this;
168
    }
169
170
    public function getSum(): Money
171
    {
172
        return $this->sum;
173
    }
174 3
175
    public function getPlan(): ?PlanInterface
176 3
    {
177
        return $this->plan;
178
    }
179
180
    public function hasCharges(): bool
181
    {
182 3
        return $this->charges !== [];
183
    }
184 3
185
    /**
186
     * @return ChargeInterface[]
187
     */
188
    public function getCharges(): array
189
    {
190
        return $this->charges;
191
    }
192
193
    /**
194
     * @param ChargeInterface[] $prices
195 1
     * @throws \Exception
196
     */
197 1
    public function setCharges(array $charges): self
198
    {
199
        if ($this->hasCharges()) {
200
            throw new CannotReassignException('bill charges');
201
        }
202
        $this->charges = $charges;
203
204
        return $this;
205
    }
206
207
    public function getState(): ?BillState
208
    {
209
        return $this->state;
210
    }
211
212
    public function setFinished(): void
213
    {
214
        $this->state = BillState::finished();
215
    }
216
217
    public function isFinished(): ?bool
218
    {
219
        return $this->state === null ? null : $this->state->isFinished();
220
    }
221
222
    public function getComment()
223
    {
224
        return $this->comment;
225
    }
226
227
    public function setComment(string $comment)
228
    {
229
        $this->comment = $comment;
230
    }
231
232
    public function jsonSerialize(): array
233
    {
234
        return array_filter(get_object_vars($this));
235
    }
236
}
237