Passed
Push — feature/job-status-transitions ( 6e8a78...301d44 )
by Chris
03:12
created

JobPosterCrudController   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 276
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 2
Metric Value
wmc 17
eloc 190
c 5
b 0
f 2
dl 0
loc 276
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setup() 0 8 2
B setupUpdateOperation() 0 94 2
A update() 0 19 4
C setupListOperation() 0 130 9
1
<?php
2
3
namespace App\Http\Controllers\Admin;
4
5
use App\Models\Lookup\Department;
6
use App\Models\Lookup\JobPosterStatus;
7
use App\Services\JobStatusTransitionManager;
8
use Backpack\CRUD\app\Http\Controllers\CrudController;
9
use Illuminate\Support\Facades\App;
10
11
class JobPosterCrudController extends CrudController
12
{
13
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
14
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation {
15
        update as traitUpdate;
16
    }
17
18
    /**
19
     * Prepare the admin interface by setting the associated
20
     * model, setting the route, and adding custom columns/fields.
21
     *
22
     * @return void
23
     */
24
    public function setup(): void
25
    {
26
        $this->crud->setModel('App\Models\JobPoster');
27
        $this->crud->setRoute('admin/job-poster');
28
        $this->crud->setEntityNameStrings('Job Poster', 'Job Posters');
29
30
        if (!$this->request->has('order')) {
31
            $this->crud->orderBy('close_date_time', 'desc');
32
        }
33
    }
34
35
    public function setupListOperation()
36
    {
37
        // Required for order logic.
38
        $locale = 'en';
39
        if (null !== $this->request->input('locale')) {
40
            $locale = $this->request->input('locale');
41
        }
42
        App::setLocale($locale);
43
44
        // Add the custom blade buttons found in resources/views/vendor/backpack/crud/buttons/.
45
        $this->crud->addButtonFromView('line', 'job_admin_edit', 'job_admin_edit', 'end');
46
        $this->crud->addButtonFromView('line', 'spb_link', 'spb_link', 'end');
47
        $this->crud->addButtonFromView('line', 'jpb_link', 'jpb_link', 'end');
48
        $this->crud->addButtonFromView('line', 'job_poster_link', 'job_poster_link', 'end');
49
        $this->crud->addButtonFromView('line', 'applicants_download', 'applicants_download', 'end');
50
51
        $this->crud->addColumn([
52
            'name' => 'id',
53
            'type' => 'number',
54
            'label' => 'ID'
55
        ]);
56
        $this->crud->addColumn([
57
            'name' => 'title',
58
            'type' => 'text',
59
            'label' => 'Title',
60
            'searchLogic' => function ($query, $column, $searchTerm) use ($locale): void {
61
                $query->orWhere('title->' . $locale, 'ilike', "%$searchTerm%");
62
            },
63
            'orderLogic' => function ($query, $column, $columnDirection) use ($locale) {
64
                return $query->orderBy('title->' . $locale, $columnDirection)->select('*');
65
            }
66
        ]);
67
        $this->crud->addColumn([
68
            'name' => 'job_poster_status.key',
69
            'label' => 'Status',
70
            'type' => 'text',
71
            'orderable' => true,
72
            'orderLogic' => function ($query, $column, $columnDirection) {
73
                return $query->leftJoin('job_poster_status', 'job_poster_status.id', '=', 'job_posters.job_poster_status_id')
74
                    ->orderBy('job_poster_status.key', $columnDirection)->select('job_posters.*');
75
            }
76
        ]);
77
        $this->crud->addColumn([
78
            'name' => 'isOpen',
79
            'label' => 'Open',
80
            'type' => 'closure',
81
            'orderable' => false,
82
            'function' => function ($entry) {
83
                return $entry->isOpen() ?
84
                    '<span><i class="fa fa-check-circle"></i></span>' :
85
                    '<span><i class="fa fa-circle"></i></span>';
86
            }
87
        ]);
88
        $this->crud->addColumn([
89
            'name' => 'isClosed',
90
            'label' => 'Closed',
91
            'type' => 'closure',
92
            'orderable' => false,
93
            'function' => function ($entry) {
94
                return $entry->isClosed() ?
95
                    '<span><i class="fa fa-check-circle"></i></span>' :
96
                    '<span><i class="fa fa-circle"></i></span>';
97
            }
98
        ]);
99
100
        $this->crud->addColumn([
101
            'name' => 'internal_only',
102
            'label' => 'Internal Only',
103
            'type' => 'check',
104
        ]);
105
106
        $this->crud->addColumn([
107
            'name' => 'manager_user_name',
108
            'type' => 'closure',
109
            'label' => 'Manager',
110
            'orderable' => false,
111
            'function' => function ($entry) {
112
                return '<a href="' . route('manager.profile.edit', $entry->manager->id) . '" target="_blank">' . $entry->manager->user->full_name . '</a>';
0 ignored issues
show
Bug introduced by
The function route 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

112
                return '<a href="' . /** @scrutinizer ignore-call */ route('manager.profile.edit', $entry->manager->id) . '" target="_blank">' . $entry->manager->user->full_name . '</a>';
Loading history...
113
            }
114
        ]);
115
        $this->crud->addColumn([
116
            'name' => 'department.name',
117
            'label' => 'Department',
118
            'type' => 'text'
119
        ]);
120
        $this->crud->addColumn([
121
            'name' => 'submitted_applications_count',
122
            'label' => 'Applications',
123
            'type' => 'closure',
124
            'function' =>
125
            function ($entry) {
126
                return $entry->submitted_applications_count() > 0 ?
127
                    '<a target="_blank" href="' . route('manager.jobs.applications', $entry->id) . '">' . $entry->submitted_applications_count() . ' (View <i class="fa fa-external-link"></i>)</a>' :
0 ignored issues
show
Bug introduced by
The function route 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

127
                    '<a target="_blank" href="' . /** @scrutinizer ignore-call */ route('manager.jobs.applications', $entry->id) . '">' . $entry->submitted_applications_count() . ' (View <i class="fa fa-external-link"></i>)</a>' :
Loading history...
128
                    $entry->submitted_applications_count();
129
            }
130
        ]);
131
132
        // Filters.
133
        $this->crud->addFilter([
134
            'name' => 'departments',
135
            'type' => 'select2_multiple',
136
            'label' => 'Filter by department'
137
        ], function () {
138
            return Department::all()->pluck('name', 'id')->toArray();
139
        }, function ($values) {
140
            $this->crud->addClause('WhereHas', 'department', function ($query) use ($values) {
141
                foreach (json_decode($values) as $key => $value) {
142
                    if ($key === 0) {
143
                        $query->where('id', $value);
144
                    } else {
145
                        $query->orWhere('id', $value);
146
                    }
147
                }
148
            });
149
        });
150
151
        $this->crud->addFilter([
152
            'name' => 'statuses',
153
            'type' => 'select2_multiple',
154
            'label' => 'Filter by status'
155
        ], function () {
156
            // Using key because some of the job status names are the same.
157
            return JobPosterStatus::all()->pluck('key', 'id')->toArray();
158
        }, function ($values) {
159
            $this->crud->addClause('WhereHas', 'job_poster_status', function ($query) use ($values) {
160
                foreach (json_decode($values) as $key => $value) {
161
                    if ($key === 0) {
162
                        $query->where('id', $value);
163
                    } else {
164
                        $query->orWhere('id', $value);
165
                    }
166
                }
167
            });
168
        });
169
    }
170
171
    public function setupUpdateOperation()
172
    {
173
        $this->crud->addField([
174
            'name' => 'title',
175
            'label' => 'Title',
176
            'type' => 'text',
177
            'attributes' => [
178
                'readonly' => 'readonly'
179
            ]
180
        ]);
181
        $this->crud->addField([
182
            'name' => 'salary_min',
183
            'type' => 'number',
184
            'label' => 'Minimum Salary',
185
        ]);
186
        $this->crud->addField([
187
            'name' => 'salary_max',
188
            'type' => 'number',
189
            'label' => 'Maximum Salary',
190
        ]);
191
        $this->crud->addField([
192
            'name' => 'noc',
193
            'type' => 'number',
194
            'label' => 'NOC Code',
195
        ]);
196
        $this->crud->addField([
197
            'name' => 'open_date_time',
198
            'label' => 'Open Date',
199
            'type' => 'date_picker',
200
            'date_picker_options' => [
201
                'todayBtn' => 'linked',
202
                'format' => 'yyyy-mm-dd',
203
            ],
204
        ]);
205
        $this->crud->addField([
206
            'name' => 'close_date_time',
207
            'label' => 'Close Date',
208
            'type' => 'date_picker',
209
            'date_picker_options' => [
210
                'todayBtn' => 'linked',
211
                'format' => 'yyyy-mm-dd',
212
            ],
213
        ]);
214
        $this->crud->addField([
215
            'name' => 'start_date_time',
216
            'label' => 'Start Date',
217
            'type' => 'date_picker',
218
            'date_picker_options' => [
219
                'todayBtn' => 'linked',
220
                'format' => 'yyyy-mm-dd',
221
            ],
222
        ]);
223
        $this->crud->addField([
224
            'name' => 'process_number',
225
            'type' => 'number',
226
            'label' => 'Process #',
227
        ]);
228
        $this->crud->addField([
229
            'name' => 'priority_clearance_number',
230
            'type' => 'number',
231
            'label' => 'Priority Clearance #',
232
        ]);
233
        $this->crud->addField([
234
            'name' => 'loo_issuance_date',
235
            'type' => 'date_picker',
236
            'label' => 'Letter of Offer Issuance Date',
237
            'date_picker_options' => [
238
                'todayBtn' => 'linked',
239
                'format' => 'yyyy-mm-dd',
240
            ],
241
        ]);
242
243
        $this->crud->addField([
244
            'name' => 'internal_only',
245
            'type' => 'checkbox',
246
            'label' => 'Internal Only (Do not list this poster on the Browse Jobs page. You must access it with the direct URL.)',
247
        ]);
248
249
        $transitionManager = new JobStatusTransitionManager();
250
        $job = $this->crud->getCurrentEntry();
251
        $legalDestinations = $transitionManager->legalDestinations($job->job_poster_status->key);
252
        $validStatuses = JobPosterStatus::all()->filter(function ($status) use ($job, $legalDestinations) {
253
            return in_array($status->key, $legalDestinations) || $status->id === $job->job_poster_status_id;
254
        });
255
        $statusOptions = $validStatuses->mapWithKeys(function ($status) {
256
            return [$status->id => $status->key];
257
        });
258
        $this->crud->addField([
259
            'name' => 'job_poster_status_id',
260
            'label' => 'Status',
261
            'type' => 'select_from_array',
262
            'options' => $statusOptions,
263
            'allows_null' => false,
264
            'default' => $job->job_poster_status_id,
265
        ]);
266
    }
267
268
    public function update()
269
    {
270
        $open_date = $this->crud->request->request->get('open_date_time');
271
        $close_date = $this->crud->request->request->get('close_date_time');
272
        $start_date = $this->crud->request->request->get('start_date_time');
273
        $this->crud->request->request->remove('open_date_time');
274
        $this->crud->request->request->remove('close_date_time');
275
        $this->crud->request->request->remove('start_date_time');
276
        // Manipulates the input fields to save the "end of day" timestamp for
277
        // open/close/start dates.
278
        $this->crud->request->request->add([
279
            'open_date_time' => $open_date !== null ? ptDayStartToUtcTime($open_date) : null,
280
            'close_date_time' => $close_date !== null ? ptDayEndToUtcTime($close_date) : null,
281
            'start_date_time' => $start_date !== null ? ptDayStartToUtcTime($start_date) : null,
282
        ]);
283
284
        $response = $this->traitUpdate();
285
286
        return $response;
287
    }
288
}
289