Completed
Push — develop ( f50f20...f9e081 )
by Adolfo
01:10
created

Plan::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
c 0
b 0
f 0
rs 9.456
cc 2
nc 2
nop 7
1
<?php
2
3
namespace Sagitarius29\LaravelSubscriptions;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
use Sagitarius29\LaravelSubscriptions\Contracts\PlanContract;
8
use Sagitarius29\LaravelSubscriptions\Contracts\GroupContract;
9
10
abstract class Plan extends Model implements PlanContract
11
{
12
    protected $table = 'plans';
13
14
    protected $fillable = [
15
        'name', 'description', 'free_days', 'sort_order', 'is_active', 'is_default', 'group',
16
    ];
17
18
    public function scopeByGroup(Builder $q, GroupContract $group = null)
19
    {
20
        return $q->where('group', $group);
21
    }
22
23
    public function scopeIsDefault(Builder $q)
24
    {
25
        return $q->where('is_default', 1);
26
    }
27
28
    public function features()
29
    {
30
        return $this->hasMany(config('subscriptions.entities.plan_feature'));
31
    }
32
33
    public function intervals()
34
    {
35
        return $this->hasMany(config('subscriptions.entities.plan_interval'), 'plan_id')
36
            ->orderBy('price');
37
    }
38
39
    public function subscriptions()
40
    {
41
        return $this->hasMany(config('subscriptions.entities.plan_subscription'));
42
    }
43
44
    public function isDefault(): bool
45
    {
46
        return $this->is_default;
47
    }
48
49
    public function isActive(): bool
50
    {
51
        return $this->is_active;
52
    }
53
54
    public function isFree(): bool
55
    {
56
        return $this->intervals()->count() == 0 || $this->intervals()->first()->price == 0;
57
    }
58
59
    public function isNotFree(): bool
60
    {
61
        return $this->intervals()->count() > 0 && $this->intervals()->first()->price > 0;
62
    }
63
64
    public function hasManyIntervals(): bool
65
    {
66
        return $this->intervals()->count() > 1;
67
    }
68
69
    public static function create(
70
        string $name,
71
        string $description,
72
        int $free_days,
73
        int $sort_order,
74
        bool $is_active = false,
75
        bool $is_default = false,
76
        GroupContract $group = null
77
    ): Model {
78
        $attributes = [
79
            'name'          => $name,
80
            'description'   => $description,
81
            'free_days'     => $free_days,
82
            'sort_order'    => $sort_order,
83
            'is_active'     => $is_active,
84
            'is_default'    => $is_default,
85
            'group'         => $group,
86
        ];
87
        $calledClass = get_called_class();
88
89
        if (! self::defaultExists($group)) {
90
           $attributes['is_default'] = true;
91
        }
92
93
        $plan = new $calledClass($attributes);
94
        $plan->save();
95
96
        return $plan;
97
    }
98
99
    public function setFree()
100
    {
101
        $this->intervals()->delete();
102
    }
103
104
    public function setDefault()
105
    {
106
        $myGroup = $this->myGroup();
107
        $calledClass = get_called_class();
108
109
        $currentDefaults = $calledClass::query()
110
            ->byGroup($myGroup)
111
            ->isDefault()
112
            ->get();
113
114
        $currentDefaults->each(function($plan) {
115
            $plan->is_default = false;
116
            $plan->save();
117
        });
118
119
        $this->is_default = true;
120
        $this->save();
121
    }
122
123
    public function myGroup(): ?GroupContract
124
    {
125
        return empty($this->group) ? null : new \Sagitarius29\LaravelSubscriptions\Entities\Group($this->group);
126
    }
127
128
    public function changeToGroup(GroupContract $group): void
129
    {
130
        $this->group = $group;
131
132
        if (! self::defaultExists($group)) {
133
            $this->is_default = true;
134
        }
135
136
        $this->save();
137
    }
138
139
    private static function defaultExists(GroupContract $group = null): bool
140
    {
141
        $calledClass = get_called_class();
142
143
        return $calledClass::query()
144
            ->byGroup($group)
145
            ->isDefault()
146
            ->exists();
147
    }
148
}
149