reconstruction of the project

This commit is contained in:
root
2026-03-08 16:33:24 -04:00
parent 23b7db1107
commit c8de5f7edc
9157 changed files with 77877 additions and 1073823 deletions
+261 -60
View File
@@ -2,12 +2,15 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;
class StudentClass extends BaseModel
{
protected $table = 'student_class';
protected $primaryKey = 'id';
protected $fillable = [
'student_id',
'class_section_id',
@@ -19,91 +22,289 @@ class StudentClass extends BaseModel
'updated_at',
'updated_by',
];
public $timestamps = true;
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
public function getClassSectionNameByStudentId(int $studentId): ?string
protected $casts = [
'student_id' => 'integer',
'school_id' => 'integer',
'class_section_id' => 'integer',
'is_event_only' => 'boolean',
'updated_by' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/* ============================================================
* Relationships (optional but recommended)
* ============================================================
*/
public function student(): BelongsTo
{
return $this->db->table($this->table)
->select('cs.class_section_name')
->join('class_sections as cs', 'cs.class_section_id', '=', 'student_class.class_section_id')
->where('student_class.student_id', $studentId)
->get()
->getRow('class_section_name');
return $this->belongsTo(Student::class, 'student_id');
}
// Custom findAll() method
public function findAll($limit = 0, $offset = 0)
public function classSection(): BelongsTo
{
// Optional: Add custom logic before fetching all records
// For example, you can add default conditions:
// $this->where('semester', 'Fall');
// Then call the parent findAll method to fetch the records
return parent::findAll($limit, $offset);
// Your CI joins on classSection.class_section_id
return $this->belongsTo(ClassSection::class, 'class_section_id', 'class_section_id');
}
// Method to get all students in a specific class section
public function getClassStudents($classSectionId)
public function school(): BelongsTo
{
return $this->where('class_section_id', $classSectionId)->findAll();
return $this->belongsTo(School::class, 'school_id');
}
public function getClassSectionsByStudentId($studentId, string $schoolYear)
public function updater(): BelongsTo
{
// Build the query
$builder = $this->db->table('student_class')
->select('cs.class_section_name')
->join('class_sections as cs', 'student_class.class_section_id', '=', 'cs.class_section_id')
->where('student_class.student_id', $studentId) // Filter by student ID
->where('student_class.class_section_id IS NOT NULL') // Ensure class_section_id is not null
->where('student_class.school_year', $schoolYear); // Filter by school year
// Fetch the result
$result = $builder->get()->getRowArray();
// Check if the result is not null before accessing the 'class_section_name'
if ($result && isset($result['class_section_name'])) {
return $result['class_section_name']; // Return the class_section_name
} else {
return ''; // Return an empty string if no class section is found
}
return $this->belongsTo(User::class, 'updated_by'); // change to Admin if needed
}
/* ============================================================
* Scopes
* ============================================================
*/
public function getStudentsByClassSectionIds(array $classSectionIds)
/**
* Scope: only students active for classes/attendance (joins students).
* Mirrors CI active().
*/
public function scopeActive(Builder $q): Builder
{
return $this->select('students.id as student_id, students.firstname, students.lastname, students.school_id, students.is_new,students.photo_consent ,students.age, student_class.semester, student_class.school_year, student_class.class_section_id')
return $q->select('student_class.*')
->join('students', 'students.id', '=', 'student_class.student_id')
->whereIn('student_class.class_section_id', $classSectionIds)
->where('students.is_active', 1);
}
public function scopeForSection(Builder $q, int $classSectionId): Builder
{
return $q->where('student_class.class_section_id', $classSectionId);
}
public function scopeForYear(Builder $q, ?string $schoolYear): Builder
{
if ($schoolYear === null || trim($schoolYear) === '') return $q;
return $q->where('student_class.school_year', $schoolYear);
}
public function scopeNonEvent(Builder $q): Builder
{
return $q->where('student_class.is_event_only', 0);
}
/* ============================================================
* CI-compatible methods (rewritten Laravel-style)
* ============================================================
*/
public static function getClassSectionNameByStudentId(int $studentId): ?string
{
return DB::table('student_class as sc')
->join('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
->where('sc.student_id', $studentId)
->value('cs.class_section_name');
}
/**
* Get all students in a specific class section (optionally scoped to schoolYear), active students only.
* Mirrors getClassStudents()
*/
public static function getClassStudents(int $classSectionId, ?string $schoolYear = null)
{
return static::query()
->active()
->forSection($classSectionId)
->forYear($schoolYear)
->get();
}
/**
* Return class section names for a student in a given school year.
* Mirrors getClassSectionsByStudentId()
*
* @return array|string
*/
public static function getClassSectionsByStudentId($studentId, string $schoolYear, bool $asArray = false)
{
$names = DB::table('student_class as sc')
->join('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
->where('sc.student_id', $studentId)
->whereNotNull('sc.class_section_id')
->where('sc.school_year', $schoolYear)
->orderBy('cs.class_section_name', 'asc')
->pluck('cs.class_section_name')
->filter(fn ($v) => $v !== null && trim((string)$v) !== '')
->unique()
->values()
->all();
return $asArray ? $names : (!empty($names) ? implode(', ', $names) : '');
}
/**
* Return class section names for a student in a given school year, with optional event flag.
* Mirrors getClassSectionsByStudentIdWithFlags()
*
* @return array|string
*/
public static function getClassSectionsByStudentIdWithFlags($studentId, string $schoolYear, bool $asArray = false)
{
$rows = DB::table('student_class as sc')
->select('cs.class_section_name', 'sc.is_event_only')
->join('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
->where('sc.student_id', $studentId)
->whereNotNull('sc.class_section_id')
->where('sc.school_year', $schoolYear)
->orderBy('cs.class_section_name', 'asc')
->get();
$names = [];
foreach ($rows as $r) {
$name = $r->class_section_name ?? null;
if (!$name) continue;
$isEvent = (int)($r->is_event_only ?? 0) === 1;
$names[] = $isEvent ? ($name . ' (Event)') : $name;
}
$names = array_values(array_unique(array_filter($names)));
return $asArray ? $names : (!empty($names) ? implode(', ', $names) : '');
}
/**
* Return class_section_id values for a student/year.
* Mirrors getClassSectionIdsByStudentId()
*/
public static function getClassSectionIdsByStudentId($studentId, string $schoolYear): array
{
$ids = DB::table('student_class')
->where('student_id', $studentId)
->whereNotNull('class_section_id')
->where('school_year', $schoolYear)
->pluck('class_section_id')
->map(fn ($v) => (int) $v)
->filter(fn ($v) => $v > 0)
->unique()
->values()
->all();
return $ids;
}
/**
* Mirrors getStudentsByClassSectionIds()
* Returns array rows (not models) like CI.
*/
public static function getStudentsByClassSectionIds(array $classSectionIds): array
{
$ids = array_values(array_unique(array_filter(array_map('intval', $classSectionIds))));
if (empty($ids)) return [];
return DB::table('student_class as sc')
->selectRaw('
students.id as student_id,
students.firstname,
students.lastname,
students.school_id,
students.is_new,
students.photo_consent,
students.age,
sc.school_year,
sc.class_section_id
')
->join('students', 'students.id', '=', 'sc.student_id')
->whereIn('sc.class_section_id', $ids)
->where('students.is_active', 1)
->get()
->getResultArray();
->map(fn ($r) => (array) $r)
->all();
}
/**
* Get the class ID (grade) for a specific student.
*
* @param int $studentId
* @return string class_id or 'N/A'
* Mirrors getStudentGrade()
*/
public function getStudentGrade(int $studentId): string
public static function getStudentGrade(int $studentId): string
{
$studentClass = $this->where('student_id', $studentId)
->orderBy('created_at', 'DESC') // in case of multiple entries, get latest
$sc = static::query()
->where('student_id', $studentId)
->where('is_event_only', 0)
->orderByDesc('created_at')
->first();
if ($studentClass && isset($studentClass['class_section_id'])) {
$classSection = $this->db->table('class_sections')
->where('class_section_id', $studentClass['class_section_id'])
->get()
->getRowArray();
return $classSection['class_id'] ?? 'N/A';
if (!$sc || !$sc->class_section_id) {
return 'N/A';
}
log_message('error', "Student class or section not found for student ID: $studentId");
return 'N/A';
$classId = DB::table('classSection')
->where('class_section_id', $sc->class_section_id)
->value('class_id');
return $classId ?: 'N/A';
}
}
/**
* Return true if the student has at least one non-event class assignment for the year.
* Mirrors hasNonEventAssignment()
*/
public static function hasNonEventAssignment(int $studentId, string $schoolYear): bool
{
return static::query()
->where('student_id', $studentId)
->where('school_year', $schoolYear)
->where('is_event_only', 0)
->exists();
}
/**
* Return student counts per class_section_id, optionally scoped to a school year.
* Mirrors getStudentCountsBySection()
*
* @return array<int|string,int> Map of class_section_id => count
*/
public static function getStudentCountsBySection(?string $schoolYear = null): array
{
$q = DB::table('student_class as sc')
->selectRaw('sc.class_section_id, COUNT(*) as total')
->join('students', 'students.id', '=', 'sc.student_id')
->where('students.is_active', 1)
->whereNotNull('sc.class_section_id')
->groupBy('sc.class_section_id');
if ($schoolYear !== null && trim($schoolYear) !== '') {
$q->where('sc.school_year', $schoolYear);
}
$rows = $q->get();
$out = [];
foreach ($rows as $r) {
$cid = $r->class_section_id;
if ($cid === null || $cid === '') continue;
$out[$cid] = (int) ($r->total ?? 0);
}
return $out;
}
/* ============================================================
* Optional validation helper
* ============================================================
*/
public static function rules(bool $updating = false): array
{
$req = $updating ? 'sometimes' : 'required';
return [
'student_id' => [$req, 'integer', 'min:1', 'exists:students,id'],
'school_id' => ['nullable', 'integer', 'min:1'],
'class_section_id' => ['nullable', 'integer'],
'school_year' => [$req, 'string', 'max:20'],
'is_event_only' => ['nullable', 'boolean'],
'description' => ['nullable', 'string', 'max:2000'],
'updated_by' => ['nullable', 'integer'],
];
}
}