e13df69885
API CI/CD / Validate (composer + pint) (push) Successful in 3m6s
API CI/CD / Test (PHPUnit) (push) Failing after 4m53s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 59s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
107 lines
3.1 KiB
PHP
107 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class PromotionQueue extends BaseModel
|
|
{
|
|
protected $table = 'promotion_queue';
|
|
|
|
protected $fillable = ['student_id', 'from_class_section_id', 'to_class_id', 'to_class_section_id', 'school_year_from', 'school_year_to', 'status', 'created_at', 'updated_at', 'updated_by'];
|
|
|
|
public $timestamps = true;
|
|
|
|
protected $casts = [
|
|
'student_id' => 'integer',
|
|
'from_class_section_id' => 'integer',
|
|
'to_class_id' => 'integer',
|
|
'to_class_section_id' => 'integer',
|
|
'updated_by' => 'integer',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
];
|
|
|
|
/* ============================================================
|
|
* Relationships (optional)
|
|
* ============================================================
|
|
*/
|
|
|
|
public function student(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Student::class, 'student_id');
|
|
}
|
|
|
|
public function fromClassSection(): BelongsTo
|
|
{
|
|
return $this->belongsTo(ClassSection::class, 'from_class_section_id');
|
|
}
|
|
|
|
public function toClassSection(): BelongsTo
|
|
{
|
|
return $this->belongsTo(ClassSection::class, 'to_class_section_id');
|
|
}
|
|
|
|
public function toClass(): BelongsTo
|
|
{
|
|
return $this->belongsTo(SchoolClass::class, 'to_class_id'); // rename model if yours is ClassModel/ClassRoom/etc.
|
|
}
|
|
|
|
/* ============================================================
|
|
* Scopes (reusable filters)
|
|
* ============================================================
|
|
*/
|
|
|
|
public function scopeForStudent(Builder $q, int $studentId): Builder
|
|
{
|
|
return $q->where('student_id', $studentId);
|
|
}
|
|
|
|
public function scopeForSchoolYearTo(Builder $q, string $schoolYearTo): Builder
|
|
{
|
|
return $q->where('school_year_to', $schoolYearTo);
|
|
}
|
|
|
|
public function scopeStatus(Builder $q, string $status): Builder
|
|
{
|
|
return $q->where('status', $status);
|
|
}
|
|
|
|
/* ============================================================
|
|
* Upsert (Laravel style)
|
|
* ============================================================
|
|
*/
|
|
|
|
/**
|
|
* True upsert by (student_id, school_year_to).
|
|
*
|
|
* Returns the saved model, or null if required keys missing.
|
|
*/
|
|
public static function upsertQueue(array $data): ?self
|
|
{
|
|
$studentId = isset($data['student_id']) ? (int) $data['student_id'] : null;
|
|
$yearTo = isset($data['school_year_to']) ? (string) $data['school_year_to'] : null;
|
|
|
|
if (! $studentId || ! $yearTo) {
|
|
return null;
|
|
}
|
|
|
|
// Only update columns that are allowed.
|
|
$payload = array_intersect_key($data, array_flip((new static)->getFillable()));
|
|
|
|
return static::updateOrCreate(
|
|
['student_id' => $studentId, 'school_year_to' => $yearTo],
|
|
$payload
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Optional: keep the same legacy signature (bool result).
|
|
*/
|
|
public static function upsertBool(array $data): bool
|
|
{
|
|
return (bool) static::upsertQueue($data);
|
|
}
|
|
}
|