Passed
Push — feature/job-builder/step-0 ( d77267 )
by Yonathan
10:26
created

JobPoster::job_poster_translations()   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
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 1
nc 1
nop 0
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 string $classification_code
36
 * @property int $classification_level
37
 * @property int $security_clearance_id
38
 * @property int $language_requirement_id
39
 * @property boolean $remote_work_allowed
40
 * @property int $manager_id
41
 * @property boolean $published
42
 * @property \Jenssegers\Date\Date $created_at
43
 * @property \Jenssegers\Date\Date $updated_at
44
 *
45
 * @property int $submitted_applications_count
46
 *
47
 * @property \App\Models\Lookup\Department $department
48
 * @property \App\Models\Lookup\JobTerm $job_term
49
 * @property \App\Models\Lookup\LanguageRequirement $language_requirement
50
 * @property \App\Models\Manager $manager
51
 * @property \App\Models\Lookup\Province $province
52
 * @property \App\Models\Lookup\SecurityClearance $security_clearance
53
 * @property \Illuminate\Database\Eloquent\Collection $criteria
54
 * @property \Illuminate\Database\Eloquent\Collection $job_applications
55
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_key_tasks
56
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_questions
57
 * @property \Illuminate\Database\Eloquent\Collection $job_poster_translations
58
 * @property \Illuminate\Database\Eloquent\Collection $submitted_applications
59
 *
60
 * Localized Properties:
61
 * @property string $city
62
 * @property string $title
63
 * @property string $impact
64
 * @property string $team_impact
65
 * @property string $hire_impact
66
 * @property string $branch
67
 * @property string $division
68
 * @property string $education
69
 *
70
 * Methods
71
 * @method boolean isOpen()
72
 * @method string timeRemaining()
73
 * @method string toApiArray()
74
 */
