Files
alrahma_sunday_school_api/app/Models/ScoreComment.php
T
2026-06-09 01:03:53 -04:00

175 lines
5.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ScoreComment extends BaseModel
{
protected $table = 'score_comments';
/**
* legacy: timestamps disabled (created_at handled by DB default).
* Keep disabled in Laravel too.
*/
public $timestamps = true;
/**
* If your DB uses created_at as default timestamp and you want Laravel
* to treat it as a date, keep it in casts below.
*/
protected $fillable = [
'student_id',
'class_section_id',
'score_type',
'semester',
'school_year',
'comment',
'comment_review',
'reviewed_by',
'commented_by',
'created_at',
];
protected $casts = [
'student_id' => 'integer',
'class_section_id' => 'integer',
'reviewed_by' => 'integer',
'commented_by' => 'integer',
'created_at' => 'datetime',
// If comment_review is a tinyint(1) flag in DB, boolean cast helps
'comment_review' => 'boolean',
];
/* ============================================================
* Relationships (optional)
* ============================================================
*/
public function student(): BelongsTo
{
return $this->belongsTo(Student::class, 'student_id');
}
public function classSection(): BelongsTo
{
return $this->belongsTo(ClassSection::class, 'class_section_id');
}
public function reviewer(): BelongsTo
{
// Change Admin/User model to match your app
return $this->belongsTo(Admin::class, 'reviewed_by');
}
public function commenter(): BelongsTo
{
// Change Admin/User model to match your app
return $this->belongsTo(Admin::class, 'commented_by');
}
/* ============================================================
* Scopes
* ============================================================
*/
public function scopeForStudent(Builder $q, int $studentId): Builder
{
return $q->where('student_id', $studentId);
}
public function scopeForClassSection(Builder $q, int $classSectionId): Builder
{
return $q->where('class_section_id', $classSectionId);
}
public function scopeForTerm(Builder $q, string $schoolYear, string $semester): Builder
{
return $q->where('school_year', $schoolYear)
->where('semester', $semester);
}
public function scopeForScoreType(Builder $q, string $scoreType): Builder
{
return $q->where('score_type', $scoreType);
}
public function scopeReviewed(Builder $q): Builder
{
// supports either boolean flag or reviewed_by presence
return $q->where(function (Builder $w) {
$w->where('comment_review', 1)
->orWhereNotNull('reviewed_by');
});
}
public function scopeUnreviewed(Builder $q): Builder
{
return $q->where(function (Builder $w) {
$w->whereNull('comment_review')->orWhere('comment_review', 0);
})->whereNull('reviewed_by');
}
/* ============================================================
* Helpers
* ============================================================
*/
/**
* Latest comment for a student/class/term/type.
*/
public static function latestFor(
int $studentId,
int $classSectionId,
string $scoreType,
string $schoolYear,
string $semester
): ?self {
return static::query()
->forStudent($studentId)
->forClassSection($classSectionId)
->forScoreType($scoreType)
->forTerm($schoolYear, $semester)
->orderByDesc('created_at')
->first();
}
/**
* Mark as reviewed (idempotent).
*/
public function markReviewed(int $reviewedBy): self
{
$this->comment_review = true;
$this->reviewed_by = $reviewedBy;
$this->save();
return $this;
}
/* ============================================================
* Optional validation rules helper (FormRequest/controller)
* ============================================================
*/
public static function rules(bool $updating = false): array
{
return [
'student_id' => [$updating ? 'sometimes' : 'required', 'integer', 'min:1'],
'class_section_id' => [$updating ? 'sometimes' : 'required', 'integer', 'min:1'],
'score_type' => [$updating ? 'sometimes' : 'required', 'string', 'max:50'],
'school_year' => [$updating ? 'sometimes' : 'required', 'string', 'max:20'],
'semester' => [$updating ? 'sometimes' : 'required', 'string', 'max:20'],
'comment' => ['nullable', 'string', 'max:5000'],
'comment_review' => ['nullable', 'boolean'],
'reviewed_by' => ['nullable', 'integer'],
'commented_by' => ['nullable', 'integer'],
// created_at is DB default; allow client to omit it
'created_at' => ['nullable', 'date'],
];
}
}