File "DiaryController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/DiaryController.php
File size: 20.2 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Models\Role;
use App\Models\SubjectTeacher;
use App\Repositories\ClassSection\ClassSectionInterface;
use App\Repositories\Diary\DiaryInterface;
use App\Repositories\DiaryCategory\DiaryCategoryInterface;
use App\Repositories\DiaryStudent\DiaryStudentInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\Student\StudentInterface;
use App\Repositories\Subject\SubjectInterface;
use App\Repositories\SubjectTeacher\SubjectTeacherInterface;
use App\Repositories\User\UserInterface;
use App\Services\BootstrapTableService;
use App\Services\CachingService;
use App\Services\ResponseService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Storage;
use Str;
use Throwable;
class DiaryController extends Controller
{
/**
* Display a listing of the resource.
*/
private ClassSectionInterface $classSection;
private SessionYearInterface $sessionYear;
private DiaryCategoryInterface $diaryCategories;
private SubjectInterface $subject;
private StudentInterface $student;
private UserInterface $user;
private DiaryInterface $diary;
private DiaryStudentInterface $diaryStudent;
private CachingService $cache;
private SubjectTeacherInterface $subjectTeacher;
public function __construct(ClassSectionInterface $classSection, SessionYearInterface $sessionYear, DiaryCategoryInterface $diaryCategories, SubjectInterface $subject, UserInterface $user, StudentInterface $student, CachingService $cache, DiaryInterface $diary, DiaryStudentInterface $diaryStudent, SubjectTeacherInterface $subjectTeacher)
{
$this->classSection = $classSection;
$this->sessionYear = $sessionYear;
$this->diaryCategories = $diaryCategories;
$this->subject = $subject;
$this->user = $user;
$this->student = $student;
$this->cache = $cache;
$this->diary = $diary;
$this->diaryStudent = $diaryStudent;
$this->subjectTeacher = $subjectTeacher;
}
public function index()
{
ResponseService::noPermissionThenRedirect('student-diary-list');
// $class_sections = $this->classSection->all(['*'], ['class', 'class.stream', 'section', 'medium']);
$sessionYearId = $this->cache->getSessionYear()->id;
$class_sections = $this->classSection->builder()->with('section', 'medium')
->with(['class' => function ($q) use ($sessionYearId) {
$q->with('stream', 'shift')
->with(['class_teachers' => function ($query) use ($sessionYearId) {
$query->where('session_year_id', $sessionYearId);
}]);
}])
->with(['subject_teachers' => function ($query) use ($sessionYearId) {
$query->where('session_year_id', $sessionYearId)->groupBy('subject_id')->with('subject');
}])
->get();
$diaryCategories = $this->diaryCategories->all();
$current_user = null;
if (Auth::user()->role == 'Teacher') {
$current_user = Auth::user()->id;
}
// Get current semester data for filtering subjects
$currentSemester = $this->cache->getSemester();
$currentSemesterId = ($currentSemester && isset($currentSemester->id)) ? $currentSemester->id : null;
return view('diary.index', compact('class_sections', 'diaryCategories', 'current_user', 'currentSemesterId'));
}
public function changeSubjectsByClassSection(Request $request)
{
$sessionYearId = $this->cache->getSessionYear()->id;
$class_section_id = $request->class_section_id;
// if ($class_section_id) {
// dd($class_section_id);
// }
$subjectTeachers = $this->subjectTeacher->builder()->where('session_year_id', $sessionYearId)->where('class_section_id', $class_section_id)->with('subject:id,name,type')->get();
return response()->json($subjectTeachers);
}
public function showStudents(Request $request)
{
ResponseService::noPermissionThenRedirect('student-diary-list');
// ResponseService::noPermissionThenRedirect('student-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'ASC');
$search = request('search');
// $class_section_ids = request('class_section_id');
$sessionYearId = $this->cache->getSessionYear()->id;
$sql = $this->student->builder()->where('session_year_id', $sessionYearId)->where(function ($query) {
$query->where('application_type', 'offline')
->orWhere(function ($q) {
$q->where('application_type', 'online')
->where('application_status', 1); // Only online applications with status 1
});
})
->with('user', 'class_section')
->where(function ($query) use ($search) {
$query->when($search, function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->orWhere('roll_number', 'LIKE', "%$search%")
->orWhereHas('user', function ($q) use ($search) {
$q->where('first_name', 'LIKE', "%$search%")
->orwhere('last_name', 'LIKE', "%$search%")
->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'");
});
});
});
//class section filter data
})
->when(request()->filled('class_section_id'), function ($query) {
$query->where('class_section_id', request('class_section_id'));
})
->when(request()->filled('session_year_id'), function ($query) {
$query->where('session_year_id', request('session_year_id'));
});
$user = Auth::user();
if ($user->hasRole('Teacher')) {
$sql->WhereHas('class_section.subject_teachers', function ($query) use ($user) {
$query->where('teacher_id', $user->id);
});
}
if ($request->show_deactive) {
$sql = $sql->whereHas('user', function ($query) {
$query->where('status', 0)->withTrashed();
});
} else {
$sql = $sql->whereHas('user', function ($query) {
$query->where('status', 1);
});
}
$total = $sql->count();
if (!empty($request->class_section_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) {
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
ResponseService::noPermissionThenSendJson('student-diary-create');
$validator = Validator::make($request->all(), [
'diary_category_id' => 'required',
'title' => 'required|string|max:255',
'description' => 'required|string',
'student_class_section_map' => 'required|not_in:0,null',
'date' => 'required|date',
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
DB::beginTransaction();
$studentsClassSections = json_decode($request->student_class_section_map, true);
if (empty($studentsClassSections)) {
ResponseService::errorResponse('Please select Students');
}
$sessionYear = $this->cache->getSessionYear();
$data = [
'diary_category_id' => $request->diary_category_id,
'title' => $request->title,
'user_id' => Auth::id(),
'subject_id' => $request->subject_id,
'session_year_id' => $sessionYear->id,
'description' => $request->description,
'date' => $request->date,
];
$diary = $this->diary->create($data);
/* -------------------------------------------------
| CORE LOGIC (UNCHANGED)
-------------------------------------------------*/
$notifyUser = [];
$studentsData = [];
foreach ($studentsClassSections as $student_id => $class_section_id) {
$studentsData[] = [
'diary_id' => $diary->id,
'student_id' => $student_id,
'class_section_id' => $class_section_id,
];
$notifyUser[] = [
'student_id' => $student_id,
'class_section_id' => $class_section_id,
];
}
$this->diaryStudent->createBulk($studentsData);
/* =================================================
| 🔒 NOTIFICATION FILTER (ONLY CHANGE)
=================================================*/
$finalStudentIds = [];
if (!$request->subject_id) {
// General diary → notify all
$finalStudentIds = collect($notifyUser)->pluck('student_id')->toArray();
} else {
foreach ($notifyUser as $entry) {
$studentId = $entry['student_id'];
$classSectionId = $entry['class_section_id'];
// Resolve class_id
$classId = DB::table('class_sections')
->where('id', $classSectionId)
->value('class_id');
if (!$classId) {
continue;
}
// Resolve class_subject for this class
$classSubject = DB::table('class_subjects')
->where('class_id', $classId)
->where('subject_id', $request->subject_id)
->first();
// Subject not in this section/class → skip
if (!$classSubject) {
continue;
}
// Compulsory → notify
if ($classSubject->type === 'Compulsory') {
$finalStudentIds[] = $studentId;
continue;
}
// Elective → notify only if assigned
$isAssigned = DB::table('student_subjects')
->where('student_id', $studentId)
->where('class_subject_id', $classSubject->id)
->exists();
if ($isAssigned) {
$finalStudentIds[] = $studentId;
}
}
}
/* -------------------------------------------------
| BUILD PAYLOADS (UNCHANGED STRUCTURE)
-------------------------------------------------*/
$students = $this->student->builder()
->whereIn('user_id', $finalStudentIds)
->with('user')
->get(['id', 'user_id', 'guardian_id']);
$allPayloads = [];
$title = "New Diary Note Received";
$body = $request->title;
$type = 'Diary';
foreach ($students as $student) {
$childId = $student->id;
$studentUid = $student->user_id;
$guardianId = $student->guardian_id;
// Guardian
if ($guardianId) {
$allPayloads = array_merge(
$allPayloads,
buildPayloads(
[$guardianId],
$title,
$body,
$type,
[
'child_id' => $childId,
'student_id' => $studentUid,
]
)
);
}
// Student
$allPayloads = array_merge(
$allPayloads,
buildPayloads(
[$studentUid],
$title,
$body,
$type,
[
'student_id' => $studentUid,
]
)
);
}
DB::commit();
if (!empty($allPayloads)) {
sendBulk($allPayloads);
}
ResponseService::successResponse('Data Stored Successfully');
} catch (Throwable $e) {
if (
Str::contains($e->getMessage(), [
'does not exist',
'file_get_contents'
])
) {
DB::commit();
ResponseService::warningResponse(
"Data Stored successfully. But App push notification not send."
);
} else {
DB::rollBack();
ResponseService::logErrorResponse($e, "Diary Controller -> Store Method");
ResponseService::errorResponse();
}
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
// dd(Auth::user()->hasRole('Teacher'));
ResponseService::noPermissionThenRedirect('student-diary-list');
$loggedInUser = Auth::user();
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = request('search');
$class_section_id = request('class_section_id');
$sessionYearId = $this->cache->getSessionYear()->id;
$sql = $this->diary->builder()
->where('session_year_id', $sessionYearId)
->with('session_year', 'diary_category', 'subject', 'diary_students.student', 'diary_students.class_section', 'diary_students.class_section.section', 'diary_students.class_section.medium', 'diary_students.class_section.class.shift', 'diary_students.class_section.class.stream', 'diary_students.class_section.class')
->where(function ($query) use ($search) {
$query->when($search, function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")
->orWhere('description', 'LIKE', "%$search%")
->orWhere('title', 'LIKE', "%$search%")
->orWhereHas('session_year', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})
->orWhereHas('diary_category', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})
->orWhereHas('subject', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})
->orWhereHas('diary_students.student', function ($q) use ($search) {
$q->where('first_name', 'LIKE', "%$search%")
->orWhere('last_name', 'LIKE', "%$search%")
->orWhereRaw("concat(first_name,' ',last_name) LIKE '%" . $search . "%'");
});
});
})
->when(request()->filled('class_section_id'), function ($query) {
$classId = request('class_section_id');
$query->whereHas('diary_students', function ($q) use ($classId) {
$q->where('class_section_id', $classId);
});
})
->when(request()->filled('filter_diary_type'), function ($query) {
$type = request('filter_diary_type');
$query->whereHas('diary_category', function ($q) use ($type) {
$q->where('type', $type);
});
})
->when(!empty($showDeleted), function ($query) {
$query->onlyTrashed();
});
if ($loggedInUser->hasRole('Teacher')) {
if ($class_section_id) {
$subjectIds = SubjectTeacher::where('teacher_id', $loggedInUser->id)->where('class_section_id', $class_section_id ?? null)->pluck('subject_id')->toArray();
$sql->whereIn('subject_id', $subjectIds);
}
}
if ($loggedInUser->hasRole('School Admin')) {
$sql->with('user');
}
$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 = [];
$bulkData['total'] = $total;
$rows = [];
$no = 1;
foreach ($res as $row) {
$stu = trans('Click here to view');
$operate = '';
$operate .= BootstrapTableService::deleteButton(route('diary.destroy', $row->id));
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$tempRow['student'] = $stu;
$tempRow['operate'] = $operate;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
ResponseService::noPermissionThenSendJson('student-diary-delete');
try {
DB::beginTransaction();
// $this->diaryCategory->findOnlyTrashedById($id);
$this->diary->findTrashedById($id)->forceDelete();
DB::commit();
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Diary Controller ->destroy Method');
ResponseService::errorResponse();
}
}
public function removeStudent($diaryId, $id)
{
ResponseService::noPermissionThenSendJson('student-diary-delete');
$studentCount = $this->diaryStudent->builder()
->where(['diary_id' => $diaryId])->count();
// dd('diary id', $diaryId, 'student', $studentCount,'id', $id);
if ($studentCount == 1 || $studentCount < 2) {
$this->destroy($diaryId);
} else {
try {
DB::beginTransaction();
// $this->diaryCategory->findOnlyTrashedById($id);
$this->diaryStudent->findTrashedById($id)->forceDelete();
DB::commit();
ResponseService::successResponse('Student Removed Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, 'Diary Controller ->removeStudent Method');
ResponseService::errorResponse();
}
}
}
}