Passed
Push — main ( f1d025...26fb74 )
by Michael
03:41 queued 10s
created

HasCoupons   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 0 Features 1
Metric Value
eloc 21
c 6
b 0
f 1
dl 0
loc 91
ccs 26
cts 26
cp 1
rs 10
wmc 7

6 Methods

Rating   Name   Duplication   Size   Complexity  
A coupons() 0 6 1
A redeemCoupon() 0 8 1
A isCouponRedeemed() 0 8 1
A isCouponOverLimit() 0 6 2
A isCouponAlreadyUsed() 0 3 1
A verifyCoupon() 0 6 1
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
     * Perform coupon verification.
33
     *
34
     * @param string|null $code
35
     *
36
     * @return CouponContract
37
     */
38 1
    public function verifyCoupon(?string $code): CouponContract
39
    {
40 1
        $service = call(CouponServiceContract::class);
41 1
        $proxy   = call($service->verifyCoupon($code, $this));
42
43 1
        return $proxy->getInternal(Call::INSTANCE);
44
    }
45
46
    /**
47
     * Use the coupon.
48
     *
49
     * @param string|null $code
50
     *
51
     * @return CouponContract
52
     */
53 17
    public function redeemCoupon(?string $code): CouponContract
54
    {
55 17
        $service = call(CouponServiceContract::class);
56 17
        $proxy   = call($service->verifyCoupon($code, $this));
57
58 13
        $coupon = $proxy->getInternal(Call::INSTANCE);
59
60 13
        return $service->applyCoupon($coupon, $this);
61
    }
62
63
    /**
64
     * Check if the coupon is already redeemed by the model at least once.
65
     *
66
     * @param string $code
67
     *
68
     * @return bool
69
     */
70 4
    public function isCouponRedeemed(string $code): bool
71
    {
72 4
        $column = call(CouponContract::class)
73 4
            ->getCodeColumn();
74
75 4
        return $this->coupons()
76 4
            ->where($column, $code)
77 4
            ->exists();
78
    }
79
80
    /**
81
     * Check if coupon with this code is already used.
82
     *
83
     * @param string|null $code
84
     *
85
     * @return bool
86
     */
87 3
    public function isCouponAlreadyUsed(?string $code): bool
88
    {
89 3
        return call($this)->isCouponRedeemed($code);
90
    }
91
92
    /**
93
     * Check if the coupon is over limit for the model.
94
     *
95
     * @param string|null $code
96
     *
97
     * @return bool
98
     *
99
     */
100 1
    public function isCouponOverLimit(?string $code): bool
101
    {
102 1
        $service = call(CouponServiceContract::class);
103 1
        $coupon  = $service->getCoupon($code);
104
105 1
        return ! is_null($coupon) && call($coupon)->isOverLimitFor($this);
106
    }
107
}
108