Passed
Push — dev ( 8bffdc...90a779 )
by Tristan
06:26 queued 11s
created

ApplicationController::submit()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
dl 0
loc 24
rs 9.7333
c 1
b 0
f 0
cc 3
nc 3
nop 2
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
        $application->loadMissing(
98
            'applicant',
99
            'application_review',
100
            'citizenship_declaration',
101
            'veteran_status',
102
            'job_application_answers'
103
        );
104
        return new JobApplicationResource($application);
105
    }
106
107
    /**
108
     * Return all Job Applications for a given Job Poster.
109
     *
110
     * @param JobPoster $jobPoster Incoming Job Poster object.
111
     *
112
     * @return mixed
113
     */
114
    public function index(JobPoster $jobPoster)
115
    {
116
        $applications = $jobPoster->submitted_applications()
117
            ->with([
118
                'applicant.user',
119
                'application_review.department',
120
                'citizenship_declaration',
121
                'veteran_status'
122
            ])
123
            ->get();
124
125
        return JobApplicationResource::collection($applications);
126
    }
127
128
    /**
129
     * Update a single Job Application Review.
130
     *
131
     * @param Request        $request     Incoming request object.
132
     * @param JobApplication $application Incoming Job Application object.
133
     *
134
     * @return mixed
135
     */
136
    public function updateReview(Request $request, JobApplication $application)
137
    {
138
        $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

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