File size: 2,609 Bytes
10dc6f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Event extends Model
{
    protected $fillable = [
        'organizer_id', 'category_id', 'title', 'slug', 'description', 'banner',
        'venue_name', 'venue_address', 'city', 'is_online',
        'start_at', 'end_at', 'status', 'terms', 'refund_policy',
    ];

    protected function casts(): array
    {
        return [
            'start_at'  => 'datetime',
            'end_at'    => 'datetime',
            'is_online' => 'boolean',
        ];
    }

    protected static function booted(): void
    {
        static::creating(function (Event $event) {
            if (empty($event->slug)) {
                $base = Str::slug($event->title);
                $slug = $base;
                $i = 1;
                while (static::where('slug', $slug)->exists()) {
                    $slug = $base . '-' . $i++;
                }
                $event->slug = $slug;
            }
        });
    }

    // ── Relationships ────────────────────────────────────

    public function organizer()
    {
        return $this->belongsTo(User::class, 'organizer_id');
    }

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function ticketTiers()
    {
        return $this->hasMany(TicketTier::class);
    }

    public function orders()
    {
        return $this->hasMany(Order::class);
    }

    // ── Scopes ───────────────────────────────────────────

    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }

    public function scopeUpcoming($query)
    {
        return $query->published()->where('start_at', '>=', now());
    }

    // ── Helpers ──────────────────────────────────────────

    public function getMinPrice(): float
    {
        return $this->ticketTiers->min('price') ?? 0;
    }

    public function getTotalQuota(): int
    {
        return $this->ticketTiers->sum('quota');
    }

    public function getTotalSold(): int
    {
        return $this->ticketTiers->sum('sold_count');
    }

    public function getAvailableStock(): int
    {
        return $this->getTotalQuota() - $this->getTotalSold();
    }

    public function isPublished(): bool
    {
        return $this->status === 'published';
    }
}