'datetime', 'cantidad' => 'integer', ]; public function referencia() { return $this->morphTo(); } public function usuario() { return $this->belongsTo(User::class, 'user_id'); } protected static function booted() { static::creating(function ($rec) { // Cantidad debe ser entero >= 1 $rec->cantidad = (int) $rec->cantidad; if ($rec->cantidad <= 0) { throw ValidationException::withMessages(['cantidad' => 'La cantidad debe ser un entero mayor que 0.']); } // Fecha por defecto if (! $rec->fecha_recepcion) { $rec->fecha_recepcion = now(); } // Validación: no permitir sobrepasar la cantidad enviada en la referencia if ($rec->referencia) { $referencia = $rec->referencia; $enviada = (int) ($referencia->cantidad_enviada ?? 0); $yaRecibido = (int) \App\Models\Recepcion::where('referencia_type', get_class($referencia)) ->where('referencia_id', $referencia->id) ->sum('cantidad'); if (($yaRecibido + $rec->cantidad) > $enviada) { throw ValidationException::withMessages(['cantidad' => "La recepción excede la cantidad pendiente (faltan: " . max(0, $enviada - $yaRecibido) . ")."]); } } // Set user if available if (! $rec->user_id && auth()->check()) { $rec->user_id = auth()->id(); } }); static::created(function ($rec) { $rec->syncParentAggregates(); // Crear un traslado parcial desde la referencia usando esta recepción if ($rec->referencia) { $referencia = $rec->referencia; $payload = [ 'cantidad_enviada' => $rec->cantidad, 'cantidad_recibida' => $rec->cantidad, 'fecha_recepcion' => $rec->fecha_recepcion, 'notas' => 'Creado desde recepción #' . $rec->id . ($rec->notas ? (" - " . $rec->notas) : ''), ]; // Map destino según tipo de referencia if ($referencia instanceof Confeccion) { $origen = 'confeccion'; $destino = 'tintoreria'; } elseif ($referencia instanceof Tintoreria) { $origen = 'tintoreria'; $destino = 'acabados'; } else { $origen = 'referencia'; $destino = 'bodega'; } \App\Models\TrasladoPrenda::crearDesdeReferencia($referencia, $origen, $destino, $payload); // Avanzar OP por seguridad $referencia->ordenProduccion?->avanzarEstado(); } }); static::updated(function ($rec) { $rec->syncParentAggregates(); }); static::deleted(function ($rec) { $rec->syncParentAggregates(); }); } public function syncParentAggregates() { if (! $this->referencia) return; $referencia = $this->referencia; $sum = (int) static::where('referencia_type', get_class($referencia)) ->where('referencia_id', $referencia->id) ->sum('cantidad'); $referencia->cantidad_recibida = $sum; $referencia->save(); } }