Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
admin_panel
/
app
/
Http
/
Controllers
:
StudentController.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace App\Http\Controllers; use App\Exports\StudentDataExport; use App\Imports\StudentsImport; use App\Models\ClassTeacher; use App\Models\School; use App\Models\SubjectTeacher; use App\Models\User; use App\Repositories\ClassSchool\ClassSchoolInterface; use App\Repositories\ClassSection\ClassSectionInterface; use App\Repositories\FormField\FormFieldsInterface; use App\Repositories\SchoolSetting\SchoolSettingInterface; use App\Repositories\SessionYear\SessionYearInterface; use App\Repositories\Student\StudentInterface; use App\Repositories\Subscription\SubscriptionInterface; use App\Repositories\User\UserInterface; use App\Services\BootstrapTableService; use App\Services\CachingService; use App\Services\FeaturesService; use App\Services\ResponseService; use App\Services\SubscriptionService; use App\Services\UserService; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; use Maatwebsite\Excel\Facades\Excel; use PDF; use Throwable; use TypeError; class StudentController extends Controller { private StudentInterface $student; private UserInterface $user; private ClassSectionInterface $classSection; private FormFieldsInterface $formFields; private SessionYearInterface $sessionYear; private CachingService $cache; private SubscriptionInterface $subscription; private SchoolSettingInterface $schoolSettings; private SubscriptionService $subscriptionService; private ClassSchoolInterface $classSchool; public function __construct(StudentInterface $student, UserInterface $user, ClassSectionInterface $classSection, FormFieldsInterface $formFields, SessionYearInterface $sessionYear, CachingService $cachingService, SubscriptionInterface $subscription, SchoolSettingInterface $schoolSettings, SubscriptionService $subscriptionService, ClassSchoolInterface $classSchool) { $this->student = $student; $this->user = $user; $this->classSection = $classSection; $this->formFields = $formFields; $this->sessionYear = $sessionYear; $this->cache = $cachingService; $this->subscription = $subscription; $this->schoolSettings = $schoolSettings; $this->subscriptionService = $subscriptionService; $this->classSchool = $classSchool; } public function index() { ResponseService::noPermissionThenRedirect('student-list'); $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'section', 'medium', 'class.shift']); $schoolSettings = $this->cache->getSchoolSettings(); if (Auth::user()->school_id) { $extraFields = $this->formFields->defaultModel()->where('user_type', 1)->orderBy('rank')->get(); } else { $extraFields = $this->formFields->defaultModel()->orderBy('rank')->get(); } $sessionYears = $this->sessionYear->all(); $features = FeaturesService::getFeatures(); return view('students.details', compact('class_sections', 'extraFields', 'sessionYears', 'features', 'schoolSettings')); } public function create() { ResponseService::noPermissionThenRedirect('student-create'); $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'section', 'medium', 'class.shift']); $sessionYear = $this->cache->getDefaultSessionYear(); $get_student = $this->student->builder()->latest('id')->withTrashed()->pluck('id')->first(); $admission_no = null; do { $uuid = mt_rand(500, 999999999); $admission_no = $sessionYear->name . '' . Auth::user()->school_id . '' . $uuid; } while ($this->student->builder()->where('admission_no', $admission_no)->exists()); if (Auth::user()->school_id) { $extraFields = $this->formFields->defaultModel()->where('user_type', 1)->orderBy('rank')->get(); } else { $extraFields = $this->formFields->defaultModel()->orderBy('rank')->get(); } $sessionYears = $this->sessionYear->all(); $features = FeaturesService::getFeatures(); return view('students.create', compact('class_sections', 'admission_no', 'extraFields', 'sessionYears', 'features')); } public function store(Request $request) { ResponseService::noPermissionThenRedirect(['student-create']); $request->validate([ 'first_name' => 'required', 'last_name' => 'required', 'mobile' => 'nullable|regex:/^([0-9\s\-\+\(\)]*)$/|digits_between:6,15', 'image' => 'nullable|mimes:jpeg,png,jpg,svg|image|max:2048', 'dob' => 'required', 'class_section_id' => 'required|numeric', /*NOTE : Unique constraint is used because it's not school specific*/ 'admission_no' => 'required|unique:users,email', 'admission_date' => 'required', 'session_year' => 'required|numeric', 'guardian_email' => 'required|email|max:255|regex:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', 'guardian_first_name' => 'required|string', 'guardian_last_name' => 'required|string', 'guardian_mobile' => 'required|numeric|digits_between:6,15', 'guardian_gender' => 'required|in:male,female', 'guardian_image' => 'nullable|mimes:jpg,jpeg,png|max:4096', 'status' => 'nullable|in:0,1', ], [ 'guardian_email.regex' => 'Please enter a valid guardian email (e.g. user@example.com).', ]); try { DB::beginTransaction(); // Check free trial package $today_date = Carbon::now()->format('Y-m-d'); $subscription = $this->subscription->builder()->doesntHave('subscription_bill')->whereDate('start_date', '<=', $today_date)->where('end_date', '>=', $today_date)->whereHas('package', function ($q) { $q->where('is_trial', 1); })->first(); // If free trail package if ($subscription) { $systemSettings = $this->cache->getSystemSettings(); $student = $this->user->builder()->role('Student')->withTrashed()->count(); if ($student >= $systemSettings['student_limit']) { $message = "The free trial allows only " . $systemSettings['student_limit'] . " students."; ResponseService::errorResponse($message); } } else { // Regular package? Check Postpaid or Prepaid $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // If prepaid plan check student limit if ($subscription && $subscription->package_type == 0) { $status = $this->subscriptionService->check_user_limit($subscription, "Students"); if (!$status) { ResponseService::errorResponse('You reach out limits'); } } } // Get the user details from the guardian details & identify whether that user is guardian or not. if not the guardian and has some other role then show appropriate message in response $guardianUser = $this->user->builder()->whereHas('roles', function ($q) { $q->where('name', '!=', 'Guardian'); })->where('email', $request->guardian_email)->withTrashed()->first(); if ($guardianUser) { ResponseService::errorResponse("Email ID is already taken for Other Role"); } $userService = app(UserService::class); $guardian = $userService->createOrUpdateParent($request->guardian_first_name, $request->guardian_last_name, $request->guardian_email, $request->guardian_mobile, $request->guardian_gender, $request->guardian_image); $is_send_notification = true; $userService->createStudentUser($request->first_name, $request->last_name, $request->admission_no, $request->mobile, $request->dob, $request->gender, $request->image, $request->class_section_id, $request->admission_date, $request->current_address, $request->permanent_address, $request->session_year, $guardian->id, $request->extra_fields ?? [], $request->status ?? 0, $is_send_notification); DB::commit(); ResponseService::successResponse('Data Stored Successfully'); } catch (Throwable $e) { // IF Exception is TypeError and message contains Mail keywords then email is not sent successfully if ( $e instanceof TypeError && Str::contains($e->getMessage(), [ 'Failed', 'Mail', 'Mailer', 'MailManager' ]) ) { DB::commit(); ResponseService::warningResponse("Student Registered successfully. But Email not sent."); } else { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller -> Store method"); ResponseService::errorResponse(); } } } public function update($id, Request $request) { ResponseService::noAnyPermissionThenSendJson(['student-create', 'student-edit']); $rules = [ 'first_name' => 'required', 'last_name' => 'required', 'mobile' => 'nullable|regex:/^([0-9\s\-\+\(\)]*)$/|digits_between:6,15', 'image' => 'nullable|mimes:jpeg,png,jpg,svg|image|max:2048', 'dob' => 'required', 'session_year_id' => 'required|numeric', 'guardian_email' => 'required|email|max:255|regex:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/|unique:users,email', ]; if (is_numeric($request->guardian_id)) { $rules['guardian_email'] = 'required|email|unique:users,email,' . $request->guardian_id; } $request->validate($rules); try { DB::beginTransaction(); $userService = app(UserService::class); $sessionYear = $this->sessionYear->findById($request->session_year_id); $guardian = $userService->createOrUpdateParent($request->guardian_first_name, $request->guardian_last_name, $request->guardian_email, $request->guardian_mobile, $request->guardian_gender, $request->guardian_image, $request->parent_reset_password); $userService->updateStudentUser($id, $request->first_name, $request->last_name, $request->mobile, $request->dob, $request->gender, $request->image, $sessionYear->id, $request->extra_fields ?? [], $guardian->id, $request->current_address, $request->permanent_address, $request->reset_password, $request->class_section_id); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller -> Update method"); ResponseService::errorResponse(); } } public function show(Request $request) { ResponseService::noPermissionThenRedirect('student-list'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'ASC'); $search = request('search'); $selectedSessionYearId = $this->cache->getSessionYear()->id; $defaultSessionYearId = $this->cache->getDefaultSessionYear()->id; $isCurrentSession = ($selectedSessionYearId == $defaultSessionYearId); $teacherClassSection = []; if (Auth::user()->hasRole('Teacher')) { $classTeacher = ClassTeacher::where('teacher_id', Auth::user()->id)->where('session_year_id', $selectedSessionYearId)->get()->pluck('class_section_id')->toArray(); $subjectTeacher = SubjectTeacher::where('teacher_id', Auth::user()->id)->where('session_year_id', $selectedSessionYearId)->get()->pluck('class_section_id')->toArray(); $teacherClassSection = array_merge($classTeacher, $subjectTeacher); // $request->validate([ // 'class_id' => 'required' // ], [ // 'class_id.required' => 'The class field is required.' // ]); } // Handle show_deactive parameter (can be 0, 1, "0", "1", or null) $showDeactive = $request->show_deactive; $showInactive = ($showDeactive == 1 || $showDeactive === '1' || $showDeactive === true); if ($isCurrentSession) { $sql = $this->student->builder() ->where('students.session_year_id', $selectedSessionYearId) ->select( 'students.*', DB::raw("'current' as record_source"), DB::raw("NULL as snapshot_roll_number"), DB::raw("NULL as snapshot_class_section_id") ); if (Auth::user()->hasRole('Teacher')) { $sql->whereIn('students.class_section_id', $teacherClassSection); } } else { $sql = $this->student->builder() ->join('promote_students', 'students.user_id', '=', 'promote_students.student_id') ->where('promote_students.session_year_id', $selectedSessionYearId) ->select( 'students.*', DB::raw("'historical' as record_source"), 'promote_students.roll_number as snapshot_roll_number', 'promote_students.class_section_id as snapshot_class_section_id' ); if (Auth::user()->hasRole('Teacher')) { $sql->whereIn('promote_students.class_section_id', $teacherClassSection); } } $sql = $sql->where(function ($query) { // Must ensure students prefix is used to prevent ambiguous column errors on application_type $query->where('students.application_type', 'offline') ->orWhere(function ($q) { $q->where('students.application_type', 'online') ->where('students.application_status', 1); // Only online applications with status 1 }); }) ->with([ 'promote_student' => function ($q) use ($selectedSessionYearId) { $q->where('session_year_id', $selectedSessionYearId) ->with('class_section.class.stream', 'class_section.section', 'class_section.class.shift', 'class_section.medium'); }, 'user.extra_student_details.form_field', 'guardian', 'class_section.class.stream', 'class_section.section', 'class_section.class.shift', 'class_section.medium' ]) ->where(function ($query) use ($search, $isCurrentSession) { $query->when($search, function ($query) use ($search, $isCurrentSession) { $query->where(function ($query) use ($search, $isCurrentSession) { $query->where('students.user_id', 'LIKE', "%$search%") ->orWhere('students.admission_no', 'LIKE', "%$search%") ->orWhere('students.admission_date', 'LIKE', date('Y-m-d', strtotime("%$search%"))) ->orWhereHas('user', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%") ->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'"); })->orWhereHas('guardian', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%") ->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'"); }); if ($isCurrentSession) { $query->orWhere('students.class_section_id', 'LIKE', "%$search%") ->orWhere('students.roll_number', 'LIKE', "%$search%"); } else { $query->orWhere('promote_students.class_section_id', 'LIKE', "%$search%") ->orWhere('promote_students.roll_number', 'LIKE', "%$search%"); } }); }); //class filter data })->when(request('class_id') != null, function ($query) use ($isCurrentSession) { $classId = request('class_id'); if ($isCurrentSession) { $query->where('students.class_section_id', $classId); } else { $query->where('promote_students.class_section_id', $classId); } }); // Filter by student status (active/inactive) if ($showInactive) { // Show inactive students (status = 0) $sql = $sql->whereHas('user', function ($query) { $query->where('status', 0); }); } else { // Show active students (status = 1) $sql = $sql->whereHas('user', function ($query) { $query->where('status', 1); }); } if ($request->exam_id && $request->exam_id != 'data-not-found') { $sql = $sql->has('exam_result')->whereHas('exam_result', function ($q) use ($request) { $q->where('exam_id', $request->exam_id); }); } $total = $sql->count(); if ($sort == 'roll_number' || !empty($request->class_id)) { if ($isCurrentSession) { $sql = $sql->orderBy("students.roll_number", $order); } else { $sql = $sql->orderBy("promote_students.roll_number", $order); } } else { // Qualify the column for sorting to avoid ambiguity if (in_array($sort, ['id', 'user_id', 'class_section_id', 'admission_no', 'admission_date'])) { $sql = $sql->orderBy('students.' . $sort, $order); } else { $sql = $sql->orderBy($sort, $order); } } if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql->skip($offset)->take($limit); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = $offset + 1; foreach ($res as $row) { $isHistoricalRow = !$isCurrentSession; if ($isHistoricalRow) { $row->roll_number = $row->snapshot_roll_number; // Force the historical class section relationship if ($row->snapshot_class_section_id) { if ($row->promote_student && $row->promote_student->class_section) { $row->setRelation('class_section', $row->promote_student->class_section); } } } $operate = ''; if (!$request->show_deactive) { if (Auth::user()->can('student-edit')) { $operate = BootstrapTableService::menuEditButton('edit', route('students.update', $row->user->id, ['data-id' => $row->id])); $operate .= BootstrapTableService::menuButton('inactive', route('student.change-status', $row->user_id), ['deactivate-student'], ['title' => __('inactive')]); } } else { if (Auth::user()->can('student-edit')) { $operate = BootstrapTableService::menuButton('active', route('student.change-status', $row->user_id), ['activate-student'], ['title' => __('active')]); } } if (Auth::user()->can('student-delete')) { // $operate .= BootstrapTableService::trashButton(route('student.trash', $row->user_id)); $operate .= BootstrapTableService::menuTrashButton('delete', route('students.destroy', $row->user_id)); } $student_gender = $row->user->gender; $guardian_gender = $row->guardian->gender ?? ''; $row->user->gender = trans(strtolower($row->user->gender)); $row->guardian->gender = trans(strtolower($row->guardian->gender ?? '')); $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['dob_org'] = $row->user->getRawOriginal('dob'); $tempRow['eng_student_gender'] = $student_gender; $tempRow['eng_guardian_gender'] = $guardian_gender; $tempRow['guardian_data'] = $row->guardian; $tempRow['extra_fields'] = $row->user->extra_student_details; foreach ($row->user->extra_student_details as $key => $field) { $data = ''; if ($field->form_field->type == 'checkbox') { $data = json_decode($field->data); } else if ($field->form_field->type == 'file' && $field->data) { $data = '<a href="' . Storage::url($field->data) . '" target="_blank">DOC</a>'; } else if ($field->form_field->type == 'dropdown') { $data = $field->form_field->default_values; $data = $field->data ?? ''; } else { $data = $field->data; } $tempRow[$field->form_field->name] = $data; } // $tempRow['operate'] = $operate; $tempRow['operate'] = BootstrapTableService::menuItem($operate); $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function destroy($user_id) { ResponseService::noPermissionThenSendJson('student-delete'); try { User::where('id', $user_id)->forceDelete(); ResponseService::successResponse('Data Deleted Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller -> Delete method"); ResponseService::errorResponse(); } } public function changeStatus($userId) { try { // ResponseService::noFeatureThenSendJson('Student Management'); ResponseService::noPermissionThenRedirect('student-edit'); DB::beginTransaction(); $user = $this->user->findTrashedById($userId); if ($user->status == 0) { $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // If prepaid plan check student limit if ($subscription && $subscription->package_type == 0) { $status = $this->subscriptionService->check_user_limit($subscription, "Students"); if (!$status) { ResponseService::errorResponse('You reach out limits'); } } } $this->user->builder()->where('id', $userId)->withTrashed()->update(['status' => $user->status == 0 ? 1 : 0, 'deleted_at' => $user->status == 1 ? now() : null]); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, 'Student Controller ---> Change Status'); ResponseService::errorResponse(); } } public function changeStatusBulk(Request $request) { // ResponseService::noFeatureThenSendJson('Student Management'); ResponseService::noPermissionThenRedirect('student-create'); try { DB::beginTransaction(); foreach (json_decode($request->ids, false, 512, JSON_THROW_ON_ERROR) as $key => $userId) { $studentUser = $this->user->findTrashedById($userId); if ($studentUser->status == 0) { $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // If prepaid plan check student limit if ($subscription && $subscription->package_type == 0) { $status = $this->subscriptionService->check_user_limit($subscription, "Students"); if (!$status) { ResponseService::errorResponse('You reach out limits'); } } } $this->user->builder()->where('id', $userId)->withTrashed()->update(['status' => $studentUser->status == 0 ? 1 : 0, 'deleted_at' => $studentUser->status == 1 ? now() : null]); } DB::commit(); ResponseService::successResponse("Status Updated Successfully"); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function trash($id) { // ResponseService::noFeatureThenSendJson('Student Management'); ResponseService::noPermissionThenSendJson('student-delete'); try { DB::beginTransaction(); // Get student record with guardian $student = $this->student->builder()->with('guardian')->where('user_id', $id)->first(); if ($student && $student->guardian) { // Count total students with same guardian_id $guardianStudentCount = $this->student->builder()->where('guardian_id', $student->guardian_id)->count(); // If guardian has exactly one student, delete the guardian if ($guardianStudentCount == 1) { $this->user->builder()->where('id', $student->guardian->id)->withTrashed()->forceDelete(); } } // Delete student and user records $this->student->builder()->where('user_id', $id)->withTrashed()->forceDelete(); $this->user->builder()->where('id', $id)->withTrashed()->forceDelete(); DB::commit(); ResponseService::successResponse("Data Deleted Permanently"); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller ->Trash Method", 'cannot_delete_because_data_is_associated_with_other_data'); ResponseService::errorResponse(); } } public function createBulkData() { ResponseService::noPermissionThenRedirect('student-create'); $class_section = $this->classSection->all(['*'], ['class', 'class.stream', 'class.shift', 'section', 'medium']); $sessionYears = $this->sessionYear->all(); return view('students.add_bulk_data', compact('class_section', 'sessionYears')); } public function storeBulkData(Request $request) { ResponseService::noPermissionThenRedirect('student-create'); $validator = Validator::make($request->all(), [ 'session_year_id' => 'required|numeric', 'class_section_id' => 'required', 'file' => 'required|mimes:csv,txt' ]); if ($validator->fails()) { ResponseService::errorResponse($validator->errors()->first()); } try { Excel::import(new StudentsImport($request->class_section_id, $request->session_year_id, $request->is_send_notification), $request->file); if ($request->is_send_notification) { $message = 'Data Stored Successfully. Email notifications have been queued and will be sent to parents shortly.'; } else { $message = 'Data Stored Successfully.'; } ResponseService::successResponse($message); } catch (ValidationException $e) { if ( $e instanceof TypeError && Str::contains($e->getMessage(), [ 'Failed', 'Mail', 'Mailer', 'MailManager' ]) ) { DB::commit(); ResponseService::warningResponse("Student Registered successfully. But Email not sent."); } else { ResponseService::errorResponse($e->getMessage()); } } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Student Controller -> Store Bulk method"); ResponseService::errorResponse(); } } public function resetPasswordIndex() { $class_section = $this->classSection->builder()->with('class', 'class.stream', 'class.shift', 'section')->get(); return view('students.reset-password', compact('class_section')); } public function resetPasswordShow() { ResponseService::noPermissionThenRedirect('reset-password-list'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'DESC'); $sql = $this->user->builder()->where('reset_request', 1); if (!empty($_GET['search'])) { $search = $_GET['search']; $sql->where(function ($query) use ($search) { $query->where('id', 'LIKE', "%$search%")->orwhere('email', 'LIKE', "%$search%") ->orwhere('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orWhereRaw("concat(users.first_name,' ',users.last_name) LIKE '%" . $search . "%'"); }); } $total = $sql->count(); if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql->orderBy($sort, $order)->skip($offset)->take($limit); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $operate = BootstrapTableService::button('fa fa-edit', route('student.reset-password.update', $row->id), ['reset_password', 'btn-gradient-primary', 'btn-action', 'btn-rounded btn-icon'], ['title' => trans("reset_password"), 'data-id' => $row->id, 'data-dob' => $row->getRawOriginal('dob')]); $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['operate'] = $operate; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function resetPasswordUpdate(Request $request) { ResponseService::noPermissionThenRedirect('student-change-password'); try { DB::beginTransaction(); $dob = date('dmY', strtotime($request->dob)); $password = Hash::make($dob); $this->user->update($request->id, ['password' => $password, 'reset_request' => 0]); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller -> Reset Password method"); ResponseService::errorResponse(); } } public function rollNumberIndex() { ResponseService::noPermissionThenRedirect('student-list'); $class_section = $this->classSection->all(['*'], ['class', 'class.stream', 'class.shift', 'section', 'medium']); return view('students.assign_roll_no', compact('class_section')); } public function rollNumberUpdate(Request $request) { ResponseService::noPermissionThenRedirect('student-list'); $validator = Validator::make( $request->all(), ['roll_number_data.*.roll_number' => 'required',], ['roll_number_data.*.roll_number.required' => trans('please_fill_all_roll_numbers_data')] ); if ($validator->fails()) { ResponseService::validationError($validator->errors()->first()); } try { DB::beginTransaction(); foreach ($request->roll_number_data as $data) { $updateRollNumberData = array( 'roll_number' => $data['roll_number'] ); // validation required when the edit of roll number is enabled // $class_roll_number_data = $this->student->builder()->where(['class_section_id' => $student->class_section_id,'roll_number' => $data['roll_number']])->whereNot('id',$data['student_id'])->count(); // if(isset($class_roll_number_data) && !empty($class_roll_number_data)){ // $response = array( // 'error' => true, // 'message' => trans('roll_number_already_exists_of_number').' - '.$i // ); // return response()->json($response); // } // TODO : Use upsert here $this->student->update($data['student_id'], $updateRollNumberData); } DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Student Controller -> updateStudentRollNumber"); ResponseService::errorResponse(); } } public function rollNumberShow(Request $request) { try { ResponseService::noPermissionThenRedirect('student-list'); $currentSessionYear = $this->cache->getSessionYear(); $class_section_id = $request->class_section_id; $sql = $this->user->builder()->with(['student.promote_student' => function ($q) use ($currentSessionYear) { $q->where('session_year_id', $currentSessionYear->id); }]); $sql = $sql->whereHas('student', function ($q) use ($class_section_id) { $q->owner()->classSection($class_section_id); }); if (!empty($_GET['search'])) { $search = $_GET['search']; $sql->where(function ($query) use ($search) { $query->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%") ->orWhereHas('student', function ($q) use ($search) { $q->where('id', 'LIKE', "%$search%") ->orWhere('user_id', 'LIKE', "%$search%") ->orWhere('class_section_id', 'LIKE', "%$search%") ->orWhere('admission_no', 'LIKE', "%$search%") ->orWhere('admission_date', 'LIKE', date('Y-m-d', strtotime("%$search%"))) ->orWhereHas('user', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%"); }); }); }); } if ($request->sort_by == 'first_name') { $sql = $sql->orderBy('first_name', $request->order_by); } if ($request->sort_by == 'last_name') { $sql = $sql->orderBy('last_name', $request->order_by); } $total = $sql->count(); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; $roll = 1; $index = 0; // TODO : improve this foreach ($res as $row) { $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['student_id'] = $row->student->id; // Priority to historical roll number for accuracy in past sessions $tempRow['old_roll_number'] = $row->student->promote_student->roll_number ?? $row->student->roll_number; // for edit roll number comment below line $tempRow['new_roll_number'] = "<input type='hidden' name='roll_number_data[" . $index . "][student_id]' class='form-control' readonly value=" . $row->student->id . "> <input type='hidden' name='roll_number_data[" . $index . "][roll_number]' class='form-control' value=" . $roll . ">" . $roll; // and uncomment below line // $tempRow['new_roll_number'] = "<input type='hidden' name='roll_number_data[" . $index . "][student_id]' class='form-control' readonly value=" . $row->student->id . "> <input type='text' name='roll_number_data[" . $index . "][roll_number]' class='form-control' value=" . $roll . ">"; $tempRow['user_id'] = $row->id; $tempRow['admission_no'] = $row->student->admission_no; $tempRow['admission_date'] = $row->student->admission_date; $rows[] = $tempRow; $index++; $roll++; } $bulkData['rows'] = $rows; return response()->json($bulkData); } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Student Controller -> listStudentRollNumber"); ResponseService::errorResponse(); } } public function downloadSampleFile() { try { return Excel::download(new StudentDataExport(), 'Student_import.xlsx'); } catch (Throwable $e) { ResponseService::logErrorResponse($e, 'Student Controller ---> Download Sample File'); ResponseService::errorResponse(); } } public function update_profile() { ResponseService::noPermissionThenRedirect('student-edit'); $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'class.shift', 'section', 'medium']); return view('students.add_bulk_profile', compact('class_sections')); } public function list($id = null, Request $request) { ResponseService::noPermissionThenRedirect('student-edit'); $search = request('search'); $sessionYearId = $this->cache->getSessionYear()->id; $res = array(); $total = 0; if (!empty($request->class_id)) { $sql = $this->student->builder()->with('user', 'guardian', 'class_section.class', 'class_section.class.shift', 'class_section.section', 'class_section.medium') ->where('session_year_id', $sessionYearId) ->where(function ($query) use ($search) { $query->when($search, function ($query) use ($search) { $query->where(function ($query) use ($search) { $query->where('user_id', 'LIKE', "%$search%") ->orWhere('roll_number', 'LIKE', "%$search%") ->orWhereHas('user', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%"); }); }); }); })->when(request('class_id') != null, function ($query) { $classId = request('class_id'); $query->where(function ($query) use ($classId) { $query->where('class_section_id', $classId); }); }); $sql = $sql->whereHas('user', function ($query) { $query->where('status', 1); }); $total = $sql->count(); $sql = $sql->orderBy('roll_number', 'ASC'); $res = $sql->get(); } $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['total'] = $total; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function store_update_profile(Request $request) { ResponseService::noAnyPermissionThenRedirect(['student-edit']); try { if (!$request->student_image && !$request->guardian_image) { ResponseService::errorResponse('Please update at least one image'); } $data = array(); if ($request->student_image) { foreach ($request->student_image as $key => $profile) { // Skip entries where no file was selected if (!$profile instanceof \Illuminate\Http\UploadedFile || !$profile->isValid()) { continue; } $data[] = [ 'id' => $key, 'image' => $profile, ]; } } if ($request->guardian_image) { foreach ($request->guardian_image as $key => $profile) { // Skip entries where no file was selected if (!$profile instanceof \Illuminate\Http\UploadedFile || !$profile->isValid()) { continue; } $data[] = [ 'id' => $key, 'image' => $profile, ]; } } if (empty($data)) { ResponseService::errorResponse('Please update at least one image'); } $this->user->upsertProfile($data, ['id'], ['image']); ResponseService::successResponse('Profile Updated Successfully'); } catch (\Throwable $th) { ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function generate_id_card_index() { ResponseService::noFeatureThenRedirect('ID Card - Certificate Generation'); ResponseService::noAnyPermissionThenRedirect(['student-list', 'class-teacher']); $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'class.shift', 'section', 'medium']); return view('students.generate_id_card', compact('class_sections')); } public function generate_id_card(Request $request) { ResponseService::noFeatureThenRedirect('ID Card - Certificate Generation'); ResponseService::noAnyPermissionThenRedirect(['student-list', 'class-teacher']); $request->validate([ 'user_id' => 'required' ], [ 'user_id.required' => trans('Please select at least one record') ]); try { $user_ids = explode(",", $request->user_id); $settings = $this->cache->getSchoolSettings(); if (!isset($settings['student_id_card_fields'])) { if (!Auth::user()->can('id-card-settings')) { return redirect()->back()->withErrors([ 'message' => trans("ID Card settings are not configured for this session year. Please update the settings to continue using this feature.") ])->send(); } return redirect()->route('id-card-settings')->with('error', trans('settings_not_found')); } $settings['student_id_card_fields'] = explode(",", $settings['student_id_card_fields']); $data = explode("storage/", $settings['signature'] ?? ''); $settings['signature'] = end($data); $data = explode("storage/", $settings['background_image'] ?? ''); $settings['background_image'] = end($data); $data = explode("storage/", $settings['horizontal_logo'] ?? ''); $settings['horizontal_logo'] = end($data); $sessionYear = $this->cache->getSessionYear(); $valid_until = date('F j, Y', strtotime($sessionYear->original_end_date)); $height = $settings['page_height'] * 2.8346456693; $width = $settings['page_width'] * 2.8346456693; // $customPaper = array(0,0,360,200); $customPaper = array(0, 0, $width, $height); $students = $this->user->builder()->select('id', 'first_name', 'last_name', 'image', 'school_id', 'gender', 'dob')->with('student', 'student.class_section.class', 'student.class_section.class.shift', 'student.class_section.section', 'student.class_section.medium', 'student.class_section.class.stream', 'student.guardian:id,mobile,first_name,last_name')->whereHas('student', function ($q) use ($user_ids) { $q->whereIn('id', $user_ids); })->with([ 'extra_student_details' => function ($q) { $q->whereHas('form_field', function ($query) { $query->where('display_on_id', 1)->whereNull('deleted_at'); })->with('form_field'); } ])->get(); $settings['page_height'] = ($settings['page_height'] * 3.7795275591) . 'px'; $pdf = PDF::loadView('students.students_id_card', compact('students', 'sessionYear', 'valid_until', 'settings')); $pdf->setPaper($customPaper); return $pdf->stream(); return view('students.id_card_pdf'); } catch (\Throwable $th) { ResponseService::logErrorResponse($th); ResponseService::errorResponse(); } } public function admissionForm() { try { if (Auth::user()) { $schoolSettings = $this->cache->getSchoolSettings(); } else { $fullDomain = $_SERVER['HTTP_HOST'] ?? ''; $parts = explode('.', $fullDomain); $subdomain = $parts[0]; $school = School::on('mysql')->where('domain', $fullDomain)->orwhere('domain', $subdomain)->first(); if ($school) { $schoolSettings = $this->cache->getSchoolSettings('*', $school->id); } } $data = explode("storage/", $schoolSettings['horizontal_logo'] ?? ''); $schoolSettings['horizontal_logo'] = end($data); if ($schoolSettings['horizontal_logo'] == null) { $systemSettings = $this->cache->getSystemSettings(); $data = explode("storage/", $systemSettings['horizontal_logo'] ?? ''); $schoolSettings['horizontal_logo'] = end($data); } $pdf = PDF::loadView('students.admission_form', compact('schoolSettings')); return $pdf->stream(); } catch (\Throwable $th) { } } public function onlineRegistrationIndex() { ResponseService::noPermissionThenRedirect('student-list'); $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'section', 'medium']); $classes = $this->classSchool->builder()->with('medium', 'stream', 'shift')->get(); $schoolSettings = $this->cache->getSchoolSettings(); $extraFields = $this->formFields->defaultModel()->orderBy('rank')->get(); $sessionYears = $this->sessionYear->all(); $features = FeaturesService::getFeatures(); return view('students.online_registration', compact('class_sections', 'extraFields', 'sessionYears', 'features', 'classes', 'schoolSettings')); } public function onlineRegistrationList(Request $request) { ResponseService::noPermissionThenRedirect('student-list'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'ASC'); $search = request('search'); $sql = $this->student->builder()->where('application_type', 'online')->where('application_status', 0)->with('user.extra_student_details.form_field', 'guardian', 'class.medium', 'class.stream', 'class.shift') ->where(function ($query) use ($search) { $query->when($search, function ($query) use ($search) { $query->where(function ($query) use ($search) { $query->where('user_id', 'LIKE', "%$search%") ->orWhere('class_section_id', 'LIKE', "%$search%") ->orWhere('admission_no', 'LIKE', "%$search%") ->orWhere('roll_number', 'LIKE', "%$search%") ->orWhere('admission_date', 'LIKE', date('Y-m-d', strtotime("%$search%"))) ->orWhereHas('user', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%") ->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'"); })->orWhereHas('guardian', function ($q) use ($search) { $q->where('first_name', 'LIKE', "%$search%") ->orwhere('last_name', 'LIKE', "%$search%") ->orwhere('email', 'LIKE', "%$search%") ->orwhere('dob', 'LIKE', "%$search%") ->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'"); }); }); }) ->whereHas('user', function ($q) { $q->where('status', 0); }); //class filter data }) ->when(request('class_id') != null, function ($query) { $classId = request('class_id'); $query->where(function ($query) use ($classId) { $query->where('class_id', $classId); }); }); if ($request->exam_id && $request->exam_id != 'data-not-found') { $sql = $sql->has('exam_result')->whereHas('exam_result', function ($q) use ($request) { $q->where('exam_id', $request->exam_id); }); } $total = $sql->count(); if (!empty($request->class_id)) { $sql = $sql->orderBy('roll_number', 'ASC'); } else { $sql = $sql->orderBy($sort, $order); } if ($offset >= $total && $total > 0) { $lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset $offset = $lastPage; } $sql->skip($offset)->take($limit); $res = $sql->get(); $bulkData = array(); $bulkData['total'] = $total; $rows = array(); $no = 1; foreach ($res as $row) { $operate = ''; if (Auth::user()->can('student-edit')) { $operate .= BootstrapTableService::editButton(route('update-application-status', $row->user->id, ['data-id' => $row->id])); } if (Auth::user()->can('student-delete')) { $operate .= BootstrapTableService::trashButton(route('student.trash', $row->user_id)); } $student_gender = $row->user->gender; $guardian_gender = $row->guardian->gender; $row->user->gender = trans(strtolower($row->user->gender)); $row->guardian->gender = trans(strtolower($row->guardian->gender)); $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['eng_student_gender'] = $student_gender; $tempRow['eng_guardian_gender'] = $guardian_gender; $tempRow['extra_fields'] = $row->user->extra_student_details; $tempRow['application_status'] = $row->application_status; foreach ($row->user->extra_student_details as $key => $field) { $data = ''; if ($field->form_field->type == 'checkbox') { $data = json_decode($field->data); } else if ($field->form_field->type == 'file') { $data = '<a href="' . Storage::url($field->data) . '" target="_blank">DOC</a>'; } else if ($field->form_field->type == 'dropdown') { $data = $field->form_field->default_values; $data = $field->data ?? ''; } else { $data = $field->data; } $tempRow[$field->form_field->name] = $data; } $tempRow['operate'] = $operate; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function updateBulkApplicationStatus(Request $request) { ResponseService::noPermissionThenRedirect('student-create'); $request->validate([ 'class_section_id' => $request->application_status == '0' ? 'nullable' : 'required' ], [ 'class_section_id' => 'The assign class section field is required' ]); try { $userService = app(UserService::class); DB::beginTransaction(); foreach (json_decode($request->ids, false, 512, JSON_THROW_ON_ERROR) as $key => $userId) { $user = $this->user->findTrashedById($userId); $student = $this->student->builder()->where('user_id', $userId)->first(); if ($user->status == 0) { $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // If prepaid plan check student limit if ($subscription && $subscription->package_type == 0) { $status = $this->subscriptionService->check_user_limit($subscription, "Students"); if (!$status) { ResponseService::errorResponse('You reach out limits'); } } } if ($request->application_status == 1) { $this->student->builder()->where('user_id', $userId)->withTrashed()->update(['application_status' => 1, 'class_section_id' => $request->class_section_id]); $password = str_replace('-', '', date('d-m-Y', strtotime($user->dob))); $guardian = $this->user->guardian()->where('id', $student->guardian_id)->firstOrFail(); $userService->sendRegistrationEmail($guardian, $user, $student->admission_no, $password); } else { $this->student->builder()->where('user_id', $userId)->withTrashed()->update(['application_status' => 0, 'class_section_id' => $request->class_section_id]); $guardian = $this->user->guardian()->where('id', $student->guardian_id)->firstOrFail(); $class = $this->classSchool->builder()->where('id', $student->class_id)->with('medium', 'stream')->first(); $class_name = $class->full_name; $userService->sendApplicationRejectEmail($user, $class_name, $guardian); } } DB::commit(); ResponseService::successResponse("Status Updated Successfully"); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function updateApplicationStatus(Request $request) { ResponseService::noPermissionThenRedirect('student-create'); $request->validate([ 'class_section_id' => 'required_if:application_status,1' ], [ 'class_section_id.required_if' => 'The class section field is required when application status is accepted.' ]); try { $userService = app(UserService::class); DB::beginTransaction(); $user = $this->user->findTrashedById($request->edit_user_id); $student = $this->student->builder()->where('user_id', $request->edit_user_id)->first(); if ($user->status == 0) { $subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id); // If prepaid plan check student limit if ($subscription && $subscription->package_type == 0) { $status = $this->subscriptionService->check_user_limit($subscription, "Students"); if (!$status) { ResponseService::errorResponse('You reach out limits'); } } } if ($request->application_status == 1) { $this->student->builder()->where('user_id', $request->edit_user_id)->withTrashed()->update(['application_status' => 1, 'class_section_id' => $request->class_section_id]); $password = str_replace('-', '', date('d-m-Y', strtotime($user->dob))); $guardian = $this->user->guardian()->where('id', $student->guardian_id)->firstOrFail(); $userService->sendRegistrationEmail($guardian, $user, $student->admission_no, $password); } else { $this->student->builder()->where('user_id', $request->edit_user_id)->withTrashed()->update(['application_status' => 0]); $guardian = $this->user->guardian()->where('id', $student->guardian_id)->firstOrFail(); $userService->sendApplicationRejectEmail($user, $student, $guardian); } DB::commit(); ResponseService::successResponse("Status Updated Successfully"); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function getclassSectionByClass($class_id) { try { $class_sections = $this->classSection->builder()->where('class_id', $class_id)->with('class', 'class.stream', 'class.shift', 'section', 'medium')->get(); ResponseService::successResponse('Data Fetched Successfully', $class_sections); } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Student Controller -> getclassSectionByClass method"); ResponseService::errorResponse(); } } }