Passed
Push — task/final-submit-fully-functi... ( c703a7...e11511 )
by Yonathan
06:38 queued 13s
created

ApplicationController::index()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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
            $application->fill([
67
                'submission_signature' => $request->input('submission_signature'),
68
                'submission_date' => $request->input('submission_date'),
69
            ]);
70
            $data = $validator->affirmationValidator($application)->validated();
71
            $application->fill($data);
72
            $application->save();
73
74
            $applicationComplete = $validator->validateComplete($application);
75
            if (!$applicationComplete) {
76
                $userId = $application->applicant->user_id;
77
                $msg = "Application $application->id for user $userId is invalid for submission: " .
78
                implode('; ', $validator->detailedValidatorErrors($application));
79
                Log::info($msg);
80
81
                throw ValidationException::withMessages($validator->detailedValidatorErrors($application));
82
            }
83
84
            $application->application_status_id = ApplicationStatus::where('name', 'submitted')->firstOrFail()->id;
85
            $application->saveProfileSnapshotTimeline();
86
            $application->save();
87
        }
88
89
        return new JobApplicationBasicResource($application);
90
    }
91
92
    /**
93
     * Return a single Job Application.
94
     *
95
     * @param JobApplication $application Incoming Job Application object.
96
     *
97
     * @return mixed
98
     */
99
    public function show(JobApplication $application)
100
    {
101
        $application->loadMissing(
102
            'applicant',
103
            'application_review',
104
            'citizenship_declaration',
105
            'veteran_status',
106
            'job_application_answers'
107
        );
108
        return new JobApplicationResource($application);
109
    }
110
111
    /**
112
     * Return all Job Applications for a given Job Poster.
113
     *
114
     * @param JobPoster $jobPoster Incoming Job Poster object.
115
     *
116
     * @return mixed
117
     */
118
    public function index(JobPoster $jobPoster)
119
    {
120
        $applications = $jobPoster->submitted_applications()
121
            ->with([
122
                'applicant.user',
123
                'application_review.department',
124
                'citizenship_declaration',
125
                'veteran_status'
126
            ])
127
            ->get();
128
129
        return JobApplicationResource::collection($applications);
130
    }
131
132
    /**
133
     * Update a single Job Application Review.
134
     *
135
     * @param Request        $request     Incoming request object.
136
     * @param JobApplication $application Incoming Job Application object.
137
     *
138
     * @return mixed
139
     */
140
    public function updateReview(Request $request, JobApplication $application)
141
    {
142
        $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

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