Project::removeTask()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Chriscreates\Projects\Models;
4
5
use BadMethodCallException;
6
use Carbon\Carbon;
7
use Chriscreates\Projects\Traits\HasStatus;
8
use Chriscreates\Projects\Traits\HasUsers;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
use Illuminate\Database\Eloquent\Relations\morphMany;
12
use Illuminate\Database\Eloquent\Relations\MorphToMany;
13
14
class Project extends Model
15
{
16
    use HasUsers, HasStatus;
17
18
    protected $table = 'projects';
19
20
    public $primaryKey = 'id';
21
22
    public $guarded = ['id'];
23
24
    public $timestamps = true;
25
26
    protected $dates = [
27
        'started_at',
28
        'delivered_at',
29
        'expected_at',
30
    ];
31
32
    protected $casts = [
33
        'visible' => 'bool',
34
    ];
35
36
    public function author() : BelongsTo
37
    {
38
        return $this->belongsTo(get_class(user_model()), 'author_id');
39
    }
40
41
    public function owner() : BelongsTo
42
    {
43
        return $this->belongsTo(get_class(user_model()), 'owner_id');
44
    }
45
46
    public function status() : BelongsTo
47
    {
48
        return $this->belongsTo(Status::class);
49
    }
50
51
    public function tasks() : MorphToMany
52
    {
53
        return $this->morphedByMany(Task::class, 'projectable');
54
    }
55
56
    public function comments() : MorphMany
57
    {
58
        return $this->morphMany(Comment::class, 'commentable');
59
    }
60
61
    public function isVisible() : bool
62
    {
63
        return $this->attributes['visible'] == true;
64
    }
65
66
    public function isNotVisible() : bool
67
    {
68
        return $this->attributes['visible'] == false;
69
    }
70
71
    public function dueIn(string $format = 'days') : int
72
    {
73
        $method = 'diffIn'.ucfirst($format);
74
75
        if ( ! $this->hasDateTarget()) {
76
            return 0;
77
        }
78
79
        if ( ! method_exists(Carbon::class, $method)) {
80
            throw new BadMethodCallException(sprintf(
81
                'Method %s::%s does not exist.',
82
                Carbon::class,
83
                $method
84
            ));
85
        }
86
87
        return $this->started_at->$method($this->expected_at);
88
    }
89
90
    public function assignTask(Task $task) : void
91
    {
92
        $this->tasks()->save($task);
93
    }
94
95
    public function removeTask(Task $task) : void
96
    {
97
        $this->tasks()->detach($task);
98
    }
99
100
    public function hasTask(Task $task) : bool
101
    {
102
        return $this->tasks->contains($task->id);
103
    }
104
105
    /**
106
     * Has the task got an expected target.
107
     *
108
     * @return bool
109
     */
110
    public function hasDateTarget() : bool
111
    {
112
        return $this->attributes['started_at'] || $this->attributes['expected_at'];
113
    }
114
115
    /**
116
     * Is the task still in process.
117
     *
118
     * @return bool
119
     */
120
    public function isInProcess() : bool
121
    {
122
        return is_null($this->attributes['delivered_at']);
123
    }
124
125
    /**
126
     * Is the task not due yet.
127
     *
128
     * @return bool
129
     */
130
    public function notDueYet() : bool
131
    {
132
        return $this->expected_at->greaterThan(now());
133
    }
134
135
    /**
136
     * Is the task complete.
137
     *
138
     * @return bool
139
     */
140
    public function completed() : bool
141
    {
142
        if ( ! $this->hasDateTarget() || $this->isInProcess()) {
143
            return false;
144
        }
145
146
        return ($this->completedOnSchedule() || $this->completedAfterSchedule())
147
        && $this->completedAllTasks();
148
    }
149
150
    /**
151
     * Was the task completed after the given deadline.
152
     *
153
     * @return bool
154
     */
155
    public function completedAfterSchedule() : bool
156
    {
157
        return $this->delivered_at->greaterThan($this->expected_at);
158
    }
159
160
    /**
161
     * Was the task completed before the given deadline.
162
     *
163
     * @return bool
164
     */
165
    public function completedBeforeSchedule() : bool
166
    {
167
        return $this->delivered_at->lessThan($this->expected_at);
168
    }
169
170
    /**
171
     * Was the task completed before or on the given deadline.
172
     *
173
     * @return bool
174
     */
175
    public function completedOnSchedule() : bool
176
    {
177
        return $this->delivered_at->lessThanOrEqualTo($this->expected_at);
178
    }
179
180
    /**
181
     * Is the task overdue.
182
     *
183
     * @return bool
184
     */
185
    public function isOverdue() : bool
186
    {
187
        return $this->isInProcess() && ! $this->notDueYet();
188
    }
189
190
    /**
191
     * Have all tasks been completed.
192
     *
193
     * @return bool
194
     */
195
    public function completedAllTasks() : bool
196
    {
197
        $this->load('tasks');
198
199
        if ($this->tasks->isEmpty()) {
200
            return true;
201
        }
202
203
        return $this->tasks->count() === $this->tasks->sum->completed();
204
    }
205
}
206