Passed
Push — main ( 045c7a...58bc73 )
by Michael
04:05 queued 13s
created

Coupon::isSameRedeemerModel()   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 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\Couponables\Models;
6
7
use Illuminate\Database\Eloquent\Factories\HasFactory;
8
use Illuminate\Database\Eloquent\Model;
9
use MichaelRubel\Couponables\Models\Contracts\CouponContract;
10
use MichaelRubel\Couponables\Models\Traits\DefinesColumns;
11
12
class Coupon extends Model implements CouponContract
13
{
14
    use HasFactory, DefinesColumns;
15
16
    /**
17
     * The attributes that aren't mass assignable.
18
     *
19
     * @var array<string>|bool
20
     */
21
    protected $guarded = [];
22
23
    /**
24
     * The attributes that should be cast.
25
     *
26
     * @var array
27
     */
28
    protected $casts = [
29
        'code'     => 'string',
30
        'type'     => 'string',
31
        'data'     => 'collection',
32
        'quantity' => 'integer',
33
        'limit'    => 'integer',
34
        'datetime' => 'datetime',
35
    ];
36
37
    /**
38
     * @param array $attributes
39
     */
40 34
    public function __construct(array $attributes = [])
41
    {
42 34
        parent::__construct($attributes);
43
44 34
        $this->table = config('couponables.table', 'coupons');
45
    }
46
47
    /**
48
     * The only model allowed to redeem the code if assigned.
49
     *
50
     * @return Model|null
51
     */
52 2
    public function redeemer(): ?Model
53
    {
54 2
        return $this->isMorphColumnsFilled()
55 2
            ? $this->morphTo()->first()
56 2
            : null;
57
    }
58
59
    /**
60
     * @param Model $model
61
     *
62
     * @return bool
63
     */
64 2
    public function isSameRedeemerModel(Model $model): bool
65
    {
66 2
        return $this->{call($this)->getRedeemerTypeColumn()} === $model->getMorphClass();
67
    }
68
69
    /**
70
     * Check if code is expired.
71
     *
72
     * @return bool
73
     */
74 21
    public function isExpired(): bool
75
    {
76 21
        $expires_at = $this->{call(CouponContract::class)->getExpiresAtColumn()};
77
78 21
        return $expires_at && now()->gte($expires_at);
79
    }
80
81
    /**
82
     * Check if code is not expired.
83
     *
84
     * @return bool
85
     */
86 1
    public function isNotExpired(): bool
87
    {
88 1
        return ! call($this)->isExpired();
89
    }
90
91
    /**
92
     * Check if code amount is over.
93
     *
94
     * @return bool
95
     */
96 18
    public function isOverQuantity(): bool
97
    {
98 18
        $quantity = $this->{call(CouponContract::class)->getQuantityColumn()};
99
100 18
        return ! is_null($quantity) && $quantity <= 0;
101
    }
102
103
    /**
104
     * Check if coupon is already redeemed by the model.
105
     *
106
     * @param Model $redeemer
107
     *
108
     * @return bool
109
     */
110 2
    public function isRedeemedBy(Model $redeemer): bool
111
    {
112 2
        $column = call(CouponContract::class)->getCodeColumn();
113 2
        $code   = $this->{$column};
114
115 2
        return ! is_null($code) && $redeemer
116 2
            ->coupons()
117 2
            ->where($column, $code)
118 2
            ->exists();
119
    }
120
121
    /**
122
     * Check if coupon is disposable.
123
     *
124
     * @return bool
125
     */
126 18
    public function isDisposable(): bool
127
    {
128 18
        $limit = $this->{call(CouponContract::class)->getLimitColumn()};
129
130 18
        return ! is_null($limit) && single($limit);
131
    }
132
133
    /**
134
     * Check if the code is reached its limit for the passed model.
135
     *
136
     * @param Model $redeemer
137
     *
138
     * @return bool
139
     */
140 18
    public function isOverLimitFor(Model $redeemer): bool
141
    {
142 18
        $column = call(CouponContract::class)->getCodeColumn();
143 18
        $limit  = $this->{call(CouponContract::class)->getLimitColumn()};
144
145 18
        return ! is_null($limit) && $limit <= $redeemer
146 5
            ->coupons()
147 5
            ->where($column, $this->{$column})
148 18
            ->count();
149
    }
150
}
151