|
@@ -0,0 +1,239 @@
|
|
|
+// ignore_for_file: use_build_context_synchronously
|
|
|
+
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:provider/provider.dart';
|
|
|
+import '../../models/models.dart';
|
|
|
+import '../../themes/themes.dart';
|
|
|
+import '../../viewmodels/viewmodels.dart';
|
|
|
+import '../../widgets/app_textfield.dart';
|
|
|
+import '../../widgets/pagination_buttons.dart';
|
|
|
+import '../../widgets/widgets_components.dart';
|
|
|
+import 'producto_form.dart';
|
|
|
+
|
|
|
+class ProductoScreen extends StatefulWidget {
|
|
|
+ const ProductoScreen({Key? key}) : super(key: key);
|
|
|
+
|
|
|
+ @override
|
|
|
+ State<ProductoScreen> createState() => Formulario();
|
|
|
+}
|
|
|
+
|
|
|
+class Formulario extends State<ProductoScreen> {
|
|
|
+ final _busqueda = TextEditingController(text: '');
|
|
|
+
|
|
|
+ @override
|
|
|
+ void initState() {
|
|
|
+ super.initState();
|
|
|
+ Future(() async {
|
|
|
+ await Provider.of<ProductoViewModel>(context, listen: false)
|
|
|
+ .fetchRegistros();
|
|
|
+ await Provider.of<CategoriaProductoViewModel>(context, listen: false)
|
|
|
+ .fetchCategoriaProductos(segmentar: true);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ go(Producto item) async {
|
|
|
+ Provider.of<ProductoViewModel>(context, listen: false).selectModelo(item);
|
|
|
+ Navigator.push(
|
|
|
+ context,
|
|
|
+ MaterialPageRoute(
|
|
|
+ builder: (context) => const ProductoForm(),
|
|
|
+ ),
|
|
|
+ ).then((value) async {
|
|
|
+ await Provider.of<ProductoViewModel>(context, listen: false)
|
|
|
+ .fetchRegistros();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ final evm = Provider.of<CategoriaProductoViewModel>(context);
|
|
|
+ List<CategoriaProducto> categoriaProductos = [];
|
|
|
+ if (evm.categoriaProductos.isNotEmpty) {
|
|
|
+ categoriaProductos = evm.categoriaProductos;
|
|
|
+ }
|
|
|
+
|
|
|
+ final mvm = Provider.of<ProductoViewModel>(context);
|
|
|
+ TextStyle estilo = const TextStyle(fontWeight: FontWeight.bold);
|
|
|
+ int vuelta = 0;
|
|
|
+ List<DataRow> registros = [];
|
|
|
+ if (mvm.registros.isNotEmpty) {
|
|
|
+ for (Producto item in mvm.registros) {
|
|
|
+ String? categoriaProducto = "";
|
|
|
+ if (item.idCategoria != null) {
|
|
|
+ categoriaProducto = item.categoria!.nombre;
|
|
|
+ }
|
|
|
+
|
|
|
+ var _tipo = vuelta % 2;
|
|
|
+ vuelta++;
|
|
|
+ registros.add(DataRow(selected: _tipo > 0, cells: [
|
|
|
+ DataCell(
|
|
|
+ Text(item.nombre.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Text(item.descripcion.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Text(categoriaProducto.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Text(item.precio.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Text(item.venta.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Text(item.existencia.toString()),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ DataCell(
|
|
|
+ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
|
|
+ PopupMenuButton(
|
|
|
+ surfaceTintColor: AppTheme.primary,
|
|
|
+ itemBuilder: (context) => [
|
|
|
+ PopupMenuItem(
|
|
|
+ child: const Text('Editar'),
|
|
|
+ onTap: () => go(item),
|
|
|
+ ),
|
|
|
+ PopupMenuItem(
|
|
|
+ child: const Text(
|
|
|
+ 'Eliminar',
|
|
|
+ ),
|
|
|
+ onTap: () async {
|
|
|
+ return showDialog(
|
|
|
+ context: context,
|
|
|
+ builder: (context) {
|
|
|
+ return AlertDialog(
|
|
|
+ title: const Text("Eliminar registro"),
|
|
|
+ content: const Text('¿Desea eliminar el registro?'),
|
|
|
+ actions: [
|
|
|
+ Row(children: [
|
|
|
+ Expanded(
|
|
|
+ child: TextButton(
|
|
|
+ onPressed: () {
|
|
|
+ Navigator.pop(context);
|
|
|
+ },
|
|
|
+ child: const Text('Cancelar'),
|
|
|
+ )),
|
|
|
+ Expanded(
|
|
|
+ child: TextButton(
|
|
|
+ onPressed: () async {
|
|
|
+ Navigator.pop(context);
|
|
|
+ },
|
|
|
+ child: const Text('Continuar'),
|
|
|
+ ))
|
|
|
+ ])
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ },
|
|
|
+ );
|
|
|
+ },
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ icon: const Icon(Icons.more_vert),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(15)),
|
|
|
+ )
|
|
|
+ ]))
|
|
|
+ ]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return Scaffold(
|
|
|
+ appBar: AppBar(
|
|
|
+ title: const Text('Productos'),
|
|
|
+ ),
|
|
|
+ floatingActionButton: FloatingActionButton(
|
|
|
+ onPressed: () {
|
|
|
+ mvm.selectModelo(Producto());
|
|
|
+ Navigator.push(
|
|
|
+ context,
|
|
|
+ MaterialPageRoute(
|
|
|
+ builder: (context) => const ProductoForm(),
|
|
|
+ ),
|
|
|
+ ).then((value) async {
|
|
|
+ await Provider.of<ProductoViewModel>(context, listen: false)
|
|
|
+ .fetchRegistros();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ child: const Icon(Icons.add),
|
|
|
+ ),
|
|
|
+ body: Column(
|
|
|
+ children: [
|
|
|
+ Expanded(
|
|
|
+ child: ListView(
|
|
|
+ padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
|
|
+ children: [
|
|
|
+ const SizedBox(height: 8),
|
|
|
+ tarjeta(Padding(
|
|
|
+ padding: const EdgeInsets.all(10),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ Expanded(
|
|
|
+ flex: 8,
|
|
|
+ child: AppTextField(
|
|
|
+ prefixIcon: const Icon(Icons.search),
|
|
|
+ maxLength: 100,
|
|
|
+ etiqueta: 'Búsqueda por nombre...',
|
|
|
+ controller: _busqueda,
|
|
|
+ hintText: 'Búsqueda por nombre...',
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ const SizedBox(width: 5),
|
|
|
+ Expanded(
|
|
|
+ flex: 2,
|
|
|
+ child: botonElevated(
|
|
|
+ accion: () async {
|
|
|
+ _busqueda.text = _busqueda.text.trim();
|
|
|
+ await Provider.of<ProductoViewModel>(context,
|
|
|
+ listen: false)
|
|
|
+ .setIsLoading(true);
|
|
|
+ await Provider.of<ProductoViewModel>(context,
|
|
|
+ listen: false)
|
|
|
+ .setBusqueda(_busqueda.text);
|
|
|
+ await Provider.of<ProductoViewModel>(context,
|
|
|
+ listen: false)
|
|
|
+ .fetchRegistros();
|
|
|
+ await Provider.of<ProductoViewModel>(context,
|
|
|
+ listen: false)
|
|
|
+ .setBusqueda("");
|
|
|
+ await Provider.of<ProductoViewModel>(context,
|
|
|
+ listen: false)
|
|
|
+ .setIsLoading(false);
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ))),
|
|
|
+ const SizedBox(height: 8),
|
|
|
+ tarjeta(DataTable(
|
|
|
+ sortAscending: true,
|
|
|
+ sortColumnIndex: 1,
|
|
|
+ columns: [
|
|
|
+ DataColumn(label: Text("NOMBRE", style: estilo)),
|
|
|
+ DataColumn(label: Text("DESCRIPCIÓN", style: estilo)),
|
|
|
+ DataColumn(
|
|
|
+ label: Text("CATEGORÍA PRODUCTOS", style: estilo)),
|
|
|
+ DataColumn(label: Text("PRECIO", style: estilo)),
|
|
|
+ DataColumn(label: Text("VENTAS", style: estilo)),
|
|
|
+ DataColumn(label: Text("EN EXISTENCIA", style: estilo)),
|
|
|
+ DataColumn(label: Text("", style: estilo)),
|
|
|
+ ],
|
|
|
+ rows: registros)),
|
|
|
+ PaginationButtons(
|
|
|
+ currentPage: mvm.pagina,
|
|
|
+ totalPages: mvm.totalPaginas,
|
|
|
+ onPageChanged: (i) => mvm.cambiarPagina(i),
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|