Initial commit
This commit is contained in:
commit
c909d539bc
7178 files changed
+756624
No files matched your search
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class BillingAccount extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'contact_name',
|
||||
'primary_parent_user_id',
|
||||
'invoice_email',
|
||||
'phone',
|
||||
'address_line1',
|
||||
'address_line2',
|
||||
'town',
|
||||
'postcode',
|
||||
'country',
|
||||
];
|
||||
|
||||
/**
|
||||
* The primary parent user linked to this billing account.
|
||||
*/
|
||||
public function primaryParent()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'primary_parent_user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Students billed under this account.
|
||||
*/
|
||||
public function students()
|
||||
{
|
||||
return $this->hasMany(StudentProfile::class, 'billing_account_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Booking extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'slot_id',
|
||||
'date',
|
||||
'student_name',
|
||||
'booked_from_page',
|
||||
'message',
|
||||
'status',
|
||||
];
|
||||
|
||||
public function slot()
|
||||
{
|
||||
return $this->belongsTo(Slot::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Chapter extends Model
|
||||
{
|
||||
protected $fillable = ['lesson_section_id', 'title', 'order'];
|
||||
|
||||
public function lessonSection()
|
||||
{
|
||||
return $this->belongsTo(LessonSection::class);
|
||||
}
|
||||
|
||||
public function lessons()
|
||||
{
|
||||
return $this->hasMany(Lesson::class)->orderBy('order');
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($chapter) {
|
||||
if (empty($chapter->slug)) {
|
||||
$chapter->slug = Str::slug($chapter->title);
|
||||
}
|
||||
});
|
||||
|
||||
static::updating(function ($chapter) {
|
||||
if ($chapter->isDirty('title')) {
|
||||
$chapter->slug = Str::slug($chapter->title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Course extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['lead_teacher', 'description', 'subject_id', 'level_id'];
|
||||
|
||||
public function subject()
|
||||
{
|
||||
return $this->belongsTo(Subject::class);
|
||||
}
|
||||
|
||||
public function level()
|
||||
{
|
||||
return $this->belongsTo(Level::class);
|
||||
}
|
||||
|
||||
public function modules()
|
||||
{
|
||||
return $this->hasMany(Module::class)->orderBy('order');
|
||||
}
|
||||
|
||||
public function lessonSections()
|
||||
{
|
||||
return $this->hasManyThrough(LessonSection::class, Module::class);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($course) {
|
||||
$subject = $course->subject?->name ?? 'unknown-subject';
|
||||
$level = $course->level?->name ?? 'unknown-level';
|
||||
$course->slug = \Illuminate\Support\Str::slug($subject . '-' . $level);
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ExternalBusyWindow extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'external_calendar_id', 'starts_at', 'ends_at',
|
||||
'transparency', 'last_seen_at'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'starts_at' => 'datetime',
|
||||
'ends_at' => 'datetime',
|
||||
'last_seen_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function calendar()
|
||||
{
|
||||
return $this->belongsTo(ExternalCalendar::class, 'external_calendar_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ExternalCalendar extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'source', 'url', 'is_enabled'];
|
||||
|
||||
public function busyWindows()
|
||||
{
|
||||
return $this->hasMany(ExternalBusyWindow::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Invoice extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'student_id',
|
||||
'period_start',
|
||||
'period_end',
|
||||
'total',
|
||||
'status',
|
||||
'pdf_path',
|
||||
];
|
||||
|
||||
/**
|
||||
* The student this invoice is for.
|
||||
*/
|
||||
public function student(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StudentProfile::class, 'student_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* All invoice line items associated with this invoice.
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvoiceItem::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class InvoiceItem extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'invoice_id',
|
||||
'attendance_id',
|
||||
'description',
|
||||
'quantity',
|
||||
'unit_price',
|
||||
'amount',
|
||||
];
|
||||
|
||||
/**
|
||||
* The invoice this line item belongs to.
|
||||
*/
|
||||
public function invoice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Invoice::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The attendance record this line item is based on.
|
||||
*/
|
||||
public function attendance(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(LessonAttendance::class, 'attendance_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Lesson extends Model
|
||||
{
|
||||
protected $fillable = ['chapter_id','lesson_section_id','title','description','order', 'slug'];
|
||||
|
||||
//protected $fillable = ['lesson_section_id', 'title', 'description', 'video_url', 'order'];
|
||||
|
||||
public function lessonSection()
|
||||
{
|
||||
return $this->belongsTo(LessonSection::class);
|
||||
}
|
||||
|
||||
public function chapter()
|
||||
{
|
||||
return $this->belongsTo(Chapter::class);
|
||||
}
|
||||
|
||||
public function videos()
|
||||
{
|
||||
return $this->hasMany(LessonVideo::class)->orderBy('order');
|
||||
}
|
||||
|
||||
public function progress()
|
||||
{
|
||||
return $this->hasMany(LessonProgress::class);
|
||||
}
|
||||
|
||||
public function questions()
|
||||
{
|
||||
return $this->hasMany(LessonQuestion::class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
class LessonAttendance extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'teaching_arrangement_id',
|
||||
'student_teacher_subject_id',
|
||||
'scheduled_start',
|
||||
'scheduled_end',
|
||||
'actual_start',
|
||||
'actual_end',
|
||||
'week_of_year',
|
||||
'status',
|
||||
'billable',
|
||||
'payable',
|
||||
'notes',
|
||||
];
|
||||
|
||||
/**
|
||||
* The scheduled arrangement this attendance record belongs to.
|
||||
*/
|
||||
public function arrangement(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeachingArrangement::class, 'teaching_arrangement_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The student–teacher–subject relationship for this attendance.
|
||||
*/
|
||||
public function studentTeacherSubject(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StudentTeacherSubject::class, 'student_teacher_subject_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice item generated from this attendance (if billed).
|
||||
*/
|
||||
public function invoiceItem(): HasOne
|
||||
{
|
||||
return $this->hasOne(InvoiceItem::class, 'attendance_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Teacher pay record generated from this attendance (if payable).
|
||||
*/
|
||||
public function payItem(): HasOne
|
||||
{
|
||||
return $this->hasOne(TeacherPayItem::class, 'attendance_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class LessonProgress extends Model
|
||||
{
|
||||
protected $fillable = ['user_id', 'lesson_id', 'completed', 'last_viewed_at'];
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function lesson() {
|
||||
return $this->belongsTo(Lesson::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class LessonQuestion extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'lesson_id',
|
||||
'user_id',
|
||||
'question',
|
||||
'answer',
|
||||
'answered_by',
|
||||
'answered_at',
|
||||
'published',
|
||||
];
|
||||
|
||||
public function lesson()
|
||||
{
|
||||
return $this->belongsTo(Lesson::class);
|
||||
}
|
||||
|
||||
public function student()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function teacher()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'answered_by');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class LessonSection extends Model
|
||||
{
|
||||
protected $fillable = ['module_id', 'title', 'year', 'order', 'slug'];
|
||||
|
||||
public function module()
|
||||
{
|
||||
return $this->belongsTo(Module::class);
|
||||
}
|
||||
|
||||
public function lessons()
|
||||
{
|
||||
return $this->hasMany(Lesson::class)->orderBy('order');
|
||||
}
|
||||
|
||||
public function chapters()
|
||||
{
|
||||
return $this->hasMany(Chapter::class)->orderBy('order');
|
||||
}
|
||||
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($section) {
|
||||
if (empty($section->slug)) {
|
||||
// Use title + uniqid to avoid collisions
|
||||
$section->slug = Str::slug($section->title . '-' . uniqid());
|
||||
}
|
||||
});
|
||||
|
||||
static::updating(function ($section) {
|
||||
if ($section->isDirty('title')) {
|
||||
// When renaming, regenerate slug based on title + id
|
||||
$section->slug = Str::slug($section->title . '-' . $section->id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class LessonVideo extends Model
|
||||
{
|
||||
protected $fillable = ['lesson_id', 'title', 'video_url', 'order'];
|
||||
|
||||
public function lesson()
|
||||
{
|
||||
return $this->belongsTo(Lesson::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Level extends Model
|
||||
{
|
||||
protected $fillable = ['name'];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Module extends Model
|
||||
{
|
||||
protected $fillable = ['course_id', 'name', 'order'];
|
||||
|
||||
public function course()
|
||||
{
|
||||
return $this->belongsTo(Course::class);
|
||||
}
|
||||
|
||||
public function lessonSections()
|
||||
{
|
||||
return $this->hasMany(LessonSection::class)->orderBy('order');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class ParentProfile extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'phone',
|
||||
'address_line1',
|
||||
'address_line2',
|
||||
'town',
|
||||
'postcode',
|
||||
'country',
|
||||
'notes',
|
||||
];
|
||||
|
||||
/**
|
||||
* Link back to the user account for this parent.
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional: link to billing accounts where this parent is primary.
|
||||
*/
|
||||
public function billingAccounts()
|
||||
{
|
||||
return $this->hasMany(BillingAccount::class, 'primary_parent_user_id', 'user_id');
|
||||
}
|
||||
|
||||
|
||||
public function students(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
StudentProfile::class,
|
||||
'parent_student',
|
||||
'parent_profile_id', // this model's FK on the pivot
|
||||
'student_profile_id' // related model's FK on the pivot
|
||||
)
|
||||
->withPivot('relationship', 'notes')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function parentProfile(): HasOne
|
||||
{
|
||||
return $this->hasOne(ParentProfile::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Slot extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['weekday', 'time', 'is_active'];
|
||||
|
||||
public function bookings()
|
||||
{
|
||||
return $this->hasMany(Booking::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\ParentProfile;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class StudentProfile extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'parent_id',
|
||||
'date_of_birth',
|
||||
'notes',
|
||||
'sen_notes',
|
||||
'year_group',
|
||||
'has_dyslexia',
|
||||
'has_dyspraxia',
|
||||
'has_autism',
|
||||
'has_adhd',
|
||||
'has_speech_needs',
|
||||
'student_type_id',
|
||||
'billing_account_id', // will exist after next migration
|
||||
];
|
||||
|
||||
|
||||
protected $casts = [
|
||||
'date_of_birth' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* The user account for this student
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parent/guardian of this student
|
||||
*/
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function parents(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
ParentProfile::class,
|
||||
'parent_student',
|
||||
'student_profile_id', // FK column pointing to THIS model
|
||||
'parent_profile_id' // FK column pointing to ParentProfile
|
||||
)
|
||||
->withPivot('relationship', 'notes')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subjects (with teachers) that this student studies
|
||||
*/
|
||||
public function subjects(): HasMany
|
||||
{
|
||||
return $this->hasMany(StudentTeacherSubject::class, 'student_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attendance records for this student
|
||||
*/
|
||||
public function attendance(): HasMany
|
||||
{
|
||||
return $this->hasMany(LessonAttendance::class, 'student_teacher_subject_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of student (online, centre, hybrid, etc)
|
||||
*/
|
||||
public function type(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StudentType::class, 'student_type_id');
|
||||
}
|
||||
|
||||
public function billingAccount()
|
||||
{
|
||||
return $this->belongsTo(BillingAccount::class);
|
||||
}
|
||||
|
||||
public function students()
|
||||
{
|
||||
return $this->belongsToMany(StudentProfile::class, 'parent_student')
|
||||
->withPivot('relationship', 'notes')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class StudentTeacherSubject extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'student_id',
|
||||
'teacher_id',
|
||||
'subject_id',
|
||||
'rate_override',
|
||||
'status',
|
||||
'notes',
|
||||
];
|
||||
|
||||
/**
|
||||
* The student this relationship belongs to.
|
||||
*/
|
||||
public function student(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StudentProfile::class, 'student_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The teacher assigned to this student for this subject.
|
||||
*/
|
||||
public function teacher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeacherProfile::class, 'teacher_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The subject being taught.
|
||||
*/
|
||||
public function subject(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Subject::class, 'subject_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Teaching arrangements (sessions/timetabled slots)
|
||||
* linking this student–teacher subject pair to actual classes.
|
||||
*/
|
||||
public function teachingArrangements(): HasMany
|
||||
{
|
||||
return $this->hasMany(TeachingArrangementStudent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attendance records for this student–teacher–subject combination.
|
||||
*/
|
||||
public function attendance(): HasMany
|
||||
{
|
||||
return $this->hasMany(LessonAttendance::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class StudentType extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
];
|
||||
|
||||
/**
|
||||
* Students who belong to this type.
|
||||
*
|
||||
* Assuming student_profiles has a student_type_id column.
|
||||
*/
|
||||
public function students()
|
||||
{
|
||||
return $this->hasMany(StudentProfile::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Subject extends Model
|
||||
{
|
||||
protected $fillable = ['name'];
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($subject) {
|
||||
if (empty($subject->slug)) {
|
||||
$subject->slug = Str::slug($subject->name);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class TeacherPayItem extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'teacher_pay_period_id',
|
||||
'attendance_id',
|
||||
'hours',
|
||||
'rate',
|
||||
'total',
|
||||
];
|
||||
|
||||
/**
|
||||
* The pay period this item belongs to.
|
||||
*/
|
||||
public function payPeriod(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeacherPayPeriod::class, 'teacher_pay_period_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The attendance record this payment item is based on.
|
||||
*/
|
||||
public function attendance(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(LessonAttendance::class, 'attendance_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class TeacherPayPeriod extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'teacher_id',
|
||||
'period_start',
|
||||
'period_end',
|
||||
'total',
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
* The teacher this pay period belongs to.
|
||||
*/
|
||||
public function teacher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeacherProfile::class, 'teacher_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each payable lesson included in this period.
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(TeacherPayItem::class, 'teacher_pay_period_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class TeacherProfile extends Model
|
||||
{
|
||||
// Which attributes can be mass-assigned (used in ::create([...]))
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'bio',
|
||||
'picture',
|
||||
'location',
|
||||
'hourly_rate',
|
||||
'qualifications',
|
||||
'active',
|
||||
];
|
||||
|
||||
/**
|
||||
* Link back to the user this profile belongs to
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subjects this teacher teaches
|
||||
*/
|
||||
public function subjects(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Subject::class, 'level_subject_teacher')
|
||||
->withPivot('level_id'); // since we’re also tracking level
|
||||
}
|
||||
|
||||
/**
|
||||
* Levels this teacher teaches
|
||||
*/
|
||||
public function levels(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Level::class, 'level_subject_teacher')
|
||||
->withPivot('subject_id');
|
||||
}
|
||||
|
||||
public function teachingArrangements(): HasMany
|
||||
{
|
||||
return $this->hasMany(TeachingArrangement::class, 'teacher_id');
|
||||
}
|
||||
|
||||
public function payPeriods(): HasMany
|
||||
{
|
||||
return $this->hasMany(TeacherPayPeriod::class, 'teacher_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class TeachingArrangement extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'teacher_id',
|
||||
'subject_id',
|
||||
'weekday',
|
||||
'start_time',
|
||||
'duration_minutes',
|
||||
'is_group',
|
||||
'max_students',
|
||||
'location_id',
|
||||
'fee_policy',
|
||||
'active',
|
||||
];
|
||||
|
||||
/**
|
||||
* The teacher running this arrangement.
|
||||
*/
|
||||
public function teacher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeacherProfile::class, 'teacher_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The subject being taught.
|
||||
*/
|
||||
public function subject(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Subject::class, 'subject_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where the session takes place (room, online, etc.)
|
||||
*/
|
||||
public function location(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Location::class, 'location_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Students assigned to this arrangement.
|
||||
*/
|
||||
public function students(): HasMany
|
||||
{
|
||||
return $this->hasMany(TeachingArrangementStudent::class, 'teaching_arrangement_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attendance records generated from this arrangement.
|
||||
*/
|
||||
public function attendance(): HasMany
|
||||
{
|
||||
return $this->hasMany(LessonAttendance::class, 'teaching_arrangement_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class TeachingArrangementStudent extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'teaching_arrangement_id',
|
||||
'student_teacher_subject_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* The teaching arrangement (scheduled slot).
|
||||
*/
|
||||
public function arrangement(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TeachingArrangement::class, 'teaching_arrangement_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The student–teacher–subject relationship linked to this slot.
|
||||
*/
|
||||
public function studentTeacherSubject(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StudentTeacherSubject::class, 'student_teacher_subject_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
use HasRoles {
|
||||
HasRoles::hasRole as spatieHasRole;
|
||||
}
|
||||
|
||||
|
||||
public function teacherProfile()
|
||||
{
|
||||
return $this->hasOne(TeacherProfile::class);
|
||||
}
|
||||
|
||||
public function studentProfile()
|
||||
{
|
||||
return $this->hasOne(StudentProfile::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
public function lessonProgress()
|
||||
{
|
||||
return $this->hasMany(LessonProgress::class);
|
||||
}
|
||||
|
||||
public function courses()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Course::class, 'course_user')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function hasRole($roles, $guard = null): bool
|
||||
{
|
||||
// God inherits all roles
|
||||
if ($this->roles->pluck('name')->contains('god')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Delegate to Spatie's HasRoles trait
|
||||
return $this->spatieHasRole($roles, $guard);
|
||||
}
|
||||
|
||||
public function getNameAttribute()
|
||||
{
|
||||
return trim($this->first_name . ' ' . $this->last_name);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user