This commit is contained in:
lizandrogd
2026-01-19 18:24:35 -05:00
parent edcd51e651
commit 084b644714
10 changed files with 412 additions and 66 deletions
+13 -25
View File
@@ -64,35 +64,23 @@ class Confeccion extends Model
}
});
// Crear traslado cuando la confección tenga recepción (en creación y en actualización)
$createTrasladoFn = function ($confeccion) {
if ($confeccion->cantidad_recibida !== null) {
// Evitar duplicados
$exists = \App\Models\TrasladoPrenda::where('referencia_type', self::class)
->where('referencia_id', $confeccion->id)
->exists();
/* Recepciones polimórficas */
public function recepciones()
{
return $this->morphMany(\App\Models\Recepcion::class, 'referencia');
}
if (! $exists) {
$destino = 'tintoreria';
// Cuantas faltan por recibir
public function getFaltantesAttribute()
{
return max(0, (int)($this->cantidad_enviada ?? 0) - (int)($this->cantidad_recibida ?? 0));
}
\App\Models\TrasladoPrenda::crearDesdeReferencia(
$confeccion,
'confeccion',
$destino
);
// Marcar el paso como terminado y avanzar la OP incluso si fue parcial
$confeccion->ordenProduccion?->avanzarEstado();
}
}
// Mantener el comportamiento anterior: si está completo, también avanzamos (por seguridad)
// Mantener avance de OP cuando la confección se completa
static::saved(function ($confeccion) {
if ($confeccion->estado === 'completo') {
$confeccion->ordenProduccion?->avanzarEstado();
}
};
static::updated($createTrasladoFn);
static::saved($createTrasladoFn);
});
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\ValidationException;
class Recepcion extends Model
{
protected $fillable = [
'referencia_type',
'referencia_id',
'user_id',
'cantidad',
'fecha_recepcion',
'notas',
];
protected $casts = [
'fecha_recepcion' => '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();
}
}
+14 -33
View File
@@ -55,42 +55,23 @@ class Tintoreria extends Model
}
});
$createTrasladoFn = function ($tintoreria) {
if ($tintoreria->cantidad_recibida !== null) {
// Evitar duplicados
$exists = \App\Models\TrasladoPrenda::where('referencia_type', self::class)
->where('referencia_id', $tintoreria->id)
->exists();
/* Recepciones polimórficas */
public function recepciones()
{
return $this->morphMany(\App\Models\Recepcion::class, 'referencia');
}
if (! $exists) {
// Mapear "perdidas" a prendas_defectuosas en el traslado
$payload = [
'prendas_defectuosas' => $tintoreria->perdidas ?? 0,
];
// Cuantas faltan por recibir
public function getFaltantesAttribute()
{
return max(0, (int)($this->cantidad_enviada ?? 0) - (int)($this->cantidad_recibida ?? 0));
}
$destino = 'acabados';
\App\Models\TrasladoPrenda::crearDesdeReferencia(
$tintoreria,
'tintoreria',
$destino,
$payload
);
// Avanzar la OP al cerrar el paso
$tintoreria->ordenProduccion?->avanzarEstado();
}
}
if (
$tintoreria->fecha_recepcion &&
$tintoreria->cantidad_recibida !== null
) {
// Avanzar OP al cerrar el paso o cuando se complete
static::saved(function ($tintoreria) {
if ($tintoreria->fecha_recepcion && $tintoreria->cantidad_recibida !== null) {
$tintoreria->ordenProduccion?->avanzarEstado();
}
};
static::updated($createTrasladoFn);
static::saved($createTrasladoFn);
});
}
}