chitfund/luckychit/lib/features/chitfund_schedule/chitfund_schedule_page.dart

490 lines
15 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../core/models/chit_group.dart';
class ChitfundSchedulePage extends StatefulWidget {
final ChitGroup chitfund;
const ChitfundSchedulePage({
Key? key,
required this.chitfund,
}) : super(key: key);
@override
State<ChitfundSchedulePage> createState() => _ChitfundSchedulePageState();
}
class _ChitfundSchedulePageState extends State<ChitfundSchedulePage> {
String _formatIndianCurrency(double amount) {
// Convert to integer to avoid decimal places
int intAmount = amount.round();
// Format with Indian numbering system (commas every 2 digits after the first 3)
String amountStr = intAmount.toString();
String formatted = '';
if (amountStr.length <= 3) {
formatted = amountStr;
} else {
// For amounts > 999, use Indian comma system
int remaining = amountStr.length;
int start = 0;
// First group (rightmost 3 digits)
if (remaining > 3) {
formatted = amountStr.substring(amountStr.length - 3);
remaining -= 3;
start = amountStr.length - 3;
} else {
formatted = amountStr;
remaining = 0;
}
// Subsequent groups (2 digits each)
while (remaining > 0) {
int groupSize = remaining >= 2 ? 2 : remaining;
int groupStart = start - groupSize;
String group = amountStr.substring(groupStart, start);
formatted = group + ',' + formatted;
start = groupStart;
remaining -= groupSize;
}
}
return '$formatted';
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade50,
appBar: AppBar(
title: Text(
'${widget.chitfund.name} - Schedule',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
),
),
backgroundColor: Colors.green.shade600,
foregroundColor: Colors.white,
elevation: 2,
),
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header with Sai Baba icon
_buildHeader(),
SizedBox(height: 24.h),
// Chitfund Schedule Table
_buildScheduleTable(),
SizedBox(height: 24.h),
// Summary Information
_buildSummaryInfo(),
],
),
),
);
}
Widget _buildHeader() {
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8.r,
offset: Offset(0, 2.h),
),
],
),
child: Row(
children: [
// Sai Baba Icon
Container(
width: 60.w,
height: 60.h,
decoration: BoxDecoration(
color: Colors.orange.shade100,
shape: BoxShape.circle,
),
child: Icon(
Icons.person,
size: 30.w,
color: Colors.orange.shade600,
),
),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.chitfund.name,
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
),
SizedBox(height: 4.h),
Text(
'Chitfund Schedule & Payment Details',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey.shade600,
),
),
],
),
),
],
),
);
}
Widget _buildScheduleTable() {
final scheduleData = _generateScheduleData();
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8.r,
offset: Offset(0, 2.h),
),
],
),
child: Column(
children: [
// Table Header
Container(
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
decoration: BoxDecoration(
color: Colors.green.shade600,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.r),
topRight: Radius.circular(12.r),
),
),
child: Row(
children: [
Expanded(
flex: 1,
child: Text(
'Sl No',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.sp,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
'Month',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.sp,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
'Chit Value',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.sp,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
'Bid Amount',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.sp,
),
textAlign: TextAlign.center,
),
),
],
),
),
// Table Rows
...scheduleData.asMap().entries.map((entry) {
final index = entry.key;
final data = entry.value;
final isTotalRow = data['isTotal'] == true;
return Container(
padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 12.w),
decoration: BoxDecoration(
color: isTotalRow
? Colors.orange.shade50
: _getRowColor(index, scheduleData.length - 1),
border: Border(
bottom: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
),
child: Row(
children: [
Expanded(
flex: 1,
child: Text(
data['slNo'],
style: TextStyle(
fontSize: 12.sp,
fontWeight: isTotalRow ? FontWeight.bold : FontWeight.normal,
color: isTotalRow ? Colors.orange.shade800 : Colors.grey.shade800,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
data['month'],
style: TextStyle(
fontSize: 12.sp,
fontWeight: isTotalRow ? FontWeight.bold : FontWeight.normal,
color: isTotalRow ? Colors.orange.shade800 : Colors.grey.shade800,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
data['chitValue'],
style: TextStyle(
fontSize: 12.sp,
fontWeight: isTotalRow ? FontWeight.bold : FontWeight.normal,
color: isTotalRow ? Colors.orange.shade800 : Colors.grey.shade800,
),
textAlign: TextAlign.center,
),
),
Expanded(
flex: 2,
child: Text(
data['bidAmount'],
style: TextStyle(
fontSize: 12.sp,
fontWeight: isTotalRow ? FontWeight.bold : FontWeight.normal,
color: isTotalRow ? Colors.orange.shade800 : Colors.grey.shade800,
),
textAlign: TextAlign.center,
),
),
],
),
);
}).toList(),
],
),
);
}
Widget _buildSummaryInfo() {
return Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8.r,
offset: Offset(0, 2.h),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Chitfund Summary',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: _buildSummaryCard(
'Total Value',
_formatIndianCurrency(widget.chitfund.totalValue),
Icons.account_balance_wallet,
Colors.blue,
),
),
SizedBox(width: 12.w),
Expanded(
child: _buildSummaryCard(
'Monthly Installment',
_formatIndianCurrency(widget.chitfund.monthlyInstallment),
Icons.payment,
Colors.green,
),
),
],
),
SizedBox(height: 12.h),
Row(
children: [
Expanded(
child: _buildSummaryCard(
'Duration',
'${widget.chitfund.durationMonths} months',
Icons.calendar_today,
Colors.orange,
),
),
SizedBox(width: 12.w),
Expanded(
child: _buildSummaryCard(
'Max Members',
'${widget.chitfund.maxMembers}',
Icons.group,
Colors.purple,
),
),
],
),
],
),
);
}
Widget _buildSummaryCard(String title, String value, IconData icon, Color color) {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.r),
border: Border.all(color: color.withOpacity(0.3)),
),
child: Column(
children: [
Icon(icon, color: color, size: 24.w),
SizedBox(height: 8.h),
Text(
title,
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey.shade600,
),
textAlign: TextAlign.center,
),
SizedBox(height: 4.h),
Text(
value,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.bold,
color: color,
),
textAlign: TextAlign.center,
),
],
),
);
}
List<Map<String, dynamic>> _generateScheduleData() {
final List<Map<String, dynamic>> scheduleData = [];
final startDate = widget.chitfund.startDate;
final totalMonths = widget.chitfund.durationMonths;
final chitValue = widget.chitfund.totalValue;
// Return empty data if startDate is null
if (startDate == null) {
return scheduleData;
}
// Calculate bid amounts (starting at 87.65% of chit value and increasing by 2,600 each month)
final bidIncrement = 2600;
var currentBidAmount = chitValue * 0.8765; // Starting at 87.65% of chit value (same as financial tab)
for (int i = 0; i < totalMonths; i++) {
final monthDate = DateTime(startDate.year, startDate.month + i);
final monthName = _getMonthName(monthDate);
scheduleData.add({
'slNo': '${i + 1}',
'month': monthName,
'chitValue': _formatIndianCurrency(chitValue),
'bidAmount': _formatIndianCurrency(currentBidAmount),
'isTotal': false,
});
currentBidAmount += bidIncrement;
}
// Add total row
final totalChitValue = chitValue * totalMonths;
final totalBidAmount = scheduleData.fold(0.0, (sum, entry) {
if (entry['isTotal'] == true) return sum;
final bidAmountStr = entry['bidAmount'].toString().replaceAll('', '').replaceAll(',', '');
return sum + double.parse(bidAmountStr);
});
scheduleData.add({
'slNo': 'Total',
'month': '',
'chitValue': _formatIndianCurrency(totalChitValue),
'bidAmount': _formatIndianCurrency(totalBidAmount),
'isTotal': true,
});
return scheduleData;
}
String _getMonthName(DateTime date) {
final months = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
return '${months[date.month - 1]}-${date.year.toString().substring(2)}';
}
Color _getRowColor(int index, int totalRows) {
if (index < 6) {
return Colors.orange.shade50; // Light orange for first 6 rows
} else if (index == 6) {
return Colors.white; // White for 7th row
} else {
return Colors.green.shade50; // Light green for remaining rows
}
}
}