Passed
Push — main ( 232d2e...3abdd4 )
by Michael
08:47 queued 04:39
created

HasCoupons::isCouponAlreadyUsed()   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 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 3
b 0
f 0
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;
6
7
use Illuminate\Database\Eloquent\Relations\MorphToMany;
8
use Illuminate\Support\Str;
9
use MichaelRubel\Couponables\Models\Contracts\CouponContract;
10
use MichaelRubel\Couponables\Models\Contracts\CouponPivotContract;
11
use MichaelRubel\Couponables\Services\Contracts\CouponServiceContract;
12
use MichaelRubel\EnhancedContainer\Call;
13
14
trait HasCoupons
15
{
16
    /**
17
     * Polymorphic relation to the coupons.
18
     *
19
     * @return MorphToMany
20
     */
21 16
    public function coupons(): MorphToMany
22
    {
23 16
        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

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