Passed
Push — main ( 760f2b...40f0da )
by Michael
12:28
created

HasCoupons   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 8
Bugs 0 Features 1
Metric Value
eloc 31
c 8
b 0
f 1
dl 0
loc 159
ccs 36
cts 36
cp 1
rs 10
wmc 11

10 Methods

Rating   Name   Duplication   Size   Complexity  
A verifyCoupon() 0 6 1
A coupons() 0 6 1
A redeemCoupon() 0 8 1
A isCouponRedeemed() 0 8 1
A isCouponOverLimit() 0 6 2
A verifyCouponOr() 0 6 1
A redeemCouponOr() 0 6 1
A isCouponAlreadyUsed() 0 3 1
A verifyOrNullifyCoupon() 0 3 1
A redeemOrNullifyCoupon() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\Couponables;
6
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\MorphToMany;
9
use Illuminate\Support\Str;
10
use MichaelRubel\Couponables\Exceptions\CouponException;
11
use MichaelRubel\Couponables\Models\Contracts\CouponContract;
12
use MichaelRubel\Couponables\Models\Contracts\CouponPivotContract;
13
use MichaelRubel\Couponables\Services\Contracts\CouponServiceContract;
14
use MichaelRubel\EnhancedContainer\Call;
15
16
trait HasCoupons
17
{
18
    /**
19
     * Polymorphic relation to the coupons.
20
     *
21
     * @return MorphToMany
22
     */
23 15
    public function coupons(): MorphToMany
24
    {
25 15
        return $this->morphToMany(app(CouponContract::class), Str::singular(
0 ignored issues
show
Bug introduced by
It seems like morphToMany() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

25
        return $this->/** @scrutinizer ignore-call */ morphToMany(app(CouponContract::class), Str::singular(
Loading history...
26 15
            config('couponables.pivot_table', 'couponables')
27 15
        ))->withPivot(
28 15
            call(CouponPivotContract::class)->getRedeemedAtColumn()
29
        );
30
    }
31
32
    /**
33
     * Perform coupon verification.
34
     *
35
     * @param string|null $code
36
     *
37
     * @return CouponContract
38
     */
39 4
    public function verifyCoupon(?string $code): CouponContract
40
    {
41 4
        $service = call(CouponServiceContract::class);
42 4
        $proxy   = call($service->verifyCoupon($code, $this));
43
44 2
        return $proxy->getInternal(Call::INSTANCE);
45
    }
46
47
    /**
48
     * Verify the coupon or do something else on fail.
49
     *
50
     * @param string|null $code
51
     * @param mixed|null $callback
52
     * @param bool $report
53
     *
54
     * @return mixed
55
     */
56 3
    public function verifyCouponOr(?string $code, mixed $callback = null, bool $report = false): mixed
57
    {
58 3
        return rescue(
59 3
            callback: fn () => call($this)->verifyCoupon($code),
60
            rescue: $callback,
61
            report: $report
62
        );
63
    }
64
65
    /**
66
     * Alias to `verifyCouponOr` with default `null`.
67
     *
68
     * @deprecated
69
     *
70
     * @param string|null $code
71
     * @param mixed|null  $rescue
72
     * @param bool        $report
73
     *
74
     * @return CouponContract|null
75
     */
76 2
    public function verifyOrNullifyCoupon(?string $code, mixed $rescue = null, bool $report = false): ?CouponContract
77
    {
78 2
        return $this->verifyCouponOr($code, $rescue, $report);
79
    }
80
81
    /**
82
     * Use the coupon.
83
     *
84
     * @param string|null $code
85
     *
86
     * @return CouponContract
87
     */
88 20
    public function redeemCoupon(?string $code): CouponContract
89
    {
90 20
        $service = call(CouponServiceContract::class);
91 20
        $proxy   = call($service->verifyCoupon($code, $this));
92
93 14
        $coupon = $proxy->getInternal(Call::INSTANCE);
94
95 14
        return $service->applyCoupon($coupon, $this);
96
    }
97
98
    /**
99
     * Redeem the coupon or do something else on fail.
100
     *
101
     * @param string|null $code
102
     * @param mixed|null $callback
103
     * @param bool $report
104
     *
105
     * @return mixed
106
     */
107 3
    public function redeemCouponOr(?string $code, mixed $callback = null, bool $report = false): mixed
108
    {
109 3
        return rescue(
110 3
            callback: fn () => call($this)->redeemCoupon($code),
111
            rescue: $callback,
112
            report: $report
113
        );
114
    }
115
116
    /**
117
     * Alias to `redeemCouponOr` with default `null`.
118
     *
119
     * @deprecated
120
     *
121
     * @param string|null $code
122
     * @param mixed|null  $rescue
123
     * @param bool        $report
124
     *
125
     * @return CouponContract|null
126
     */
127 2
    public function redeemOrNullifyCoupon(?string $code, mixed $rescue = null, bool $report = false): ?CouponContract
128
    {
129 2
        return $this->redeemCouponOr($code, $rescue, $report);
130
    }
131
132
    /**
133
     * Check if the coupon is already redeemed by the model at least once.
134
     *
135
     * @param string $code
136
     *
137
     * @return bool
138
     */
139 4
    public function isCouponRedeemed(string $code): bool
140
    {
141 4
        $column = call(CouponContract::class)
142 4
            ->getCodeColumn();
143
144 4
        return $this->coupons()
145 4
            ->where($column, $code)
146 4
            ->exists();
147
    }
148
149
    /**
150
     * Check if coupon with this code is already used.
151
     *
152
     * @param string|null $code
153
     *
154
     * @return bool
155
     */
156 3
    public function isCouponAlreadyUsed(?string $code): bool
157
    {
158 3
        return call($this)->isCouponRedeemed($code);
159
    }
160
161
    /**
162
     * Check if the coupon is over limit for the model.
163
     *
164
     * @param string|null $code
165
     *
166
     * @return bool
167
     *
168
     */
169 1
    public function isCouponOverLimit(?string $code): bool
170
    {
171 1
        $service = call(CouponServiceContract::class);
172 1
        $coupon  = $service->getCoupon($code);
173
174 1
        return ! is_null($coupon) && call($coupon)->isOverLimitFor($this);
175
    }
176
}
177