add: agregar campo de código de barras a inventarios y actualizar validaciones

This commit is contained in:
Juan Felipe Zapata Moreno 2026-01-05 20:31:34 -06:00
parent 40bc2b5735
commit 388ba3eff2
7 changed files with 43 additions and 1 deletions

View File

@ -30,7 +30,8 @@ public function index(Request $request)
if ($request->has('q') && $request->q) { if ($request->has('q') && $request->q) {
$products->where(function($query) use ($request) { $products->where(function($query) use ($request) {
$query->where('name', 'like', "%{$request->q}%") $query->where('name', 'like', "%{$request->q}%")
->orWhere('sku', 'like', "%{$request->q}%"); ->orWhere('sku', 'like', "%{$request->q}%")
->orWhere('barcode', $request->q);
}); });
} }
@ -124,6 +125,7 @@ public function downloadTemplate()
$headers = [ $headers = [
'nombre', 'nombre',
'sku', 'sku',
'codigo_barras',
'categoria', 'categoria',
'stock', 'stock',
'costo', 'costo',
@ -135,6 +137,7 @@ public function downloadTemplate()
[ [
'nombre' => 'Samsung Galaxy A55', 'nombre' => 'Samsung Galaxy A55',
'sku' => 'SAM-A55-BLK', 'sku' => 'SAM-A55-BLK',
'codigo_barras' => '7502276853456',
'categoria' => 'Electrónica', 'categoria' => 'Electrónica',
'stock' => 15, 'stock' => 15,
'costo' => 5000.00, 'costo' => 5000.00,
@ -144,6 +147,7 @@ public function downloadTemplate()
[ [
'nombre' => 'Coca Cola 600ml', 'nombre' => 'Coca Cola 600ml',
'sku' => 'COCA-600', 'sku' => 'COCA-600',
'codigo_barras' => '750227686666',
'categoria' => 'Bebidas', 'categoria' => 'Bebidas',
'stock' => 100, 'stock' => 100,
'costo' => 12.50, 'costo' => 12.50,
@ -153,6 +157,7 @@ public function downloadTemplate()
[ [
'nombre' => 'Laptop HP Pavilion 15', 'nombre' => 'Laptop HP Pavilion 15',
'sku' => 'HP-LAP-15', 'sku' => 'HP-LAP-15',
'codigo_barras' => '7502276854443',
'categoria' => 'Computadoras', 'categoria' => 'Computadoras',
'stock' => 5, 'stock' => 5,
'costo' => 8500.00, 'costo' => 8500.00,

View File

@ -50,6 +50,7 @@ public static function rowRules(): array
return [ return [
'nombre' => ['required', 'string', 'max:100'], 'nombre' => ['required', 'string', 'max:100'],
'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'], 'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'],
'codigo_barras' => ['nullable', 'string', 'max:100', 'unique:inventories,barcode'],
'categoria' => ['nullable', 'string', 'max:100'], 'categoria' => ['nullable', 'string', 'max:100'],
'stock' => ['required', 'integer', 'min:0'], 'stock' => ['required', 'integer', 'min:0'],
'costo' => ['required', 'numeric', 'min:0'], 'costo' => ['required', 'numeric', 'min:0'],
@ -68,6 +69,7 @@ public static function rowMessages(): array
'nombre.max' => 'El nombre no debe exceder los 100 caracteres.', 'nombre.max' => 'El nombre no debe exceder los 100 caracteres.',
'sku.unique' => 'El SKU ya existe en el sistema.', 'sku.unique' => 'El SKU ya existe en el sistema.',
'sku.max' => 'El SKU no debe exceder los 50 caracteres.', 'sku.max' => 'El SKU no debe exceder los 50 caracteres.',
'codigo_barras.unique' => 'El código de barras ya existe en el sistema.',
'stock.required' => 'El stock es requerido.', 'stock.required' => 'El stock es requerido.',
'stock.integer' => 'El stock debe ser un número entero.', 'stock.integer' => 'El stock debe ser un número entero.',
'stock.min' => 'El stock no puede ser negativo.', 'stock.min' => 'El stock no puede ser negativo.',

View File

@ -22,6 +22,7 @@ public function rules(): array
// Campos de Inventory // Campos de Inventory
'name' => ['required', 'string', 'max:100'], 'name' => ['required', 'string', 'max:100'],
'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'], 'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'],
'barcode' => ['nullable', 'string', 'unique:inventories,barcode'],
'category_id' => ['required', 'exists:categories,id'], 'category_id' => ['required', 'exists:categories,id'],
'stock' => ['nullable', 'integer', 'min:0'], 'stock' => ['nullable', 'integer', 'min:0'],
@ -42,6 +43,8 @@ public function messages(): array
'sku.string' => 'El SKU debe ser una cadena de texto.', 'sku.string' => 'El SKU debe ser una cadena de texto.',
'sku.max' => 'El SKU no debe exceder los 50 caracteres.', 'sku.max' => 'El SKU no debe exceder los 50 caracteres.',
'sku.unique' => 'El SKU ya está en uso.', 'sku.unique' => 'El SKU ya está en uso.',
'barcode.string' => 'El código de barras debe ser una cadena de texto.',
'barcode.unique' => 'El código de barras ya está registrado en otro producto.',
'category_id.required' => 'La categoría es obligatoria.', 'category_id.required' => 'La categoría es obligatoria.',
'category_id.exists' => 'La categoría seleccionada no es válida.', 'category_id.exists' => 'La categoría seleccionada no es válida.',
'stock.min' => 'El stock no puede ser negativo.', 'stock.min' => 'El stock no puede ser negativo.',

View File

@ -18,10 +18,13 @@ public function authorize(): bool
*/ */
public function rules(): array public function rules(): array
{ {
$inventoryId = $this->route('inventario')?->id;
return [ return [
// Campos de Inventory // Campos de Inventory
'name' => ['nullable', 'string', 'max:100'], 'name' => ['nullable', 'string', 'max:100'],
'sku' => ['nullable', 'string', 'max:50'], 'sku' => ['nullable', 'string', 'max:50'],
'barcode' => ['nullable', 'string', 'unique:inventories,barcode,' . $inventoryId],
'category_id' => ['nullable', 'exists:categories,id'], 'category_id' => ['nullable', 'exists:categories,id'],
'stock' => ['nullable', 'integer', 'min:0'], 'stock' => ['nullable', 'integer', 'min:0'],
@ -41,6 +44,8 @@ public function messages(): array
'sku.string' => 'El SKU debe ser una cadena de texto.', 'sku.string' => 'El SKU debe ser una cadena de texto.',
'sku.max' => 'El SKU no debe exceder los 50 caracteres.', 'sku.max' => 'El SKU no debe exceder los 50 caracteres.',
'sku.unique' => 'El SKU ya está en uso.', 'sku.unique' => 'El SKU ya está en uso.',
'barcode.string' => 'El código de barras debe ser una cadena de texto.',
'barcode.unique' => 'El código de barras ya está registrado en otro producto.',
'category_id.exists' => 'La categoría seleccionada no es válida.', 'category_id.exists' => 'La categoría seleccionada no es válida.',
'stock.min' => 'El stock no puede ser negativo.', 'stock.min' => 'El stock no puede ser negativo.',

View File

@ -69,6 +69,7 @@ public function model(array $row)
$inventory = new Inventory(); $inventory = new Inventory();
$inventory->name = trim($row['nombre']); $inventory->name = trim($row['nombre']);
$inventory->sku = !empty($row['sku']) ? trim($row['sku']) : null; $inventory->sku = !empty($row['sku']) ? trim($row['sku']) : null;
$inventory->barcode = !empty($row['codigo_barras']) ? trim($row['codigo_barras']) : null;
$inventory->category_id = $categoryId; $inventory->category_id = $categoryId;
$inventory->stock = (int) $row['stock']; $inventory->stock = (int) $row['stock'];
$inventory->is_active = true; $inventory->is_active = true;

View File

@ -19,6 +19,7 @@ class Inventory extends Model
'category_id', 'category_id',
'name', 'name',
'sku', 'sku',
'barcode',
'stock', 'stock',
'is_active', 'is_active',
]; ];

View File

@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('inventories', function (Blueprint $table) {
$table->string('barcode')
->nullable()
->unique()
->after('sku');
});
}
public function down(): void
{
Schema::table('inventories', function (Blueprint $table) {
$table->dropColumn('barcode');
});
}
};