Completed
Push — dev ( 6eb6b3...0bce63 )
by Tristan
05:55 queued 05:46
created

JobPoster::resolveRouteBinding()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * Created by Reliese Model.
5
 * Date: Thu, 12 Jul 2018 22:39:27 +0000.
6
 */
7
8
namespace App\Models;
9
10
use App\Events\JobSaved;
11
use App\Models\JobApplication;
12
use Illuminate\Notifications\Notifiable;
13
use Illuminate\Support\Facades\App;
14
use Illuminate\Support\Facades\Lang;
15
use Jenssegers\Date\Date;
16
use \Backpack\CRUD\CrudTrait;
17
18
/**
19
 * Class JobPoster
20
 *
21
 * @property int $id
22
 * @property int $job_term_id
23
 * @property int $term_qty
24
 * @property \Jenssegers\Date\Date $open_date_time
25
 * @property \Jenssegers\Date\Date $close_date_time
26
 * @property \Jenssegers\Date\Date $start_date_time
27
 * @property \Jenssegers\Date\Date $review_requested_at
28
 * @property \Jessengers\Date\Date $published_at
29
 * @property int $department_id
30
 * @property int $province_id
31
 * @property int $salary_min
32
 * @property int $salary_max
33
 * @property int $noc
34
 * @property string $classification
35
 * @property int $security_clearance_id
36
 * @property int $language_requirement_id
37
 * @property boolean $remote_work_allowed
38
 * @property int $manager_id
39
 * @property boolean $published
40
 * @property \Jenssegers\Date\Date $created_at
41
 * @property \Jenssegers\Date\Date $updated_at
42
 *
43
 * @property int $submitted_applications_count
44
 *
45
 * @property \App\Models\Lookup\Department $department
46
 * @property \App\Models\Lookup\JobTerm $job_term
47
 * @property \App\Models\Lookup\LanguageRequirement $language_requirement
48
 * @property \App\Models\Manager $manager
49
 * @property \App\Models\Lookup\Province $province
50
 * @property \App\Models\Lookup\SecurityClearance $security_clearance
51
 * @property \Illuminate\Database\Eloquent\Collection $criteria
52
 * @property \Illuminate\Database\Eloquent\Collection $job_applications
53
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_key_tasks
54
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_questions
55
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_translations
56
 * @property \Illuminate\Database\Eloquent\Collection $submitted_applications
57
 * @property \Illuminate\Database\Eloquent\Collection[ScreeningPlan] $screening_plans
58
 *
59
 * Localized Properties:
60
 * @property string $city
61
 * @property string $title
62
 * @property string $impact
63
 * @property string $branch
64
 * @property string $division
65
 * @property string $education
66
 *
67
 * Methods
68
 * @method boolean isOpen()
69
 * @method string timeRemaining()
70
 */
