salecontroller en proceso creativo
This commit is contained in:
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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');
|
||||||
|
|||||||
Reference in New Issue
Block a user