affiliations

This commit is contained in:
ghassan committed 2026-01-27 16:34:46 +03:00
1 parent 4f3f9c9aad
commit 0b5b3dd3ee
177 files changed
+9660 -8531

No files matched your search

+23
View File
@@ -49,6 +49,29 @@ class ClubAffiliation extends Model
return $this->hasMany(AffiliationMedia::class);
}
/**
* Get the subscriptions associated with this affiliation.
*/
public function subscriptions(): HasMany
{
return $this->hasMany(ClubMemberSubscription::class, 'club_affiliation_id');
}
/**
* Get the packages through subscriptions.
*/
public function packages()
{
return $this->hasManyThrough(
ClubPackage::class,
ClubMemberSubscription::class,
'club_affiliation_id', // Foreign key on subscriptions table
'id', // Foreign key on packages table
'id', // Local key on affiliations table
'package_id' // Local key on subscriptions table
);
}
/**
* Get the duration of the affiliation in months.
*/
+25
View File
@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ClubInstructor extends Model
{
@@ -68,4 +69,28 @@ class ClubInstructor extends Model
return $this->belongsToMany(ClubPackage::class, 'club_package_activities', 'instructor_id', 'package_id')
->withTimestamps();
}
/**
* Get the reviews for the instructor.
*/
public function reviews(): HasMany
{
return $this->hasMany(InstructorReview::class, 'instructor_id');
}
/**
* Get average rating from reviews.
*/
public function getAverageRatingAttribute(): float
{
return $this->reviews()->avg('rating') ?? 0;
}
/**
* Get total number of reviews.
*/
public function getReviewsCountAttribute(): int
{
return $this->reviews()->count();
}
}
+9
View File
@@ -27,6 +27,7 @@ class ClubMemberSubscription extends Model
protected $fillable = [
'tenant_id',
'user_id',
'club_affiliation_id',
'package_id',
'start_date',
'end_date',
@@ -73,6 +74,14 @@ class ClubMemberSubscription extends Model
return $this->belongsTo(ClubPackage::class, 'package_id');
}
/**
* Get the club affiliation associated with the subscription.
*/
public function clubAffiliation(): BelongsTo
{
return $this->belongsTo(ClubAffiliation::class, 'club_affiliation_id');
}
/**
* Get the transactions for the subscription.
*/
+8
View File
@@ -87,4 +87,12 @@ class ClubPackage extends Model
return $this->hasMany(ClubMemberSubscription::class, 'package_id')
->where('status', 'active');
}
/**
* Get the package activities (with instructors).
*/
public function packageActivities(): HasMany
{
return $this->hasMany(ClubPackageActivity::class, 'package_id');
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ClubPackageActivity extends Model
{
protected $fillable = [
'package_id',
'activity_id',
'instructor_id',
];
/**
* Get the package that owns this activity assignment.
*/
public function package(): BelongsTo
{
return $this->belongsTo(ClubPackage::class, 'package_id');
}
/**
* Get the activity.
*/
public function activity(): BelongsTo
{
return $this->belongsTo(ClubActivity::class, 'activity_id');
}
/**
* Get the instructor assigned to this activity.
*/
public function instructor(): BelongsTo
{
return $this->belongsTo(ClubInstructor::class, 'instructor_id');
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class InstructorReview extends Model
{
protected $fillable = [
'instructor_id',
'reviewer_user_id',
'rating',
'comment',
'reviewed_at',
];
protected $casts = [
'reviewed_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* Get the instructor that owns the review.
*/
public function instructor(): BelongsTo
{
return $this->belongsTo(ClubInstructor::class, 'instructor_id');
}
/**
* Get the user who wrote the review.
*/
public function reviewer(): BelongsTo
{
return $this->belongsTo(User::class, 'reviewer_user_id');
}
/**
* Check if review was updated after initial creation.
*/
public function wasUpdated(): bool
{
return $this->updated_at && $this->updated_at->gt($this->created_at);
}
/**
* Get formatted review date.
*/
public function getFormattedDateAttribute(): string
{
if ($this->wasUpdated()) {
return 'Updated ' . $this->updated_at->diffForHumans();
}
return $this->reviewed_at->diffForHumans();
}
}
+32
View File
@@ -9,14 +9,22 @@ class SkillAcquisition extends Model
{
protected $fillable = [
'club_affiliation_id',
'package_id',
'activity_id',
'instructor_id',
'skill_name',
'icon',
'duration_months',
'start_date',
'end_date',
'proficiency_level',
'notes',
];
protected $casts = [
'duration_months' => 'integer',
'start_date' => 'date',
'end_date' => 'date',
];
/**
@@ -27,6 +35,30 @@ class SkillAcquisition extends Model
return $this->belongsTo(ClubAffiliation::class);
}
/**
* Get the package associated with this skill.
*/
public function package(): BelongsTo
{
return $this->belongsTo(ClubPackage::class, 'package_id');
}
/**
* Get the activity associated with this skill.
*/
public function activity(): BelongsTo
{
return $this->belongsTo(ClubActivity::class, 'activity_id');
}
/**
* Get the instructor who taught this skill.
*/
public function instructor(): BelongsTo
{
return $this->belongsTo(ClubInstructor::class, 'instructor_id');
}
/**
* Get formatted duration.
*/