HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux Bradford-Sitios 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64
User: www-data (33)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/api-talleres.bradford/app/Models/ClubOrderItem.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ClubOrderItem extends Model
{
    use HasFactory;

    protected $table = 'club_order_items';
    protected $primaryKey = 'id';

    protected $fillable = [
        'club_order_id',
        'student_id',
        'club_id',
        'club_period_id',
        'price_snapshot',
        'club_title_snapshot',
        'cancelled_at',
        'cancelled_by',
        'cancellation_reason',
        'deleted',
        'deleted_at',
        'user_created',
        'user_updated',
        'user_deleted',
    ];

    protected $hidden = [
        'deleted',
        'deleted_at',
        'user_deleted',
    ];

    protected $casts = [
        'price_snapshot' => 'decimal:0',
        'cancelled_at' => 'datetime',
    ];

    // =========================================================================
    // RELACIONES
    // =========================================================================

    /**
     * Pedido al que pertenece este item.
     */
    public function order()
    {
        return $this->belongsTo(ClubOrder::class, 'club_order_id');
    }

    /**
     * Alias de order() para compatibilidad.
     */
    public function clubOrder()
    {
        return $this->belongsTo(ClubOrder::class, 'club_order_id');
    }

    /**
     * Alumno inscrito.
     */
    public function student()
    {
        return $this->belongsTo(Student::class, 'student_id');
    }

    /**
     * Taller seleccionado.
     */
    public function club()
    {
        return $this->belongsTo(Club::class, 'club_id');
    }

    /**
     * Relación club-periodo para control de cupos.
     */
    public function clubPeriod()
    {
        return $this->belongsTo(ClubPeriod::class, 'club_period_id');
    }

    /**
     * Usuario que canceló el item.
     */
    public function cancelledBy()
    {
        return $this->belongsTo(User::class, 'cancelled_by');
    }

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

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

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

    // =========================================================================
    // HELPERS
    // =========================================================================

    /**
     * Verifica si el item está cancelado administrativamente.
     */
    public function isCancelled(): bool
    {
        return $this->cancelled_at !== null;
    }

    /**
     * Verifica si el item es gratuito.
     */
    public function isFree(): bool
    {
        return $this->price_snapshot == 0;
    }

    /**
     * Obtiene el estado efectivo del item (hereda del pedido o cancelado).
     */
    public function getEffectiveStatus(): string
    {
        if ($this->isCancelled()) {
            return 'cancelled';
        }
        return $this->order->status ?? 'unknown';
    }

    // =========================================================================
    // SCOPES
    // =========================================================================

    /**
     * Items no cancelados.
     */
    public function scopeNotCancelled($query)
    {
        return $query->whereNull('cancelled_at');
    }

    /**
     * Items cancelados.
     */
    public function scopeCancelled($query)
    {
        return $query->whereNotNull('cancelled_at');
    }

    /**
     * Items de un alumno específico.
     */
    public function scopeForStudent($query, int $studentId)
    {
        return $query->where('student_id', $studentId);
    }

    /**
     * Items de un taller específico.
     */
    public function scopeForClub($query, int $clubId)
    {
        return $query->where('club_id', $clubId);
    }

    /**
     * Items no eliminados.
     */
    public function scopeNotDeleted($query)
    {
        return $query->where('deleted', 0);
    }
}