Passed
Push — main ( 329592...4b3ce9 )
by Michael
04:19
created

HasCoupons::isCouponDisposable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
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\Exceptions\InvalidCouponException;
10
use MichaelRubel\Couponables\Models\Contracts\CouponContract;
11
use MichaelRubel\Couponables\Models\Contracts\CouponPivotContract;
12
use MichaelRubel\Couponables\Services\Contracts\CouponServiceContract;
13
use MichaelRubel\EnhancedContainer\Call;
14
15
trait HasCoupons
16
{
17
    /**
18
     * Polymorphic relation to the coupons.
19
     *
20
     * @return MorphToMany
21
     */
22 14
    public function coupons(): MorphToMany
23
    {
24 14
        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

24
        return $this->/** @scrutinizer ignore-call */ morphToMany(app(CouponContract::class), Str::singular(
Loading history...
25 14
            config('couponables.pivot_table', 'couponables')
26 14
        ))->withPivot(
27 14
            call(CouponPivotContract::class)->getRedeemedAtColumn()
28
        );
29
    }
30
31
    /**
32
     * Use the coupon.
33
     *
34
     * @param string $code
35
     *
36
     * @return CouponContract
37
     */
38 17
    public function redeemCoupon(string $code): CouponContract
39
    {
40 17
        $service = call(CouponServiceContract::class);
41 17
        $proxy   = call($service->verifyCoupon($code, $this));
42
43 13
        $coupon  = $proxy->getInternal(Call::INSTANCE);
44
45 13
        return $service->applyCoupon($coupon, $this);
46
    }
47
48
    /**
49
     * Check if the coupon is already redeemed by the model at least once.
50
     *
51
     * @param string $code
52
     *
53
     * @return bool
54
     */
55 3
    public function isCouponRedeemed(string $code): bool
56
    {
57 3
        $column = call(CouponContract::class)
58 3
            ->getCodeColumn();
59
60 3
        return $this->coupons()
61 3
            ->where($column, $code)
62 3
            ->exists();
63
    }
64
65
    /**
66
     * Check if coupon with this code is already used.
67
     *
68
     * @param string $code
69
     *
70
     * @return bool
71
     */
72 3
    public function isCouponAlreadyUsed(string $code): bool
73
    {
74 3
        return call($this)->isCouponRedeemed($code);
75
    }
76
77
    /**
78
     * Check if the coupon is over limit for the model.
79
     *
80
     * @param string $code
81
     *
82
     * @return bool
83
     *
84
     * @throws InvalidCouponException
85
     */
86 1
    public function isCouponOverLimit(string $code): bool
87
    {
88 1
        $service = call(CouponServiceContract::class);
89 1
        $coupon  = call($service->getCoupon($code));
90
91 1
        return $coupon->isOverLimitFor($this);
92
    }
93
94
    /**
95
     * Check if coupon is disposable.
96
     *
97
     * @param string $code
98
     *
99
     * @return bool
100
     */
101 14
    public function isCouponDisposable(string $code): bool
102
    {
103 14
        $service = call(CouponServiceContract::class);
104 14
        $coupon  = call($service->getCoupon($code));
105
106 14
        $limit = $coupon->{call(CouponContract::class)->getLimitColumn()};
107
108 14
        return ! is_null($limit)
109 14
            && single($limit)
110 14
            && single($this->coupons()->count());
111
    }
112
}
113