ARREGLOS: Correccion de comentarios y cambio en tablas productos, cambiados los tipos de productos a (bike, accessory, clothing, spare) para manejo futuro de repuestos y carga de datos de excel de productos.

This commit is contained in:
Bryam105
2026-01-28 09:44:01 -03:30
parent 5b5c8b2fc6
commit 869d3e1a2c
22 changed files with 76 additions and 123 deletions
+3 -3
View File
@@ -20,11 +20,11 @@ class CatalogoController extends Controller
$searchTerm = $request->input('search');
$query->where(function($q) use ($searchTerm) {
$q->where('name', 'like', "%{$searchTerm}%") // Buscar por nombre
->orWhere('sku', 'like', "%{$searchTerm}%"); // O por código SKU
$q->where('name', 'like', "%{$searchTerm}%")
->orWhere('sku', 'like', "%{$searchTerm}%");
});
}
$query->whereIn('type', ['bike', 'accessory']);// Filtros para el público
$query->whereIn('type', ['bike', 'accessory', 'clothing', 'spare']);
$query->where('stock_quantity', '>', 0); // Solo mostrar si tiene stock
// Resultados paginados
+8 -4
View File
@@ -20,7 +20,6 @@ class ClientController extends Controller
return $q->where('name', 'like', "%{$query}%");
})
->orderBy('name', 'asc')
//->orderBy('create_at', 'asc')
->paginate(10) // Paginamos de a 10
->withQueryString(); // Mantiene el filtro de búsqueda al cambiar de página
@@ -53,13 +52,18 @@ class ClientController extends Controller
// 2. Verificamos el origen
if ($request->input('origin') === 'sales') {
// Si vino de ventas, volvemos a ventas
// Y pasamos el ID del nuevo cliente para auto-seleccionarlo
// Si vino de ventas, volvemos a ventas con el cliente nuevo
return redirect()->route('sales.create', ['new_client_id' => $client->id])
->with('success', 'Cliente creado. Ya puedes seleccionarlo.');
}
else if ($request->input('origin') === 'taller') {
// Si vino de taller, volvemos a taller con el cliente nuevo
return redirect()->route('taller.create', ['new_client_id' => $client->id])
->with('success', 'Cliente creado. Ya puedes seleccionarlo.');
}
// 3. Si no, comportamiento normal (volver al index de clientes)
// 3. Si no, vuelvo al index de clientes
return redirect()->route('clients.index')
->with('success', 'Cliente creado correctamente.');
}
+3 -3
View File
@@ -11,9 +11,9 @@ class HomeController extends Controller
{
// Si tuvieras un campo 'sales_count', podrías usar ->orderByDesc('sales_count')
$destacados = Product::where('type', 'bike')
->latest() // Las más nuevas
->take(5)
->get();
->latest() // Las más nuevas
->take(5)
->get();
// Si no hay bicis, traemos cualquier cosa para que no se rompa
if ($destacados->isEmpty()) {
+3 -3
View File
@@ -14,13 +14,13 @@ class LoginController extends Controller
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
return back()->withErrors([
'email' => 'Los datos no coinciden.',
])->onlyInput('email');
+12 -15
View File
@@ -4,8 +4,8 @@ namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule; // Necesario para validar unicidad al editar
use Illuminate\Support\Facades\Storage; // <--- IMPORTANTE: Agregar esto arriba
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Storage;
class ProductosController extends Controller
{
@@ -14,33 +14,30 @@ class ProductosController extends Controller
*/
public function index(Request $request)
{
// Recuperamos lo que el usuario escribió en el buscador (si escribió algo)
// Recuperamos lo escrito en el buscador (si aplica)
$query = $request->input('search');
$status = $request->input('stock_status');
// Construimos la consulta
$products = Product::query()
->when($query, function ($q) use ($query) {
// Si hay búsqueda, filtra por nombre o SKU
// Filtra por nombre o SKU
return $q->where('name', 'like', "%{$query}%")
->orWhere('sku', 'like', "%{$query}%");
->orWhere('sku', 'like', "%{$query}%");
})
->when($status, function ($q) use ($status) {
if ($status === 'low') {
// Rojo: Menor o igual a la alerta
return $q->whereColumn('stock_quantity', '<', 'min_stock_alert')
->where('type', '!=', 'service'); // Ignoramos servicios
return $q->whereColumn('stock_quantity', '<', 'min_stock_alert');
}
elseif ($status === 'medium') {
// Amarillo: Mayor a alerta PERO menor o igual a alerta + 2 (margen pequeño)
// Amarillo: Mayor al min y menor o igual al min + 5
return $q->whereColumn('stock_quantity', '>=', 'min_stock_alert')
->whereRaw('stock_quantity <= (min_stock_alert + 1)') // Ajusta este "+ 5" según tu criterio de "amarillo"
->where('type', '!=', 'service');
->whereRaw('stock_quantity <= (min_stock_alert + 5)');
}
elseif ($status === 'ok') {
// Verde: Stock saludable
return $q->whereRaw('stock_quantity > (min_stock_alert + 1)')
->where('type', '!=', 'service');
return $q->whereRaw('stock_quantity > (min_stock_alert + 5)');
}
})
->orderBy('stock_quantity', 'asc') // Ordenamos primero los que tienen poco stock (Alerta visual)
@@ -72,7 +69,7 @@ class ProductosController extends Controller
'cost' => 'nullable|numeric|min:0', // Costo opcional
'stock_quantity' => 'required|integer|min:0',
'min_stock_alert' => 'required|integer|min:0',
'type' => 'required|in:bike,accessory,service', // Solo permite estos 3 valores
'type' => 'required|in:bike,accessory,clothing,spare', // Solo permite estos valores
'serial_number' => 'nullable|string|max:100',
'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048',
]);
@@ -93,6 +90,7 @@ class ProductosController extends Controller
// Para no romper la logica del supplier
$validated['suppliers_id'] = 1;
// 3. Creamos el producto
Product::create($validated);
@@ -103,7 +101,6 @@ class ProductosController extends Controller
/**
* Muestra el detalle de un producto.
* Usamos Route Model Binding: Laravel busca el ID solo.
*/
public function show(Product $product)
{
@@ -132,7 +129,7 @@ class ProductosController extends Controller
'cost' => 'nullable|numeric|min:0',
'stock_quantity' => 'required|integer|min:0',
'min_stock_alert' => 'required|integer|min:0',
'type' => 'required|in:bike,accessory,service',
'type' => 'required|in:bike,accessory,clothing,spare',
'serial_number' => 'nullable|string|max:100',
'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048',
@@ -18,7 +18,6 @@ class RegisterController extends Controller
]);
$userData['password'] = bcrypt($userData['password']);
$user = User::create($userData);
Auth::login($user);
+1 -1
View File
@@ -35,7 +35,7 @@ class TallerController extends Controller
{
$clients = Client::orderBy('name')->get();
$products = Product::whereIn('type', ['accessory'])
$products = Product::whereIn('type', ['accessory','spare'])
->where('stock_quantity', '>', 0)
->get(['id', 'name', 'price', 'sku', 'stock_quantity']); // Solo campos necesarios