Files
pos_heidiver/app/Models/Recepcion.php
T
2026-01-29 17:14:05 -05:00

169 lines
6.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\ValidationException;
class Recepcion extends Model
{
// Nombre de tabla coincidente con la migración
protected $table = 'recepciones';
protected $fillable = [
'referencia_type',
'referencia_id',
'user_id',
'cantidad',
'prendas_defectuosas',
'fecha_recepcion',
'notas',
];
protected $casts = [
'fecha_recepcion' => 'datetime',
'cantidad' => 'integer',
'prendas_defectuosas' => '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;
$rec->prendas_defectuosas = (int) ($rec->prendas_defectuosas ?? 0);
if ($rec->cantidad <= 0) {
throw ValidationException::withMessages(['cantidad' => 'La cantidad debe ser un entero mayor que 0.']);
}
if ($rec->prendas_defectuosas < 0) {
throw ValidationException::withMessages(['prendas_defectuosas' => 'La cantidad de prendas defectuosas no puede ser negativa.']);
}
if ($rec->prendas_defectuosas > $rec->cantidad) {
throw ValidationException::withMessages(['prendas_defectuosas' => 'Las prendas defectuosas no pueden superar la cantidad recibida.']);
}
// Fecha por defecto
if (! $rec->fecha_recepcion) {
$rec->fecha_recepcion = now();
}
// Validación: no permitir sobrepasar la cantidad enviada en la referencia (considerando cobros)
if ($rec->referencia) {
$referencia = $rec->referencia;
$enviada = (int) ($referencia->cantidad_enviada ?? 0);
// Ya recibido efectivo (cantidad - defectuosos) - arreglos permiten re-recepción
$yaRecibido = (int) \App\Models\Recepcion::where('referencia_type', get_class($referencia))
->where('referencia_id', $referencia->id)
->sum(\DB::raw('cantidad - COALESCE(prendas_defectuosas, 0)'));
// Los arreglos se restan porque permiten re-recepción cuando regresen
$arreglos = 0;
if (method_exists($referencia, 'ajustes')) {
$arreglos = (int) $referencia->ajustes()->where('tipo', 'arreglo')->sum('cantidad');
}
// Los cobros NO permiten más recepciones (son prendas que no llegaron)
$cobros = 0;
if (method_exists($referencia, 'cobros')) {
$cobros = (int) $referencia->cobros()->sum('cantidad');
}
$efectivo = $rec->cantidad - $rec->prendas_defectuosas;
$yaRecibidoNeto = $yaRecibido - $arreglos;
$maxPermitido = $enviada - $cobros;
if (($yaRecibidoNeto + $efectivo) > $maxPermitido) {
$disponible = max(0, $maxPermitido - $yaRecibidoNeto);
throw ValidationException::withMessages([
'cantidad' => "La recepción excede lo permitido.
📊 Resumen:
• Enviadas: {$enviada}
• Ya recibidas (neto): {$yaRecibidoNeto}
• Cobros registrados: {$cobros}
• Arreglos (permiten re-recepción): {$arreglos}
• Disponible para recibir: {$disponible}
➡️ Solo puedes recibir {$disponible} prendas más."
]);
}
}
// 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;
$efectivo = (int) ($rec->cantidad - ($rec->prendas_defectuosas ?? 0));
$payload = [
'cantidad_enviada' => $rec->cantidad,
'cantidad_recibida' => $efectivo,
'fecha_recepcion' => $rec->fecha_recepcion,
'notas' => 'Creado desde recepción #' . $rec->id . ($rec->notas ? (" - " . $rec->notas) : ''),
'prendas_defectuosas' => $rec->prendas_defectuosas ?? 0,
];
// 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(\DB::raw('cantidad - COALESCE(prendas_defectuosas, 0)'));
$referencia->cantidad_recibida = $sum;
$referencia->save();
}
}