import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../domain/customer.dart'; import '../providers/invoices_provider.dart'; import '../../transactions/providers/providers.dart'; class CustomerLedgerScreen extends ConsumerStatefulWidget { final Customer customer; const CustomerLedgerScreen({super.key, required this.customer}); @override ConsumerState createState() => _CustomerLedgerScreenState(); } class _CustomerLedgerScreenState extends ConsumerState { @override Widget build(BuildContext context) { final invoicesState = ref.watch(invoicesProvider); final formatCurrency = NumberFormat.currency(symbol: '₹'); return Scaffold( appBar: AppBar( title: Text('${widget.customer.name} Ledger'), backgroundColor: Colors.white, foregroundColor: Colors.black, elevation: 0, ), body: invoicesState.when( loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('Error: $err')), data: (invoices) { final customerInvoices = invoices .where((i) => i.customerId == widget.customer.id) .toList(); if (customerInvoices.isEmpty) { return const Center( child: Text('No invoices found for this customer.'), ); } // Sort chronological customerInvoices.sort((a, b) => a.issueDate.compareTo(b.issueDate)); double runningBalance = 0.0; List rows = []; final wallets = ref.read(walletProvider).value ?? []; int index = 1; for (var inv in customerInvoices) { // Add row for Invoice (Debit) runningBalance += inv.totalAmount; rows.add( DataRow( cells: [ DataCell(Text('${index++}')), DataCell( Text(DateFormat('dd MMM yyyy').format(inv.issueDate)), ), DataCell( Text( inv.invoiceNumber, style: const TextStyle(fontWeight: FontWeight.w600), ), ), const DataCell(Text('Invoice')), const DataCell(Text('-')), const DataCell(Text('-')), DataCell( Text( formatCurrency.format(inv.totalAmount), style: TextStyle( color: Colors.red.shade700, fontWeight: FontWeight.bold, ), ), ), DataCell( Text( formatCurrency.format(runningBalance), style: const TextStyle(fontWeight: FontWeight.bold), ), ), ], ), ); // Add row for Payment (Credit) if (inv.payments != null && inv.payments!.isNotEmpty) { for (var p in inv.payments!) { runningBalance -= p.amount; final walletName = wallets .firstWhere( (w) => w.id == p.walletId, orElse: () => wallets.first, ) .name; rows.add( DataRow( cells: [ DataCell(Text('${index++}')), DataCell( Text( p.paymentDate != null ? DateFormat('dd MMM yyyy').format(p.paymentDate!) : DateFormat('dd MMM yyyy').format(inv.issueDate), ), ), DataCell( Text( inv.invoiceNumber, style: const TextStyle(fontWeight: FontWeight.w600), ), ), const DataCell(Text('Payment')), DataCell(Text(p.paymentMethod)), DataCell(Text(p.walletId != null ? walletName : '-')), DataCell( Text( formatCurrency.format(p.amount), style: TextStyle( color: Colors.green.shade700, fontWeight: FontWeight.bold, ), ), ), DataCell( Text( formatCurrency.format(runningBalance), style: const TextStyle(fontWeight: FontWeight.bold), ), ), ], ), ); } } else if (inv.amountPaid > 0) { runningBalance -= inv.amountPaid; rows.add( DataRow( cells: [ DataCell(Text('${index++}')), DataCell( Text(DateFormat('dd MMM yyyy').format(inv.issueDate)), ), DataCell( Text( inv.invoiceNumber, style: const TextStyle(fontWeight: FontWeight.w600), ), ), const DataCell(Text('Payment')), const DataCell(Text('-')), const DataCell(Text('-')), DataCell( Text( formatCurrency.format(inv.amountPaid), style: TextStyle( color: Colors.green.shade700, fontWeight: FontWeight.bold, ), ), ), DataCell( Text( formatCurrency.format(runningBalance), style: const TextStyle(fontWeight: FontWeight.bold), ), ), ], ), ); } } return Column( children: [ Container( width: double.infinity, color: Colors.blue.withOpacity(0.05), padding: const EdgeInsets.all(24), child: Column( children: [ const Text( 'Outstanding Balance', style: TextStyle(color: Colors.grey, fontSize: 14), ), const SizedBox(height: 8), Text( formatCurrency.format(runningBalance), style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: runningBalance > 0 ? Colors.red.shade700 : Colors.green.shade700, ), ), ], ), ), Expanded( child: SingleChildScrollView( scrollDirection: Axis.vertical, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( headingRowColor: WidgetStateProperty.resolveWith( (states) => Colors.grey.shade100, ), columnSpacing: 24, columns: const [ DataColumn( label: Text( 'S.No', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Date', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Invoice #', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Type', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Mode', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Wallet', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Amount', style: TextStyle(fontWeight: FontWeight.bold), ), ), DataColumn( label: Text( 'Balance', style: TextStyle(fontWeight: FontWeight.bold), ), ), ], rows: rows, ), ), ), ), ], ); }, ), ); } }