File "PromoteStudentController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/PromoteStudentController.php
File size: 19.54 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Models\PromoteStudent;
use App\Models\Students;
use App\Models\StudentSubject;
use App\Models\User;
use App\Repositories\ClassSection\ClassSectionInterface;
use App\Repositories\PromoteStudent\PromoteStudentInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\Student\StudentInterface;
use App\Repositories\StudentSubject\StudentSubjectInterface;
use App\Repositories\User\UserInterface;
use App\Services\CachingService;
use App\Services\ResponseService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Throwable;
class PromoteStudentController extends Controller
{
private ClassSectionInterface $classSection;
private SessionYearInterface $sessionYear;
private StudentInterface $student;
private UserInterface $user;
private PromoteStudentInterface $promoteStudent;
private CachingService $cache;
private StudentSubjectInterface $studentSubject;
public function __construct(ClassSectionInterface $classSection, SessionYearInterface $sessionYear, StudentInterface $student, UserInterface $user, PromoteStudentInterface $promoteStudent, CachingService $cachingService, StudentSubjectInterface $studentSubject)
{
$this->classSection = $classSection;
$this->sessionYear = $sessionYear;
$this->student = $student;
$this->user = $user;
$this->promoteStudent = $promoteStudent;
$this->cache = $cachingService;
$this->studentSubject = $studentSubject;
}
public function index()
{
ResponseService::noAnyPermissionThenRedirect(['promote-student-list', 'transfer-student-list']);
$classSections = $this->classSection->all(['*'], ['class', 'section', 'medium', 'class.stream', 'class.shift']);
$sessionYears = $this->sessionYear->builder()->select(['id', 'name', 'start_date'])->orderBy('start_date', 'asc')->get();
return view('promote_student.index', compact('classSections', 'sessionYears'));
}
public function store(Request $request)
{
ResponseService::noAnyPermissionThenSendJson(['promote-student-create', 'promote-student-edit']);
$request->validate([
'class_section_id' => 'required',
'promote_data' => 'required',
'new_class_section_id' => [
$request->is_final_year ? 'nullable' : 'required',
$request->is_final_year ? '' : 'exists:class_sections,id',
function ($attr, $value, $fail) use ($request) {
if ($request->is_final_year) return;
$oldClass = \App\Models\ClassSection::find($request->class_section_id)?->class_id;
$newClass = \App\Models\ClassSection::find($value)?->class_id;
if ($oldClass && $newClass && $oldClass === $newClass) {
$fail(__('Cannot promote student to the same class.'));
}
},
],
], ['promote_data.required' => "No Student Data Found"]);
if (empty($request->promote_data)) {
ResponseService::errorResponse("Please select at least one student.");
}
try {
DB::beginTransaction();
$sessionYearId = $request->from_session_year_id; // Get Current Session Year
$promoteStudentData = array();
// Fetch current roll numbers for all students being promoted/transferred
$studentUserIds = collect($request->promote_data)->pluck('student_id');
$currentStudents = $this->student->builder()->whereIn('user_id', $studentUserIds)->get(['user_id', 'roll_number'])->keyBy('user_id');
foreach ($request->promote_data as $key => $data) {
$isFinalYear = $request->has('is_final_year') && $request->is_final_year;
// If Final Year and Pass, force Leave
if ($isFinalYear && $data['result'] == 1) {
$data['status'] = 0; // Leave
}
$promoteRecord = array(
'student_id' => $data['student_id'],
'session_year_id' => $sessionYearId,
'result' => $data['result'],
'status' => $data['status'],
'roll_number' => $currentStudents[$data['student_id']]->roll_number ?? null,
);
if ($data['result'] == 1) {
// IF Student Then Store New Class Section in Promote Data
$promoteRecord['class_section_id'] = $request->class_section_id;
if ($data['status'] == 1) {
// IF Student Continues then get students IDs
$passStudentsIds[] = $data['student_id'];
}
} else {
// IF Students Fails then store Current Class Section in Promote Data
$promoteRecord['class_section_id'] = $request->class_section_id;
if ($data['status'] == 1) {
// IF Student Fails then get students IDs
$failStudentsIds[] = $data['student_id'];
}
}
// IF Student Leaves then get Student IDs
if ($data['status'] == 0) {
$leftStudentSIds[] = $data['student_id'];
}
if ($isFinalYear && $data['status'] == 0) {
// Graduated/Passed out finale: No target class/session
$targetClassSectionId = null;
$targetSessionYearId = null;
} else if ($isFinalYear) {
// Final year + Fail + Continue
$targetClassSectionId = $request->class_section_id;
$targetSessionYearId = $request->session_year_id;
} else {
// Normal promotion
$targetClassSectionId = $data['result'] == 1 ? $request->new_class_section_id : $request->class_section_id;
$targetSessionYearId = $request->session_year_id;
}
$promoteRecord['current_class_section_id'] = $targetClassSectionId;
$promoteRecord['current_session_year_id'] = $targetSessionYearId;
$promoteStudentData[] = $promoteRecord;
}
if (!empty($passStudentsIds)) {
// Get Sort Value and Order Value from Settings
$sortBy = !empty($this->cache->getSchoolSettings('roll_number_sort_column')) ? $this->cache->getSchoolSettings('roll_number_sort_column') : 'first_name';
$orderBy = !empty($this->cache->getSchoolSettings('roll_number_sort_order')) ? $this->cache->getSchoolSettings('roll_number_sort_order') : 'asc';
// Get The Data of Users who is passed with Student Relation and make Array to Update Student Details
$studentUsers = $this->user->builder()->role('Student')->whereIn('id', $passStudentsIds)->with('studentWithoutOwner')->orderBy('users.' . $sortBy, $orderBy)->get();
$studentsData = array();
foreach ($studentUsers as $key => $user) {
$studentsData[] = array(
'id' => $user->studentWithoutOwner->id,
'roll_number' => (int) $key + 1,
'class_section_id' => $request->new_class_section_id,
'session_year_id' => $request->session_year_id,
);
}
// Upsert Student Data
$this->student->upsert($studentsData, ['id'], ['roll_number', 'class_section_id', 'session_year_id']);
}
if (!empty($failStudentsIds)) {
Students::whereIn('user_id', $failStudentsIds)->update(array(
'session_year_id' => $request->session_year_id,
));
}
// Reactivate Continue Students
$continueStudentUserIds = array_merge($passStudentsIds ?? [], $failStudentsIds ?? []);
if (!empty($continueStudentUserIds)) {
$this->user->builder()->withTrashed()->whereIn('id', $continueStudentUserIds)->update(['status' => 1, 'deleted_at' => null]);
}
if (!empty($leftStudentSIds)) {
// If student leaves, deactivate user AND revert enrollment to the old session
$this->user->builder()->whereIn('id', $leftStudentSIds)->update(['status' => 0, 'deleted_at' => now()]);
$this->student->builder()->whereIn('user_id', $leftStudentSIds)->update([
'class_section_id' => $request->class_section_id,
'session_year_id' => $request->from_session_year_id,
]);
}
$this->promoteStudent->upsert($promoteStudentData, ['class_section_id', 'student_id', 'session_year_id'], ['status', 'result', 'roll_number', 'current_class_section_id', 'current_session_year_id']);
DB::commit();
ResponseService::successResponse("Data Updated Successfully");
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function getPromoteData(Request $request)
{
$response = PromoteStudent::where(['class_section_id' => $request->class_section_id])->get();
return response()->json($response);
}
public function show(Request $request)
{
ResponseService::noPermissionThenRedirect('promote-student-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'ASC');
$search = request('search');
$from_session_year_id = $request->from_session_year_id;
$class_section_id = $request->class_section_id;
$promotion_status = $request->promotion_status;
$sql = $this->student->model()->where('school_id', Auth::user()->school_id)->where(function ($q) use ($class_section_id, $from_session_year_id, $promotion_status) {
if ($promotion_status === '1') {
// Promoted Only
$q->whereHas('promote_student', function ($sq) use ($from_session_year_id, $class_section_id) {
$sq->where('class_section_id', $class_section_id)->where('session_year_id', $from_session_year_id);
});
} elseif ($promotion_status === '0') {
// Pending Only
$q->where(['class_section_id' => $class_section_id, 'session_year_id' => $from_session_year_id])
->whereDoesntHave('promote_student', function ($sq) use ($from_session_year_id, $class_section_id) {
$sq->where('class_section_id', $class_section_id)->where('session_year_id', $from_session_year_id);
});
} else {
// All
$q->where(['class_section_id' => $class_section_id, 'session_year_id' => $from_session_year_id])->orWhereHas('promote_student', function ($sq) use ($from_session_year_id, $class_section_id) {
$sq->where('class_section_id', $class_section_id)->where('session_year_id', $from_session_year_id);
});
}
})->with(['user', 'promote_student' => function ($q) use ($class_section_id, $from_session_year_id) {
$q->where(['class_section_id' => $class_section_id, 'session_year_id' => $from_session_year_id])->with('current_class_section.class.stream', 'current_class_section.section', 'current_class_section.medium');
}])
->where(function ($query) use ($search) {
$query->when($search, function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")
->orWhereHas('user', function ($q) use ($search) {
$q->whereRaw("concat(users.first_name,' ',users.last_name) LIKE '%" . $search . "%'");
});
});
});
$total = $sql->count();
// $sql->orderBy($sort, $order)->skip($offset)->take($limit);
$sql->orderBy($sort, $order);
$res = $sql->get();
$bulkData = array();
$bulkData['total'] = $total;
$rows = array();
$no = 1;
foreach ($res as $row) {
$tempRow = $row->toArray();
$tempRow['no'] = $offset + $no++;
$tempRow['promotion_status'] = $row->promote_student ? 1 : 0;
$tempRow['result'] = $row->promote_student->result ?? '';
$tempRow['status'] = $row->promote_student->status ?? '';
$tempRow['promoted_to'] = ($row->promote_student && $row->promote_student->current_class_section) ? $row->promote_student->current_class_section->full_name : '-';
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
// Calculate School Overall Progress based strictly on session year
$school_promoted = $this->student->model()->where('school_id', Auth::user()->school_id)
->whereHas('promote_student', function ($sq) use ($from_session_year_id) {
$sq->where('session_year_id', $from_session_year_id);
})->count();
$school_pending = $this->student->model()->where('school_id', Auth::user()->school_id)
->where('session_year_id', $from_session_year_id)
->whereDoesntHave('promote_student', function ($sq) use ($from_session_year_id) {
$sq->where('session_year_id', $from_session_year_id);
})->count();
$bulkData['school_total'] = $school_promoted + $school_pending;
$bulkData['school_promoted'] = $school_promoted;
$bulkData['school_pending'] = $school_pending;
return response()->json($bulkData);
}
public function transferStudentIndex()
{
ResponseService::noPermissionThenRedirect('transfer-student-create');
$classSections = $this->classSection->all(['*'], ['class', 'section', 'medium', 'class.stream', 'class.shift']);
$sessionYears = $this->sessionYear->builder()->select(['id', 'name', 'start_date'])->orderBy('start_date', 'asc')->get();
$defaultSessionYear = $this->cache->getDefaultSessionYear();
return view('promote_student.transfer', compact('classSections', 'sessionYears', 'defaultSessionYear'));
}
public function showTransferStudent(Request $request)
{
// ResponseService::noFeatureThenRedirect('Academics Management');
ResponseService::noPermissionThenRedirect('transfer-student-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'ASC');
$search = request('search');
$class_section_id = $request->current_class_section;
// $sessionYear = $request->transfer_session_year_id; // Get Current Session Year
$defaultSessionYear = $this->cache->getDefaultSessionYear();
$sessionYear = $defaultSessionYear->id;
$sql = Students::where(['class_section_id' => $class_section_id, 'session_year_id' => $sessionYear])->whereHas('user', function ($query) {
$query->where('status', 1);
})->with('user')
->where(function ($q) use ($search) {
$q->when($search, function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")
->orWhereHas('user', function ($q) use ($search) {
$q->whereRaw("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) {
$tempRow['no'] = $offset + $no++;
$tempRow['student_id'] = $row->id;
$tempRow['user_id'] = $row->user_id;
$tempRow['name'] = $row->full_name;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function storeTransferStudent(Request $request)
{
// ResponseService::noFeatureThenRedirect('Academics Management');
ResponseService::noAnyPermissionThenSendJson(['transfer-student-list', 'transfer-student-edit']);
$request->validate([
'current_class_section_id' => 'required',
'new_class_section_id' => 'required',
'student_ids' => 'required'
]);
try {
DB::beginTransaction();
// $studentIds = json_decode($request->student_ids);
$studentIds = explode(",", $request->student_ids);
$roll_number_db = $this->student->builder()->select(DB::raw('max(roll_number)'))->where('class_section_id', $request->new_class_section_id)->first();
$roll_number_db = $roll_number_db['max(roll_number)'];
$updateStudent = array();
foreach ($studentIds as $id) {
$updateStudent[] = array(
'id' => $id,
'class_section_id' => $request->new_class_section_id,
'roll_number' => (int) $roll_number_db + 1,
// 'session_year_id' => $request->transfer_session_year_id,
);
}
// foreach ($updateStudent as $student) {
// $user = $this->student->builder()->where('id', $student['id'])->with('user')->first();
// $studentSubject = $this->studentSubject->builder()->where('student_id', $user->user_id)->get();
// if ($studentSubject->count() > 0) {
// foreach ($studentSubject as $subject) {
// $subject->delete();
// }
// }
// }
$user = User::whereHas('student', function ($q) use ($studentIds) {
$q->whereIn('id', $studentIds);
})->get()->pluck('id');
StudentSubject::whereIn('student_id', $user)->delete();
// $studentSubject = $this->studentSubject->builder()->whereIn('student_id', $user)->get();
// if ($studentSubject->count() > 0) {
// foreach ($studentSubject as $subject) {
// $subject->delete();
// }
// }
// $promoteStudentData = $this->promoteStudent->builder()->where('current_session_year_id', $request->transfer_session_year_id)->where('current_class_section_id', $request->current_class_section_id)->get();
// if ($promoteStudentData) {
// foreach ($promoteStudentData as $data) {
// $data->current_class_section_id = $request->new_class_section_id;
// $data->save();
// }
// }
Students::upsert($updateStudent, ['id'], ['class_section_id', 'roll_number']);
// $this->student->upsert($updateStudent, ['id'], ['class_section_id', 'roll_number']);
DB::commit();
ResponseService::successResponse("Data Updated Successfully");
} catch (Throwable $e) {
DB::rollback();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
}