Completed
Push — master ( e81539...abb491 )
by Olivier
01:40
created

Subscription::createFromArray()   B

Complexity

Conditions 8
Paths 128

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 27
cts 27
cp 1
rs 8.0088
c 0
b 0
f 0
cc 8
nc 128
nop 1
crap 8
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This software may be modified and distributed under the terms
7
 * of the MIT license. See the LICENSE file for details.
8
 */
9
10
namespace Shapin\Stripe\Model\Subscription;
11
12
use Shapin\Stripe\Model\ContainsMetadata;
13
use Shapin\Stripe\Model\CreatableFromArray;
14
use Shapin\Stripe\Model\Discount\Discount;
15
use Shapin\Stripe\Model\LivemodeTrait;
16
use Shapin\Stripe\Model\MetadataTrait;
17
use Shapin\Stripe\Model\MetadataCollection;
18
use Shapin\Stripe\Model\Plan\Plan;
19
20
final class Subscription implements CreatableFromArray, ContainsMetadata
21
{
22
    use LivemodeTrait, MetadataTrait;
23
24
    const BILLING_CHARGE_AUTOMATICALLY = 'charge_automatically';
25
    const BILLING_SEND_INVOICE = 'send_invoice';
26
27
    const STATUS_EXPIRED = 'incomplete_expired';
28
    const STATUS_INCOMPLETE = 'incomplete';
29
    const STATUS_TRIALING = 'trialing';
30
    const STATUS_ACTIVE = 'active';
31
    const STATUS_PAST_DUE = 'past_due';
32
    const STATUS_CANCELED = 'canceled';
33
    const STATUS_UNPAID = 'unpaid';
34
35
    /**
36
     * @var string
37
     */
38
    private $id;
39
40
    /**
41
     * @var ?float
42
     */
43
    private $applicationFeePercent;
44
45
    /**
46
     * @var string
47
     */
48
    private $billing;
49
50
    /**
51
     * @var mixed
52
     */
53
    private $billingCycleAnchor;
54
55
    /**
56
     * @var bool
57
     */
58
    private $cancelAtPeriodEnd;
59
60
    /**
61
     * @var ?\DateTimeImmutable
62
     */
63
    private $canceledAt;
64
65
    /**
66
     * @var \DateTimeImmutable
67
     */
68
    private $createdAt;
69
70
    /**
71
     * @var \DateTimeImmutable
72
     */
73
    private $currentPeriodEndAt;
74
75
    /**
76
     * @var \DateTimeImmutable
77
     */
78
    private $currentPeriodStartAt;
79
80
    /**
81
     * @var string
82
     */
83
    private $customer;
84
85
    /**
86
     * @var ?int
87
     */
88
    private $daysUntilDue;
89
90
    /**
91
     * @var ?string
92
     */
93
    private $defaultSource;
94
95
    /**
96
     * @var array
97
     */
98
    private $defaultTaxRates;
99
100
    /**
101
     * @var ?Discount
102
     */
103
    private $discount;
104
105
    /**
106
     * @var ?\DateTimeImmutable
107
     */
108
    private $endedAt;
109
110
    /**
111
     * @var ItemCollection
112
     */
113
    private $items;
114
115
    /**
116
     * @var Plan
117
     */
118
    private $plan;
119
120
    /**
121
     * @var int
122
     */
123
    private $quantity;
124
125
    /**
126
     * @var \DateTimeImmutable
127
     */
128
    private $startAt;
129
130
    /**
131
     * @var string
132
     */
133
    private $status;
134
135
    /**
136
     * @var ?\DateTimeImmutable
137
     */
138
    private $trialEndAt;
139
140
    /**
141
     * @var ?\DateTimeImmutable
142
     */
143
    private $trialStartAt;
144
145 8
    public static function createFromArray(array $data): self
146
    {
147 8
        $model = new self();
148 8
        $model->id = $data['id'];
149 8
        $model->applicationFeePercent = null !== $data['application_fee_percent'] ? (float) $data['application_fee_percent'] : null;
150 8
        $model->billing = $data['billing'];
151 8
        $model->billingCycleAnchor = $data['billing_cycle_anchor'];
152 8
        $model->cancelAtPeriodEnd = (bool) $data['cancel_at_period_end'];
153 8
        $model->canceledAt = null !== $data['canceled_at'] ? new \DateTimeImmutable('@'.$data['canceled_at']) : null;
154 8
        $model->createdAt = new \DateTimeImmutable('@'.$data['created']);
155 8
        $model->currentPeriodEndAt = new \DateTimeImmutable('@'.$data['current_period_end']);
156 8
        $model->currentPeriodStartAt = new \DateTimeImmutable('@'.$data['current_period_start']);
157 8
        $model->customer = $data['customer'];
158 8
        $model->daysUntilDue = null !== $data['days_until_due'] ? (int) $data['days_until_due'] : null;
159 8
        $model->defaultSource = $data['default_source'] ?? null;
160 8
        $model->defaultTaxRates = $data['default_tax_rates'];
161 8
        $model->discount = isset($data['discount']) ? Discount::createFromArray($data['discount']) : null;
162 8
        $model->endedAt = null !== $data['ended_at'] ? new \DateTimeImmutable('@'.$data['ended_at']) : null;
163 8
        $model->items = ItemCollection::createFromArray($data['items']);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Shapin\Stripe\Model\Sub...omArray($data['items']) of type object<self> is incompatible with the declared type object<Shapin\Stripe\Mod...ription\ItemCollection> of property $items.

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...
164 8
        $model->live = $data['livemode'];
165 8
        $model->metadata = MetadataCollection::createFromArray($data['metadata']);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Shapin\Stripe\Model\Met...rray($data['metadata']) of type object<self> is incompatible with the declared type object<Shapin\Stripe\Model\MetadataCollection> of property $metadata.

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...
166 8
        $model->plan = Plan::createFromArray($data['plan']);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Shapin\Stripe\Model\Pla...romArray($data['plan']) of type object<self> is incompatible with the declared type object<Shapin\Stripe\Model\Plan\Plan> of property $plan.

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...
167 8
        $model->quantity = (int) $data['quantity'];
168 8
        $model->startAt = new \DateTimeImmutable('@'.$data['start']);
169 8
        $model->status = $data['status'];
170 8
        $model->trialEndAt = null !== $data['trial_end'] ? new \DateTimeImmutable('@'.$data['trial_end']) : null;
171 8
        $model->trialStartAt = null !== $data['trial_start'] ? new \DateTimeImmutable('@'.$data['trial_start']) : null;
172
173 8
        return $model;
174
    }
175
176 1
    public function isBilledAutomatically(): bool
177
    {
178 1
        return self::BILLING_CHARGE_AUTOMATICALLY === $this->billing;
179
    }
180
181
    public function isIncomplete(): bool
182
    {
183
        return self::STATUS_INCOMPLETE === $this->status;
184
    }
185
186
    public function isExpired(): bool
187
    {
188
        return self::STATUS_EXPIRED === $this->status;
189
    }
190
191
    public function isTrialing(): bool
192
    {
193
        return self::STATUS_TRIALING === $this->status;
194
    }
195
196
    public function isActive(): bool
197
    {
198
        return self::STATUS_ACTIVE === $this->status;
199
    }
200
201
    public function isPastDue(): bool
202
    {
203
        return self::STATUS_PAST_DUE === $this->status;
204
    }
205
206
    public function isCanceled(): bool
207
    {
208
        return self::STATUS_CANCELED === $this->status;
209
    }
210
211
    public function isUnpaid(): bool
212
    {
213
        return self::STATUS_UNPAID === $this->status;
214
    }
215
216
    public function hasDefaultSource(): bool
217
    {
218
        return null !== $this->defaultSource;
219
    }
220
221 1
    public function getId(): string
222
    {
223 1
        return $this->id;
224
    }
225
226 1
    public function getApplicationFeePercent(): ?float
227
    {
228 1
        return $this->applicationFeePercent;
229
    }
230
231 1
    public function getBilling(): string
232
    {
233 1
        return $this->billing;
234
    }
235
236 1
    public function getBillingCycleAnchor()
237
    {
238 1
        return $this->billingCycleAnchor;
239
    }
240
241 1
    public function willBeCanceledAtPeriodEnd(): bool
242
    {
243 1
        return $this->cancelAtPeriodEnd;
244
    }
245
246 1
    public function getCanceledAt(): ?\DateTimeImmutable
247
    {
248 1
        return $this->canceledAt;
249
    }
250
251 1
    public function getCreatedAt(): \DateTimeImmutable
252
    {
253 1
        return $this->createdAt;
254
    }
255
256 1
    public function getCurrentPeriodEndAt(): \DateTimeImmutable
257
    {
258 1
        return $this->currentPeriodEndAt;
259
    }
260
261 1
    public function getCurrentPeriodStartAt(): \DateTimeImmutable
262
    {
263 1
        return $this->currentPeriodStartAt;
264
    }
265
266 1
    public function getCustomer(): string
267
    {
268 1
        return $this->customer;
269
    }
270
271 1
    public function getDaysUntilDue(): ?int
272
    {
273 1
        return $this->daysUntilDue;
274
    }
275
276 1
    public function getDefaultSource(): ?string
277
    {
278 1
        return $this->defaultSource;
279
    }
280
281 1
    public function getDefaultTaxRates(): array
282
    {
283 1
        return $this->defaultTaxRates;
284
    }
285
286 1
    public function getDiscount(): ?Discount
287
    {
288 1
        return $this->discount;
289
    }
290
291 1
    public function hasDiscount(): bool
292
    {
293 1
        return null !== $this->discount;
294
    }
295
296 1
    public function hasActiveDiscountForCurrentPeriod(): bool
297
    {
298 1
        if (!$this->hasDiscount()) {
299 1
            return false;
300
        }
301
302
        // Discount start after the current period
303
        if ($this->getCurrentPeriodEndAt() < $this->discount->getStartAt()) {
304
            return false;
305
        }
306
307
        // Discount has ended before the current period
308
        $endAt = $this->discount->getEndAt() ?? $this->discount->getStartAt();
309
        if ($this->getCurrentPeriodStartAt() > $endAt) {
310
            return false;
311
        }
312
313
        return true;
314
    }
315
316 1
    public function getEndedAt(): ?\DateTimeImmutable
317
    {
318 1
        return $this->endedAt;
319
    }
320
321 1
    public function getItems(): ItemCollection
322
    {
323 1
        return $this->items;
324
    }
325
326
    public function getPlan(): Plan
327
    {
328
        return $this->plan;
329
    }
330
331 1
    public function getQuantity(): int
332
    {
333 1
        return $this->quantity;
334
    }
335
336 1
    public function getStartAt(): \DateTimeImmutable
337
    {
338 1
        return $this->startAt;
339
    }
340
341 1
    public function getStatus(): string
342
    {
343 1
        return $this->status;
344
    }
345
346 1
    public function getTrialEndAt(): ?\DateTimeImmutable
347
    {
348 1
        return $this->trialEndAt;
349
    }
350
351 1
    public function getTrialStartAt(): ?\DateTimeImmutable
352
    {
353 1
        return $this->trialStartAt;
354
    }
355
}
356