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
:
SessionYearController.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace App\Http\Controllers; use App\Repositories\Chat\ChatInterface; use App\Repositories\SchoolSetting\SchoolSettingInterface; use App\Repositories\SessionYear\SessionYearInterface; use App\Rules\uniqueForSchool; use App\Services\BootstrapTableService; use App\Services\CachingService; use App\Services\ResponseService; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; use Carbon\Carbon; use Throwable; class SessionYearController extends Controller { private SessionYearInterface $sessionYear; private CachingService $cache; private SchoolSettingInterface $schoolSettings; private ChatInterface $chat; public function __construct(SessionYearInterface $sessionYear, CachingService $cache, SchoolSettingInterface $schoolSettings, ChatInterface $chat) { $this->sessionYear = $sessionYear; $this->cache = $cache; $this->schoolSettings = $schoolSettings; $this->chat = $chat; } public function index() { ResponseService::noPermissionThenRedirect('session-year-list'); $sessionYears = $this->sessionYear->builder()->orderBy('id', 'DESC')->get(); return view('session_years.index', compact('sessionYears')); } public function store(Request $request) { ResponseService::noPermissionThenSendJson('session-year-create'); $request->validate([ 'name' => ['required', new uniqueForSchool('session_years', 'name')], 'start_date' => 'required|date_format:d-m-Y', 'end_date' => 'required|date_format:d-m-Y|after_or_equal:start_date', 'migrate_session_year_id' => 'nullable|exists:session_years,id', 'migrate_options' => 'nullable|array', 'semester_data' => 'nullable|array', 'semester_data.*.start_date' => 'required_with:semester_data|date_format:d-m-Y', 'semester_data.*.end_date' => 'required_with:semester_data|date_format:d-m-Y|after_or_equal:semester_data.*.start_date' ]); try { $sessionYears = $this->sessionYear->builder()->withTrashed()->get(); foreach ($sessionYears as $sessionYear) { if ( Carbon::createFromFormat('d-m-Y', $request->start_date)->between($sessionYear->original_start_date, $sessionYear->original_end_date) || Carbon::createFromFormat('d-m-Y', $request->end_date)->between($sessionYear->original_start_date, $sessionYear->original_end_date) || Carbon::createFromFormat('d-m-Y', $request->start_date)->lte($sessionYear->original_start_date) && Carbon::createFromFormat('d-m-Y', $request->end_date)->gte($sessionYear->original_end_date) ) { return response()->json(['error' => true, 'message' => __('The session year overlaps with an existing session year. (Can not be overlapped with deleted session year.)')]); } } $data = [ 'name' => $request->name, 'school_id' => Auth::user()->school_id, // required if fillable 'start_date' => Carbon::createFromFormat('d-m-Y', $request->start_date)->format('Y-m-d'), 'end_date' => Carbon::createFromFormat('d-m-Y', $request->end_date)->format('Y-m-d'), 'created_at' => now(), 'updated_at' => now(), ]; $newSessionYearId = DB::table('session_years')->insertGetId($data); if ($request->migrate_session_year_id && $request->migrate_options) { $migrateOptions = $request->migrate_options; // Server-side safeguard: If some classes require semesters, force it in options $mustRequireSemesters = DB::table('classes') ->where('school_id', Auth::user()->school_id) ->where('include_semesters', 1) ->whereNull('deleted_at') ->exists(); if ($mustRequireSemesters && !in_array('semesters', $migrateOptions)) { $migrateOptions[] = 'semesters'; } // Validation: Semester dates must be within new session year dates AND not overlap if ($request->semester_data && in_array('semesters', $migrateOptions)) { $sessionStart = Carbon::createFromFormat('d-m-Y', $request->start_date)->startOfDay(); $sessionEnd = Carbon::createFromFormat('d-m-Y', $request->end_date)->endOfDay(); $semesters = collect($request->semester_data)->map(function ($sem) { return [ 'start' => Carbon::createFromFormat('d-m-Y', $sem['start_date'])->startOfDay(), 'end' => Carbon::createFromFormat('d-m-Y', $sem['end_date'])->endOfDay(), ]; })->sortBy('start')->values(); foreach ($semesters as $index => $sem) { // 1. Check against Session Year boundaries if (!$sem['start']->between($sessionStart, $sessionEnd) || !$sem['end']->between($sessionStart, $sessionEnd)) { return response()->json(['error' => true, 'message' => __('Semester dates must be within the session year range.')]); } // 2. Check overlap with previous semester if ($index > 0) { $prevSem = $semesters[$index - 1]; if ($sem['start']->lte($prevSem['end'])) { return response()->json(['error' => true, 'message' => __('Semester dates cannot overlap with each other.')]); } } } } \App\Jobs\SessionYearMigrationJob::dispatch( Auth::user()->school_id, (int)$request->migrate_session_year_id, (int)$newSessionYearId, $migrateOptions, $request->semester_data ); } $this->cache->removeSchoolCache(config('constants.CACHE.SCHOOL.ALL_SESSION_YEARS')); ResponseService::successResponse('Data Stored Successfully'); } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Session Year Controller -> Store method"); ResponseService::errorResponse(); } } public function update($id, Request $request) { ResponseService::noPermissionThenSendJson('session-year-edit'); $request->validate([ 'name' => ['required', new uniqueForSchool('session_years', 'name', $id)], 'start_date' => 'required|date', 'end_date' => 'required|date|after_or_equal:start_date', ]); try { DB::beginTransaction(); $sessionYears = $this->sessionYear->builder()->withTrashed()->get(); foreach ($sessionYears as $sessionYear) { if ($sessionYear->id != $id) { if ( Carbon::createFromFormat('d-m-Y', $request->start_date)->between($sessionYear->original_start_date, $sessionYear->original_end_date) || Carbon::createFromFormat('d-m-Y', $request->end_date)->between($sessionYear->original_start_date, $sessionYear->original_end_date) || Carbon::createFromFormat('d-m-Y', $request->start_date)->lte($sessionYear->original_start_date) && Carbon::createFromFormat('d-m-Y', $request->end_date)->gte($sessionYear->original_end_date) ) { return response()->json(['error' => true, 'message' => __('The session year overlaps with an existing session year. (Can not be overlapped with deleted session year.)')]); } } } DB::table('session_years') ->where('id', $id) ->update([ 'name' => $request->name, 'start_date' => Carbon::createFromFormat('d-m-Y', $request->start_date)->format('Y-m-d'), 'end_date' => Carbon::createFromFormat('d-m-Y', $request->end_date)->format('Y-m-d'), 'updated_at' => now(), ]); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.SESSION_YEAR")); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.ALL_SESSION_YEARS")); DB::commit(); ResponseService::successResponse('Data Updated Successfully'); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Session Year Controller -> Update method"); ResponseService::errorResponse(); } } public function show() { ResponseService::noPermissionThenRedirect('session-year-list'); $offset = request('offset', 0); $limit = request('limit', 10); $sort = request('sort', 'id'); $order = request('order', 'DESC'); $search = request('search'); $showDeleted = request('show_deleted'); $sql = $this->sessionYear->builder() ->where(function ($query) use ($search) { $query->when($search, function ($query) use ($search) { $query->where('id', 'LIKE', "%$search%") ->orwhere('name', 'LIKE', "%$search%") ->orwhere('start_date', 'LIKE', "%$search%") ->orwhere('end_date', 'LIKE', "%$search%"); }); }) ->when(!empty($showDeleted), function ($query) { $query->onlyTrashed(); }); $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 = ''; if ($showDeleted) { //Show Restore and Hard Delete Buttons $operate .= BootstrapTableService::restoreButton(route('session-year.restore', $row->id)); $operate .= BootstrapTableService::trashButton(route('session-year.trash', $row->id)); } else { //Show Edit and Soft Delete Buttons if (!$row->default) { $operate .= BootstrapTableService::button('fa fa-calendar-check-o', route('session-year.default', $row->id), ['btn-gradient-success', 'default-session-year'], ["title" => trans("Set Default Session Year")]); } $operate .= BootstrapTableService::editButton(route('session-year.update', $row->id)); if (!$row->default) { $operate .= BootstrapTableService::deleteButton(route('session-year.destroy', $row->id)); } } $tempRow = $row->toArray(); $tempRow['no'] = $no++; $tempRow['operate'] = $operate; $rows[] = $tempRow; } $bulkData['rows'] = $rows; return response()->json($bulkData); } public function destroy($id) { ResponseService::noPermissionThenSendJson('session-year-delete'); try { DB::beginTransaction(); $year = $this->sessionYear->findById($id); if ($year->default == 1) { $response = array( 'error' => true, 'message' => trans('default_session_year_cannot_delete') ); } else { $this->sessionYear->deleteById($id); DB::commit(); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.ALL_SESSION_YEARS")); ResponseService::successResponse('Data Deleted Successfully'); } } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e, "Session Year Controller -> Delete method"); ResponseService::errorResponse(); } return response()->json($response); } public function restore(int $id) { ResponseService::noPermissionThenSendJson('session-year-delete'); try { $this->sessionYear->findOnlyTrashedById($id)->restore(); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.ALL_SESSION_YEARS")); ResponseService::successResponse("Data Restored Successfully"); } catch (Throwable $e) { ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function trash($id) { ResponseService::noPermissionThenSendJson('session-year-delete'); try { $this->sessionYear->findOnlyTrashedById($id)->forceDelete(); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.ALL_SESSION_YEARS")); ResponseService::successResponse("Data Deleted Permanently"); } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Session Year Controller -> Trash Method", 'cannot_delete_because_data_is_associated_with_other_data'); ResponseService::errorResponse(); } } public function default($id) { ResponseService::noPermissionThenRedirect('session-year-delete'); try { DB::beginTransaction(); $defaultSessionYear = $this->cache->getDefaultSessionYear(); $this->chat->builder()->whereDate('created_at', '<=', $defaultSessionYear->end_date)->delete(); // Change the Current Default Session Year to Non-Default Session Year $this->sessionYear->builder()->where(['default' => 1])->update(['default' => 0]); // Make new SessionYear as Default Session Year $this->sessionYear->builder()->where('id', $id)->update(['default' => 1]); $data[] = [ "name" => 'session_year', "data" => $id, "type" => "number", ]; $this->schoolSettings->upsert($data, ["name"], ["data"]); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.SESSION_YEAR")); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.SEMESTER")); $this->cache->removeSchoolCache(config("constants.CACHE.SCHOOL.ALL_SESSION_YEARS")); DB::commit(); ResponseService::successResponse("Default Session has been Changed SuccessFully"); } catch (Throwable $e) { DB::rollBack(); ResponseService::logErrorResponse($e); ResponseService::errorResponse(); } } public function setSessionYear(Request $request) { $request->validate([ 'session_year_id' => 'required|numeric' ]); $this->cache->setSessionYear($request->session_year_id); return response()->json(['error' => false, 'message' => __('Session year changed successfully.')]); } public function getSemesters($session_year_id) { try { $semesters = DB::table('semesters') ->where('session_year_id', $session_year_id) ->where('school_id', Auth::user()->school_id) ->whereNull('deleted_at') ->get(['id', 'name', 'start_date', 'end_date']); $mustRequireSemesters = DB::table('classes') ->where('school_id', Auth::user()->school_id) ->where('include_semesters', 1) ->whereNull('deleted_at') ->exists(); return response()->json([ 'semesters' => $semesters, 'must_require_semesters' => $mustRequireSemesters ]); } catch (Throwable $e) { ResponseService::logErrorResponse($e, "Session Year Controller -> getSemesters method"); return response()->json(['error' => true, 'message' => trans('error_occurred')], 500); } } }