> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rocky.global/llms.txt
> Use this file to discover all available pages before exploring further.

# MODELS DOCUMENTATION

# Database Models & Relationships Documentation

## Table of Contents

1. [Overview](#overview)
2. [Core Models](#core-models)
3. [Event Management Models](#event-management-models)
4. [User Management Models](#user-management-models)
5. [Payment & Order Models](#payment--order-models)
6. [Ranking Models](#ranking-models)
7. [Merchandise Models](#merchandise-models)
8. [Communication Models](#communication-models)
9. [Configuration Models](#configuration-models)
10. [Model Relationships](#model-relationships)
11. [Model Scopes & Accessors](#model-scopes--accessors)
12. [Database Migrations](#database-migrations)

## Overview

The event management system uses Laravel's Eloquent ORM with a well-structured database design. The models are organized into logical groups and include proper relationships, scopes, and accessors for efficient data handling.

## Core Models

### Evento (Event)

The central model representing events in the system.

```php theme={null}
class Evento extends Model
{
    const STATE_ACTIVE = true;
    const STATE_INACTIVE = false;
    const TABLE_NAME = 'eventos';
    
    protected $fillable = [
        'name',
        'description',
        'ciudad',
        'pais',
        'pagina_web',
        'date_from',
        'date_to',
        'participants',
        'enrolled',
        'category',
        'date_from_register',
        'date_to_register',
        'facebook',
        'instagram',
        'phone_number',
        'x',
        'organizador_id',
        'created_by',
        'email',
        'latitude',
        'longitude',
        'address',
        'json_forms',
        'flag_active',
        'general_aspect',
        'url_image',
        'timezone'
    ];

    protected $casts = [
        'tarifas' => 'array',
        'general_aspect' => 'array',
        'date_from' => 'datetime',
        'date_to' => 'datetime',
        'date_from_register' => 'datetime',
        'date_to_register' => 'datetime',
        'json_maps' => 'array',
        'json_forms' => 'array',
    ];

    protected $appends = [
        'created_at_format',
        'category_name',
        'date_from_format',
        'date_from_format_input',
        'date_to_format',
        'date_to_format_input',
        'date_from_register_format',
        'date_from_register_format_input',
        'date_to_register_format',
        'date_to_register_format_input',
        'tarifas_full'
    ];
}
```

#### Relationships

```php theme={null}
// Event belongs to an organizer
public function organizador() {
    return $this->belongsTo(Organizador::class, 'organizador_id');
}

// Event belongs to a category
public function category() {
    return $this->belongsTo(CategoriaDeEvento::class, 'category');
}

// Event has many registrations
public function eventoXUsuario() {
    return $this->hasMany(EventoXUsuario::class, 'evento_id');
}

// Event has many rankings
public function rankings() {
    return $this->hasMany(Ranking::class, 'evento_id')
        ->whereNull('deleted_at');
}

// Event has many event rankings
public function eventRankings() {
    return $this->hasMany(EventRanking::class, 'evento_id')
        ->whereNull('deleted_at');
}

// Event has many bookings
public function booking() {
    return $this->hasMany(Booking::class, 'evento_id')
        ->whereNull('deleted_at');
}

// Event has many registrations with user data
public function eventoXUsuarioFull() {
    return $this->hasMany(EventoXUsuario::class, 'evento_id')
        ->with('usuario');
}

// Event has many catalogs (merchandise)
public function catalogos() {
    return $this->hasMany(Catalogo::class, 'evento_id');
}
```

#### Accessors & Mutators

```php theme={null}
// Get formatted created date
public function getCreatedAtFormatAttribute() {
    if (!is_null($this->created_at)) {
        return $this->created_at->format("d/m/Y H:i:s");
    }
    return "--";
}

// Get formatted start date
public function getDateFromFormatAttribute() {
    if (!is_null($this->date_from)) {
        return $this->date_from->format("d/m/Y H:i:s");
    }
    return "--";
}

// Get formatted start date for input fields
public function getDateFromFormatInputAttribute() {
    if (!is_null($this->date_from)) {
        return $this->date_from->format("Y-m-d H:i");
    }
    return "--";
}

// Get category name
public function getCategoryNameAttribute() {
    if ($this->categoryObj) {
        return $this->categoryObj->name;
    }
    return "--";
}

// Get full tariff objects
public function getTarifasFullAttribute() {
    $tarifas = [];
    
    try {
        if (!is_null($this->tarifas)) {
            $tarifasIds = is_string($this->tarifas) ? 
                json_decode($this->tarifas, true) : $this->tarifas;
            
            if (is_array($tarifasIds) && !empty($tarifasIds)) {
                $tarifa = TarifaDeEvento::whereNull(TarifaDeEvento::TABLE_NAME . '.deleted_at')
                    ->whereIn('id', $tarifasIds)
                    ->get();
                
                if ($tarifa && $tarifa->count() > 0) {
                    foreach ($tarifa as $t) {
                        $tarifas[] = is_array($t) ? (object) $t : $t;
                    }
                }
            }
        }
    } catch (\Exception $e) {
        \Log::error('Error in getTarifasFullAttribute: ' . $e->getMessage());
    }
    
    return $tarifas;
}
```

### User

The user model representing system users.

```php theme={null}
class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
        'organizador_id',
        'phone',
        'address'
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];
}
```

#### Relationships

```php theme={null}
// User belongs to an organizer
public function organizador() {
    return $this->belongsTo(Organizador::class, 'organizador_id');
}

// User has many event registrations
public function eventoXUsuario() {
    return $this->hasMany(EventoXUsuario::class, 'user_id');
}

// User has many orders
public function orders() {
    return $this->hasMany(Order::class, 'user_id');
}
```

### Organizador (Organizer)

Represents event organizers.

```php theme={null}
class Organizador extends Model
{
    protected $fillable = [
        'name',
        'email',
        'phone',
        'address',
        'description',
        'logo_url',
        'website',
        'flag_active'
    ];

    protected $casts = [
        'flag_active' => 'boolean'
    ];
}
```

#### Relationships

```php theme={null}
// Organizer has many events
public function eventos() {
    return $this->hasMany(Evento::class, 'organizador_id');
}

// Organizer has many users
public function users() {
    return $this->hasMany(User::class, 'organizador_id');
}
```

## Event Management Models

### EventoXUsuario (Event Registration)

Represents user registrations for events.

```php theme={null}
class EventoXUsuario extends Model
{
    protected $fillable = [
        'evento_id',
        'user_id',
        'tarifa_id',
        'status',
        'payment_status',
        'total_amount',
        'discount_amount',
        'form_data',
        'transaction_id',
        'payment_method'
    ];

    protected $casts = [
        'form_data' => 'array',
        'total_amount' => 'decimal:2',
        'discount_amount' => 'decimal:2'
    ];
}
```

#### Relationships

```php theme={null}
// Registration belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Registration belongs to a user
public function usuario() {
    return $this->belongsTo(User::class, 'user_id');
}

// Registration belongs to a tariff
public function tarifa() {
    return $this->belongsTo(TarifaDeEvento::class, 'tarifa_id');
}
```

### CategoriaDeEvento (Event Category)

Represents event categories.

```php theme={null}
class CategoriaDeEvento extends Model
{
    protected $fillable = [
        'name',
        'description',
        'color',
        'icon',
        'flag_active'
    ];

    protected $casts = [
        'flag_active' => 'boolean'
    ];
}
```

#### Relationships

```php theme={null}
// Category has many events
public function eventos() {
    return $this->hasMany(Evento::class, 'category');
}
```

### TarifaDeEvento (Event Tariff)

Represents pricing tiers for events.

```php theme={null}
class TarifaDeEvento extends Model
{
    protected $fillable = [
        'name',
        'description',
        'prices',
        'evento_id',
        'flag_active',
        'max_participants',
        'registration_deadline'
    ];

    protected $casts = [
        'prices' => 'array',
        'flag_active' => 'boolean',
        'registration_deadline' => 'datetime'
    ];
}
```

#### Relationships

```php theme={null}
// Tariff belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Tariff has many registrations
public function registrations() {
    return $this->hasMany(EventoXUsuario::class, 'tarifa_id');
}
```

## User Management Models

### Role & Permission Models

```php theme={null}
class Role extends Model
{
    protected $fillable = [
        'name',
        'guard_name'
    ];
}

class ModelHasRole extends Model
{
    protected $fillable = [
        'role_id',
        'model_type',
        'model_id'
    ];
}
```

## Payment & Order Models

### Order

Represents payment orders.

```php theme={null}
class Order extends Model
{
    protected $fillable = [
        'user_id',
        'evento_id',
        'order_number',
        'total_amount',
        'status',
        'payment_method',
        'transaction_id',
        'payment_date',
        'billing_address',
        'shipping_address'
    ];

    protected $casts = [
        'total_amount' => 'decimal:2',
        'payment_date' => 'datetime',
        'billing_address' => 'array',
        'shipping_address' => 'array'
    ];
}
```

#### Relationships

```php theme={null}
// Order belongs to a user
public function user() {
    return $this->belongsTo(User::class, 'user_id');
}

// Order belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Order has many items
public function items() {
    return $this->hasMany(OrderItem::class, 'order_id');
}
```

### OrderItem

Represents individual items in an order.

```php theme={null}
class OrderItem extends Model
{
    protected $fillable = [
        'order_id',
        'product_id',
        'variant_id',
        'quantity',
        'unit_price',
        'total_price',
        'product_name',
        'variant_attributes'
    ];

    protected $casts = [
        'unit_price' => 'decimal:2',
        'total_price' => 'decimal:2',
        'variant_attributes' => 'array'
    ];
}
```

#### Relationships

```php theme={null}
// Order item belongs to an order
public function order() {
    return $this->belongsTo(Order::class, 'order_id');
}

// Order item belongs to a product
public function product() {
    return $this->belongsTo(Producto::class, 'product_id');
}

// Order item belongs to a variant
public function variant() {
    return $this->belongsTo(Variant::class, 'variant_id');
}
```

### Refund

Represents payment refunds.

```php theme={null}
class Refund extends Model
{
    protected $fillable = [
        'order_id',
        'amount',
        'reason',
        'status',
        'processed_at'
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'processed_at' => 'datetime'
    ];
}
```

## Ranking Models

### EventRanking

Represents rankings for specific events.

```php theme={null}
class EventRanking extends Model
{
    protected $fillable = [
        'evento_id',
        'name',
        'description',
        'criteria',
        'results',
        'is_active',
        'calculated_at'
    ];

    protected $casts = [
        'criteria' => 'array',
        'results' => 'array',
        'is_active' => 'boolean',
        'calculated_at' => 'datetime'
    ];
}
```

#### Relationships

```php theme={null}
// Ranking belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}
```

### GeneralRanking

Represents general rankings across multiple events.

```php theme={null}
class GeneralRanking extends Model
{
    protected $fillable = [
        'name',
        'description',
        'criteria',
        'results',
        'is_active',
        'calculated_at',
        'period_start',
        'period_end'
    ];

    protected $casts = [
        'criteria' => 'array',
        'results' => 'array',
        'is_active' => 'boolean',
        'calculated_at' => 'datetime',
        'period_start' => 'datetime',
        'period_end' => 'datetime'
    ];
}
```

### Ranking

Base ranking model.

```php theme={null}
class Ranking extends Model
{
    protected $fillable = [
        'evento_id',
        'user_id',
        'position',
        'score',
        'category',
        'ranking_date'
    ];

    protected $casts = [
        'score' => 'decimal:2',
        'ranking_date' => 'datetime'
    ];
}
```

#### Relationships

```php theme={null}
// Ranking belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Ranking belongs to a user
public function user() {
    return $this->belongsTo(User::class, 'user_id');
}
```

## Merchandise Models

### Catalogo (Catalog)

Represents merchandise catalogs.

```php theme={null}
class Catalogo extends Model
{
    protected $fillable = [
        'name',
        'description',
        'evento_id',
        'is_active',
        'image_url'
    ];

    protected $casts = [
        'is_active' => 'boolean'
    ];
}
```

#### Relationships

```php theme={null}
// Catalog belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Catalog has many products
public function productos() {
    return $this->hasMany(Producto::class, 'catalogo_id');
}
```

### Producto (Product)

Represents merchandise products.

```php theme={null}
class Producto extends Model
{
    protected $fillable = [
        'name',
        'description',
        'price',
        'stock',
        'catalogo_id',
        'is_active',
        'images',
        'attributes'
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'stock' => 'integer',
        'is_active' => 'boolean',
        'images' => 'array',
        'attributes' => 'array'
    ];
}
```

#### Relationships

```php theme={null}
// Product belongs to a catalog
public function catalogo() {
    return $this->belongsTo(Catalogo::class, 'catalogo_id');
}

// Product has many variants
public function variants() {
    return $this->hasMany(Variant::class, 'producto_id');
}
```

### Variant

Represents product variants (size, color, etc.).

```php theme={null}
class Variant extends Model
{
    protected $fillable = [
        'producto_id',
        'name',
        'attributes',
        'price',
        'stock',
        'sku'
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'stock' => 'integer',
        'attributes' => 'array'
    ];
}
```

#### Relationships

```php theme={null}
// Variant belongs to a product
public function producto() {
    return $this->belongsTo(Producto::class, 'producto_id');
}
```

### VariantName

Represents attribute names for variants.

```php theme={null}
class VariantName extends Model
{
    protected $fillable = [
        'name',
        'type',
        'options'
    ];

    protected $casts = [
        'options' => 'array'
    ];
}
```

## Communication Models

### Communication

Represents communication templates.

```php theme={null}
class Communication extends Model
{
    protected $fillable = [
        'name',
        'subject',
        'message',
        'evento_id',
        'type',
        'is_active'
    ];

    protected $casts = [
        'is_active' => 'boolean'
    ];
}
```

#### Relationships

```php theme={null}
// Communication belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Communication has many logs
public function logs() {
    return $this->hasMany(CommunicationLog::class, 'communication_id');
}
```

### CommunicationLog

Represents communication delivery logs.

```php theme={null}
class CommunicationLog extends Model
{
    protected $fillable = [
        'communication_id',
        'user_id',
        'status',
        'sent_at',
        'error_message'
    ];

    protected $casts = [
        'sent_at' => 'datetime'
    ];
}
```

#### Relationships

```php theme={null}
// Log belongs to a communication
public function communication() {
    return $this->belongsTo(Communication::class, 'communication_id');
}

// Log belongs to a user
public function user() {
    return $this->belongsTo(User::class, 'user_id');
}
```

## Configuration Models

### Discount

Represents discount codes and promotions.

```php theme={null}
class Discount extends Model
{
    protected $fillable = [
        'name',
        'code',
        'amount',
        'type_amount',
        'quantity',
        'in_use',
        'evento_id',
        'flag_active',
        'cumulative',
        'valid_from',
        'valid_to'
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'quantity' => 'integer',
        'in_use' => 'integer',
        'flag_active' => 'boolean',
        'cumulative' => 'boolean',
        'valid_from' => 'datetime',
        'valid_to' => 'datetime'
    ];
}
```

#### Relationships

```php theme={null}
// Discount belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}
```

### Idioma (Language)

Represents supported languages.

```php theme={null}
class Idioma extends Model
{
    protected $fillable = [
        'name',
        'code',
        'url_image',
        'flag_active'
    ];

    protected $casts = [
        'flag_active' => 'boolean'
    ];
}
```

### Tarifa (Tariff)

Represents base tariff templates.

```php theme={null}
class Tarifa extends Model
{
    protected $fillable = [
        'name',
        'description',
        'prices',
        'flag_active'
    ];

    protected $casts = [
        'prices' => 'array',
        'flag_active' => 'boolean'
    ];
}
```

### Booking

Represents event bookings and reservations.

```php theme={null}
class Booking extends Model
{
    protected $fillable = [
        'evento_id',
        'user_id',
        'booking_date',
        'status',
        'notes',
        'total_amount'
    ];

    protected $casts = [
        'booking_date' => 'datetime',
        'total_amount' => 'decimal:2'
    ];
}
```

#### Relationships

```php theme={null}
// Booking belongs to an event
public function evento() {
    return $this->belongsTo(Evento::class, 'evento_id');
}

// Booking belongs to a user
public function user() {
    return $this->belongsTo(User::class, 'user_id');
}
```

### Cities & Countries

Geographic data models.

```php theme={null}
class Cities extends Model
{
    protected $fillable = [
        'name',
        'country_code',
        'state_code',
        'latitude',
        'longitude'
    ];

    protected $casts = [
        'latitude' => 'decimal:8',
        'longitude' => 'decimal:8'
    ];
}

class Countries extends Model
{
    protected $fillable = [
        'name',
        'iso2',
        'iso3',
        'flag_active'
    ];

    protected $casts = [
        'flag_active' => 'boolean'
    ];
}
```

## Model Relationships

### Complete Relationship Diagram

```php theme={null}
// Event Relationships
Evento
├── belongsTo(Organizador)
├── belongsTo(CategoriaDeEvento)
├── hasMany(EventoXUsuario)
├── hasMany(Ranking)
├── hasMany(EventRanking)
├── hasMany(Booking)
├── hasMany(Catalogo)
└── hasMany(Order)

// User Relationships
User
├── belongsTo(Organizador)
├── hasMany(EventoXUsuario)
├── hasMany(Order)
└── hasMany(Booking)

// Organizer Relationships
Organizador
├── hasMany(Evento)
└── hasMany(User)

// Event Registration Relationships
EventoXUsuario
├── belongsTo(Evento)
├── belongsTo(User)
└── belongsTo(TarifaDeEvento)

// Order Relationships
Order
├── belongsTo(User)
├── belongsTo(Evento)
└── hasMany(OrderItem)

// Product Relationships
Producto
├── belongsTo(Catalogo)
└── hasMany(Variant)

// Catalog Relationships
Catalogo
├── belongsTo(Evento)
└── hasMany(Producto)
```

## Model Scopes & Accessors

### Common Scopes

```php theme={null}
// Active scope for most models
public function scopeActive($query) {
    return $query->where('flag_active', true);
}

// Recent scope for events
public function scopeRecent($query, $days = 30) {
    return $query->where('created_at', '>=', now()->subDays($days));
}

// Upcoming events scope
public function scopeUpcoming($query) {
    return $query->where('date_from', '>=', now());
}

// Past events scope
public function scopePast($query) {
    return $query->where('date_from', '<', now());
}

// Available scope for products
public function scopeAvailable($query) {
    return $query->where('stock', '>', 0)->where('is_active', true);
}
```

### Custom Accessors

```php theme={null}
// Get full name for users
public function getFullNameAttribute() {
    return $this->name;
}

// Get status label
public function getStatusLabelAttribute() {
    $statuses = [
        'active' => 'Active',
        'inactive' => 'Inactive',
        'pending' => 'Pending',
        'cancelled' => 'Cancelled'
    ];
    
    return $statuses[$this->status] ?? $this->status;
}

// Get formatted price
public function getFormattedPriceAttribute() {
    return number_format($this->price, 2) . ' €';
}

// Get remaining stock
public function getRemainingStockAttribute() {
    return max(0, $this->stock - $this->reserved_stock);
}
```

## Database Migrations

### Key Migration Examples

```php theme={null}
// Events table migration
Schema::create('eventos', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->text('description')->nullable();
    $table->string('ciudad');
    $table->string('pais');
    $table->string('pagina_web');
    $table->datetime('date_from');
    $table->datetime('date_to')->nullable();
    $table->integer('participants');
    $table->integer('enrolled')->default(0);
    $table->foreignId('category')->constrained('categorias_de_eventos');
    $table->datetime('date_from_register');
    $table->datetime('date_to_register');
    $table->string('facebook')->nullable();
    $table->string('instagram')->nullable();
    $table->string('phone_number')->nullable();
    $table->string('x')->nullable();
    $table->foreignId('organizador_id')->constrained('organizadores');
    $table->foreignId('created_by')->constrained('users');
    $table->string('email');
    $table->decimal('latitude', 10, 8);
    $table->decimal('longitude', 11, 8);
    $table->string('address');
    $table->json('json_forms')->nullable();
    $table->boolean('flag_active')->default(true);
    $table->json('general_aspect')->nullable();
    $table->string('url_image')->nullable();
    $table->string('timezone')->default('UTC');
    $table->timestamps();
    $table->softDeletes();
});

// Event registrations table migration
Schema::create('eventos_x_usuarios', function (Blueprint $table) {
    $table->id();
    $table->foreignId('evento_id')->constrained('eventos')->onDelete('cascade');
    $table->foreignId('user_id')->constrained('users')->onDelete('cascade');
    $table->foreignId('tarifa_id')->constrained('tarifas_de_eventos');
    $table->enum('status', ['PENDING', 'CONFIRMED', 'CANCELLED'])->default('PENDING');
    $table->enum('payment_status', ['PENDING', 'PAID', 'FAILED', 'REFUNDED'])->default('PENDING');
    $table->decimal('total_amount', 10, 2);
    $table->decimal('discount_amount', 10, 2)->default(0);
    $table->json('form_data')->nullable();
    $table->string('transaction_id')->nullable();
    $table->string('payment_method')->nullable();
    $table->timestamps();
});

// Orders table migration
Schema::create('orders', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained('users');
    $table->foreignId('evento_id')->constrained('eventos');
    $table->string('order_number')->unique();
    $table->decimal('total_amount', 10, 2);
    $table->enum('status', ['PENDING', 'PAID', 'CANCELLED', 'REFUNDED'])->default('PENDING');
    $table->string('payment_method')->nullable();
    $table->string('transaction_id')->nullable();
    $table->datetime('payment_date')->nullable();
    $table->json('billing_address')->nullable();
    $table->json('shipping_address')->nullable();
    $table->timestamps();
    $table->softDeletes();
});
```

### Indexes and Constraints

```php theme={null}
// Add indexes for better performance
$table->index(['evento_id', 'status']);
$table->index(['user_id', 'created_at']);
$table->index(['date_from', 'flag_active']);
$table->index(['organizador_id', 'flag_active']);

// Add unique constraints
$table->unique(['evento_id', 'user_id'], 'unique_event_registration');
$table->unique('order_number');
$table->unique(['code', 'evento_id'], 'unique_discount_code');
```

This comprehensive model documentation provides a complete overview of all database models, their relationships, attributes, and usage patterns in the event management system. The documentation includes practical examples and best practices for working with the models.
