File "ClassSchoolController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/ClassSchoolController.php
File size: 33.69 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Models\Fee;
use App\Models\Exam;
use App\Models\Syllabus;
use App\Repositories\ClassSchool\ClassSchoolInterface;
use App\Repositories\ClassSection\ClassSectionInterface;
use App\Repositories\ClassSubject\ClassSubjectInterface;
use App\Repositories\ElectiveSubjectGroup\ElectiveSubjectGroupInterface;
use App\Repositories\Medium\MediumInterface;
use App\Repositories\Section\SectionInterface;
use App\Repositories\Semester\SemesterInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\Shift\ShiftInterface;
use App\Repositories\Stream\StreamInterface;
use App\Repositories\Subject\SubjectInterface;
use App\Repositories\Timetable\TimetableInterface;
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 Illuminate\Support\Facades\Validator;
use Throwable;
class ClassSchoolController extends Controller
{
private MediumInterface $medium;
private SectionInterface $section;
private ClassSchoolInterface $class;
private ClassSectionInterface $classSection;
private SubjectInterface $subject;
private ClassSubjectInterface $classSubject;
private ElectiveSubjectGroupInterface $electiveSubjectGroup;
private CachingService $cache;
private SemesterInterface $semester;
private ShiftInterface $shift;
private StreamInterface $stream;
private TimetableInterface $timetable;
public function __construct(MediumInterface $medium, SectionInterface $section, ClassSchoolInterface $class, ClassSectionInterface $classSection, SubjectInterface $subject, ClassSubjectInterface $classSubject, ElectiveSubjectGroupInterface $electiveSubjectGroup, SemesterInterface $semester, CachingService $cache, ShiftInterface $shift, StreamInterface $stream, TimetableInterface $timetable)
{
$this->medium = $medium;
$this->section = $section;
$this->class = $class;
$this->classSection = $classSection;
$this->subject = $subject;
$this->classSubject = $classSubject;
$this->electiveSubjectGroup = $electiveSubjectGroup;
$this->semester = $semester;
$this->cache = $cache;
$this->shift = $shift;
$this->stream = $stream;
$this->timetable = $timetable;
}
public function index()
{
ResponseService::noPermissionThenRedirect('class-list');
$classes = $this->class->builder()->orderBy('id', 'DESC')->with('stream', 'medium', 'sections')->get();
$sections = $this->section->builder()->orderBy('id', 'ASC')->get();
$mediums = $this->medium->builder()->orderBy('id', 'ASC')->get();
$subjects = $this->subject->builder()->orderBy('id', 'ASC')->get();
$semesters = $this->semester->all();
$shifts = $this->shift->active();
$streams = $this->stream->all();
return response(view('class.index', compact('classes', 'sections', 'mediums', 'subjects', 'semesters', 'shifts', 'streams')));
}
public function store(Request $request)
{
ResponseService::noPermissionThenSendJson('class-create');
$validator = Validator::make($request->all(), [
'medium_id' => 'required|numeric',
'name' => [
'required',
new uniqueForSchool('classes', ['name' => $request->name, 'medium_id' => $request->medium_id, 'stream_id' => $request->stream_id, 'shift_id' => $request->shift_id])
],
'stream_id' => 'nullable|array',
'shift_id' => 'nullable|numeric',
'stream_id.*' => 'nullable|numeric',
'section_id' => 'nullable|array',
'section_id.*.*' => 'nullable|numeric',
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
DB::beginTransaction();
// $request->stream_id = $request->stream_id ?? [0];
/* Create Class */
if (!empty($request->stream_id) && $request->stream_id[0] != null) {
foreach ($request->stream_id as $stream) {
$classDetails = [
...$request->all(),
'stream_id' => ($stream != 0) ? $stream : null,
'include_semesters' => $request->include_semesters[$stream] ?? 0,
];
$class = $this->class->create($classDetails);
/* Create Class Sections */
$class_section = array();
if (!empty($request->section_id[$stream])) {
foreach ($request->section_id[$stream] as $section_id) {
$class_section[] = array('class_id' => $class->id, 'section_id' => $section_id, 'medium_id' => $request->medium_id);
}
} else {
$class_section[] = array('class_id' => $class->id, 'medium_id' => $request->medium_id);
}
$this->classSection->createBulk($class_section);
}
} else {
$classDetails = [
...$request->all(),
'stream_id' => null,
'include_semesters' => $request->include_semesters[0] ?? 0,
];
$class = $this->class->create($classDetails);
/* Create Class Sections */
$class_section = array();
if (!empty($request->section_id[0])) {
foreach ($request->section_id[0] as $section_id) {
$class_section[] = array('class_id' => $class->id, 'section_id' => $section_id, 'medium_id' => $request->medium_id);
}
} else {
$class_section[] = array('class_id' => $class->id, 'medium_id' => $request->medium_id);
}
$this->classSection->createBulk($class_section);
}
DB::commit();
ResponseService::successResponse('Data Stored Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function edit($id)
{
ResponseService::noPermissionThenRedirect('class-edit');
$class = $this->class->findById($id, ['*'], ['stream', 'sections', 'core_subjects:id', 'elective_subject_groups.subjects:id']);
$class_section = $class->sections->pluck('id');
$subjects = $this->subject->builder()->where('medium_id', $class->medium_id)->orderBy('id', 'ASC')->get();
$sections = $this->section->builder()->orderBy('id', 'ASC')->get();
$semesters = $this->semester->all();
$shifts = $this->shift->active();
$streams = $this->stream->all();
return response(view('class.edit', compact('class', 'subjects', 'sections', 'class_section', 'id', 'semesters', 'shifts', 'streams')));
}
public function update(Request $request, $id)
{
ResponseService::noPermissionThenRedirect('class-edit');
$validator = Validator::make($request->all(), [
'name' => [
'required',
new uniqueForSchool('classes', ['name' => $request->name, 'medium_id' => $request->medium_id, 'stream_id' => $request->stream_id, 'shift_id' => $request->shift_id], $id)
],
'stream_id' => 'nullable|numeric',
'shift_id' => 'nullable|numeric',
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
DB::beginTransaction();
$sessionYearId = $this->cache->getSessionYear()->id;
// Class Update
$class = $this->class->findById($id, ['*'], ['class_sections']);
$semesterIncluded = $request->include_semesters[0] ?? 0;
if ($class->include_semesters != $semesterIncluded) {
//If include_semester is changed then delete the class subjects
$this->electiveSubjectGroup->builder()->where('class_id', $class->id)->where('session_year_id', $sessionYearId)->delete();
$this->classSubject->builder()->where('class_id', $class->id)->where('session_year_id', $sessionYearId)->delete();
}
// if (count($class->class_sections ?? []) == 0 && count($request->section_id ?? []) == 0) {
// ResponseService::errorResponse("Class Section is Required");
// }
$this->class->update($id, [...$request->all(), 'include_semesters' => $semesterIncluded]);
// Section Update
if (!empty($request->section_id)) {
$class_section = array();
foreach ($request->section_id ?? [] as $section_id) {
$class_section[] = array(
'class_id' => $id,
'section_id' => $section_id,
'medium_id' => $class->medium_id,
'deleted_at' => null
);
}
$this->classSection->upsert($class_section, ['class_id', 'section_id'], ['deleted_at']);
}
// Subjects Update
$coreSubjects = array();
if (!empty($request->core_subject)) {
foreach ($request->core_subject as $row) {
$coreSubjects[] = array('class_id' => $id, 'type' => "Compulsory", 'subject_id' => $row['id'], "elective_subject_group_id" => null, "semester_id" => $row['semester_id'] ?? null);
}
}
// Upsert Elective Subjects
$electiveSubject = [];
if (!empty($request->elective_subject_group)) {
foreach ($request->elective_subject_group as $subjectGroup) {
$electiveSubjectGroup = $this->electiveSubjectGroup->updateOrCreate(
['id' => $subjectGroup['id'],],
[
'total_subjects' => count($subjectGroup['subject']),
'total_selectable_subjects' => $subjectGroup['total_selectable_subjects'],
'class_id' => $id,
"semester_id" => $subjectGroup['semester_id'] ?? null
]
);
foreach ($subjectGroup['subject'] as $subject) {
$electiveSubject[] = array('class_id' => $id, 'type' => "Elective", 'subject_id' => $subject['id'], 'elective_subject_group_id' => $electiveSubjectGroup->id, "semester_id" => $subjectGroup['semester_id'] ?? null);
}
}
}
// Check that If Elective Subjects exists then merge or else store only Core Subjects
$classSubjects = array_merge($coreSubjects, $electiveSubject);
$this->classSubject->upsert($classSubjects, ['class_id', 'subject_id', 'semester_id'], ['type']);
$sessionYearId = $this->cache->getSessionYear()->id;
$this->timetable->builder()->where('session_year_id', $sessionYearId)->whereHas('class_section', function ($q) use ($id) {
$q->where('class_id', $id);
})->delete();
DB::commit();
ResponseService::successResponse('Data Updated Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function show(Request $request)
{
ResponseService::noPermissionThenRedirect('class-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = $request->search;
$showDeleted = $request->show_deleted;
// $currentSemester = $this->cache->getDefaultSemesterData();
$semesters = $this->semester->all();
$sql = $this->class->builder()->with('stream', 'sections', 'medium', 'stream:id,name', 'shift:id,name')
->where(function ($query) use ($search) {
$query->when($search, function ($q) use ($search) {
$q->where('id', 'LIKE', "%$search%")->orwhere('name', 'LIKE', "%$search%")->orWhereHas('sections', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})->orWhereHas('medium', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})->orWhereHas('shift', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})->Owner();
});
})
->when(!empty($showDeleted), function ($q) {
$q->onlyTrashed()->Owner()->with('section');
});
if (!empty($request->medium_id)) {
$sql = $sql->where('medium_id', $request->medium_id);
}
if (!empty($request->shift_id)) {
$sql = $sql->where('shift_id', $request->shift_id);
}
$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) {
if ($request->show_deleted) {
//Show Restore and Hard Delete Buttons
$operate = BootstrapTableService::restoreButton(route('class.restore', $row->id));
$operate .= BootstrapTableService::trashButton(route('class.trash', $row->id));
} else {
//Show Edit and Soft Delete Buttons
$operate = BootstrapTableService::editButton(route('class.edit', $row->id), false);
$operate .= BootstrapTableService::deleteButton(route('class.destroy', $row->id));
}
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
if (empty($showDeleted)) {
$tempRow['section_names'] = $row->sections->pluck('name');
} else {
$tempRow['section_names'] = $row->section->pluck('name');
}
$tempRow['semesters'] = $semesters;
$tempRow['operate'] = $operate;
$tempRow['created_at'] = $row->created_at;
$tempRow['updated_at'] = $row->updated_at;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function destroy($id)
{
ResponseService::noPermissionThenSendJson('class-delete');
try {
DB::beginTransaction();
$class = $this->class->findById($id, ['*'], ['class_sections']);
// Safety Check: Prevent deletion if any historical data exists across any session
$hasSubjects = $this->classSubject->builder()->where('class_id', $id)->exists();
$hasFees = Fee::where('class_id', $id)->exists();
$hasExams = Exam::where('class_id', $id)->exists();
$hasSectionsWithData = false;
if ($class->class_sections) {
foreach ($class->class_sections as $section) {
// Check if students are assigned to this class section in any session
if ($section->students()->exists()) {
$hasSectionsWithData = true;
break;
}
}
}
if ($hasSubjects || $hasFees || $hasExams || $hasSectionsWithData) {
return ResponseService::errorResponse("Cannot delete this class because it is associated with records (subjects, fees, exams, or students) in one or more academic sessions. Please remove those associations first.");
}
if (!empty($class->class_sections)) {
foreach ($class->class_sections as $section) {
$section->delete();
}
}
$this->class->deleteById($id);
DB::commit();
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function restore(int $id)
{
ResponseService::noPermissionThenSendJson('class-delete');
try {
$this->class->findOnlyTrashedById($id)->restore();
$this->classSection->builder()->where('class_id', $id)->restore();
ResponseService::successResponse("Data Restored Successfully");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function trash($id)
{
ResponseService::noPermissionThenSendJson('class-delete');
try {
// Safety Check: Prevent permanent deletion if any historical data exists
$hasSubjects = $this->classSubject->builder()->where('class_id', $id)->exists();
$hasFees = Fee::where('class_id', $id)->exists();
$hasExams = Exam::where('class_id', $id)->exists();
if ($hasSubjects || $hasFees || $hasExams) {
return ResponseService::errorResponse("Cannot delete this class permanently because it is associated with subjects, fees, or exams in academic sessions.");
}
$this->class->findOnlyTrashedById($id)->forceDelete();
ResponseService::successResponse("Data Deleted Permanently");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e, "ClassSchool Controller -> Trash Method", 'cannot_delete_because_data_is_associated_with_other_data');
ResponseService::errorResponse();
}
}
public function classSubjectIndex()
{
ResponseService::noPermissionThenRedirect('class-list');
$classes = $this->class->builder()->orderBy('id', 'DESC')->with('stream', 'medium', 'sections')->get();
$sections = $this->section->builder()->orderBy('id', 'ASC')->get();
$mediums = $this->medium->builder()->orderBy('id', 'ASC')->get();
$subjects = $this->subject->builder()->orderBy('id', 'ASC')->get();
$semesters = $this->semester->all();
$shifts = $this->shift->active();
$streams = $this->stream->all();
return response(view('class-subject.index', compact('classes', 'sections', 'mediums', 'subjects', 'semesters', 'shifts', 'streams')));
}
public function classSubjectEdit($id)
{
ResponseService::noPermissionThenRedirect('class-edit');
$sessionYearId = $this->cache->getSessionYear()->id;
$class = $this->class->findById($id, ['*'], [
'stream',
'sections',
'medium',
'shift',
'core_subjects' => function ($query) use ($sessionYearId) {
$query->wherePivot('session_year_id', $sessionYearId);
},
'elective_subject_groups' => function ($query) use ($sessionYearId) {
$query->where('session_year_id', $sessionYearId)->with(['subjects' => function ($q) use ($sessionYearId) {
$q->where('class_subjects.session_year_id', $sessionYearId);
}]);
}
]);
$subjects = $this->subject->builder()->where('medium_id', $class->medium_id)->orderBy('id', 'ASC')->get();
$semesters = $class->include_semesters ? $this->semester->all() : [];
$syllabus = Syllabus::where('status', 'active')->where('class_id', $id)->get();
return response(view('class-subject.edit', compact('class', 'subjects', 'id', 'semesters', 'syllabus')));
}
public function classSubjectUpdate(Request $request, $id)
{
ResponseService::noPermissionThenRedirect('class-edit');
$validator = Validator::make($request->all(), [
'core_subject' => 'nullable|array',
'core_subject.*.id' => 'required|numeric',
'elective_subject_group' => 'array|nullable',
'elective_subjects.*.subject.*.id' => 'required|array',
'elective_subjects.*.total_selectable_subjects' => 'required|numeric'
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
$sessionYearId = $this->cache->getSessionYear()->id;
$schoolId = Auth::user()->school_id;
$coreSubjects = array();
if (!empty($request->core_subject)) {
foreach ($request->core_subject as $row) {
$coreSubjects[] = array(
'class_id' => $id,
'type' => "Compulsory",
'subject_id' => $row['id'],
"elective_subject_group_id" => null,
"semester_id" => $row['semester_id'] ?? null,
"session_year_id" => $sessionYearId,
"school_id" => $schoolId,
'syllabus_id' => $row['syllabus_id'] ?? null,
);
}
}
// Scope deletion only to the current session year
$this->classSubject->builder()->where('class_id', $id)->where('session_year_id', $sessionYearId)->delete();
// Upsert Elective Subjects
$electiveSubject = [];
if (!empty($request->elective_subject_group)) {
foreach ($request->elective_subject_group as $subjectGroup) {
$electiveSubjectGroup = $this->electiveSubjectGroup->updateOrCreate(
['id' => $subjectGroup['id'],],
[
'total_subjects' => count($subjectGroup['subject']),
'total_selectable_subjects' => $subjectGroup['total_selectable_subjects'],
'class_id' => $id,
"semester_id" => $subjectGroup['semester_id'] ?? null,
"session_year_id" => $sessionYearId,
"school_id" => $schoolId
]
);
foreach ($subjectGroup['subject'] as $subject) {
$electiveSubject[] = array(
'class_id' => $id,
'type' => "Elective",
'subject_id' => $subject['id'],
'elective_subject_group_id' => $electiveSubjectGroup->id,
"semester_id" => $subjectGroup['semester_id'] ?? null,
"session_year_id" => $sessionYearId,
"school_id" => $schoolId,
'syllabus_id' => $subject['syllabus_id'] ?? null,
);
}
}
}
// Check that If Elective Subjects exists then merge or else store only Core Subjects
$classSubjects = array_merge($coreSubjects, $electiveSubject);
foreach ($classSubjects as $subject) {
// Check if the subject exists in the database and is soft-deleted FOR THIS SESSION YEAR
$existingSubject = $this->classSubject->builder()->onlyTrashed()
->where('class_id', $subject['class_id'])
->where('subject_id', $subject['subject_id'])
->where('semester_id', $subject['semester_id'])
->where('session_year_id', $sessionYearId)
->first();
// If the subject exists and is soft-deleted, restore it
if ($existingSubject && $existingSubject->trashed()) {
$existingSubject->restore();
}
}
// Using model's query builder directly to bypass the broken SaaSRepository::upsert loop.
// Unique keys now include session_year_id to match the database's updated unique index.
$this->classSubject->builder()->upsert(
$classSubjects,
['class_id', 'subject_id', 'semester_id', 'session_year_id'],
['type', 'elective_subject_group_id', 'school_id', 'syllabus_id']
);
DB::commit();
ResponseService::successResponse('Data Updated Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function classSubjectList(Request $request)
{
ResponseService::noPermissionThenRedirect('class-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = $request->search;
$showDeleted = $request->show_deleted;
$currentSemester = $this->cache->getDefaultSemesterData();
$semesters = $this->semester->all();
$sessionYearId = $this->cache->getSessionYear()->id;
$sql = $this->class->builder()->with([
'stream',
'sections',
'medium',
'stream:id,name',
'shift:id,name',
'core_subjects' => function ($query) use ($sessionYearId) {
$query->wherePivot('session_year_id', $sessionYearId);
},
'elective_subject_groups' => function ($query) use ($sessionYearId) {
$query->where('session_year_id', $sessionYearId)->with([
'subjects' => function ($q) use ($sessionYearId) {
$q->where('class_subjects.session_year_id', $sessionYearId);
}
]);
},
])->where(function ($query) use ($search) {
$query->when($search, function ($q) use ($search) {
$q->where('id', 'LIKE', "%$search%")->orwhere('name', 'LIKE', "%$search%")->orWhereHas('sections', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})->orWhereHas('medium', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})->Owner();
});
})
->when(!empty($showDeleted), function ($q) {
$q->onlyTrashed()->Owner();
});
if (!empty($request->medium_id)) {
$sql = $sql->where('medium_id', $request->medium_id);
}
if (!empty($request->shift_id)) {
$sql = $sql->where('shift_id', $request->shift_id);
}
if (!empty($request->stream_id)) {
$sql = $sql->where('stream_id', $request->stream_id);
}
if (!empty($request->core_subject_id)) {
$sql = $sql->whereHas('core_subjects', function ($q) use ($request) {
$q->where('id', $request->core_subject_id);
});
}
if (!empty($request->elective_subject_group_id)) {
$sql = $sql->whereHas('elective_subject_groups.subjects', function ($q) use ($request) {
$q->where('id', $request->elective_subject_group_id);
});
}
$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) {
$operate = BootstrapTableService::restoreButton(route('class.restore', $row->id));
} else {
$operate = BootstrapTableService::editButton(route('class.subject.edit', $row->id), false);
}
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$tempRow['section_names'] = $row->sections->pluck('name');
$tempRow['semesters'] = $semesters;
$tempRow['semester_wise_core_subjects'] = array();
// Explicitly filter core subjects by session year
$coreSubjects = $row->core_subjects->filter(function ($data) use ($sessionYearId) {
return $data->pivot->session_year_id == $sessionYearId;
});
// Explicitly filter elective subject groups by session year
$electiveSubjectGroups = $row->elective_subject_groups->filter(function ($data) use ($sessionYearId) {
return $data->session_year_id == $sessionYearId;
});
if ($row->include_semesters && $currentSemester->id) {
$tempRow['core_subjects'] = array_values($coreSubjects->filter(function ($data) use ($currentSemester) {
return $data->pivot->semester_id == $currentSemester->id;
})->toArray());
$tempRow['elective_subject_groups'] = array_values($electiveSubjectGroups->filter(function ($data) use ($currentSemester) {
return $data->semester_id == $currentSemester->id;
})->toArray());
$tempRow['semester_wise_core_subjects'] = $coreSubjects->values()->toArray();
$tempRow['semester_wise_elective_subject_groups'] = $electiveSubjectGroups->values()->toArray();
} else {
$tempRow['core_subjects'] = $coreSubjects->values()->toArray();
$tempRow['elective_subject_groups'] = $electiveSubjectGroups->values()->toArray();
}
$tempRow['operate'] = $operate;
$tempRow['created_at'] = $row->created_at;
$tempRow['updated_at'] = $row->updated_at;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function deleteClassSubject($id)
{
// TODO : Set Permission
try {
DB::beginTransaction();
$class_subject = $this->classSubject->findById($id);
if ($class_subject->type == "Elective") {
$this->electiveSubjectGroup->findById($class_subject->elective_subject_group_id)->decrement('total_subjects');
}
$class_subject->delete();
DB::commit();
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, "ClassSchool Controller ->deleteClassSubject Method", 'cannot_delete_because_data_is_associated_with_other_data');
ResponseService::errorResponse();
}
}
public function deleteClassSubjectGroup($id)
{
// TODO : Set Permission
try {
// Delete Subject Group will automatically delete ClassSubject
$this->electiveSubjectGroup->deleteById($id);
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
ResponseService::logErrorResponse($e, "ClassSchool Controller ->deleteClassSubjectGroup Method", 'cannot_delete_because_data_is_associated_with_other_data');
ResponseService::errorResponse();
}
}
public function classAttendance($id = null)
{
ResponseService::noPermissionThenSendJson('attendance-list');
try {
$sessionYear = $this->cache->getDefaultSessionYear();
$sql = $this->classSection->builder()->select('id', 'section_id', 'class_id')->where('class_id', $id)->with('section', 'class', 'class.medium')
->withCount([
'attendance as present' => function ($q) use ($sessionYear) {
$q->where('type', 1)->where('session_year_id', $sessionYear->id);
}
])
->withCount([
'attendance as absent' => function ($q) use ($sessionYear) {
$q->where('type', 0)->where('session_year_id', $sessionYear->id);
}
])
->withCount([
'attendance' => function ($q) use ($sessionYear) {
$q->where('session_year_id', $sessionYear->id);
}
])
->get();
$data = $sql->map(function ($q) {
if ($q->attendance_count) {
return [
optional($q->section)->name ?? $q->class->full_name,
number_format(($q->present * 100) / $q->attendance_count, 2)
];
}
})->toArray();
$data = array_filter($data);
if (count($data)) {
$attendance = [
'section' => $this->pluck($data, 0),
'data' => $this->pluck($data, 1)
];
} else {
$attendance = [
'section' => ['A', 'B', 'C', 'D'],
'data' => [0, 0, 0, 0]
];
}
ResponseService::successResponse('Data Fetched Successfully', $attendance);
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function pluck($array, $key)
{
return array_map(function ($item) use ($key) {
return $item[$key];
}, $array);
}
}