diff --git a/app/Models/InventarioPrendaDistribucion.php b/app/Models/InventarioPrendaDistribucion.php index 70f773b..0def919 100644 --- a/app/Models/InventarioPrendaDistribucion.php +++ b/app/Models/InventarioPrendaDistribucion.php @@ -41,6 +41,43 @@ class InventarioPrendaDistribucion extends Model protected static function booted() { + // Validaciones: impedir que la suma de distribuciones supere la cantidad terminada + static::creating(function ($dist) { + $parentId = $dist->inventario_prenda_id ?? null; + if (! $parentId) return; + + $parent = \App\Models\InventarioPrenda::find($parentId); + if (! $parent) return; + + $cantidad = intval($dist->cantidad ?? 0); + $sumExistentes = (int) self::where('inventario_prenda_id', $parentId)->sum('cantidad'); + + if (($sumExistentes + $cantidad) > (int) $parent->cantidad_terminada) { + throw \Illuminate\Validation\ValidationException::withMessages([ + 'cantidad' => 'La suma de las distribuciones excede la cantidad terminada disponible (' . $parent->cantidad_terminada . ').', + ]); + } + }); + + static::updating(function ($dist) { + $parentId = $dist->inventario_prenda_id ?? null; + if (! $parentId) return; + + $parent = \App\Models\InventarioPrenda::find($parentId); + if (! $parent) return; + + $newCantidad = intval($dist->cantidad ?? 0); + $othersSum = (int) self::where('inventario_prenda_id', $parentId) + ->where('id', '<>', $dist->id) + ->sum('cantidad'); + + if (($othersSum + $newCantidad) > (int) $parent->cantidad_terminada) { + throw \Illuminate\Validation\ValidationException::withMessages([ + 'cantidad' => 'La suma de las distribuciones excede la cantidad terminada disponible (' . $parent->cantidad_terminada . ').', + ]); + } + }); + // Al crear una distribución, incrementar stock static::created(function ($dist) { $cantidad = $dist->cantidad ?? 0; diff --git a/tests/Feature/InventarioDistribucionTest.php b/tests/Feature/InventarioDistribucionTest.php index 678c456..eb424f0 100644 --- a/tests/Feature/InventarioDistribucionTest.php +++ b/tests/Feature/InventarioDistribucionTest.php @@ -78,4 +78,60 @@ class InventarioDistribucionTest extends TestCase $method->setAccessible(true); $method->invoke($page, $data); } + + public function test_creating_distribution_directly_exceeding_throws_validation_exception() + { + $categoria = \App\Models\Categoria::create(['nombre' => 'Ropa']); + $producto = Producto::create(['nombre' => 'Camisa', 'descripcion' => '', 'stock' => 0, 'estado' => true, 'precio_compra' => 0, 'precio_venta' => 0, 'unidad_medida' => 'unidad', 'codigo_barras' => '', 'categoria_id' => $categoria->id, 'imagen' => '']); + + $op = OrdenProduccion::create(['numero_orden' => 'OP-0003', 'prenda_modelo' => 'Camisa', 'referencia' => 'C-02', 'cantidad_total' => 10, 'metros_requeridos' => 0, 'fecha_inicio' => now(), 'fecha_entrega_estimada' => now()->addDays(7)]); + + $inv = InventarioPrenda::create(['orden_produccion_id' => $op->id, 'cantidad_terminada' => 5, 'cantidad_disponible' => 5, 'fecha_ingreso' => now(), 'estado' => 'en_bodega', 'producto_id' => $producto->id]); + + // Crear primera distribución 2 + InventarioPrendaDistribucion::create([ + 'inventario_prenda_id' => $inv->id, + 'bodega_id' => 1, + 'cantidad' => 2, + ]); + + $this->expectException(\Illuminate\Validation\ValidationException::class); + + // Intentar crear una segunda distribución que exceda (4) => 2 + 4 = 6 > 5 + InventarioPrendaDistribucion::create([ + 'inventario_prenda_id' => $inv->id, + 'bodega_id' => 1, + 'cantidad' => 4, + ]); + } + + public function test_updating_distribution_exceeding_throws_validation_exception() + { + $categoria = \App\Models\Categoria::create(['nombre' => 'Ropa']); + $producto = Producto::create(['nombre' => 'Saco', 'descripcion' => '', 'stock' => 0, 'estado' => true, 'precio_compra' => 0, 'precio_venta' => 0, 'unidad_medida' => 'unidad', 'codigo_barras' => '', 'categoria_id' => $categoria->id, 'imagen' => '']); + + $op = OrdenProduccion::create(['numero_orden' => 'OP-0004', 'prenda_modelo' => 'Saco', 'referencia' => 'S-01', 'cantidad_total' => 10, 'metros_requeridos' => 0, 'fecha_inicio' => now(), 'fecha_entrega_estimada' => now()->addDays(7)]); + + $inv = InventarioPrenda::create(['orden_produccion_id' => $op->id, 'cantidad_terminada' => 5, 'cantidad_disponible' => 5, 'fecha_ingreso' => now(), 'estado' => 'en_bodega', 'producto_id' => $producto->id]); + + // Crear dos distribuciones 2 y 2 + $d1 = InventarioPrendaDistribucion::create([ + 'inventario_prenda_id' => $inv->id, + 'bodega_id' => 1, + 'cantidad' => 2, + ]); + + $d2 = InventarioPrendaDistribucion::create([ + 'inventario_prenda_id' => $inv->id, + 'bodega_id' => 1, + 'cantidad' => 2, + ]); + + $this->expectException(\Illuminate\Validation\ValidationException::class); + + // Intentar actualizar d1 a 4 => 4 + 2 = 6 > 5 + $d1->cantidad = 4; + $d1->save(); + } } +