add projet
This commit is contained in:
+150
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\View;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Student;
|
||||
use App\Models\Teacher;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ClassController extends Controller
|
||||
{
|
||||
protected ClassSection $classSection;
|
||||
protected Student $student;
|
||||
protected Teacher $teacher;
|
||||
protected Configuration $config;
|
||||
protected ?string $semester;
|
||||
protected ?string $schoolYear;
|
||||
|
||||
public function __construct(
|
||||
ClassSection $classSection,
|
||||
Student $student,
|
||||
Teacher $teacher,
|
||||
Configuration $config
|
||||
) {
|
||||
$this->classSection = $classSection;
|
||||
$this->student = $student;
|
||||
$this->teacher = $teacher;
|
||||
$this->config = $config;
|
||||
|
||||
$this->semester = $this->config->getConfig('semester');
|
||||
$this->schoolYear = $this->config->getConfig('school_year');
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
$classSections = $this->classSection
|
||||
->newQuery()
|
||||
->orderBy('class_section_name', 'ASC')
|
||||
->get();
|
||||
|
||||
return view('administrator.class_section', [
|
||||
'classsection' => $classSections,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('administrator.create_class');
|
||||
}
|
||||
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$data = $request->only(['name', 'description']);
|
||||
// TODO: persist the payload once the backing model/table columns are finalized.
|
||||
|
||||
return redirect()->to('/administrator/classes')->with([
|
||||
'payload' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(int $id): View
|
||||
{
|
||||
return view('administrator.edit_class', [
|
||||
'class' => $this->classSection->find($id),
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateClass(Request $request, int $id): RedirectResponse
|
||||
{
|
||||
$data = $request->only(['name', 'description']);
|
||||
// TODO: persist the payload once the backing model/table columns are finalized.
|
||||
|
||||
return redirect()->to('/administrator/classes')->with([
|
||||
'payload' => $data,
|
||||
'id' => $id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroyClass(int $id): RedirectResponse
|
||||
{
|
||||
// TODO: remove the record once the backing model/table columns are finalized.
|
||||
|
||||
return redirect()->to('/administrator/classes')->with([
|
||||
'deleted_id' => $id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function addClasses(): RedirectResponse
|
||||
{
|
||||
$classes = [
|
||||
['class_name' => 'Class 1', 'teacher_id' => 1, 'schedule' => 'Monday 9:00 AM - 10:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 2', 'teacher_id' => 2, 'schedule' => 'Tuesday 9:00 AM - 10:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 3', 'teacher_id' => 3, 'schedule' => 'Wednesday 9:00 AM - 10:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 4', 'teacher_id' => 4, 'schedule' => 'Thursday 9:00 AM - 10:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 5', 'teacher_id' => 5, 'schedule' => 'Friday 9:00 AM - 10:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 6', 'teacher_id' => 6, 'schedule' => 'Monday 10:00 AM - 11:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 7', 'teacher_id' => 7, 'schedule' => 'Tuesday 10:00 AM - 11:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 8', 'teacher_id' => 8, 'schedule' => 'Wednesday 10:00 AM - 11:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Class 9', 'teacher_id' => 9, 'schedule' => 'Thursday 10:00 AM - 11:00 AM', 'capacity' => 30],
|
||||
['class_name' => 'Youth', 'teacher_id' => 10, 'schedule' => 'Friday 10:00 AM - 11:00 AM', 'capacity' => 30],
|
||||
];
|
||||
|
||||
DB::transaction(function () use ($classes) {
|
||||
foreach ($classes as $class) {
|
||||
DB::table('classes')->insert($class);
|
||||
}
|
||||
});
|
||||
|
||||
return redirect()->to('/parent/classes')->with('success', 'Classes added successfully.');
|
||||
}
|
||||
|
||||
public function classAttendance(int $classSectionId): RedirectResponse|View
|
||||
{
|
||||
$teacherId = (int) (session()->get('user_id') ?? 0);
|
||||
if ($teacherId <= 0) {
|
||||
return redirect()->to('/teacher/classes')->with('error', 'Missing teacher session.');
|
||||
}
|
||||
|
||||
$teacherData = $this->teacher->find($teacherId);
|
||||
|
||||
$studentsData = $this->student->newQuery()
|
||||
->join('student_class', 'students.id', '=', 'student_class.student_id')
|
||||
->leftJoin('class_sections', 'class_sections.id', '=', 'student_class.class_section_id')
|
||||
->where('student_class.class_section_id', $classSectionId)
|
||||
->select('students.*', 'student_class.class_section_id', 'class_sections.class_section_name')
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
$className = $studentsData[0]['class_section_name'] ?? 'Class Name Not Available';
|
||||
|
||||
if (empty($teacherData) || empty($studentsData)) {
|
||||
return redirect()->to('/teacher/classes')->with('error', 'No data found for this class.');
|
||||
}
|
||||
$teacherFirst = $teacherData['teacher_first'] ?? $teacherData['firstname'] ?? '';
|
||||
$teacherLast = $teacherData['teacher_last'] ?? $teacherData['lastname'] ?? '';
|
||||
|
||||
return view('teacher.classes', [
|
||||
'teacher_name' => trim($teacherFirst . ' ' . $teacherLast),
|
||||
'students' => $studentsData,
|
||||
'class_name' => $className,
|
||||
'semester' => $this->semester,
|
||||
'class_section_id' => $classSectionId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+545
@@ -0,0 +1,545 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\View;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ClassPrepAdjustment;
|
||||
use App\Models\ClassPreparationLog;
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\StudentClass;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ClassPreparationController extends Controller
|
||||
{
|
||||
protected StudentClass $studentClass;
|
||||
protected ClassPreparationLog $prepLog;
|
||||
protected ClassSection $classSection;
|
||||
protected Configuration $config;
|
||||
protected ClassPrepAdjustment $adjustment;
|
||||
protected ?string $schoolYear;
|
||||
protected ?string $semester;
|
||||
|
||||
private array $allowedPrepCategories = [
|
||||
'Grade Box',
|
||||
'Large Table',
|
||||
'Regular Chair',
|
||||
'Small Chair',
|
||||
'Small Table',
|
||||
'Teacher Chair',
|
||||
'Trash Bin',
|
||||
'White Board',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
StudentClass $studentClass,
|
||||
ClassPreparationLog $prepLog,
|
||||
ClassSection $classSection,
|
||||
Configuration $config,
|
||||
ClassPrepAdjustment $adjustment
|
||||
) {
|
||||
$this->studentClass = $studentClass;
|
||||
$this->prepLog = $prepLog;
|
||||
$this->classSection = $classSection;
|
||||
$this->config = $config;
|
||||
$this->adjustment = $adjustment;
|
||||
|
||||
$this->schoolYear = $this->config->getConfig('school_year');
|
||||
$this->semester = $this->config->getConfig('semester');
|
||||
}
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$schoolYear = (string) ($request->query('school_year') ?? $this->schoolYear ?? '');
|
||||
$semParam = $request->query('semester');
|
||||
$semester = is_string($semParam) && $semParam !== '' ? $semParam : (string) ($this->semester ?? '');
|
||||
$allowed = $this->allowedPrepCategories;
|
||||
|
||||
$classSections = $this->studentClass->newQuery()
|
||||
->selectRaw('class_section_id, COUNT(DISTINCT student_id) AS student_count')
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $semester)
|
||||
->groupBy('class_section_id')
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
$inventoryMap = $this->buildInventoryMap($schoolYear, $semester);
|
||||
|
||||
$requiredTotals = array_fill_keys($allowed, 0);
|
||||
$prepResults = [];
|
||||
|
||||
foreach ($classSections as $section) {
|
||||
$classSectionId = (string) ($section['class_section_id'] ?? '');
|
||||
$studentCount = (int) ($section['student_count'] ?? 0);
|
||||
$classLevel = $this->getClassLevelBySection($classSectionId);
|
||||
$className = $this->classSection->getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;
|
||||
|
||||
$baseItems = $this->calculatePrepItems($studentCount, $classLevel, $classSectionId);
|
||||
|
||||
$rawAdjustments = $this->adjustment->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('adjustable', 1)
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
$adjMap = ['Large Table' => 0, 'Small Table' => 0];
|
||||
|
||||
foreach ($rawAdjustments as $adjustment) {
|
||||
$item = $adjustment['item_name'] ?? '';
|
||||
$delta = (int) ($adjustment['adjustment'] ?? 0);
|
||||
|
||||
if (array_key_exists($item, $adjMap)) {
|
||||
$adjMap[$item] = $delta;
|
||||
}
|
||||
|
||||
if (isset($baseItems[$item])) {
|
||||
$baseItems[$item] = max(0, (int) $baseItems[$item] + $delta);
|
||||
} elseif (in_array($item, $allowed, true)) {
|
||||
$baseItems[$item] = max(0, $delta);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($allowed as $category) {
|
||||
$requiredTotals[$category] += (int) ($baseItems[$category] ?? 0);
|
||||
}
|
||||
|
||||
$oldSnap = $this->prepLog->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->orderBy('created_at', 'DESC')
|
||||
->first();
|
||||
|
||||
$oldPrep = $oldSnap ? json_decode($oldSnap['prep_data'] ?? '[]', true) : [];
|
||||
$hasChanged = $this->hasPrepChanged($baseItems, $oldPrep);
|
||||
|
||||
$prepResults[] = [
|
||||
'class_section' => $className,
|
||||
'class_section_id' => $classSectionId,
|
||||
'student_count' => $studentCount,
|
||||
'class_level' => $classLevel,
|
||||
'prep_items' => $baseItems,
|
||||
'needs_print' => $hasChanged,
|
||||
'last_printed_at' => $oldSnap['created_at'] ?? null,
|
||||
'adjustments' => $adjMap,
|
||||
];
|
||||
}
|
||||
|
||||
$shortages = [];
|
||||
foreach ($requiredTotals as $item => $required) {
|
||||
$available = (int) ($inventoryMap[$item] ?? 0);
|
||||
if ($available < (int) $required) {
|
||||
$shortages[$item] = (int) $required - $available;
|
||||
}
|
||||
}
|
||||
|
||||
return view('class_prep/list', [
|
||||
'prepResults' => $prepResults,
|
||||
'schoolYear' => $schoolYear,
|
||||
'semester' => $semester,
|
||||
'shortages' => $shortages,
|
||||
'totalNeeded' => $requiredTotals,
|
||||
'available' => $inventoryMap,
|
||||
]);
|
||||
}
|
||||
|
||||
public function saveAdjustment(Request $request): RedirectResponse
|
||||
{
|
||||
$data = $request->all();
|
||||
$sectionId = (string) ($data['class_section_id'] ?? '');
|
||||
$schoolYear = (string) ($data['school_year'] ?? $this->schoolYear ?? '');
|
||||
$adjustments = is_array($data['adjustments'] ?? null) ? $data['adjustments'] : [];
|
||||
|
||||
foreach ($adjustments as $itemName => $adjustment) {
|
||||
$row = $this->adjustment->newQuery()
|
||||
->where('class_section_id', $sectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('item_name', $itemName)
|
||||
->first();
|
||||
|
||||
if ($row) {
|
||||
$this->adjustment->update($row['id'], [
|
||||
'adjustment' => (int) $adjustment,
|
||||
'adjustable' => 1,
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->adjustment->insert([
|
||||
'class_section_id' => $sectionId,
|
||||
'item_name' => $itemName,
|
||||
'adjustment' => (int) $adjustment,
|
||||
'school_year' => $schoolYear,
|
||||
'adjustable' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->to('/class-prep?school_year=' . urlencode($schoolYear))
|
||||
->with('success', 'Adjustments saved successfully.');
|
||||
}
|
||||
|
||||
public function print(string $classSectionId, string $schoolYear): View
|
||||
{
|
||||
$className = $this->classSection->getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;
|
||||
|
||||
$studentRow = $this->studentClass->newQuery()
|
||||
->selectRaw('COUNT(DISTINCT student_id) AS cnt')
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $this->semester)
|
||||
->first();
|
||||
|
||||
$studentCount = (int) ($studentRow['cnt'] ?? 0);
|
||||
$classLevel = $this->getClassLevelBySection($classSectionId);
|
||||
$items = $this->calculatePrepItems($studentCount, $classLevel, $classSectionId);
|
||||
|
||||
$rawAdjustments = $this->adjustment->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('adjustable', 1)
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
foreach ($rawAdjustments as $adjustment) {
|
||||
$item = $adjustment['item_name'] ?? '';
|
||||
$delta = (int) ($adjustment['adjustment'] ?? 0);
|
||||
if (isset($items[$item])) {
|
||||
$items[$item] = max(0, (int) $items[$item] + $delta);
|
||||
}
|
||||
}
|
||||
|
||||
$this->prepLog->insert([
|
||||
'class_section_id' => $classSectionId,
|
||||
'class_section' => $className,
|
||||
'school_year' => $schoolYear,
|
||||
'prep_data' => json_encode($items),
|
||||
'created_at' => utc_now(),
|
||||
]);
|
||||
|
||||
return view('class_prep/print', [
|
||||
'classSectionId' => $classSectionId,
|
||||
'classSection' => $className,
|
||||
'schoolYear' => $schoolYear,
|
||||
'prepItems' => $items,
|
||||
]);
|
||||
}
|
||||
|
||||
public function apiList(Request $request): JsonResponse
|
||||
{
|
||||
$schoolYear = (string) ($request->query('school_year') ?? $this->schoolYear ?? '');
|
||||
$allowed = $this->allowedPrepCategories;
|
||||
|
||||
$classSections = $this->studentClass->newQuery()
|
||||
->selectRaw('class_section_id, COUNT(DISTINCT student_id) AS student_count')
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $this->semester)
|
||||
->groupBy('class_section_id')
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
$inventoryMap = $this->buildInventoryMap($schoolYear, $this->semester);
|
||||
|
||||
$requiredTotals = array_fill_keys($allowed, 0);
|
||||
$results = [];
|
||||
|
||||
foreach ($classSections as $row) {
|
||||
$classSectionId = (string) ($row['class_section_id'] ?? '');
|
||||
$studentCount = (int) ($row['student_count'] ?? 0);
|
||||
$classLevel = $this->getClassLevelBySection($classSectionId);
|
||||
$className = $this->classSection->getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;
|
||||
|
||||
$baseItems = $this->calculatePrepItems($studentCount, $classLevel, $classSectionId);
|
||||
|
||||
$rawAdjustments = $this->adjustment->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('adjustable', 1)
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
$adjMap = ['Large Table' => 0, 'Small Table' => 0];
|
||||
|
||||
foreach ($rawAdjustments as $adjustment) {
|
||||
$item = $adjustment['item_name'] ?? '';
|
||||
$delta = (int) ($adjustment['adjustment'] ?? 0);
|
||||
if (array_key_exists($item, $adjMap)) {
|
||||
$adjMap[$item] = $delta;
|
||||
}
|
||||
if (isset($baseItems[$item])) {
|
||||
$baseItems[$item] = max(0, (int) $baseItems[$item] + $delta);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($allowed as $cat) {
|
||||
$requiredTotals[$cat] += (int) ($baseItems[$cat] ?? 0);
|
||||
}
|
||||
|
||||
$oldSnap = $this->prepLog->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->orderBy('created_at', 'DESC')
|
||||
->first();
|
||||
|
||||
$oldPrep = $oldSnap ? json_decode($oldSnap['prep_data'] ?? '[]', true) : [];
|
||||
$hasChanged = $this->hasPrepChanged($baseItems, $oldPrep);
|
||||
|
||||
$results[] = [
|
||||
'class_section' => $className,
|
||||
'class_section_id' => $classSectionId,
|
||||
'student_count' => $studentCount,
|
||||
'class_level' => $classLevel,
|
||||
'prep_items' => $baseItems,
|
||||
'needs_print' => $hasChanged,
|
||||
'last_printed_at' => $oldSnap['created_at'] ?? null,
|
||||
'adjustments' => $adjMap,
|
||||
];
|
||||
}
|
||||
|
||||
$shortages = [];
|
||||
foreach ($requiredTotals as $item => $required) {
|
||||
$available = (int) ($inventoryMap[$item] ?? 0);
|
||||
if ($available < (int) $required) {
|
||||
$shortages[$item] = (int) $required - $available;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'schoolYear' => $schoolYear,
|
||||
'results' => $results,
|
||||
'totals' => $requiredTotals,
|
||||
'shortages' => $shortages,
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_token(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function apiMarkPrinted(Request $request): JsonResponse
|
||||
{
|
||||
$schoolYear = (string) ($request->post('school_year') ?? $this->schoolYear ?? '');
|
||||
$ids = $request->post('class_section_ids', []);
|
||||
if (!is_array($ids)) {
|
||||
$ids = $ids ? [$ids] : [];
|
||||
}
|
||||
$ids = array_values(array_unique(array_filter(array_map('strval', $ids))));
|
||||
|
||||
$count = 0;
|
||||
foreach ($ids as $classSectionId) {
|
||||
$studentRow = $this->studentClass->newQuery()
|
||||
->selectRaw('COUNT(DISTINCT student_id) AS cnt')
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $this->semester)
|
||||
->first();
|
||||
|
||||
$studentCount = (int) ($studentRow['cnt'] ?? 0);
|
||||
$classLevel = $this->getClassLevelBySection($classSectionId);
|
||||
$className = $this->classSection->getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;
|
||||
$items = $this->calculatePrepItems($studentCount, $classLevel, $classSectionId);
|
||||
|
||||
$rawAdjustments = $this->adjustment->newQuery()
|
||||
->where('class_section_id', $classSectionId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('adjustable', 1)
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
foreach ($rawAdjustments as $adjustment) {
|
||||
$item = $adjustment['item_name'] ?? '';
|
||||
$delta = (int) ($adjustment['adjustment'] ?? 0);
|
||||
if (isset($items[$item])) {
|
||||
$items[$item] = max(0, (int) $items[$item] + $delta);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->prepLog->insert([
|
||||
'class_section_id' => $classSectionId,
|
||||
'class_section' => $className,
|
||||
'school_year' => $schoolYear,
|
||||
'prep_data' => json_encode($items),
|
||||
'created_at' => utc_now(),
|
||||
]);
|
||||
$count++;
|
||||
} catch (\Throwable $e) {
|
||||
// ignore and continue to next section
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'updated' => $count,
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_token(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function getTeacherCountForSection(string $classSectionId, ?string $schoolYear = null): int
|
||||
{
|
||||
$schoolYear = $schoolYear ?? $this->schoolYear;
|
||||
|
||||
$row = DB::table('teacher_class')
|
||||
->selectRaw('COUNT(*) AS cnt')
|
||||
->where('class_section_id', $classSectionId)
|
||||
->whereIn('position', ['main', 'ta'])
|
||||
->where('school_year', $schoolYear)
|
||||
->first();
|
||||
|
||||
return (int) ($row->cnt ?? 0);
|
||||
}
|
||||
|
||||
private function calculatePrepItems(int $students, int $classLevel, string $classSectionId): array
|
||||
{
|
||||
$allowed = $this->allowedPrepCategories;
|
||||
$items = array_fill_keys($allowed, 0);
|
||||
|
||||
$categories = DB::table('inventory_categories')
|
||||
->select('name', 'grade_min', 'grade_max')
|
||||
->where('type', 'classroom')
|
||||
->whereIn('name', $allowed)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->toArray();
|
||||
|
||||
$isLowerGrades = in_array($classLevel, [1, 2], true);
|
||||
$teacherCount = $this->getTeacherCountForSection($classSectionId);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$name = $category['name'] ?? '';
|
||||
$gradeMin = $category['grade_min'];
|
||||
$gradeMax = $category['grade_max'];
|
||||
|
||||
if ($gradeMin !== null && $classLevel < (int) $gradeMin) {
|
||||
$items[$name] = 0;
|
||||
continue;
|
||||
}
|
||||
if ($gradeMax !== null && $classLevel > (int) $gradeMax) {
|
||||
$items[$name] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
$qty = 0;
|
||||
switch (strtolower($name)) {
|
||||
case 'small table':
|
||||
$qty = $isLowerGrades ? (int) ceil($students / 3) : 0;
|
||||
break;
|
||||
case 'large table':
|
||||
$qty = $isLowerGrades ? 0 : (int) ceil($students / 4);
|
||||
break;
|
||||
case 'small chair':
|
||||
$qty = $isLowerGrades ? $students : 0;
|
||||
break;
|
||||
case 'regular chair':
|
||||
$qty = $isLowerGrades ? 0 : $students;
|
||||
break;
|
||||
case 'teacher chair':
|
||||
$qty = $teacherCount;
|
||||
break;
|
||||
case 'trash bin':
|
||||
case 'white board':
|
||||
case 'grade box':
|
||||
$qty = 1;
|
||||
break;
|
||||
default:
|
||||
$qty = 0;
|
||||
}
|
||||
|
||||
if (array_key_exists($name, $items)) {
|
||||
$items[$name] = $qty;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function hasPrepChanged(array $new, array $old): bool
|
||||
{
|
||||
ksort($new);
|
||||
ksort($old);
|
||||
|
||||
return json_encode($new) !== json_encode($old);
|
||||
}
|
||||
|
||||
private function buildInventoryMap(string $schoolYear, string $semester): array
|
||||
{
|
||||
$allowed = $this->allowedPrepCategories;
|
||||
$inventoryMap = array_fill_keys($allowed, 0);
|
||||
|
||||
$queries = [
|
||||
DB::table('inventory_items as ii')
|
||||
->selectRaw('ic.name AS item_name, COALESCE(SUM(ii.good_qty),0) AS available')
|
||||
->join('inventory_categories as ic', 'ic.id', '=', 'ii.category_id')
|
||||
->where('ii.type', 'classroom')
|
||||
->where('ii.school_year', $schoolYear)
|
||||
->where('ii.semester', $semester)
|
||||
->whereIn('ic.name', $allowed)
|
||||
->groupBy('ic.name'),
|
||||
DB::table('inventory_items')
|
||||
->selectRaw('name AS item_name, COALESCE(SUM(good_qty),0) AS available')
|
||||
->where('type', 'classroom')
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $semester)
|
||||
->whereIn('name', $allowed)
|
||||
->groupBy('name'),
|
||||
DB::table('inventory_items as ii')
|
||||
->selectRaw('ic.name AS item_name, COALESCE(SUM(CASE WHEN ii.`condition`="good" THEN ii.quantity ELSE 0 END),0) AS available')
|
||||
->join('inventory_categories as ic', 'ic.id', '=', 'ii.category_id')
|
||||
->where('ii.type', 'classroom')
|
||||
->where('ii.school_year', $schoolYear)
|
||||
->where('ii.semester', $semester)
|
||||
->whereIn('ic.name', $allowed)
|
||||
->groupBy('ic.name'),
|
||||
DB::table('inventory_items')
|
||||
->selectRaw('name AS item_name, COALESCE(SUM(CASE WHEN `condition`="good" THEN quantity ELSE 0 END),0) AS available')
|
||||
->where('type', 'classroom')
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $semester)
|
||||
->whereIn('name', $allowed)
|
||||
->groupBy('name'),
|
||||
];
|
||||
|
||||
foreach ($queries as $query) {
|
||||
foreach ($query->get()->toArray() as $row) {
|
||||
$row = (array) $row;
|
||||
$name = (string) ($row['item_name'] ?? $row['name'] ?? '');
|
||||
$val = (int) ($row['available'] ?? 0);
|
||||
|
||||
if ($name !== '' && isset($inventoryMap[$name])) {
|
||||
$inventoryMap[$name] = max($inventoryMap[$name], $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $inventoryMap;
|
||||
}
|
||||
|
||||
private function getClassLevelBySection(string $classSectionId): int
|
||||
{
|
||||
if (preg_match('/^(kg|k)(\b|[^a-z0-9])/i', $classSectionId)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$numeric = (int) preg_replace('/\D/', '', $classSectionId);
|
||||
if ($numeric > 0 && $numeric < 30) {
|
||||
$firstDigit = (int) substr((string) $numeric, 0, 1);
|
||||
return match ($firstDigit) {
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
default => 3,
|
||||
};
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\View;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Role;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class DashboardRedirectController extends Controller
|
||||
{
|
||||
public function __construct(protected Role $role)
|
||||
{
|
||||
}
|
||||
|
||||
public function dashboard(): RedirectResponse
|
||||
{
|
||||
$session = session();
|
||||
$roles = $session->get('roles') ?? [];
|
||||
|
||||
if (empty($roles) && $session->has('role')) {
|
||||
$roles = [$session->get('role')];
|
||||
}
|
||||
|
||||
return $this->redirectToDashboard($roles);
|
||||
}
|
||||
|
||||
private function redirectToDashboard(array $roles): RedirectResponse
|
||||
{
|
||||
if (empty($roles)) {
|
||||
log_message('error', 'Empty roles array passed to redirectToDashboard.');
|
||||
return redirect()->to('/landing_page/guest_dashboard');
|
||||
}
|
||||
|
||||
$rows = $this->role->findByNamesOrSlugs($roles);
|
||||
|
||||
if (!empty($rows)) {
|
||||
$route = $rows[0]['dashboard_route'] ?? '/landing_page/guest_dashboard';
|
||||
log_message('debug', 'Redirecting user to: ' . $route);
|
||||
return redirect()->to($route);
|
||||
}
|
||||
|
||||
log_message('warning', 'No matching role found. Redirecting to guest dashboard.');
|
||||
return redirect()->to('/landing_page/guest_dashboard');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user