178 lines
6.5 KiB
PHP
178 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class Recepcion extends Model
|
|
{
|
|
// Nombre de tabla coincidente con la migración
|
|
protected $table = 'recepciones';
|
|
|
|
protected $fillable = [
|
|
'referencia_type',
|
|
'referencia_id',
|
|
'user_id',
|
|
'proveedor_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');
|
|
}
|
|
|
|
public function proveedor()
|
|
{
|
|
return $this->belongsTo(Proveedor::class, 'proveedor_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)
|
|
$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/reprocesos permiten re-recepción cuando regresen
|
|
$arreglos = 0;
|
|
if (method_exists($referencia, 'ajustes')) {
|
|
// Contar tanto 'arreglo' como 'reproceso'
|
|
$arreglos = (int) $referencia->ajustes()->whereIn('tipo', ['arreglo', 'reproceso'])->sum('cantidad');
|
|
}
|
|
|
|
// Los cobros son sobre prendas que YA llegaron (no afectan lo que puede recibir)
|
|
$cobros = 0;
|
|
if (method_exists($referencia, 'cobros')) {
|
|
$cobros = (int) $referencia->cobros()->sum('cantidad');
|
|
}
|
|
|
|
$efectivo = $rec->cantidad - $rec->prendas_defectuosas;
|
|
$yaRecibidoNeto = $yaRecibido - $arreglos;
|
|
$maxPermitido = $enviada; // NO restar cobros - los cobros no afectan lo que puede recibir
|
|
|
|
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}
|
|
• Arreglos/Reprocesos (permiten re-recepción): {$arreglos}
|
|
• Cobros (sobre prendas recibidas): {$cobros}
|
|
• 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();
|
|
}
|
|
}
|