75
class JobPoster extends BaseModel
76
{
77
    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...
78
    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...
79
    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...
80
81
    const DATE_FORMAT = [
82
        'en' => 'M jS, Y',
83
        'fr' => 'd M Y',
84
    ];
85
    const TIME_FORMAT = [
86
        'en' => 'h:i A T',
87
        'fr' => 'H \h i T',
88
    ];
89
    const TIMEZONE = 'America/Toronto';
90
91
    /**
92
     * @var string[] $translatedAttributes
93
     */
94
    public $translatedAttributes = [
95
        'city',
96
        'title',
97
        'impact',
98
        'team_impact',
99
        'hire_impact',
100
        'branch',
101
        'division',
102
        'education'
103
    ];
104
105
    /**
106
     * @var string[] $casts
107
     */
108
    protected $casts = [
109
        'job_term_id' => 'int',
110
        'department_id' => 'int',
111
        'province_id' => 'int',
112
        'salary_min' => 'int',
113
        'salary_max' => 'int',
114
        'noc' => 'int',
115
        'classification_code' => 'string',
116
        'classification_level' => 'int',
117
        'security_clearance_id' => 'int',
118
        'language_requirement_id' => 'int',
119
        'remote_work_allowed' => 'boolean',
120
        'manager_id' => 'int',
121
        'published' => 'boolean'
122
    ];
123
124
    /**
125
     * @var string[] $dates
126
     */
127
    protected $dates = [
128
        'open_date_time',
129
        'close_date_time',
130
        'start_date_time',
131
        'review_requested_at',
132
        'published_at'
133
    ];
134
135
    /**
136
     * @var string[] $fillable
137
     */
138
    protected $fillable = [
139
        'job_term_id',
140
        'term_qty',
141
        'open_date_time',
142
        'close_date_time',
143
        'start_date_time',
144
        'department_id',
145
        'province_id',
146
        'salary_min',
147
        'salary_max',
148
        'noc',
149
        'classification',
150
        'classification_code',
151
        'classification_level',
152
        'security_clearance_id',
153
        'language_requirement_id',
154
        'remote_work_allowed',
155
        'published'
156
    ];
157
158
    /**
159
     * @var mixed[] $dispatchesEvents
160
     */
161
    protected $dispatchesEvents = [
162
        'saved' => JobSaved::class,
163
    ];
164
165
    // @codeCoverageIgnoreStart
166
167
    public function department() // phpcs:ignore
168
    {
169
        return $this->belongsTo(\App\Models\Lookup\Department::class);
170
    }
171
172
    public function job_term() // phpcs:ignore
173
    {
174
        return $this->belongsTo(\App\Models\Lookup\JobTerm::class);
175
    }
176
177
    public function language_requirement() // phpcs:ignore
178
    {
179
        return $this->belongsTo(\App\Models\Lookup\LanguageRequirement::class);
180
    }
181
182
    public function manager() // phpcs:ignore
183
    {
184
        return $this->belongsTo(\App\Models\Manager::class);
185
    }
186
187
    public function province() // phpcs:ignore
188
    {
189
        return $this->belongsTo(\App\Models\Lookup\Province::class);
190
    }
191
192
    public function security_clearance() // phpcs:ignore
193
    {
194
        return $this->belongsTo(\App\Models\Lookup\SecurityClearance::class);
195
    }
196
197
    public function criteria() // phpcs:ignore
198
    {
199
        return $this->hasMany(\App\Models\Criteria::class);
200
    }
201
202
    public function job_applications() // phpcs:ignore
203
    {
204
        return $this->hasMany(\App\Models\JobApplication::class);
205
    }
206
207
    public function job_poster_key_tasks() // phpcs:ignore
208
    {
209
        return $this->hasMany(\App\Models\JobPosterKeyTask::class);
210
    }
211
212
    public function job_poster_questions() // phpcs:ignore
213
    {
214
        return $this->hasMany(\App\Models\JobPosterQuestion::class);
215
    }
216
217
    public function job_poster_translations() // phpcs:ignore
218
    {
219
        return $this->hasMany(\App\Models\JobPosterTranslation::class);
220
    }
221
222
    // Artificial Relations
223
224
    /**
225
     * Get all of the Job Applications submitted to this
226
     * Job Poster.
227
     *
228
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
229
     */
230
    public function submitted_applications() // phpcs:ignore
231
    {
232
        return $this->hasMany(\App\Models\JobApplication::class)->whereDoesntHave('application_status', function ($query) : void {
233
            $query->where('name', 'draft');
234
        });
235
    }
236
237
    // Overrides
238
239
    /**
240
     * Retrieve the model for a bound value.
241
     * Seems to be a useful workaround for providing submitted_applications_count
242
     * to any bound routes that receive a jobPoster instance without using the
243
     * withCount property on the model itself.
244
     * See https://github.com/laravel/framework/issues/23957 for more info.
245
     *
246
     * @param mixed $value Value used to retrieve the model instance.
247
     *
248
     * @return \Illuminate\Database\Eloquent\Model|null
249
     */
250
    public function resolveRouteBinding($value) // phpcs:ignore
251
    {
252
        return $this->withCount('submitted_applications')->where('id', $value)->first() ?? abort(404);
253
    }
254
255
    // @codeCoverageIgnoreEnd
256
257
    // Accessors
258
259
    // Mutators
260
261
    /**
262
     * Intercept setting the "published" attribute, and set the
263
     * "published_at" timestamp if true.
264
     *
265
     * @param mixed $value Incoming value for the 'published' attribute.
266
     *
267
     * @return void
268
     */
269 36
    public function setPublishedAttribute($value) : void
270
    {
271 36
        if ($value && $this->open_date_time->isPast()) {
272 23
            $this->attributes['published_at'] = new Date();
273 32
        } elseif ($value && $this->open_date_time->isFuture()) {
274 1
            $this->attributes['published_at'] = $this->open_date_time;
275
        }
276 36
        $this->attributes['published'] = $value;
277 36
    }
278
279
    // Methods
280
281 6
    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...
282
    {
283 6
        return $this->submitted_applications()->count();
284
    }
285
286
    /**
287
     * Formatted and localized date and time the Job Poster closes.
288
     *
289
     * @return string[]
290
     */
291 1
    public function applyBy() : array
292
    {
293 1
        $localCloseDate = new Date($this->close_date_time); // This initializes the date object in UTC time
294 1
        $localCloseDate->setTimezone(new \DateTimeZone(self::TIMEZONE)); // Then set the time zone for display
295
        $displayDate = [
296 1
            'date' => $localCloseDate->format(self::DATE_FORMAT[App::getLocale()]),
297 1
            'time' => $localCloseDate->format(self::TIME_FORMAT[App::getLocale()])
298
        ];
299
300 1
        if (App::isLocale('fr')) {
301
            $displayDate['time'] = str_replace(['EST', 'EDT'], ['HNE', 'HAE'], $displayDate['time']);
302
        }
303
304 1
        return $displayDate;
305
    }
306
307
    /**
308
     * Return whether the Job is Open or Closed.
309
     * Used by the Admin Portal JobPosterCrudController.
310
     *
311
     * @return string
312
     */
313
    public function displayStatus() : string
314
    {
315
        return $this->isOpen() ? 'Open' : 'Closed';
316
    }
317
318
    /**
319
     * Check if a Job Poster is open for applications.
320
     *
321
     * @return boolean
322
     */
323 6
    public function isOpen() : bool
324
    {
325 6
        return $this->published
326 6
            && $this->open_date_time->isPast()
327 6
            && $this->close_date_time->isFuture();
328
    }
329
330
    /**
331
     * Check if a Job Poster is closed for applications.
332
     *
333
     * @return boolean
334
     */
335 4
    public function isClosed() : bool
336
    {
337 4
        return $this->published
338 4
            && $this->open_date_time->isPast()
339 4
            && $this->close_date_time->isPast();
340
    }
341
342
    /**
343
     * Calculate the remaining time a Job Poster is open.
344
     *
345
     * @return string
346
     */
347 1
    public function timeRemaining() : string
348
    {
349 1
        $interval = $this->close_date_time->diff(Date::now());
350
351 1
        $d = $interval->d;
352 1
        $h = $interval->h;
353 1
        $m = $interval->i;
354 1
        $s = $interval->s;
355
356 1
        if ($d > 0) {
357 1
            $unit = 'day';
358 1
            $count = $d;
359 1
        } elseif ($h > 0) {
360 1
            $unit = 'hour';
361 1
            $count = $h;
362 1
        } elseif ($m > 0) {
363 1
            $unit = 'minute';
364 1
            $count = $m;
365
        } else {
366
            $unit = 'second';
367
            $count = $s;
368
        }
369
370 1
        $key = "common/time.$unit";
371
372 1
        return Lang::choice($key, $count);
373
    }
374
375
    /**
376
     * Return the current status for the Job Poster.
377
     * Possible values are "draft", "submitted", "published" and "closed".
378
     *
379
     * @return string
380
     */
381 3
    public function status() : string
382
    {
383 3
        $status = 'draft';
384 3
        if ($this->isOpen()) {
385 1
            $status = 'published';
386 3
        } elseif ($this->isClosed()) {
387 1
            $status = 'closed';
388 3
        } elseif ($this->review_requested_at !== null) {
389 3
            $status = 'submitted';
390
        } else {
391 1
            $status = 'draft';
392
        }
393
394 3
        return $status;
395
    }
396
397
    /**
398
     * Return the array of values used to represent this object in an api response.
399
     * This array should contain no nested objects (besides translations).
400
     *
401
     * @return mixed[]
402
     */
403 3
    public function toApiArray()
0 ignored issues
show
introduced by
Method \App\Models\JobPoster::toApiArray() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[]".
Loading history...
404
    {
405 3
        $jobWithTranslations = array_merge($this->toArray(), $this->getTranslationsArray());
406 3
        $jobCollection = collect($jobWithTranslations)->only([
407 3
            'id',
408
            'manager_id',
409
            'term_qty',
410
            'open_date_time',
411
            'close_date_time',
412
            'start_date_time',
413
            'department_id',
414
            'province_id',
415
            'salary_min',
416
            'salary_max',
417
            'noc',
418
            'classification_code',
419
            'classification_level',
420
            'security_clearance_id',
421
            'language_requirement_id',
422
            'remote_work_allowed',
423
            'published_at',
424
            'review_requested_at',
425
            'en',
426
            'fr',
427 3
        ])->all();
428 3
        return $jobCollection;
429
    }
430
}
431