$installments * @property string|null $payment_method * @property string|null $file_url * @property string|null $file_type * @property \Illuminate\Support\Carbon|null $enrollment_due_date * @property string|null $package_value * @property int|null $package_installments * @property \Illuminate\Support\Carbon|null $package_due_date * @property int $version * @property int|null $derived_from_contract_id * @property int|null $created_by_user_id * @property string|null $signed_file_url * @property string|null $signed_file_type * @property-read \App\Models\ClassPackageUnit|null $classPackageUnit * @property-read \App\Models\User|null $createdBy * @property-read StudentContract|null $derivedFrom * @property-read \Illuminate\Database\Eloquent\Collection $derivedVersions * @property-read int|null $derived_versions_count * @property-read int|null $installments_count * @property-read \Illuminate\Database\Eloquent\Collection $medias * @property-read int|null $medias_count * @property-read \App\Models\Student $student * @property-read \App\Models\Unit $unit * @method static Builder|StudentContract latestVersion() * @method static Builder|StudentContract newModelQuery() * @method static Builder|StudentContract newQuery() * @method static Builder|StudentContract onlyTrashed() * @method static Builder|StudentContract query() * @method static Builder|StudentContract whereClassPackageUnitId($value) * @method static Builder|StudentContract whereClassQuantity($value) * @method static Builder|StudentContract whereCreatedAt($value) * @method static Builder|StudentContract whereCreatedByUserId($value) * @method static Builder|StudentContract whereDeletedAt($value) * @method static Builder|StudentContract whereDerivedFromContractId($value) * @method static Builder|StudentContract whereEarlyPaymentDiscount($value) * @method static Builder|StudentContract whereEndDate($value) * @method static Builder|StudentContract whereEndTime($value) * @method static Builder|StudentContract whereEnrollmentDueDate($value) * @method static Builder|StudentContract whereFileType($value) * @method static Builder|StudentContract whereFileUrl($value) * @method static Builder|StudentContract whereFineCancelled($value) * @method static Builder|StudentContract whereId($value) * @method static Builder|StudentContract whereInstallments($value) * @method static Builder|StudentContract whereInterestRate($value) * @method static Builder|StudentContract whereNotes($value) * @method static Builder|StudentContract wherePackageDueDate($value) * @method static Builder|StudentContract wherePackageInstallments($value) * @method static Builder|StudentContract wherePackageValue($value) * @method static Builder|StudentContract wherePaymentMethod($value) * @method static Builder|StudentContract whereProtocol($value) * @method static Builder|StudentContract whereRecurringDay($value) * @method static Builder|StudentContract whereSecondEndTime($value) * @method static Builder|StudentContract whereSecondStartTime($value) * @method static Builder|StudentContract whereSecondWeekday($value) * @method static Builder|StudentContract whereSignatureDate($value) * @method static Builder|StudentContract whereSignedFileType($value) * @method static Builder|StudentContract whereSignedFileUrl($value) * @method static Builder|StudentContract whereStartTime($value) * @method static Builder|StudentContract whereStatus($value) * @method static Builder|StudentContract whereStudentId($value) * @method static Builder|StudentContract whereTaxRegister($value) * @method static Builder|StudentContract whereUnitId($value) * @method static Builder|StudentContract whereUpdatedAt($value) * @method static Builder|StudentContract whereVersion($value) * @method static Builder|StudentContract whereWeekday($value) * @method static Builder|StudentContract withTrashed(bool $withTrashed = true) * @method static Builder|StudentContract withoutTrashed() * @mixin \Eloquent */ class StudentContract extends Model { use HasFactory, SoftDeletes; protected $table = 'student_contracts'; protected $guarded = ['id']; protected $casts = [ 'version' => 'integer', 'signature_date' => 'date:Y-m-d', 'end_date' => 'date:Y-m-d', 'enrollment_due_date' => 'date:Y-m-d', 'package_due_date' => 'date:Y-m-d', 'materials_due_date' => 'date:Y-m-d', 'total_due_date' => 'date:Y-m-d', 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; public function scopeLatestVersion(Builder $query): Builder { return $query->whereDoesntHave( 'derivedVersions', fn (Builder $derivedQuery) => $derivedQuery->withTrashed(), ); } protected static function booted(): void { static::saving(function (StudentContract $contract) { $contract->class_quantity = $contract->calculateClassQuantity(); }); $updateStudentStatus = function (StudentContract $contract): void { if ($contract->student_id) { // Use withoutGlobalScopes or just normal relation if no scopes affect it $contract->student()->first()?->updateStatus(); } }; static::saved($updateStudentStatus); static::deleted($updateStudentStatus); static::restored($updateStudentStatus); } public function calculateClassQuantity(): int { if (!$this->signature_date || !$this->end_date) { return (int) $this->class_quantity; // Fallback to current if missing } $start = $this->signature_date->copy()->startOfDay(); $end = $this->end_date->copy()->startOfDay(); if ($start->greaterThan($end)) { return 0; } $count = 0; for ($date = $start; $date->lessThanOrEqualTo($end); $date->addDay()) { $dayOfWeek = $date->dayOfWeek; // 0 (Sunday) to 6 (Saturday) if ($this->weekday !== null && $dayOfWeek === (int) $this->weekday) { $count++; } if ($this->second_weekday !== null && $dayOfWeek === (int) $this->second_weekday) { $count++; } } return $count; } public function derivedFrom(): BelongsTo { return $this->belongsTo(self::class, 'derived_from_contract_id'); } public function derivedVersions(): HasMany { return $this->hasMany(self::class, 'derived_from_contract_id'); } public function createdBy(): BelongsTo { return $this->belongsTo(User::class, 'created_by_user_id'); } public function student(): BelongsTo { return $this->belongsTo(Student::class); } public function unit(): BelongsTo { return $this->belongsTo(Unit::class); } public function classPackageUnit(): BelongsTo { return $this->belongsTo(ClassPackageUnit::class); } public function medias(): HasMany { return $this->hasMany(StudentMedia::class); } public function installments(): HasMany { return $this->hasMany(StudentContractInstallment::class); } }