Primero tengo un arreglo que tiene dos arreglos; por cada uno muestro una nueva fila. Después hago un ciclo dentro del anterior, por cada módulo. Utilizo el nombre para cargar las imágenes y poner el título, así como las rutas.
La única excepción es con acerca_de que no se ve legible para el ser humano al convertirla en mayúsculas, por eso es que he usado el operador ternario para mostrar su valor.
He agregado el módulo de usuarios, que es un simple CRUD. Comenzamos viendo su controlador:
<?phpnamespaceApp\Http\Controllers;
useApp\User;
useIlluminate\Http\Request;
useIlluminate\Support\Facades\Hash;
classUserControllerextendsController{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/publicfunctionindex()
{
returnview("usuarios.usuarios_index", ["usuarios"=>User::all()]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/publicfunctioncreate()
{
returnview("usuarios.usuarios_create");
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/publicfunctionstore(Request $request)
{
$usuario =newUser($request->input());
$usuario->password=Hash::make($usuario->password);
$usuario->saveOrFail();
returnredirect()->route("usuarios.index")->with("mensaje", "Usuario guardado");
}
/**
* Display the specified resource.
*
* @param \App\User $user
* @return \Illuminate\Http\Response
*/publicfunctionshow(User $user)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\User $user
* @return \Illuminate\Http\Response
*/publicfunctionedit(User $user)
{
$user->password="";
returnview("usuarios.usuarios_edit", ["usuario"=> $user,
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\User $user
* @return \Illuminate\Http\Response
*/publicfunctionupdate(Request $request, User $user)
{
$user->fill($request->input());
$user->password=Hash::make($user->password);
$user->saveOrFail();
returnredirect()->route("usuarios.index")->with("mensaje", "Usuario actualizado");
}
/**
* Remove the specified resource from storage.
*
* @param \App\User $user
* @return \Illuminate\Http\Response
*/publicfunctiondestroy(User $user)
{
$user->delete();
returnredirect()->route("usuarios.index")->with("mensaje", "Usuario eliminado");
}
}
Es parecido a los otros, pues se usa un simple resource. Por cierto, no estoy validando que la contraseña coincida (al registrar o actualizar). La lista se ve así:
En este caso no tuve que generar el modelo, pues ya viene incluido al generar la autenticación de Laravel.
Tuve que hacer unas modificaciones a la base de datos ya que tenía que crear la relación entre el cliente y la venta. Para ello, generé una migración:
<?phpuseIlluminate\Database\Migrations\Migration;
useIlluminate\Database\Schema\Blueprint;
useIlluminate\Support\Facades\Schema;
classAgregarIdClienteVentasextendsMigration{
/**
* Run the migrations.
*
* @return void
*/publicfunctionup()
{
Schema::table('ventas', function (Blueprint $table) {
$table->unsignedBigInteger('id_cliente');
$table->foreign("id_cliente")
->references("id")
->on("clientes")
->onDelete("cascade")
->onUpdate("cascade");
});
}
/**
* Reverse the migrations.
*
* @return void
*/publicfunctiondown()
{
Schema::table('ventas', function (Blueprint $table) {
//
});
}
}
Ahora que lo veo, no agregué el código para revertir la migración, así que hay que tener cuidado con esa parte. Más tarde agregué la relación en el modelo de venta indicando que una venta le pertenece a un cliente:
La parte más compleja de esto fue arreglar el diseño, ya que los botones de Terminar venta, Cancelar venta y Agregar producto apuntaban a distintas rutas; pero al agregar el cliente tuve que modificarlo.
Al final decidí que ambos botones de la venta apuntaran a la misma ruta y, dentro del controlador verificar cuál botón fue presionado e invocar a una función u otra:
<divclass="row"><divclass="col-12 col-md-6"><formaction="{{route("terminarOCancelarVenta")}}"method="post">@csrf<divclass="form-group"><labelfor="id_cliente">Cliente</label><selectrequiredclass="form-control"name="id_cliente"id="id_cliente">@foreach($clientes as $cliente)
<optionvalue="{{$cliente->id}}">{{$cliente->nombre}}</option>@endforeach</select></div>@if(session("productos") !==null)
<divclass="form-group"><buttonname="accion"value="terminar"type="submit"class="btn btn-success">Terminarventa</button><buttonname="accion"value="cancelar"type="submit"class="btn btn-danger">Cancelarventa</button></div>@endif</form></div><divclass="col-12 col-md-6"><formaction="{{route("agregarProductoVenta")}}"method="post">@csrf<divclass="form-group"><labelfor="codigo">Códigodebarras</label><inputid="codigo"autocomplete="off"requiredautofocusname="codigo"type="text"class="form-control"placeholder="Código de barras"></div></form></div></div>
Como ves, se dibuja un select que permite seleccionar al cliente. Una posible mejora sería que se quede el mismo cliente seleccionado, ya que si se selecciona antes de vender, el cambio se pierde pues al agregar un producto la página se refresca.
El resultado de la interfaz para agregar una venta con selección de cliente quedó así:
Detalle de venta con cliente
Del mismo modo, en el detalle de la venta (y también en el listado) aparece el nombre del cliente al que fue hecha la venta:
Más adelante traeré la aplicación móvil que corresponde a este sistema.
Si el post ha sido de tu agrado te invito a que me sigas para saber cuando haya escrito un nuevo post, haya
actualizado algún sistema o publicado un nuevo software.
Facebook
| X
| Instagram
| Telegram |
También estoy a tus órdenes para cualquier contratación en mi página de contacto