This commit is contained in:
Lizandro Guarnizo
2026-02-09 15:02:56 -05:00
parent d1813e262e
commit 2d99bfe244
7 changed files with 535 additions and 36 deletions
+75 -29
View File
@@ -3,6 +3,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class ProcesoAcabado extends Model
{
@@ -38,6 +39,67 @@ class ProcesoAcabado extends Model
return $this->belongsTo(Proveedor::class);
}
/* Recepciones polimórficas */
public function recepciones()
{
return $this->morphMany(\App\Models\Recepcion::class, 'referencia');
}
public function cobros()
{
return $this->morphMany(\App\Models\Cobro::class, 'referencia');
}
public function ajustes()
{
return $this->morphMany(\App\Models\Ajuste::class, 'referencia');
}
// Total recibido calculado desde recepciones (fuente de verdad)
// Menos reprocesos (permiten re-recepción) y menos cobros (no pasan a inventario)
public function getRecibidoTotalAttribute()
{
$recepciones = (int) $this->recepciones()->sum(DB::raw('cantidad - COALESCE(prendas_defectuosas, 0)'));
$reprocesos = (int) $this->ajustes()->where('tipo', 'reproceso')->sum('cantidad');
$cobros = (int) $this->cobros()->sum('cantidad');
return max(0, $recepciones - $reprocesos - $cobros);
}
// Total de pérdidas registradas en las recepciones
public function getPerdidasTotalAttribute()
{
return (int) $this->recepciones()->sum('prendas_defectuosas');
}
public function getCobrosTotalAttribute()
{
return (float) $this->cobros()->sum('valor');
}
// Cuantas faltan por recibir
public function getFaltantesAttribute()
{
$enviada = (int)($this->cantidad_enviada ?? 0);
$recepciones = (int) $this->recepciones()->sum(DB::raw('cantidad - COALESCE(prendas_defectuosas, 0)'));
$reprocesos = (int) $this->ajustes()->where('tipo', 'reproceso')->sum('cantidad');
// Lo que puede recibir = enviadas - recepciones + reprocesos (reprocesos permiten re-recepción)
return max(0, $enviada - $recepciones + $reprocesos);
}
// Estado de recepción (Parcial / Completado)
public function getEstadoRecepcionAttribute()
{
$faltan = $this->faltantes ?? 0;
if (($this->cantidad_enviada ?? 0) <= 0) {
return 'Sin envío';
}
return $faltan > 0 ? 'Parcial' : 'Completado';
}
/* Lógica de negocio */
protected static function booted()
{
@@ -58,34 +120,21 @@ class ProcesoAcabado extends Model
}
});
$createTrasladoFn = function ($acabado) {
if ($acabado->cantidad_recibida !== null) {
// Evitar duplicados
$exists = \App\Models\TrasladoPrenda::where('referencia_type', self::class)
->where('referencia_id', $acabado->id)
->exists();
// Al guardar recepciones, avanzar estado de la OP
static::saved(function ($acabado) {
// Verificar si el proceso está completado (todas las prendas recibidas)
$faltantes = $acabado->faltantes ?? 0;
if ($faltantes === 0 && ($acabado->cantidad_enviada ?? 0) > 0) {
// Avanzar la OP al completar este proceso
$acabado->ordenProduccion?->avanzarEstado();
if (! $exists) {
$destino = 'bodega';
\App\Models\TrasladoPrenda::crearDesdeReferencia(
$acabado,
'acabados',
$destino
);
// Avanzar la OP al cerrar este proceso
$acabado->ordenProduccion?->avanzarEstado();
}
}
if (
$acabado->fecha_recepcion &&
$acabado->cantidad_recibida !== null
) {
// Validar si ya no quedan procesos pendientes
$pendientes = self::where('orden_produccion_id', $acabado->orden_produccion_id)
->whereNull('fecha_recepcion')
->where(function($q) {
$q->whereNull('cantidad_enviada')
->orWhereRaw('cantidad_enviada > 0 AND (SELECT COALESCE(SUM(cantidad - COALESCE(prendas_defectuosas, 0)), 0) FROM recepciones WHERE referencia_type = ? AND referencia_id = proceso_acabados.id) < cantidad_enviada', [self::class]);
})
->exists();
if (!$pendientes) {
@@ -93,9 +142,6 @@ class ProcesoAcabado extends Model
$acabado->ordenProduccion?->tryFinalize();
}
}
};
static::updated($createTrasladoFn);
static::saved($createTrasladoFn);
});
}
}