|
@@ -1,3 +1,4 @@
|
|
|
+import '../../models/models.dart';
|
|
|
import '../../widgets/widgets.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:provider/provider.dart';
|
|
@@ -19,11 +20,21 @@ class CorteCajaFinalizadoScreen extends StatefulWidget {
|
|
|
class _CorteCajaFinalizadoScreenState extends State<CorteCajaFinalizadoScreen> {
|
|
|
Map<String, bool> _expandedSections = {};
|
|
|
|
|
|
+ List<Pedido> _pedidosCancelados = [];
|
|
|
+
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
final viewModel = Provider.of<CorteCajaViewModel>(context, listen: false);
|
|
|
viewModel.fetchDepositosAndRetiros(widget.corteCajaId!);
|
|
|
+
|
|
|
+ viewModel.fetchPedidosCancelados(widget.corteCajaId!).then((pedidos) {
|
|
|
+ setState(() {
|
|
|
+ _pedidosCancelados = pedidos;
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ viewModel.fetchPedidosConPropinas(widget.corteCajaId!);
|
|
|
}
|
|
|
|
|
|
@override
|
|
@@ -76,6 +87,15 @@ class _CorteCajaFinalizadoScreenState extends State<CorteCajaFinalizadoScreen> {
|
|
|
_buildExpandableTable(
|
|
|
"Retiros", viewModel.retiros, totalRetiro),
|
|
|
_buildExpandableTable("Gastos", viewModel.gastos, totalGasto),
|
|
|
+ _buildExpandablePropinas(
|
|
|
+ "Propinas",
|
|
|
+ viewModel.pedidosConPropinas,
|
|
|
+ viewModel.totalPropinas,
|
|
|
+ ),
|
|
|
+ _buildExpandablePedidosCancelados(
|
|
|
+ "Pedidos Cancelados",
|
|
|
+ _pedidosCancelados,
|
|
|
+ ),
|
|
|
Table(
|
|
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
columnWidths: {
|
|
@@ -208,4 +228,223 @@ class _CorteCajaFinalizadoScreenState extends State<CorteCajaFinalizadoScreen> {
|
|
|
],
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ Widget _buildExpandablePedidosCancelados(String title, List<Pedido> pedidos) {
|
|
|
+ final isExpanded = _expandedSections[title] ?? true;
|
|
|
+
|
|
|
+ return Column(
|
|
|
+ children: [
|
|
|
+ GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ setState(() {
|
|
|
+ _expandedSections[title] = !isExpanded;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ child: Container(
|
|
|
+ child: Table(
|
|
|
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
+ columnWidths: {0: FlexColumnWidth(4), 1: FlexColumnWidth(2)},
|
|
|
+ children: [
|
|
|
+ TableRow(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration:
|
|
|
+ BoxDecoration(border: Border.all(color: Colors.grey)),
|
|
|
+ child: Text(
|
|
|
+ title,
|
|
|
+ style: TextStyle(
|
|
|
+ fontWeight: FontWeight.bold, fontSize: 18),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration:
|
|
|
+ BoxDecoration(border: Border.all(color: Colors.grey)),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ "Total: ${pedidos.length}",
|
|
|
+ style: TextStyle(
|
|
|
+ fontWeight: FontWeight.bold, fontSize: 18),
|
|
|
+ ),
|
|
|
+ Icon(isExpanded
|
|
|
+ ? Icons.expand_less
|
|
|
+ : Icons.expand_more),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+
|
|
|
+ // Contenido expandido
|
|
|
+ if (isExpanded)
|
|
|
+ pedidos.isNotEmpty
|
|
|
+ ? Table(
|
|
|
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
+ columnWidths: {0: FlexColumnWidth(4), 1: FlexColumnWidth(2)},
|
|
|
+ children: pedidos.map((pedido) {
|
|
|
+ // Construir fila con folio, totalPedido y tipoPago si existe
|
|
|
+ // Observa que en la primer celda pondremos el texto completo
|
|
|
+ // y la segunda celda podría quedar vacía o un " - "
|
|
|
+ final tipoPago = (pedido.tipoPago?.isNotEmpty ?? false)
|
|
|
+ ? " - ${pedido.tipoPago}"
|
|
|
+ : "";
|
|
|
+ return TableRow(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(color: Colors.grey)),
|
|
|
+ child: Text(
|
|
|
+ "Folio: ${pedido.folio} "
|
|
|
+ "$tipoPago",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16, fontWeight: FontWeight.w600),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(color: Colors.grey)),
|
|
|
+ child: Text(
|
|
|
+ "\$${pedido.totalPedido?.toStringAsFixed(2) ?? '0.00'}",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16, fontWeight: FontWeight.w600),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }).toList(),
|
|
|
+ )
|
|
|
+ : Padding(
|
|
|
+ padding: const EdgeInsets.all(8.0),
|
|
|
+ child: Text(
|
|
|
+ "No hay pedidos cancelados para este corte.",
|
|
|
+ style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildExpandablePropinas(
|
|
|
+ String title, List<Pedido> pedidos, double totalPropinas) {
|
|
|
+ final isExpanded = _expandedSections[title] ?? true;
|
|
|
+
|
|
|
+ return Column(
|
|
|
+ children: [
|
|
|
+ GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ setState(() {
|
|
|
+ _expandedSections[title] = !isExpanded;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ child: Container(
|
|
|
+ child: Table(
|
|
|
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
+ columnWidths: {0: FlexColumnWidth(4), 1: FlexColumnWidth(2)},
|
|
|
+ children: [
|
|
|
+ TableRow(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration:
|
|
|
+ BoxDecoration(border: Border.all(color: Colors.grey)),
|
|
|
+ child: Text(
|
|
|
+ title,
|
|
|
+ style: TextStyle(
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
+ fontSize: 18,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration:
|
|
|
+ BoxDecoration(border: Border.all(color: Colors.grey)),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ children: [
|
|
|
+ // Mostramos el total general de propinas
|
|
|
+ Text(
|
|
|
+ "\$${totalPropinas.toStringAsFixed(2)}",
|
|
|
+ style: TextStyle(
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
+ fontSize: 18,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Icon(isExpanded
|
|
|
+ ? Icons.expand_less
|
|
|
+ : Icons.expand_more),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ if (isExpanded)
|
|
|
+ pedidos.isNotEmpty
|
|
|
+ ? Table(
|
|
|
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
+ columnWidths: {0: FlexColumnWidth(4), 1: FlexColumnWidth(2)},
|
|
|
+ children: pedidos.map((pedido) {
|
|
|
+ // Sumar propinas para este pedido en particular
|
|
|
+ double sumaPropinasPedido = pedido.propinas.fold(
|
|
|
+ 0.0,
|
|
|
+ (prev, propina) => prev + (propina.cantidad ?? 0),
|
|
|
+ );
|
|
|
+ return TableRow(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(color: Colors.grey),
|
|
|
+ ),
|
|
|
+ child: Text(
|
|
|
+ "Folio: ${pedido.folio} - Total: \$${(pedido.totalPedido ?? 0).toStringAsFixed(2)}",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsets.all(8.5),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(color: Colors.grey),
|
|
|
+ ),
|
|
|
+ child: Text(
|
|
|
+ "\$${sumaPropinasPedido.toStringAsFixed(2)}",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }).toList(),
|
|
|
+ )
|
|
|
+ : Padding(
|
|
|
+ padding: const EdgeInsets.all(8.0),
|
|
|
+ child: Text(
|
|
|
+ "No hay propinas registradas para este corte.",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: FontWeight.w600,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|