diff --git a/app/Console/Commands/ImportarExcelLimpio.php b/app/Console/Commands/ImportarExcelLimpio.php index ef2e364..de40db8 100644 --- a/app/Console/Commands/ImportarExcelLimpio.php +++ b/app/Console/Commands/ImportarExcelLimpio.php @@ -9,22 +9,15 @@ use Illuminate\Support\Facades\Storage; class ImportarExcelLimpio extends Command { - // Este es el comando que vas a escribir en la terminal protected $signature = 'importar:excel'; - protected $description = 'Importa el catálogo limpio desde el archivo CSV'; + protected $description = 'Importa el catálogo desde CSV con asociación dinámica de proveedores'; public function handle() { - $this->info("Iniciando importación del Excel limpio..."); + $this->info("Iniciando importación del Excel con lógica de proveedores..."); - // 1. Asegurarnos de que existe el proveedor comodín (para evitar el error de la llave foránea) - Supplier::firstOrCreate( - ['id' => 1], - [ - 'name' => 'Proveedor General Lauck', - 'phone' => '0000000000' - ] - ); + // Aseguramos que existan al menos los 3 proveedores básicos por si acaso + $this->asegurarProveedores(); $rutaCompleta = storage_path('app/imports/catalogo_limpio.csv'); @@ -32,45 +25,58 @@ class ImportarExcelLimpio extends Command $this->error("No se encontró el archivo en: " . $rutaCompleta); return; } - $file = fopen($rutaCompleta, 'r'); - // Saltamos la primera fila (porque son los títulos: tipo, descripcion, costo, precio) - fgetcsv($file); + $file = fopen($rutaCompleta, 'r'); + fgetcsv($file); // Saltar cabecera $contador = 0; while (($fila = fgetcsv($file, 1000, ',')) !== false) { - // Asignamos las columnas del Excel (0 a 3) - $tipoRaw = strtolower(trim($fila[0] ?? '')); - $descripcion = trim($fila[1] ?? ''); - $costoRaw = trim($fila[2] ?? ''); - $precioRaw = trim($fila[3] ?? ''); + // 1. Lectura de las 6 columnas + $tipoRaw = strtolower(trim($fila[0] ?? '')); + $nombreRaw = trim($fila[1] ?? ''); + $descripcionRaw = trim($fila[2] ?? ''); + $costoRaw = trim($fila[3] ?? ''); + $precioRaw = trim($fila[4] ?? ''); + $proveedorId = trim($fila[5] ?? 1); // ID del proveedor - // Si la descripción está vacía, saltamos la fila - if (empty($descripcion)) { - continue; - } + if (empty($nombreRaw)) continue; - // --- Lógica de limpieza de Tipos --- - // Si en el Excel dice "bicicleta", lo guardamos como "bike" para mantener el estándar. - $tipoFinal = ($tipoRaw === 'bicicleta') ? 'bike' : $tipoRaw; + // 2. Limpieza de Nombre (Primera letra de cada palabra) + $nombreSinEspacios = preg_replace('/\s+/', ' ', $nombreRaw); + $nombreFinal = mb_convert_case($nombreSinEspacios, MB_CASE_TITLE, "UTF-8"); - // --- Lógica de limpieza de Precios ("$ 7,200" -> 7200.0) --- - // Borramos el signo peso, los espacios y las comas de los miles + // 3. Traductor de Categorías (Evita errores SQL de truncado) + $tipoRaw = preg_replace('/[\xEF\xBB\xBF]/', '', $tipoRaw); // Limpieza de BOM + $mapeoTipos = [ + 'bicicleta' => 'bike', 'bicicletas' => 'bike', 'bike' => 'bike', + 'indumentaria' => 'clothing', 'ropa' => 'clothing', 'clothing' => 'clothing', + 'accesorio' => 'accessory', 'accesorios' => 'accessory', 'accessory' => 'accessory', + 'repuesto' => 'spare', 'repuestos' => 'spare', 'spare' => 'spare', + 'infantil' => 'children', 'niños' => 'children', 'children' => 'children', + 'rollers' => 'rollers', 'roller' => 'rollers', + 'skate' => 'skate', 'skates' => 'skate', + 'servicio' => 'service', 'service' => 'service', + 'otro' => 'other', 'otros' => 'other', 'other' => 'other' + ]; + $tipoFinal = $mapeoTipos[$tipoRaw] ?? 'other'; + + // 4. Limpieza de Precios $costoLimpio = (float) str_replace(['$', ' ', ','], '', $costoRaw); $precioLimpio = (float) str_replace(['$', ' ', ','], '', $precioRaw); - // Guardamos en la base de datos + // 5. Creación o Actualización Product::updateOrCreate( - ['name' => $descripcion], // Buscamos por descripción + ['name' => $nombreFinal], [ - 'type' => $tipoFinal, - 'cost' => $costoLimpio, - 'price' => $precioLimpio, - 'stock_quantity' => 20, // Al ser lista de precios, entra con stock 0 + 'description' => $descripcionRaw, + 'type' => $tipoFinal, + 'cost' => $costoLimpio, + 'price' => $precioLimpio, + 'suppliers_id' => $proveedorId, // Asociación dinámica + 'stock_quantity' => 20, 'min_stock_alert' => 5, - 'suppliers_id' => 1, ] ); @@ -78,6 +84,25 @@ class ImportarExcelLimpio extends Command } fclose($file); - $this->info("¡Éxito! Se importaron/actualizaron {$contador} productos."); + $this->info("¡Éxito! Se procesaron {$contador} productos con sus respectivos proveedores."); + } + + /** + * Crea los proveedores básicos si no existen para evitar errores de integridad. + */ + private function asegurarProveedores() + { + $proveedores = [ + 1 => 'Proveedor General Lauck', + 2 => 'Distribuidora Norte', + 3 => 'Repuestos Express' + ]; + + foreach ($proveedores as $id => $name) { + Supplier::firstOrCreate( + ['id' => $id], + ['name' => $name, 'phone' => '0000000000'] + ); + } } } \ No newline at end of file diff --git a/app/Http/Controllers/ProductosController.php b/app/Http/Controllers/ProductosController.php index 6ddeded..ea104a4 100644 --- a/app/Http/Controllers/ProductosController.php +++ b/app/Http/Controllers/ProductosController.php @@ -3,16 +3,14 @@ namespace App\Http\Controllers; use App\Models\Product; +use App\Models\Supplier; use Illuminate\Http\Request; use Illuminate\Validation\Rule; use Illuminate\Support\Facades\Storage; class ProductosController extends Controller { - /** - * Muestra la lista de productos con buscador y paginación. - */ - public function index(Request $request) + /*public function index(Request $request) { $query = $request->input('search'); $status = $request->input('stock_status'); @@ -40,89 +38,79 @@ class ProductosController extends Controller ->where('type', '!=', 'service'); } }) - ->orderBy('stock_quantity', 'asc') // Ordena primero los que tienen poco stock - ->paginate(10) // Muestra de a 10 productos - ->withQueryString(); // Mantiene los filtros al pasar a la página 2, 3, etc. + ->orderBy('stock_quantity', 'asc') + ->paginate(10) + ->withQueryString(); + + return view('productos.index', compact('products')); + }*/ + public function index() + { + // Traemos todos los productos ordenados (sin paginar, para que JS los pueda buscar todos) + $products = Product::orderBy('name', 'asc')->get(); return view('productos.index', compact('products')); } - /** - * Muestra el formulario de creación. - */ public function create() { - return view('productos.create'); + $suppliers = Supplier::orderBy('name')->get(); + return view('productos.create', compact('suppliers')); } - /** - * Guarda el producto nuevo en la base de datos. - */ public function store(Request $request) { - // 1. Validamos los datos con las nuevas columnas $validated = $request->validate([ - 'name' => 'required|string|max:255', // CORREGIDO: description en lugar de name + 'name' => 'required|string|max:255', 'price' => 'required|numeric|min:0', 'cost' => 'nullable|numeric|min:0', 'stock_quantity' => 'required|integer|min:0', 'min_stock_alert' => 'required|integer|min:0', 'type' => 'required|in:bike,accessory,clothing,spare,service,children,skate,rollers,other', 'serial_number' => 'nullable|string|max:100', - 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048', + 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048', + 'suppliers_id' => 'required|exists:suppliers,id', + 'description' => 'nullable|string' ]); - // 2. Validacion de imagenes if ($request->hasFile('image')) { $path = $request->file('image')->store('products', 'public'); $validated['image_path'] = $path; } unset($validated['image']); - // Para no romper la logica del supplier - $validated['suppliers_id'] = 1; - - // 3. Creamos el producto Product::create($validated); - // 4. Redireccionamos return redirect()->route('productos.index') ->with('success', 'Producto creado correctamente.'); } - /** - * Muestra el detalle de un producto. - */ public function show(Product $product) { return view('productos.show', compact('product')); } - /** - * Muestra el formulario de edición. - */ public function edit(Product $product) { - return view('productos.edit', compact('product')); + $suppliers = Supplier::orderBy('name')->get(); + return view('productos.edit', compact('product', 'suppliers')); } - /** - * Actualiza el producto existente. - */ public function update(Request $request, Product $product) { $validated = $request->validate([ - 'name' => 'required|string|max:255', // CORREGIDO - 'type' => 'required|in:bike,accessory,clothing,spare,service,children,skate,rollers,other', // CORREGIDO + 'name' => 'required|string|max:255', + 'type' => 'required|in:bike,accessory,clothing,spare,service,children,skate,rollers,other', 'price' => 'required|numeric|min:0', 'cost' => 'nullable|numeric|min:0', 'stock_quantity' => 'required|integer|min:0', 'min_stock_alert' => 'required|integer|min:0', 'serial_number' => 'nullable|string|max:100', 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048', + 'suppliers_id' => 'required|exists:suppliers,id', + 'description' => 'nullable|string' ]); - // 2. Manejo de imagen al actualizar if ($request->hasFile('image')) { if ($product->image_path) { Storage::disk('public')->delete($product->image_path); @@ -132,8 +120,6 @@ class ProductosController extends Controller $validated['image_path'] = $path; } unset($validated['image']); - - $validated['suppliers_id'] = 1; $product->update($validated); @@ -141,9 +127,6 @@ class ProductosController extends Controller ->with('success', 'Producto actualizado exitosamente.'); } - /** - * Elimina el producto. - */ public function destroy(Product $product) { if ($product->image_path) { diff --git a/app/Http/Controllers/SupplierController.php b/app/Http/Controllers/SupplierController.php new file mode 100644 index 0000000..f279594 --- /dev/null +++ b/app/Http/Controllers/SupplierController.php @@ -0,0 +1,101 @@ +input('search'); + + $suppliers = Supplier::query() + ->when($query, function ($q) use ($query) { + return $q->where('name', 'like', "%{$query}%"); + }) + ->orderBy('name', 'asc') + ->paginate(10) + ->withQueryString(); + + return view('suppliers.index', compact('suppliers')); + } + + /** + * para crear un proveedor + */ + public function create() + { + return view('suppliers.create'); + } + + + public function store(Request $request) + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'phone' => 'nullable|string|max:50', + 'email' => 'nullable|email|max:255|unique:suppliers,email', + 'address' => 'nullable|string|max:255', + ]); + + Supplier::create($validated); + + return redirect()->route('suppliers.index') + ->with('success', 'Proveedor creado correctamente.'); + } + + /** + * muestra un proveedor + */ + public function show(Supplier $supplier) + { + return view('suppliers.show', compact('supplier')); + } + + public function edit(Supplier $supplier) + { + return view('suppliers.edit', compact('supplier')); + } + + public function update(Request $request, Supplier $supplier) + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'phone' => 'nullable|string|max:50', + 'email' => 'nullable|email|max:255|unique:suppliers,email,' . $supplier->id, + 'address' => 'nullable|string|max:255', + ]); + + $supplier->update($validated); + + return redirect()->route('suppliers.index') + ->with('success', 'Proveedor actualizado correctamente.'); + } + + /** + * elimina (solo si no tiene productos asociados) + */ + public function destroy(Supplier $supplier) + { + try { + $supplier->delete(); + return redirect()->route('suppliers.index') + ->with('success', 'Proveedor eliminado correctamente.'); + + } catch (\Illuminate\Database\QueryException $e) { + // Si el proveedor tiene productos asociados, va a tirar un error de llave foránea. + return back()->with('error', 'No se puede eliminar el proveedor porque tiene productos registrados en el inventario.'); + } + } + /** + * trae todos los productos de un proveedor + */ + public function order(Supplier $supplier) + { + $products = $supplier->products()->orderBy('name')->get(); + + return view('suppliers.order', compact('supplier', 'products')); + } +} \ No newline at end of file diff --git a/app/Models/Product.php b/app/Models/Product.php index f9ce056..664995f 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -8,7 +8,18 @@ use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; - protected $guarded = []; + protected $fillable = [ + 'name', + 'description', + 'type', + 'cost', + 'price', + 'stock_quantity', + 'min_stock_alert', + 'serial_number', + 'image_path', + 'suppliers_id' + ]; public function hasLowStock(): bool @@ -20,16 +31,11 @@ class Product extends Model { return $this->belongsTo(Supplier::class); } - - // Opción 1: Relación directa con los detalles (Renglones de ticket) - // Útil para saber cantidad total vendida: $product->saleDetails->sum('quantity') public function saleDetails() { return $this->hasMany(SaleDetail::class); } - // Opción 2 (Pro Tip): Relación directa con las Ventas a través de los detalles - // Útil para saber EN QUÉ fechas se vendió: $product->sales public function sales() { return $this->belongsToMany(Sale::class, 'sale_details'); diff --git a/app/Models/Supplier.php b/app/Models/Supplier.php index 5690a35..bc3da55 100644 --- a/app/Models/Supplier.php +++ b/app/Models/Supplier.php @@ -1,15 +1,18 @@ hasMany(Product::class); + return $this->hasMany(Product::class, 'suppliers_id'); } -} +} \ No newline at end of file diff --git a/database/migrations/2025_12_06_182358_create_products_table.php b/database/migrations/2025_12_06_182358_create_products_table.php index fe306b5..d500b03 100644 --- a/database/migrations/2025_12_06_182358_create_products_table.php +++ b/database/migrations/2025_12_06_182358_create_products_table.php @@ -13,20 +13,13 @@ return new class extends Migration { Schema::create('products', function (Blueprint $table) { $table->id(); - $table->enum('type', ['bike', 'accessory', 'clothing', 'spare', 'children', 'skate', 'rollers','other']); // Tipo de producto - //$table->string('name'); - //$table->string('sku')->unique()->nullable(); // Código de barras o interno + $table->enum('type', ['bike', 'accessory', 'clothing', 'spare', 'children', 'skate', 'rollers','other']); $table->text('name')->nullable(); - - $table->decimal('price', 10, 2); // Precio venta - $table->decimal('cost', 10, 2)->nullable(); // Costo (solo admin) - + $table->text('description')->nullable();; + $table->decimal('price', 10, 2); // Precio + $table->decimal('cost', 10, 2)->nullable(); // Costo $table->integer('stock_quantity')->default(100); $table->integer('min_stock_alert')->default(5); // Alerta - - - $table->string('serial_number')->nullable(); // Solo para bicis - $table->foreignId('suppliers_id')->constrained()->default(1); $table->timestamps(); }); diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 43e49c8..0db80de 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -39,8 +39,7 @@ - - + diff --git a/resources/views/productos/create.blade.php b/resources/views/productos/create.blade.php index e3e742f..2d626f0 100644 --- a/resources/views/productos/create.blade.php +++ b/resources/views/productos/create.blade.php @@ -12,10 +12,18 @@ - +
- - + + + @error('suppliers_id') {{ $message }} @enderror
diff --git a/resources/views/productos/edit.blade.php b/resources/views/productos/edit.blade.php index c5c0fc4..a75622e 100644 --- a/resources/views/productos/edit.blade.php +++ b/resources/views/productos/edit.blade.php @@ -2,30 +2,37 @@
-
+ @csrf @method('PUT')
-
- +
- +
- - + + + @error('suppliers_id') {{ $message }} @enderror
- +
- +
diff --git a/resources/views/productos/index.blade.php b/resources/views/productos/index.blade.php index 11efe83..c8f31fc 100644 --- a/resources/views/productos/index.blade.php +++ b/resources/views/productos/index.blade.php @@ -2,207 +2,242 @@ - -
- - - - - + +
- +
- +
-
- + + + + + + + + + +
-
- + + + +
+
- - @if (request('search') || request('type') || request('stock_status')) - - @endif - - - - + + Nuevo Producto
- -
+
- - + + - + @forelse($products as $product) - - - - - - + + + + + + + + + + - + + + + @empty - - - + + + @endforelse
ProductoTipo +
+ Categoría + Detalle del Producto +
+
Costo Precio Stock Acciones
-
{{ $product->name }}
-
- {{ $product->sku ?? 'Sin SKU' }}
-
- @if ($product->type === 'bike') - Bicicleta - @elseif($product->type === 'clothing') - Indumentaria - @elseif($product->type === 'spare') - Repuesto - @elseif($product->type === 'children') - Infantil - @elseif($product->type === 'rollers') - Rollers - @elseif($product->type === 'skate') - Skate - @else - Accesorio / Otro - @endif - - ${{ number_format($product->price, 2) }} - - @if ($product->stock_quantity < $product->min_stock_alert) - {{ $product->stock_quantity }} - @elseif($product->stock_quantity <= $product->min_stock_alert + 5) - {{ $product->stock_quantity }} - @else - {{ $product->stock_quantity }} - @endif - - - +
+
+
+
+ @if($product->type === 'bike') BICICLETA + @elseif($product->type === 'clothing') INDUMENTARIA + @elseif($product->type === 'spare') REPUESTO + @elseif($product->type === 'children') INFANTIL + @elseif($product->type === 'rollers') ROLLERS + @elseif($product->type === 'skate') SKATE + @elseif($product->type === 'service') SERVICIO + @else ACCESORIO / OTRO @endif +
+
+ {{ $product->name }} +
+
+
+
+ ${{ number_format($product->cost, 2) }} + + ${{ number_format($product->price, 2) }} + + @if($product->stock_quantity <= $product->min_stock_alert) + {{ $product->stock_quantity }} + @elseif($product->stock_quantity <= $product->min_stock_alert+5) + {{ $product->stock_quantity }} + @else + {{ $product->stock_quantity }} + @endif + +
+ + - - @php - $isAdmin = auth()->user()?->role === 'admin'; - $classes = $isAdmin - ? 'text-blue-800 border-blue-800 hover:bg-blue-800 hover:text-white' - : 'border-black-400 text-black-400 opacity-50 cursor-not-allowed dark:border-gray-400 dark:text-gray-400'; - @endphp - - - + + - - @if (auth()->user()?->role === 'admin') -
- @csrf - @method('DELETE') - -
- @else - - @endif -
- No se encontraron productos. -
+ No se encontraron productos en la base de datos. +
- -
- {{ $products->links() }} +
+
+ Cargando productos... +
+
+ + +
+ + diff --git a/resources/views/productos/show.blade.php b/resources/views/productos/show.blade.php index 9858012..d9b84ec 100644 --- a/resources/views/productos/show.blade.php +++ b/resources/views/productos/show.blade.php @@ -1,42 +1,100 @@ + + - - + @php + $proveedor = \App\Models\Supplier::find($product->suppliers_id); + + // Mapeo para traducir el tipo de producto al español + $tipos = [ + 'accessory' => 'Accesorio', + 'bike' => 'Bicicleta', + 'clothing' => 'Indumentaria', + 'spare' => 'Repuesto', + 'children' => 'Infantil', + 'rollers' => 'Rollers', + 'skate' => 'Skate', + 'service' => 'Servicio', + 'other' => 'Otro' + ]; + $tipoTraducido = $tipos[$product->type] ?? 'Desconocido'; + @endphp -
-
-
-
Marca
-
{{$product->name}}
+
+ +
+ +
+ +
+ {{ $product->name }} +
-
-
SKU
-
{{$product->sku}}
+ +
+ +
+ {{ $proveedor ? $proveedor->name : 'Proveedor no asignado' }} +
-
-
Descripcion
-
{{$product->description}}
+ +
+ +
+ {{ $tipoTraducido }} +
-
-
Costo
-
{{$product->cost}}
+ +
+ +
+ ${{ number_format($product->price, 2, ',', '.') }} +
-
-
Precio
-
{{$product->price}}
+ +
+ +
+ {{ $product->stock_quantity }} unidades + + @if($product->stock_quantity <= $product->min_stock_alert) + ¡Bajo Stock! + @endif +
-
-
Cantidad en Stock
-
{{$product->stock_quantity}}
+ +
+ +
+ {{ $product->description ?: 'No hay descripción cargada para este producto.' }} +
-
-
Tipo
-
{{$product->type}}
+ +
+ +
+ @if($product->image_path) + {{ $product->name }} + @else +
+ + Sin imagen asignada +
+ @endif +
-
-
- Volver
+ + +
\ No newline at end of file diff --git a/resources/views/suppliers/create.blade.php b/resources/views/suppliers/create.blade.php new file mode 100644 index 0000000..cb046c9 --- /dev/null +++ b/resources/views/suppliers/create.blade.php @@ -0,0 +1,43 @@ + + + +
+
+ @csrf + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + @error('address') + {{ $message }} + @enderror +
+
+ +
+ Cancelar + +
+ +
+
+
\ No newline at end of file diff --git a/resources/views/suppliers/edit.blade.php b/resources/views/suppliers/edit.blade.php new file mode 100644 index 0000000..1952dc8 --- /dev/null +++ b/resources/views/suppliers/edit.blade.php @@ -0,0 +1,45 @@ + + + +
+
+ @csrf + @method('PUT') + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + + @error('address') + {{ $message }} + @enderror +
+
+ +
+ Cancelar + +
+ +
+
+
\ No newline at end of file diff --git a/resources/views/suppliers/index.blade.php b/resources/views/suppliers/index.blade.php new file mode 100644 index 0000000..7fd2443 --- /dev/null +++ b/resources/views/suppliers/index.blade.php @@ -0,0 +1,114 @@ + + + + + + @if(session('success')) +
+ {{ session('success') }} +
+ @endif + + +
+ +
+
+
+ +
+ +
+
+ + + + Nuevo Proveedor + +
+ +
+ + + + + + + + + + + @forelse($suppliers as $supplier) + + + + + + + + @empty + + + + @endforelse + +
Proveedor / EmailTeléfono / WhatsAppDirecciónAcciones
+
{{ $supplier->name }}
+
+ {{ $supplier->email ?? 'Sin email registrado' }} +
+
+ @if($supplier->phone) +
+ {{ $supplier->phone }} + WA +
+ @else + No registrado + @endif +
+ + {{ $supplier->address ?? '-' }} + + + + + + + + +
+ @csrf + @method('DELETE') + +
+
+
+ + + +

No se encontraron proveedores.

+
+
+
+ +
+ {{ $suppliers->links() }} +
+ +
\ No newline at end of file diff --git a/resources/views/suppliers/order.blade.php b/resources/views/suppliers/order.blade.php new file mode 100644 index 0000000..34a5429 --- /dev/null +++ b/resources/views/suppliers/order.blade.php @@ -0,0 +1,203 @@ + + + +
+ +
+
+

Seleccioná los productos

+

Teléfono registrado: {{ $supplier->phone ?? 'Ninguno' }}

+
+ Volver al listado +
+ + @if($products->isEmpty()) +
+ Este proveedor todavía no tiene productos asociados en el sistema. +
+ @else +
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ + + + + + + + + + + @foreach($products as $product) + + + + + + + + @endforeach + +
PedirCantidadProductoStock Actual
+ + + + + {{ $product->name }} + + @if($product->stock_quantity <= $product->min_stock_alert) + + {{ $product->stock_quantity }} (¡Bajo!) + + @else + + {{ $product->stock_quantity }} + + @endif +
+
+ +
+ +
+ @endif + +
+ + + + +
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 44a06e5..3d05023 100644 --- a/routes/web.php +++ b/routes/web.php @@ -12,6 +12,7 @@ use App\Http\Controllers\RegisterController; use App\Http\Controllers\TallerController; use App\Http\Controllers\AgendaController; use App\Http\Controllers\AppointmentController; +use App\Http\Controllers\SupplierController; use App\Models\Product; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; @@ -37,6 +38,11 @@ Route::post('logout', function(){ Route::middleware(['auth'])->group(function () { Route::view('dashboard', 'dashboard')->name('dashboard'); Route::resource('clients', ClientController::class); + Route::get('suppliers/{supplier}/order', [SupplierController::class, 'order'])->name('suppliers.order'); + Route::resource('suppliers', SupplierController::class); + Route::resource('productos', ProductosController::class)->parameters([ + 'productos' => 'product' + ]); Route::resource('sales', SaleController::class)->only(['index', 'create', 'store', 'show']); Route::get('/agenda', [AgendaController::class, 'index'])->name('agenda'); Route::get('/appointments/{appointment}', [AppointmentController::class, 'show'])->name('appointments.show'); @@ -61,6 +67,5 @@ Route::middleware(['auth'])->group(function () { ->only(['create', 'store', 'edit', 'update', 'destroy']) ->parameters(['productos' => 'product']); - // Si tienes más cosas de admin (ej: reportes), van aquí }); });