77use App \Mail \ApplicationFileUploaded ;
88use App \Mail \ApplicationNoteChanged ;
99use App \Models \Application ;
10+ use App \Models \ApplicationWorkshop ;
1011use App \Models \Semester ;
12+ use App \Models \SemesterStatus ;
1113use App \Models \User ;
1214use App \Models \RoleUser ;
1315use App \Models \File ;
1719use App \Utils \HasPeriodicEvent ;
1820use Carbon \Carbon ;
1921use Illuminate \Auth \Access \AuthorizationException ;
22+ use Illuminate \Database \Eloquent \Builder ;
2023use Illuminate \Database \Eloquent \Collection ;
2124use Illuminate \Http \RedirectResponse ;
2225use Illuminate \Http \Request ;
@@ -178,54 +181,78 @@ public function update(Request $request, Application $application): RedirectResp
178181 return redirect ()->back ();
179182 }
180183
184+ /**
185+ * Show the finalize page with final names and statistics
186+ */
187+ public function indexFinalize (): View
188+ {
189+ $ this ->authorize ('finalize ' , Application::class);
190+ if (!($ this ->getDeadline () < now ())) {
191+ throw new \InvalidArgumentException ('The application deadline has not passed yet. ' );
192+ }
193+ [$ admitted , $ not_admitted , $ users_to_delete ] = $ this ->getApplications ();
194+ return view ('auth.admission.finalize ' , [
195+ 'semester ' => $ this ->semester (),
196+ 'admitted_applications ' => $ admitted ,
197+ 'users_to_delete ' => $ users_to_delete
198+ ->with ('application ' )
199+ ->orderBy ('name ' )
200+ ->get ()
201+ ]);
202+ }
203+
204+
181205 /**
182206 * Accept and delete applciations.
183207 * @return RedirectResponse
184208 * @throws AuthorizationException
185209 */
186210 public function finalize (): RedirectResponse
187211 {
188- // $this->authorize('finalizeApplicationProcess', User::class);
189- // Cache::forget('collegists');
190- // $not_handled_applicants = User::query()->withoutGlobalScope('verified')
191- // ->where('verified', 0)
192- // ->whereHas('application', function ($query) {
193- // $query->where('submitted', true);
194- // })
195- // ->count();
196- // if ($not_handled_applicants > 0) {
197- // return redirect()->back()->with('error', 'Még vannak feldolgozatlan jelentkezések!');
198- // }
199- // DB::transaction(function () {
200- // User::query()->withoutGlobalScope('verified')
201- // ->where('verified', 0)
202- // ->whereHas('application', function ($query) {
203- // $query->where('status', Application::STATUS_ACCEPTED);
204- // })
205- // ->update(['verified' => true]);
206- // $usersToDelete = User::query()->withoutGlobalScope('verified')
207- // ->where('verified', 0)->whereHas('application');
208- // foreach ($usersToDelete->get() as $user) {
209- // if ($user->profilePicture!=null) {
210- // Storage::delete($user->profilePicture->path);
211- // $user->profilePicture()->delete();
212- // }
213- // }
214- // $files = File::where('application_id', '!=', null);
215- // foreach ($files->get() as $file) {
216- // Storage::delete($file->path);
217- // }
218- // $files->delete();
219- // Application::query()->delete();
220- // $usersToDelete->forceDelete();
221- //
222- // RoleUser::where('role_id', Role::get(Role::APPLICATION_COMMITTEE_MEMBER)->id)->delete();
223- // RoleUser::where('role_id', Role::get(Role::AGGREGATED_APPLICATION_COMMITTEE_MEMBER)->id)->delete();
224- // });
225- //
226- // Cache::clear();
227- // return back()->with('message', 'Sikeresen jóváhagyta az elfogadott jelentkezőket');
228- return back ()->with ('error ' , 'Még nincs implementálva. ' );
212+ $ this ->authorize ('finalize ' , Application::class);
213+ if (!($ this ->getDeadline () < now ())) {
214+ throw new \InvalidArgumentException ('The application deadline has not passed yet. ' );
215+ }
216+ if (!$ this ->semester ()) {
217+ throw new \InvalidArgumentException ('No semester can be retrieved from the application periodic event. ' );
218+ }
219+ DB ::transaction (function () {
220+ [$ admitted , $ not_admitted , $ users_to_delete ] = $ this ->getApplications ();
221+ // admit users
222+ foreach ($ admitted as $ application ) {
223+ $ application ->user ->update (['verified ' => true ]);
224+ if ($ application ->admitted_for_resident_status ) {
225+ $ application ->user ->setResident ();
226+ } else {
227+ $ application ->user ->setExtern ();
228+ }
229+ $ application ->user ->workshops ()->sync ($ application ->admittedWorkshops );
230+ $ application ->user ->setStatusFor ($ this ->semester (), SemesterStatus::ACTIVE );
231+ $ application ->user ->internetAccess ->extendInternetAccess ($ this ->semester ()->getStartDate ()->addMonth ());
232+ }
233+ // delete data for not admitted users
234+ $ files = File::query ()
235+ ->whereIn ('application_id ' , $ not_admitted ->pluck ('id ' )) // application files
236+ ->orWhereIn ('user_id ' , $ not_admitted ->pluck ('user_id ' )); // profile pictures
237+ foreach ($ files ->get () as $ file ) {
238+ Storage::delete ($ file ->path );
239+ }
240+ $ files ->delete ();
241+ // soft deletes application, keep them for future reference
242+ // (see https://github.com/EotvosCollegium/mars/issues/332#issuecomment-2014058021)
243+ Application::whereIn ('id ' , $ admitted ->pluck ('id ' ))->delete ();
244+ Application::whereNotIn ('id ' , $ admitted ->pluck ('id ' ))->forceDelete ();
245+ ApplicationWorkshop::query ()->delete ();
246+
247+ // Note: users with not submitted applications will also be deleted
248+ $ users_to_delete ->forceDelete ();
249+
250+ RoleUser::where ('role_id ' , Role::get (Role::APPLICATION_COMMITTEE_MEMBER )->id )->delete ();
251+ RoleUser::where ('role_id ' , Role::get (Role::AGGREGATED_APPLICATION_COMMITTEE_MEMBER )->id )->delete ();
252+ });
253+
254+ Cache::clear ();
255+ return back ()->with ('message ' , __ ('general.successful_modification ' ));
229256 }
230257
231258
@@ -252,4 +279,21 @@ public function getAccessibleWorkshops(User $user): Collection
252279 }
253280 return Workshop::all ();
254281 }
282+
283+ /**
284+ * Helper function to get admittted, not admitted applications and users to delete.
285+ * @return array
286+ */
287+ private function getApplications ()
288+ {
289+ $ admitted = Application::query ()->with (['user ' , 'applicationWorkshops ' ])->admitted ()->get ()->sortBy ('user.name ' );
290+ $ not_admitted = Application::query ()->whereNotIn ('id ' , $ admitted ->pluck ('id ' ))->get ();
291+ $ users_to_delete_query = User::query ()
292+ ->withoutGlobalScope ('verified ' )
293+ ->whereIn ('id ' , $ not_admitted ->pluck ('user_id ' ))
294+ //ignore users with any existing role
295+ ->whereDoesntHave ('roles ' );
296+
297+ return [$ admitted , $ not_admitted , $ users_to_delete_query ];
298+ }
255299}
0 commit comments