Completed
Push — master ( 02dfbd...2340d0 )
by Christopher
01:13
created

Project::isVisible()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
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\MorphToMany;
12
13
class Project extends Model
14
{
15
    use HasUsers, HasStatus;
16
17
    protected $table = 'projects';
18
19
    public $primaryKey = 'id';
20
21
    public $guarded = ['id'];
22
23
    public $timestamps = true;
24
25
    protected $dates = [
26
        'started_at',
27
        'delivered_at',
28
        'expected_at',
29
    ];
30
31
    protected $casts = [
32
        'visible' => 'bool',
33
    ];
34
35
    public function __construct(array $attributes = [])
36
    {
37
        parent::__construct($attributes);
38
    }
39
40
    public function owner() : BelongsTo
41
    {
42
        return $this->belongsTo(get_class(user_model()));
43
    }
44
45
    public function status() : BelongsTo
46
    {
47
        return $this->belongsTo(Status::class);
48
    }
49
50
    public function tasks() : MorphToMany
51
    {
52
        return $this->morphedByMany(Task::class, 'projectable');
53
    }
54
55
    public function isVisible() : bool
56
    {
57
        return $this->attributes['visible'] == true;
58
    }
59
60
    public function isNotVisible() : bool
61
    {
62
        return $this->attributes['visible'] == false;
63
    }
64
65
    public function dueIn(string $format = 'days') : int
66
    {
67
        $method = 'diffIn'.ucfirst($format);
68
69
        if ( ! $this->hasDateTarget()) {
70
            return 0;
71
        }
72
73
        if ( ! method_exists(Carbon::class, $method)) {
74
            throw new BadMethodCallException(sprintf(
75
                'Method %s::%s does not exist.',
76
                Carbon::class,
77
                $method
78
            ));
79
        }
80
81
        return $this->started_at->$method($this->expected_at);
82
    }
83
84
    public function assignTask(Task $task) : void
85
    {
86
        $this->tasks()->save($task);
87
88
        $this->refresh();
89
    }
90
91
    public function removeTask(Task $task) : void
92
    {
93
        $this->tasks()->detach($task);
94
95
        $this->refresh();
96
    }
97
98
    public function hasTask(Task $task) : bool
99
    {
100
        $this->refresh();
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()
147
        || $this->completedAfterSchedule())
148
        && $this->completedAllTasks();
149
    }
150
151
    /**
152
     * Was the task completed after the given deadline.
153
     *
154
     * @return bool
155
     */
156
    public function completedAfterSchedule() : bool
157
    {
158
        return $this->delivered_at->greaterThan($this->expected_at);
159
    }
160
161
    /**
162
     * Was the task completed before the given deadline.
163
     *
164
     * @return bool
165
     */
166
    public function completedBeforeSchedule() : bool
167
    {
168
        return $this->delivered_at->lessThan($this->expected_at);
169
    }
170
171
    /**
172
     * Was the task completed before or on the given deadline.
173
     *
174
     * @return bool
175
     */
176
    public function completedOnSchedule() : bool
177
    {
178
        return $this->delivered_at->lessThanOrEqualTo($this->expected_at);
179
    }
180
181
    /**
182
     * Is the task overdue.
183
     *
184
     * @return bool
185
     */
186
    public function isOverdue() : bool
187
    {
188
        return $this->isInProcess() && ! $this->notDueYet();
189
    }
190
191
    /**
192
     * Have all tasks been completed.
193
     *
194
     * @return bool
195
     */
196
    public function completedAllTasks() : bool
197
    {
198
        $this->load('tasks');
199
200
        if ($this->tasks->isEmpty()) {
201
            return true;
202
        }
203
204
        return $this->tasks->count() === $this->tasks->sum->completed();
205
    }
206
}
207