diff --git a/app/Http/Controllers/App/InventoryController.php b/app/Http/Controllers/App/InventoryController.php index 5db920d..526b38d 100644 --- a/app/Http/Controllers/App/InventoryController.php +++ b/app/Http/Controllers/App/InventoryController.php @@ -30,7 +30,8 @@ public function index(Request $request) if ($request->has('q') && $request->q) { $products->where(function($query) use ($request) { $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 = [ 'nombre', 'sku', + 'codigo_barras', 'categoria', 'stock', 'costo', @@ -135,6 +137,7 @@ public function downloadTemplate() [ 'nombre' => 'Samsung Galaxy A55', 'sku' => 'SAM-A55-BLK', + 'codigo_barras' => '7502276853456', 'categoria' => 'Electrónica', 'stock' => 15, 'costo' => 5000.00, @@ -144,6 +147,7 @@ public function downloadTemplate() [ 'nombre' => 'Coca Cola 600ml', 'sku' => 'COCA-600', + 'codigo_barras' => '750227686666', 'categoria' => 'Bebidas', 'stock' => 100, 'costo' => 12.50, @@ -153,6 +157,7 @@ public function downloadTemplate() [ 'nombre' => 'Laptop HP Pavilion 15', 'sku' => 'HP-LAP-15', + 'codigo_barras' => '7502276854443', 'categoria' => 'Computadoras', 'stock' => 5, 'costo' => 8500.00, diff --git a/app/Http/Requests/App/InventoryImportRequest.php b/app/Http/Requests/App/InventoryImportRequest.php index 26dcfab..d45b29f 100644 --- a/app/Http/Requests/App/InventoryImportRequest.php +++ b/app/Http/Requests/App/InventoryImportRequest.php @@ -50,6 +50,7 @@ public static function rowRules(): array return [ 'nombre' => ['required', 'string', 'max:100'], 'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'], + 'codigo_barras' => ['nullable', 'string', 'max:100', 'unique:inventories,barcode'], 'categoria' => ['nullable', 'string', 'max:100'], 'stock' => ['required', 'integer', '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.', 'sku.unique' => 'El SKU ya existe en el sistema.', '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.integer' => 'El stock debe ser un número entero.', 'stock.min' => 'El stock no puede ser negativo.', diff --git a/app/Http/Requests/App/InventoryStoreRequest.php b/app/Http/Requests/App/InventoryStoreRequest.php index b99129e..ac93521 100644 --- a/app/Http/Requests/App/InventoryStoreRequest.php +++ b/app/Http/Requests/App/InventoryStoreRequest.php @@ -22,6 +22,7 @@ public function rules(): array // Campos de Inventory 'name' => ['required', 'string', 'max:100'], 'sku' => ['nullable', 'string', 'max:50', 'unique:inventories,sku'], + 'barcode' => ['nullable', 'string', 'unique:inventories,barcode'], 'category_id' => ['required', 'exists:categories,id'], 'stock' => ['nullable', 'integer', 'min:0'], @@ -42,6 +43,8 @@ public function messages(): array 'sku.string' => 'El SKU debe ser una cadena de texto.', 'sku.max' => 'El SKU no debe exceder los 50 caracteres.', '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.exists' => 'La categoría seleccionada no es válida.', 'stock.min' => 'El stock no puede ser negativo.', diff --git a/app/Http/Requests/App/InventoryUpdateRequest.php b/app/Http/Requests/App/InventoryUpdateRequest.php index e4d5f2f..edf78cb 100644 --- a/app/Http/Requests/App/InventoryUpdateRequest.php +++ b/app/Http/Requests/App/InventoryUpdateRequest.php @@ -18,10 +18,13 @@ public function authorize(): bool */ public function rules(): array { + $inventoryId = $this->route('inventario')?->id; + return [ // Campos de Inventory 'name' => ['nullable', 'string', 'max:100'], 'sku' => ['nullable', 'string', 'max:50'], + 'barcode' => ['nullable', 'string', 'unique:inventories,barcode,' . $inventoryId], 'category_id' => ['nullable', 'exists:categories,id'], 'stock' => ['nullable', 'integer', 'min:0'], @@ -41,6 +44,8 @@ public function messages(): array 'sku.string' => 'El SKU debe ser una cadena de texto.', 'sku.max' => 'El SKU no debe exceder los 50 caracteres.', '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.', 'stock.min' => 'El stock no puede ser negativo.', diff --git a/app/Imports/ProductsImport.php b/app/Imports/ProductsImport.php index 8d9676f..ffdce08 100644 --- a/app/Imports/ProductsImport.php +++ b/app/Imports/ProductsImport.php @@ -69,6 +69,7 @@ public function model(array $row) $inventory = new Inventory(); $inventory->name = trim($row['nombre']); $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->stock = (int) $row['stock']; $inventory->is_active = true; diff --git a/app/Models/Inventory.php b/app/Models/Inventory.php index 4c5c673..b119568 100644 --- a/app/Models/Inventory.php +++ b/app/Models/Inventory.php @@ -19,6 +19,7 @@ class Inventory extends Model 'category_id', 'name', 'sku', + 'barcode', 'stock', 'is_active', ]; diff --git a/database/migrations/2026_01_05_200533_add_barcode_to_inventories_table.php b/database/migrations/2026_01_05_200533_add_barcode_to_inventories_table.php new file mode 100644 index 0000000..c622759 --- /dev/null +++ b/database/migrations/2026_01_05_200533_add_barcode_to_inventories_table.php @@ -0,0 +1,25 @@ +string('barcode') + ->nullable() + ->unique() + ->after('sku'); + }); + } + + public function down(): void + { + Schema::table('inventories', function (Blueprint $table) { + $table->dropColumn('barcode'); + }); + } +};