salecontroller en proceso creativo

This commit is contained in:
GianellaDelMestre
2025-12-08 23:57:02 -03:00
parent 832f9228af
commit 68534a7603
3 changed files with 153 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
use App\Models\Sale;
use App\Models\SaleDetail;
use Illuminate\Support\Facades\DB;
class SaleController extends Controller
{
public function create()
{
// Buscamos productos que tengan stock mayor a 0 para mostrar en el selector
$products = Product::where('stock', '>', 0)->get();
// Retornamos la vista (que crearemos en el paso 4) pasando los productos
return view('sales.create', compact('products'));
}
public function store(Request $request)
{
$request->validate([
'payment_method' => 'required|string',
'items' => 'required|array',
'items.*.product_id' => 'required|exists:products,id',
'items.*.quantity' => 'required|integer|min:1',
]);
try {
DB::transaction(function () use ($request) {
$totalVenta = 0;
foreach ($request->items as $item) {
$producto = Product::find($item['product_id']);
$totalVenta += $producto->price * $item['quantity'];
if ($producto->stock < $item['quantity']) {
throw new \Exception("No hay suficiente stock de " . $producto->name);
}
}
// raro arreglar
$sale = Sale::create([
'user_id' => auth()->id(), // El empleado logueado
'total' => $totalVenta,
'payment_method' => $request->payment_method,
]);
foreach ($request->items as $item) {
$producto = Product::find($item['product_id']);
SaleDetail::create([
'sale_id' => $sale->id,
'product_id' => $producto->id,
'quantity' => $item['quantity'],
'price' => $producto->price,
]);
$producto->decrement('stock', $item['quantity']);
}
});
// 5. REDIRECCIÓN DE ÉXITO
// Redirigimos al usuario con un mensaje flash [cite: 668]
return redirect()->route('sales.create')->with('success', '¡Venta registrada correctamente!');
} catch (\Exception $e) {
// Si algo falló (ej: falta stock), volvemos atrás con el error
return back()->with('error', 'Error en la venta: ' . $e->getMessage());
}
}
}
+72
View File
@@ -0,0 +1,72 @@
@extends('layouts.app')
@section('title', 'Nueva Venta')
@section('main')
<div class="py-12 bg-gray-100 min-h-screen">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg p-6">
<h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-2">Nueva Venta en Mostrador</h2>
@if (session('success'))
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">¡Éxito!</strong>
<span class="block sm:inline">{{ session('success') }}</span>
</div>
@endif
@if (session('error'))
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">Error:</strong>
<span class="block sm:inline">{{ session('error') }}</span>
</div>
@endif
<form action="{{ route('sales.store') }}" method="POST">
@csrf
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="col-span-1">
<label class="block text-sm font-medium text-gray-700 mb-1">Producto</label>
<select name="items[0][product_id]" class="w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3 border" required>
<option value="" selected disabled>Seleccione un producto...</option>
@foreach($products as $product)
<option value="{{ $product->id }}">
{{ $product->code }} - {{ $product->name }} (${{ $product->price }})
</option>
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Cantidad</label>
<input type="number" name="items[0][quantity]" value="1" min="1" class="w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3 border" required>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Método de Pago</label>
<select name="payment_method" class="w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3 border">
<option value="Efectivo">Efectivo</option>
<option value="Tarjeta de Débito">Tarjeta de Débito</option>
<option value="Tarjeta de Crédito">Tarjeta de Crédito</option>
<option value="Transferencia">Transferencia</option>
</select>
</div>
</div>
<div class="mt-8 flex gap-4">
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-6 rounded shadow-lg transition duration-150 ease-in-out">
Confirmar Venta
</button>
<a href="{{ url('/') }}" class="bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow">
Cancelar
</a>
</div>
</form>
</div>
</div>
</div>
@endsection
+9
View File
@@ -2,6 +2,7 @@
use App\Http\Controllers\AuthController; use App\Http\Controllers\AuthController;
use App\Http\Controllers\CatalogoController; use App\Http\Controllers\CatalogoController;
use App\Http\Controllers\SaleController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController; use App\Http\Controllers\HomeController;
use App\Http\Controllers\LoginController; use App\Http\Controllers\LoginController;
@@ -47,5 +48,13 @@ Route::middleware(['auth'])->group(function () {
Route::delete('/productos/{id}', [ProductosController::class,'destroy'])->name('productos.destroy'); Route::delete('/productos/{id}', [ProductosController::class,'destroy'])->name('productos.destroy');
}); });
Route::middleware(['auth'])->group(function () {
// mostrar
Route::get('/sales/create', [SaleController::class, 'create'])->name('sales.create');
// procesar
Route::post('/sales', [SaleController::class, 'store'])->name('sales.store');
});
Route::get('/catalogo', [CatalogoController::class,'catalogo'])->name('catalogo'); Route::get('/catalogo', [CatalogoController::class,'catalogo'])->name('catalogo');
Route::get('/productos/{id}/vistaUsuario', [ProductosController::class,'vistaUsuario'])->name('productos.vistaUsuario'); Route::get('/productos/{id}/vistaUsuario', [ProductosController::class,'vistaUsuario'])->name('productos.vistaUsuario');