0 ignored issues
show
Documentation Bug introduced by
The doc comment \Illuminate\Database\Elo...llection[ScreeningPlan] at position 1 could not be parsed: Expected ']' at position 1, but found '['.
Loading history...
71
class JobPoster extends BaseModel
72
{
73
    use CrudTrait;
0 ignored issues
show
introduced by
The trait Backpack\CRUD\CrudTrait requires some properties which are not provided by App\Models\JobPoster: $Type, $fakeColumns
Loading history...
74
    use \Dimsav\Translatable\Translatable;
0 ignored issues
show
introduced by
The trait Dimsav\Translatable\Translatable requires some properties which are not provided by App\Models\JobPoster: $translations, $useTranslationFallback, $translationModel, $localeKey, $translationForeignKey
Loading history...
75
    use Notifiable;
0 ignored issues
show
introduced by
The trait Illuminate\Notifications\Notifiable requires some properties which are not provided by App\Models\JobPoster: $email, $phone_number
Loading history...
76
77
    const DATE_FORMAT = [
78
        'en' => 'M jS, Y',
79
        'fr' => 'd M Y',
80
    ];
81
    const TIME_FORMAT = [
82
        'en' => 'h:i A T',
83
        'fr' => 'H \h i T',
84
    ];
85
    const TIMEZONE = 'America/Toronto';
86
87
    /**
88
     * @var string[] $translatedAttributes
89
     */
90
    public $translatedAttributes = [
91
        'city',
92
        'title',
93
        'impact',
94
        'branch',
95
        'division',
96
        'education'
97
    ];
98
99
    /**
100
     * @var string[] $casts
101
     */
102
    protected $casts = [
103
        'job_term_id' => 'int',
104
        'department_id' => 'int',
105
        'province_id' => 'int',
106
        'salary_min' => 'int',
107
        'salary_max' => 'int',
108
        'noc' => 'int',
109
        'security_clearance_id' => 'int',
110
        'language_requirement_id' => 'int',
111
        'remote_work_allowed' => 'boolean',
112
        'manager_id' => 'int',
113
        'published' => 'boolean'
114
    ];
115
116
    /**
117
     * @var string[] $dates
118
     */
119
    protected $dates = [
120
        'open_date_time',
121
        'close_date_time',
122
        'start_date_time',
123
        'review_requested_at',
124
        'published_at'
125
    ];
126
127
    /**
128
     * @var string[] $fillable
129
     */
130
    protected $fillable = [
131
        'job_term_id',
132
        'term_qty',
133
        'open_date_time',
134
        'close_date_time',
135
        'start_date_time',
136
        'department_id',
137
        'province_id',
138
        'salary_min',
139
        'salary_max',
140
        'noc',
141
        'classification',
142
        'security_clearance_id',
143
        'language_requirement_id',
144
        'remote_work_allowed',
145
    ];
146
147
    /**
148
     * @var mixed[] $dispatchesEvents
149
     */
150
    protected $dispatchesEvents = [
151
        'saved' => JobSaved::class,
152
    ];
153
154
    // @codeCoverageIgnoreStart
155
156
    public function department() // phpcs:ignore
157
    {
158
        return $this->belongsTo(\App\Models\Lookup\Department::class);
159
    }
160
161
    public function job_term() // phpcs:ignore
162
    {
163
        return $this->belongsTo(\App\Models\Lookup\JobTerm::class);
164
    }
165
166
    public function language_requirement() // phpcs:ignore
167
    {
168
        return $this->belongsTo(\App\Models\Lookup\LanguageRequirement::class);
169
    }
170
171
    public function manager() // phpcs:ignore
172
    {
173
        return $this->belongsTo(\App\Models\Manager::class);
174
    }
175
176
    public function province() // phpcs:ignore
177
    {
178
        return $this->belongsTo(\App\Models\Lookup\Province::class);
179
    }
180
181
    public function security_clearance() // phpcs:ignore
182
    {
183
        return $this->belongsTo(\App\Models\Lookup\SecurityClearance::class);
184
    }
185
186
    public function criteria() // phpcs:ignore
187
    {
188
        return $this->hasMany(\App\Models\Criteria::class);
189
    }
190
191
    public function job_applications() // phpcs:ignore
192
    {
193
        return $this->hasMany(\App\Models\JobApplication::class);
194
    }
195
196
    public function job_poster_key_tasks() // phpcs:ignore
197
    {
198
        return $this->hasMany(\App\Models\JobPosterKeyTask::class);
199
    }
200
201
    public function job_poster_questions() // phpcs:ignore
202
    {
203
        return $this->hasMany(\App\Models\JobPosterQuestion::class);
204
    }
205
206
    public function job_poster_translations() // phpcs:ignore
207
    {
208
        return $this->hasMany(\App\Models\JobPosterTranslation::class);
209
    }
210
211
    public function screening_plans() // phpcs:ignore
212
    {
213
        return $this->hasMany(\App\Models\ScreeningPlan::class);
214
    }
215
216
    // Artificial Relations
217
218
    /**
219
     * Get all of the Job Applications submitted to this
220
     * Job Poster.
221
     *
222
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
223
     */
224
    public function submitted_applications() // phpcs:ignore
225
    {
226
        return $this->hasMany(\App\Models\JobApplication::class)->whereDoesntHave('application_status', function ($query) : void {
227
            $query->where('name', 'draft');
228
        });
229
    }
230
231
    // Overrides
232
233
    /**
234
     * Retrieve the model for a bound value.
235
     * Seems to be a useful workaround for providing submitted_applications_count
236
     * to any bound routes that receive a jobPoster instance without using the
237
     * withCount property on the model itself.
238
     * See https://github.com/laravel/framework/issues/23957 for more info.
239
     *
240
     * @param mixed $value Value used to retrieve the model instance.
241
     *
242
     * @return \Illuminate\Database\Eloquent\Model|null
243
     */
244
    public function resolveRouteBinding($value) // phpcs:ignore
245
    {
246
        return $this->withCount('submitted_applications')->where('id', $value)->first() ?? abort(404);
1 ignored issue
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
247
    }
248
249
    // @codeCoverageIgnoreEnd
250
251
    // Accessors
252
253
    // Mutators
254
255
    /**
256
     * Intercept setting the "published" attribute, and set the
257
     * "published_at" timestamp if true.
258
     *
259
     * @param mixed $value Incoming value for the 'published' attribute.
260
     *
261
     * @return void
262
     */
263 22
    public function setPublishedAttribute($value) : void
264
    {
265 22
        if ($value && $this->open_date_time->isPast()) {
266 17
            $this->attributes['published_at'] = new Date();
267 19
        } elseif ($value && $this->open_date_time->isFuture()) {
268 1
            $this->attributes['published_at'] = $this->open_date_time;
269
        }
270 22
        $this->attributes['published'] = $value;
271 22
    }
272
273
    // Methods
274
275 4
    public function submitted_applications_count()
1 ignored issue
show
Coding Style introduced by
Method name "JobPoster::submitted_applications_count" is not in camel caps format
Loading history...
introduced by
Method \App\Models\JobPoster::submitted_applications_count() does not have return type hint nor @return annotation for its return value.
Loading history...
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
276
    {
277 4
        return $this->submitted_applications()->count();
278
    }
279
280
    /**
281
     * Formatted and localized date and time the Job Poster closes.
282
     *
283
     * @return string[]
284
     */
285 1
    public function applyBy() : array
286
    {
287 1
        $localCloseDate = new Date($this->close_date_time); // This initializes the date object in UTC time
288 1
        $localCloseDate->setTimezone(new \DateTimeZone(self::TIMEZONE)); // Then set the time zone for display
289
        $displayDate = [
290 1
            'date' => $localCloseDate->format(self::DATE_FORMAT[App::getLocale()]),
291 1
            'time' => $localCloseDate->format(self::TIME_FORMAT[App::getLocale()])
292
        ];
293
294 1
        if (App::isLocale('fr')) {
295
            $displayDate['time'] = str_replace(['EST', 'EDT'], ['HNE', 'HAE'], $displayDate['time']);
296
        }
297
298 1
        return $displayDate;
299
    }
300
301
    /**
302
     * Return whether the Job is Open or Closed.
303
     * Used by the Admin Portal JobPosterCrudController.
304
     *
305
     * @return string
306
     */
307
    public function displayStatus() : string
308
    {
309
        return $this->isOpen() ? 'Open' : 'Closed';
310
    }
311
312
    /**
313
     * Check if a Job Poster is open for applications.
314
     *
315
     * @return boolean
316
     */
317 6
    public function isOpen() : bool
318
    {
319 6
        return $this->published
320 6
            && $this->open_date_time->isPast()
321 6
            && $this->close_date_time->isFuture();
322
    }
323
324
    /**
325
     * Check if a Job Poster is closed for applications.
326
     *
327
     * @return boolean
328
     */
329 4
    public function isClosed() : bool
330
    {
331 4
        return $this->published
332 4
            && $this->open_date_time->isPast()
333 4
            && $this->close_date_time->isPast();
334
    }
335
336
    /**
337
     * Calculate the remaining time a Job Poster is open.
338
     *
339
     * @return string
340
     */
341 1
    public function timeRemaining() : string
342
    {
343 1
        $interval = $this->close_date_time->diff(Date::now());
344
345 1
        $d = $interval->d;
346 1
        $h = $interval->h;
347 1
        $m = $interval->i;
348 1
        $s = $interval->s;
349
350 1
        if ($d > 0) {
351 1
            $unit = 'day';
352 1
            $count = $d;
353 1
        } elseif ($h > 0) {
354 1
            $unit = 'hour';
355 1
            $count = $h;
356 1
        } elseif ($m > 0) {
357 1
            $unit = 'minute';
358 1
            $count = $m;
359
        } else {
360 1
            $unit = 'second';
361 1
            $count = $s;
362
        }
363
364 1
        $key = "common/time.$unit";
365
366 1
        return Lang::choice($key, $count);
367
    }
368
369
    /**
370
     * Return the current status for the Job Poster.
371
     * Possible values are "draft", "submitted", "published" and "closed".
372
     *
373
     * @return string
374
     */
375 3
    public function status() : string
376
    {
377 3
        $status = 'draft';
378 3
        if ($this->isOpen()) {
379 1
            $status = 'published';
380 3
        } elseif ($this->isClosed()) {
381 1
            $status = 'closed';
382 3
        } elseif ($this->review_requested_at !== null) {
383 3
            $status = 'submitted';
384
        } else {
385 1
            $status = 'draft';
386
        }
387
388 3
        return $status;
389
    }
390
}
391