ApplicationController   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 85
dl 0
loc 213
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A updateBasic() 0 7 1
A getBasic() 0 3 1
A setAvailability() 0 17 1
A touchStep() 0 8 1
A submit() 0 24 3
A index() 0 19 3
A show() 0 16 2
A updateReview() 0 40 4
1
<?php
2
3
namespace App\Http\Controllers\Api;
4
5
use App\Http\Controllers\Controller;
6
use App\Http\Requests\UpdateJobApplicationBasic;
7
use App\Http\Resources\JobApplication as JobApplicationResource;
8
use App\Http\Resources\JobApplicationBasic as JobApplicationBasicResource;
9
use App\Models\ApplicationReview;
10
use App\Models\JobApplication;
11
use App\Models\JobPoster;
12
use App\Models\Lookup\ApplicationStatus;
13
use App\Models\Lookup\Department;
14
use App\Models\Lookup\ReviewStatus;
15
use App\Models\Lookup\JobApplicationStep;
16
use App\Services\Validation\ApplicationTimelineValidator;
17
use Illuminate\Http\Request;
18
use Illuminate\Http\Resources\Json\JsonResource;
19
use Illuminate\Support\Facades\Log;
20
use Illuminate\Validation\Rule;
21
use Illuminate\Validation\ValidationException;
22
23
class ApplicationController extends Controller
24
{
25
    /**
26
     * Retrieve Application properties, not including relationships.
27
     *
28
     * @param JobApplication $application Incoming Job Application object.
29
     *
30
     * @return mixed
31
     */
32
    public function getBasic(JobApplication $application)
33
    {
34
        return new JobApplicationBasicResource($application);
35
    }
36
37
    /**
38
     * Update Application properties, not including relationships.
39
     *
40
     * @param UpdateJobApplicationBasic $request     Form Validation casted request object.
41
     * @param JobApplication            $application Incoming Job Application object.
42
     *
43
     * @return mixed
44
     */
45
    public function updateBasic(UpdateJobApplicationBasic $request, JobApplication $application)
46
    {
47
        $data = $request->validated();
48
        $application->fill($data);
49
        $application->save();
50
51
        return new JobApplicationBasicResource($application);
52
    }
53
54
    /**
55
     * Validate and submit the Application.
56
     *
57
     * @param Request        $request     Incoming request object.
58
     * @param JobApplication $application Incoming Job Application object.
59
     *
60
     * @return mixed
61
     */
62
    public function submit(Request $request, JobApplication $application)
63
    {
64
        if ($application->application_status->name == 'draft') {
65
            $validator = new ApplicationTimelineValidator();
66
            $data = $request->validate($validator->affirmationRules);
67
            $application->fill($data);
68
            $application->save();
69
70
            $applicationComplete = $validator->validateComplete($application);
71
            if (!$applicationComplete) {
72
                $userId = $application->applicant->user_id;
73
                $msg = "Application $application->id for user $userId is invalid for submission: " .
74
                    implode('; ', $validator->detailedValidatorErrors($application));
75
                Log::info($msg);
76
77
                throw ValidationException::withMessages($validator->detailedValidatorErrors($application));
78
            }
79
80
            $application->application_status_id = ApplicationStatus::where('name', 'submitted')->firstOrFail()->id;
81
            $application->save();
82
            $application->saveProfileSnapshotTimeline();
83
        }
84
85
        return new JobApplicationBasicResource($application);
86
    }
87
88
    /**
89
     * Return a single Job Application.
90
     *
91
     * @param JobApplication $application Incoming Job Application object.
92
     *
93
     * @return mixed
94
     */
95
    public function show(JobApplication $application)
96
    {
97
        // Initialize an empty Application Review if none exists. This
98
        // simplifies the front end logic when performing batch updates.
99
        if ($application->application_review === null) {
100
            $application->application_review = new ApplicationReview();
101
            $application->application_review->job_application_id = $application->id;
102
            $application->application_review->save();
103
        }
104
105
        return new JobApplicationResource($application->fresh([
106
            'applicant.user',
107
            'application_review',
108
            'citizenship_declaration',
109
            'veteran_status',
110
            'job_application_answers'
111
        ]));
112
    }
113
114
    /**
115
     * Return all Job Applications for a given Job Poster.
116
     *
117
     * @param JobPoster $jobPoster Incoming Job Poster object.
118
     *
119
     * @return mixed
120
     */
121
    public function index(JobPoster $jobPoster)
122
    {
123
        $applications = $jobPoster->submitted_applications()->get();
124
125
        // Initialize an empty Application Review if none exists. This
126
        // simplifies the front end logic when performing batch updates.
127
        foreach ($applications as $application) {
128
            if ($application->application_review === null) {
129
                $application->application_review = new ApplicationReview();
130
                $application->application_review->job_application_id = $application->id;
131
                $application->application_review->save();
132
            }
133
        }
134
135
        return JobApplicationResource::collection($applications->fresh([
136
            'applicant.user',
137
            'application_review.department',
138
            'citizenship_declaration',
139
            'veteran_status'
140
        ]));
141
    }
142
143
    /**
144
     * Update a single Job Application Review.
145
     *
146
     * @param Request        $request     Incoming request object.
147
     * @param JobApplication $application Incoming Job Application object.
148
     *
149
     * @return mixed
150
     */
151
    public function updateReview(Request $request, JobApplication $application)
152
    {
153
        $strategicResponseDepartmentId = config('app.strategic_response_department_id');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

153
        $strategicResponseDepartmentId = /** @scrutinizer ignore-call */ config('app.strategic_response_department_id');
Loading history...
154
        $availabilityStatuses = ReviewStatus::whereIn('name', ['allocated', 'not_available'])->get()->pluck('id');
155
156
        $request->validate([
157
            'review_status_id' => [
158
                'nullable',
159
                Rule::in(ReviewStatus::all()->pluck('id')->toArray())
160
            ],
161
            'department_id' => [
162
                'nullable',
163
                Rule::in(Department::all()->pluck('id')->toArray())
164
            ],
165
            'notes' => 'nullable|string'
166
        ]);
167
168
        $review = $application->application_review;
169
        if ($review === null) {
170
            $review = new ApplicationReview();
171
            $review->job_application()->associate($application);
172
        }
173
        $review->fill([
174
            'review_status_id' => $request->input('review_status_id'),
175
            'department_id' => $request->input('department_id'),
176
            'notes' => $request->input('notes'),
177
        ]);
178
        $review->save();
179
180
        if (
181
            $application->job_poster->department_id === $strategicResponseDepartmentId
182
            && in_array($review->review_status_id, $availabilityStatuses->toArray())
183
        ) {
184
            $this->setAvailability($application);
185
        }
186
187
        $review = $review->fresh();
188
        $review->loadMissing('department');
189
190
        return new JsonResource($review);
191
    }
192
193
    /**
194
     * Sets the review status for any other application reviews
195
     * belonging to a given Applicant to `not_available`.
196
     * Designed to be used for the Strategic Talent Response screening,
197
     * but could be repurposed.
198
     *
199
     * @param JobApplication $application Incoming Job Application object.
200
     *
201
     * @return void
202
     */
203
    protected function setAvailability(JobApplication $application)
204
    {
205
        $departmentId = $application->job_poster->department_id;
206
        $submittedStatusId = ApplicationStatus::where('name', 'submitted')->value('id');
207
        $unavailableStatusId = ReviewStatus::where('name', 'not_available')->value('id');
208
209
        // This is kinda gross, but it seems to filter out the correct subset, and allows a single database call
210
        // to perform the update. Seems better than returning a result set, looping, and pushing individual changes.
211
        ApplicationReview::whereHas('job_application.job_poster', function ($query) use ($departmentId) {
212
            $query->where('department_id', $departmentId);
213
        })->whereHas('job_application', function ($query) use ($application, $submittedStatusId) {
214
            $query->where([
215
                ['id', '<>', $application->id],
216
                ['application_status_id', $submittedStatusId],
217
                ['applicant_id', $application->applicant->id]
218
            ]);
219
        })->update(['review_status_id' => $unavailableStatusId]);
220
    }
221
222
    /**
223
     * Update the job application step
224
     *
225
     * @param Step $step Incoming Job Application Step
226
     * @return mixed
227
     */
228
    public function touchStep(Request $request, JobApplication $application, JobApplicationStep $jobApplicationStep)
229
    {
230
        $touchedApplicationStep = $application->touched_application_steps
231
            ->where('step_id', $jobApplicationStep->id)
232
            ->first();
233
        $touchedApplicationStep->update(['touched' => true]);
234
235
        return new JsonResource($application->jobApplicationSteps());
236
    }
237
}
238