111 lines
5.4 KiB
Dart
111 lines
5.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:intl/intl.dart';
|
|
import '../providers/factura_provider.dart';
|
|
import '../providers/servicio_provider.dart';
|
|
import '../providers/configuracion_provider.dart';
|
|
|
|
class FacturasScreen extends StatefulWidget {
|
|
const FacturasScreen({super.key});
|
|
|
|
@override
|
|
State<FacturasScreen> createState() => _FacturasScreenState();
|
|
}
|
|
|
|
class _FacturasScreenState extends State<FacturasScreen> {
|
|
String? _filtroEstado;
|
|
int? _filtroServicio;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
context.read<FacturaProvider>().cargarFacturas();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final facturaProv = context.watch<FacturaProvider>();
|
|
final servicioProv = context.watch<ServicioProvider>();
|
|
final configProv = context.watch<ConfiguracionProvider>();
|
|
final moneda = configProv.config?.moneda ?? 'USD';
|
|
final symbol = moneda == 'USD' ? '\$' : moneda == 'EUR' ? '€' : moneda == 'MXN' ? 'MX\$' : '\$';
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Facturas')),
|
|
body: Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: Row(
|
|
children: [
|
|
FilterChip(label: const Text('Todas'), selected: _filtroEstado == null && _filtroServicio == null, onSelected: (_) => setState(() { _filtroEstado = null; _filtroServicio = null; facturaProv.cargarFacturas(); })),
|
|
const SizedBox(width: 8),
|
|
FilterChip(label: const Text('Pendientes'), selected: _filtroEstado == 'Pendiente', onSelected: (_) => setState(() { _filtroEstado = 'Pendiente'; _filtroServicio = null; facturaProv.cargarFacturas(estado: 'Pendiente'); })),
|
|
const SizedBox(width: 8),
|
|
FilterChip(label: const Text('Pagadas'), selected: _filtroEstado == 'Pagada', onSelected: (_) => setState(() { _filtroEstado = 'Pagada'; _filtroServicio = null; facturaProv.cargarFacturas(estado: 'Pagada'); })),
|
|
const SizedBox(width: 8),
|
|
FilterChip(label: const Text('Vencidas'), selected: _filtroEstado == 'vencidas', onSelected: (_) => setState(() { _filtroEstado = 'vencidas'; _filtroServicio = null; facturaProv.facturasVencidas; })),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: facturaProv.cargando
|
|
? const Center(child: CircularProgressIndicator())
|
|
: ListView.builder(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
itemCount: facturaProv.facturas.length + (facturaProv.facturas.isEmpty ? 1 : 0),
|
|
itemBuilder: (_, i) {
|
|
if (facturaProv.facturas.isEmpty) {
|
|
return Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(48),
|
|
child: Column(
|
|
children: [
|
|
Icon(Icons.receipt_long, size: 64, color: Colors.grey[400]),
|
|
const SizedBox(height: 16),
|
|
Text('No hay facturas', style: Theme.of(context).textTheme.bodyLarge),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
final f = facturaProv.facturas[i];
|
|
final servicio = servicioProv.servicios.where((s) => s.id == f.servicioId).firstOrNull;
|
|
final vencida = f.estado == 'Pendiente' && DateTime.tryParse(f.fechaVencimiento)?.isBefore(DateTime.now()) == true;
|
|
return Card(
|
|
child: ListTile(
|
|
leading: CircleAvatar(
|
|
backgroundColor: Color(servicio?.color ?? 0xFF6200EE),
|
|
child: Text(servicio?.nombre.substring(0, 2).toUpperCase() ?? '??',
|
|
style: const TextStyle(color: Colors.white, fontSize: 12)),
|
|
),
|
|
title: Text('${servicio?.nombre ?? 'Desconocido'} - $symbol${NumberFormat('#,##0.00').format(f.monto)}'),
|
|
subtitle: Text('Vence: ${f.fechaVencimiento}${f.estado == 'Pagada' ? ' Pagada: ${f.fechaPago ?? ''}' : ''}'),
|
|
trailing: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
if (f.estado == 'Pendiente')
|
|
IconButton(
|
|
icon: Icon(Icons.check_circle, color: vencida ? Colors.red : Colors.green),
|
|
onPressed: () => facturaProv.marcarPagada(f.id!),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(Icons.delete_outline, color: Colors.red),
|
|
onPressed: () => facturaProv.eliminarFactura(f.id!),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|