Code Merged

This commit is contained in:
sanjeev.p 2026-01-03 17:53:37 +05:30
parent 7e1b5c1022
commit 1fefb22f46
7 changed files with 342 additions and 218 deletions

File diff suppressed because one or more lines are too long

View File

@ -1718,6 +1718,28 @@ class ApiService {
return response;
}
Future<Map<String, dynamic>> fetchAgentUnusedCommissionList(id,broker_id) async {
print('fetchAGENTNameDropDown');
if (_token == null) {
await _initializeToken();
}
dynamic url;
print('fetchAGENTNameDropDown 1');
url = Uri.parse(
'${Env.apiUrl}invoice/getAgentUnusedCommissionList?manager_id=$id&broker_id=$broker_id',
);
print('fetchAGENTNameDropDown 2');
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature,
};
print('fetchAGENTNameDropDown 3');
final response = await _makeGetRequest(url, headers);
print('fetchAGENTNameDropDown 4 - $response');
return response;
}
static late String _baseUrl;
static void initialize(String baseUrl) {
@ -2093,7 +2115,7 @@ class ApiService {
Future<void> generatePolicyExcel(managerId, fromDate, toDate, searchValue) async {
final url = Uri.parse(
'${Env.apiUrl}reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}',
'${Env.apiUrl}reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&search=${searchValue ?? ''}',
);
// final url = Uri.parse( 'http://localhost/nhance_partner_be/reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&search=${searchValue ?? ''}', );

View File

@ -93,9 +93,10 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
// getPartnerDetails(userID);
// }
if (managerId != null) {
if (managerId != null && widget.selectedBroker != null) {
print('managerId - $managerId');
getAgentList(managerId);
print('SelectedBroker - $widget.selectedBroker');
getAgentList(managerId,widget.selectedBroker);
}
});
@ -133,24 +134,31 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
}
}
Future<void> getAgentList(id) async {
Future<void> getAgentList(id,broker_id) async {
print('getAgentListData called');
setState(() {
isLoadingAgentList = true;
});
try {
final response = await apiService.fetchAgentNameDropDown(id);
final response = await apiService.fetchAgentUnusedCommissionList(id,broker_id);
print('getAgentListData called response');
print('get Agent- ${response['data']}');
if (response['status'] == 'success') {
print('get Agent- ${response['data']}');
setState(() {
getPartnerData = List<Map<String, dynamic>>.from(response['data']);
print('API Data - $getPartnerData');
// 1. Convert the response to a list
final rawList = List<Map<String, dynamic>>.from(response['data']);
print('API Data - rawList');
// 2. Filter out items where agent_id is null or empty
getPartnerData = rawList.where((item) {
final id = item['agent_id'];
return id != null && id.toString().isNotEmpty;
}).toList();
print('Filtered API Data (No Null IDs) - $getPartnerData');
// 3. Sync the filtered data to your display list
filteredPartnerData = List.from(getPartnerData);
print('originalAgentData - $filteredPartnerData');
});
} else {
getPartnerData = [];
@ -499,18 +507,35 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
},
// constraints: BoxConstraints(),
),
// onChanged: (val) {
// if (val != null) {
// print("Selected Broker : ${val['name']}");
// print("Id: ${val['id']}");
// // selectedBroker = val['id'];
// widget.onBrokerChanged?.call(val['id'].toString());
// // widget.onBrokerChanged?.call(val['id']);
// // controllers['agentId']?.text = val['agent_code'];
// // agentId = agent['id'];
// }
// },
onChanged: (val) {
if (val != null) {
print("Selected Broker : ${val['name']}");
print("Id: ${val['id']}");
// selectedBroker = val['id'];
widget.onBrokerChanged?.call(val['id'].toString());
// widget.onBrokerChanged?.call(val['id']);
// controllers['agentId']?.text = val['agent_code'];
// agentId = agent['id'];
String selectedId = val['id'].toString();
// 1. Notify parent of the change
widget.onBrokerChanged?.call(selectedId);
// 2. Clear current partner list so user doesn't see old data
setState(() {
filteredPartnerData = [];
});
// 3. Fetch new agents based on this broker
getAgentList(managerId!, selectedId);
}
},
),
),
],
@ -523,7 +548,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Referer *", style: _textStyle),
Text("Referer", style: _textStyle),
SizedBox(height: 5),
SizedBox(
height: 35,
@ -536,7 +561,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
// : null,
selectedItems: filteredPartnerData
.where(
(item) => (widget.selectedParnter ?? []).contains(item['id']),
(item) => (widget.selectedParnter ?? []).contains(item['agent_id']),
)
.toList(),
@ -549,26 +574,27 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
return filteredPartnerData;
},
itemAsString: (val) => val['name'].toString(), // what to show
itemAsString: (val) => // what to show
"${val['agent_name']} | ${val['unused_commission_amount']} (${val['total_policies']})",
compareFn: (item, selectedItem) =>
item['id'] == selectedItem['id'], // compare by id
item['agent_id'] == selectedItem['agent_id'], // compare by id
// validator: (val) {
// if (val == null) {
// return "Required"; // error message
// }
// return null;
// },
validator: (val) {
if (val == null || val.isEmpty) {
return ""; // 👈 triggers error border, no text
}
return null;
// if (val == null || val.isEmpty) {
// return "Required";
// }
// return null;
},
// validator: (val) {
// if (val == null || val.isEmpty) {
// return ""; // 👈 triggers error border, no text
// }
// return null;
//
// // if (val == null || val.isEmpty) {
// // return "Required";
// // }
// // return null;
// },
decoratorProps: DropDownDecoratorProps(
decoration:
@ -641,7 +667,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
vertical: 3,
),
child: Text(
item['name'].toString(),
"${item['agent_name']} | ${item['unused_commission_amount']} (${item['total_policies']})",
style: GoogleFonts.inter(fontSize: 12, color: Colors.black),
),
);
@ -652,7 +678,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRowPayout> {
// selectedPartnerIds = selectedVals
// .map((v) => v['id'].toString())
// .toList();
final ids = selectedVals.map((v) => v['id'].toString()).toList();
final ids = selectedVals.map((v) => v['agent_id'].toString()).toList();
print("Selected PArnter IDs: $widget.selectedPartnerIds");
widget.onPartnerChanges?.call(ids);
// widget.onPartnerChanges!(v['id']);

View File

@ -138,7 +138,7 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
print('invoiceID $invoiceID');
print('brokerID $brokerID');
_loadEditData(invoiceID, brokerID);
_loadEditData(invoiceID, brokerID,managerId);
}
}
@ -230,7 +230,7 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
});
}
void _loadEditData(String invoiceID, brokerID) async {
void _loadEditData(String invoiceID, brokerID, managerID) async {
setState(() => isLoadingEditData = true);
print('_loadEditData');
@ -238,6 +238,7 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
// "id": invoiceID,
"invoice_id": invoiceID,
"broker_id": int.tryParse(brokerID ?? ''),
"manager_id": managerID
// "issued_date": formattedTillDate,
};
@ -442,6 +443,28 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
);
}
// if (dashboardKey == 'f' &&
// isDashboardInitialLoad &&
// SelectedStatus == "P") {
//
//
// fromDt = "";toDt = "";
// isDashboardInitialLoad = false;
//
// } else if (dashboardKey == 'f' && isDashboardInitialLoad && SelectedStatus != '') {
// fromDt = "";toDt = "";
// isDashboardInitialLoad = false;
// } else if (fromDateVal.isEmpty && toDateVal.isEmpty) {
// // Default fallback
// final today = DateTime.now();
// fromDt = DateFormat('dd-MM-yyyy').format(today.subtract(const Duration(days: 5)));
// toDt = DateFormat('dd-MM-yyyy').format(today);
// } else {
// // USER SELECTED DATE ALWAYS RESPECT THIS
// fromDt = fromDateVal;
// toDt = toDateVal;
// }
// Load policies (simulate API)
Future<void> loadPolicies() async {
print('loadPolicies');
@ -454,7 +477,9 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
"from_date": controllers['startDate']?.text,
"to_date": controllers['endDate']?.text,
"broker_id": int.tryParse(selectedBrokerID ?? ''),
"agent_id": agentIds,
"manager_id": managerId,
if (agentIds != null && agentIds.isNotEmpty) "agent_id": agentIds,
// "agent_id": agentIds,
// "issued_date": formattedTillDate,
};
final response = await apiService.getCommissionRateList(jsondata);
@ -1296,6 +1321,8 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
}
double _calculateTotalCommission() {
print("ASD");
print(filteredPolicies);
double total = 0.0;
for (var p in filteredPolicies) {

View File

@ -44,12 +44,16 @@ import 'enquiry_inline_SubRow.dart';
import 'multi_file_list.dart';
class EnquiryListStaffInline extends ConsumerStatefulWidget {
const EnquiryListStaffInline({super.key});
@override
ConsumerState<EnquiryListStaffInline> createState() => EnquiryStaffState();
}
class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// bool fromDashboard = false;
bool _dashboardInitHandled = false;
bool _resetKeyEnable = false;
int currentPage = 1;
int itemsPerPage = 10;
// int itemsPerPage = 5;
@ -169,9 +173,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic> dataDetails() {
final data = {
"agent_id":
((roleId == 'handler') ||
(roleId == 'manager') ||
(roleId == 'staff'))
((roleId == 'handler') ||
(roleId == 'manager') ||
(roleId == 'staff'))
? selectedAgent
: userId,
"name": controllers["name"]?.text,
@ -198,19 +202,19 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
}
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownSelectPaymentModeKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
//---------------------- Assign Staff starts -------------------------------- //
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyInsurerEnqAsgn =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKeyBroker =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<Map<String, dynamic>> getStaffDetailsDataEnqAsgn = [];
List<Map<String, dynamic>> filteredStaffDataEnqAsgn = [];
@ -234,6 +238,26 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
//---------------------- Assign Staff Ends -------------------------------- //
//---------------------- Enquiry TAB Initializations Ends -------------------------------- //
// @override
// void didChangeDependencies() {
// super.didChangeDependencies();
// if (_dashboardInitHandled) return;
// _dashboardInitHandled = true;
// final extra = GoRouterState.of(context).extra;
// if (extra is Map<String, dynamic>) {
// fromDashboard = extra['fromDashboard'] ?? false;
// }
// // 🔥 IMPORTANT: Clear date pickers ONLY when coming from dashboard
// if (fromDashboard) {
// controllers['startDate']?.clear();
// controllers['endDate']?.clear();
// }
// }
@override
void initState() {
super.initState();
@ -298,9 +322,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
getPaymentMode();
refreshSub = ref.listenManual<bool>(enquiryRefreshProvider, (
previous,
next,
) {
previous,
next,
) {
if (next == true) {
print('refresh triggered Quick Creation');
autoRefrshfilterDateRange();
@ -505,6 +529,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
}
Future<void> refrshfilterDateRange() async {
setState(() {
_resetKeyEnable = true;
});
print('refrshfilterDateRange');
// setState(() async {
final prefs = await SharedPreferences.getInstance();
@ -603,13 +630,13 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
}
Future<void> getStaffList(
int managerId,
role, {
String fromDate = '',
String toDate = '',
String SelectedStatus = '',
String SelectedStaffId = '',
}) async {
int managerId,
role, {
String fromDate = '',
String toDate = '',
String SelectedStatus = '',
String SelectedStaffId = '',
}) async {
print('A613 => Fns called => $managerId | $role');
setState(() {
isLoadingStaffList = true;
@ -624,16 +651,21 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final dateFormat = DateFormat('dd-MM-yyyy');
if (dashboardKey == 'fromDashboard' && SelectedStatus == "PrevPending") {
setState(() {
_dashboardInitHandled = true;
});
// For PREV PENDING set date range until yesterday
final today = DateTime.now();
print('A813 => Fns called => $managerId | $role');
// Change to dd-MM-yyyy
final dateFormat = DateFormat('dd-MM-yyyy');
// final dateFormat = DateFormat('dd-MM-yyyy');
//
// final yesterday = today.subtract(Duration(days: 1));
final yesterday = today.subtract(Duration(days: 1));
fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15)));
toDt = dateFormat.format(yesterday);
fromDt = _dashboardInitHandled ? controllers['startDate']?.text : '';
toDt = _dashboardInitHandled ? controllers['endDate']?.text : '';
// fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15)));
// toDt = dateFormat.format(yesterday);
print('PrevPending FROM TO - $fromDt - $toDt');
} else if (dashboardKey == 'fromDashboard' &&
@ -645,8 +677,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Change to dd-MM-yyyy
final dateFormat = DateFormat('dd-MM-yyyy');
fromDt = dateFormat.format(today);
toDt = dateFormat.format(today);
// fromDt = dateFormat.format(today);
// toDt = dateFormat.format(today);
fromDt = _dashboardInitHandled ? controllers['startDate']?.text : '';
toDt = _dashboardInitHandled ? controllers['endDate']?.text : '';
print('PrevPending FROM TO - $fromDt - $toDt');
} else if (dashboardKey != 'fromDashboard' &&
@ -664,8 +699,25 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} else {
print('A1113 => Fns called => $managerId | $role');
print('Enq 1- $fromDt - $toDt');
fromDt = fromDateVal;
toDt = toDateVal;
if(_resetKeyEnable = true){
final dateFormat = DateFormat('dd-MM-yyyy');
final today = DateTime.now();
final yesterday = today.subtract(Duration(days: 1));
fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15)));
toDt = dateFormat.format(yesterday);
setState(() {
controllers['startDate']?.text = fromDt;
controllers['endDate']?.text = toDt;
});
} else {
fromDt = fromDateVal;
toDt = toDateVal;
}
}
print('Enq 2- $fromDt - $toDt');
String finalStatus = SelectedStatus;
@ -678,13 +730,13 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
managerId,
userId,
role,
fromDate: fromDt,
toDate: toDt,
fromDate: _dashboardInitHandled ? controllers['startDate']?.text : fromDt,
toDate: _dashboardInitHandled ? controllers['endDate']?.text : toDt,
// selectedStatus: (finalStatus != '' && finalStatus != 'PrevPending')
// ? finalStatus
// : '',
selectedStatus:
(SelectedStatus != '' && SelectedStatus != 'PrevPending')
(SelectedStatus != '' && SelectedStatus != 'PrevPending')
? SelectedStatus
: '',
selectedStaffId: SelectedStaffId ?? '',
@ -700,8 +752,13 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
print('A1213 => Fns called => $managerId | $role');
setState(() {
_resetKeyEnable = false;
controllers['startDate']?.text = fromDate;
controllers['endDate']?.text = toDate;
if (data is List) {
getStaffData = List<Map<String, dynamic>>.from(data);
@ -946,8 +1003,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Search within the current tab's data
filteredData = sourceList.where((item) {
return (item['agent_name'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
query.toLowerCase(),
) ||
(item['agent_code'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
@ -1013,11 +1070,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
}
Future<void> handleStaff(
BuildContext context,
dynamic data,
id,
regNum,
) async {
BuildContext context,
dynamic data,
id,
regNum,
) async {
showDialog(
context: context,
builder: (ctx) => AssignStaffDialog(
@ -1152,7 +1209,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final bool isNewRow =
int.tryParse(id.toString()) != null &&
int.parse(id.toString()) > 1000000000000;
int.parse(id.toString()) > 1000000000000;
print('isNewRow - $isNewRow');
@ -1160,20 +1217,20 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
if (isNewRow) {
// Check if this is a new unsaved row
final row = getStaffData.firstWhere(
(item) => item['id'].toString() == id.toString(),
(item) => item['id'].toString() == id.toString(),
orElse: () => {},
);
// If policy_number is empty, it's a new row - remove it
if (row.isNotEmpty) {
getStaffData.removeWhere(
(item) => item['id'].toString() == id.toString(),
(item) => item['id'].toString() == id.toString(),
);
originalData.removeWhere(
(item) => item['id'].toString() == id.toString(),
(item) => item['id'].toString() == id.toString(),
);
filteredData.removeWhere(
(item) => item['id'].toString() == id.toString(),
(item) => item['id'].toString() == id.toString(),
);
rowControllers.remove(id);
}
@ -1293,10 +1350,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Future<void> attachFiles(http.MultipartRequest request) async {
Future<void> addFileOrKeepName(
PlatformFile? file,
String? apiFileName,
String fieldName,
) async {
PlatformFile? file,
String? apiFileName,
String fieldName,
) async {
if (file != null) {
// User uploaded a new file send as multipart
if (file.bytes != null) {
@ -1347,8 +1404,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Future<void> createUserData(Map<String, dynamic> userData) async {
final bool isNewRow =
idPrimary != null &&
int.tryParse(idPrimary.toString()) != null &&
int.parse(idPrimary.toString()) > 1000000000000;
int.tryParse(idPrimary.toString()) != null &&
int.parse(idPrimary.toString()) > 1000000000000;
final bool isUpdating =
idPrimary != null && idPrimary != 'null' && !isNewRow;
@ -1577,26 +1634,26 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// SizedBox(height: 5),
ResponsiveLayout.isMobile(context)
? Container(
height: MediaQuery.of(context).size.height * 0.69,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(2),
child: _buildContent(context),
),
),
)
height: MediaQuery.of(context).size.height * 0.69,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(2),
child: _buildContent(context),
),
),
)
:
// Expanded(
// child:
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.69,
// padding: EdgeInsets.symmetric(
// horizontal: 8.0,
// vertical: 2.0,
// ),
child: _buildContent(context),
),
// Expanded(
// child:
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.69,
// padding: EdgeInsets.symmetric(
// horizontal: 8.0,
// vertical: 2.0,
// ),
child: _buildContent(context),
),
],
),
),
@ -1615,7 +1672,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final result = await showDialog(
context: context,
barrierDismissible:
false, // optional - prevents closing by tapping outside
false, // optional - prevents closing by tapping outside
builder: (context) => TabEnquiryStaffList(showKey: val),
);
@ -1626,10 +1683,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
}
Future<void> buildPolicyCreatedStatusActions(
BuildContext context,
status,
id,
) async {
BuildContext context,
status,
id,
) async {
print("Actionsstatus - $status -$id");
dynamic val;
if (status == 'Awaiting Proposal' || status == 'Proposal Created') {
@ -1641,7 +1698,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final result = await showDialog(
context: context,
barrierDismissible:
false, // optional - prevents closing by tapping outside
false, // optional - prevents closing by tapping outside
builder: (context) => PolicyStaffEnqList(),
);
@ -1748,7 +1805,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
userPreference = newValue; // Save this as the new "normal"
});
final prefs =
await SharedPreferences.getInstance();
await SharedPreferences.getInstance();
await prefs.setBool(
'isActionable',
newValue,
@ -1817,7 +1874,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// });
},
child: ThemedSearchField(
hintText: 'Search *',
hintText: 'Search',
backgroundColor: Color(0xFFFFFFFF),
txtHeight: 30,
controller: _searchStaffController,
@ -1851,11 +1908,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
txt: !ResponsiveLayout.isMobile(context) ? true : false,
displayHeaders: [
"Received Date & Time",
"Partner",
"Assigned To",
"Partner",
"Insurer",
"Vehicle.No.",
"Insured Name",
"Vehicle.No.",
"Assigned Date & Time",
"Premium",
"Payment Mode",
@ -1864,14 +1921,14 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
],
keys: [
"created_on",
"agent_name",
"assigned_to_name",
"agent_name",
"insurer_short_name",
"reg_no",
"insured_name",
"reg_no",
"updated_on",
"premium_amount",
"payment_mode",
"payment_mode_value",
"policy_number",
"status",
],
@ -1885,12 +1942,12 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
ResponsiveLayout.isMobile(context)
? _buildDataTable(context)
: Container(
height: MediaQuery.of(context).size.height * 0.55,
// decoration: BoxDecoration(
// color: Colors.white
// ),
child: _buildDataTable(context),
),
height: MediaQuery.of(context).size.height * 0.55,
// decoration: BoxDecoration(
// color: Colors.white
// ),
child: _buildDataTable(context),
),
],
);
}
@ -2036,54 +2093,54 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Calculate minimum width based on screen size
double minTableWidth = isMobile ? screenWidth * 1.5 : 1300;
return
// Expanded(
// child:
LayoutBuilder(
builder: (context, constraints) {
double tableWidth = constraints.maxWidth > minTableWidth
? constraints.maxWidth
: minTableWidth;
// Expanded(
// child:
LayoutBuilder(
builder: (context, constraints) {
double tableWidth = constraints.maxWidth > minTableWidth
? constraints.maxWidth
: minTableWidth;
final isDesktop = !ResponsiveLayout.isMobile(context);
final isDesktop = !ResponsiveLayout.isMobile(context);
return ScrollConfiguration(
behavior: const MaterialScrollBehavior().copyWith(
dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch},
),
child: SingleChildScrollView(
controller: _horizontalScrollController, // 👈 Shared controller
scrollDirection: Axis.horizontal,
child: SizedBox(
// width: minWidth,
width: tableWidth,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Fixed Header
Container(
decoration: BoxDecoration(
// color: Colors.white,
color: Color(0xFFF1F5F9),
borderRadius: BorderRadius.circular(5),
return ScrollConfiguration(
behavior: const MaterialScrollBehavior().copyWith(
dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch},
),
child: SingleChildScrollView(
controller: _horizontalScrollController, // 👈 Shared controller
scrollDirection: Axis.horizontal,
child: SizedBox(
// width: minWidth,
width: tableWidth,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Fixed Header
Container(
decoration: BoxDecoration(
// color: Colors.white,
color: Color(0xFFF1F5F9),
borderRadius: BorderRadius.circular(5),
),
child: _buildTableHeader(isDesktop),
),
child: _buildTableHeader(isDesktop),
),
// Scrollable Data Content
Expanded(
child: Container(
decoration: BoxDecoration(color: Colors.white),
child: _buildDataTableContent(), // 👈 New method
// Scrollable Data Content
Expanded(
child: Container(
decoration: BoxDecoration(color: Colors.white),
child: _buildDataTableContent(), // 👈 New method
),
),
),
_buildPaginationControls(),
],
_buildPaginationControls(),
],
),
),
),
),
);
},
);
);
},
);
// );
}
@ -2295,10 +2352,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Build action buttons
Widget _buildActionButtons(
Map<String, dynamic> item,
int id,
String selectId,
) {
Map<String, dynamic> item,
int id,
String selectId,
) {
return Row(
children: [
_buildInfoTooltip(item),
@ -2370,8 +2427,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
onTap: () async {
final button = buttonContext.findRenderObject() as RenderBox;
final overlay =
Overlay.of(buttonContext).context.findRenderObject()
as RenderBox;
Overlay.of(buttonContext).context.findRenderObject()
as RenderBox;
final position = button.localToGlobal(
Offset.zero,
ancestor: overlay,
@ -2417,9 +2474,6 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
);
}
String normalizedStatus(dynamic value) {
return value?.toString().trim().toLowerCase() ?? '';
}
// Helper: Status cell with conditional actions
Widget _buildStatusCell(
Map<String, dynamic> item,
@ -2461,11 +2515,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Status display container
Widget _buildStatusContainer(
Map<String, dynamic> item,
int id,
Color bgColor,
Color borderColor,
) {
Map<String, dynamic> item,
int id,
Color bgColor,
Color borderColor,
) {
return Material(
color: Colors.white,
child: InkWell(
@ -2484,13 +2538,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
(item['enquiry_status'] ?? '-')
.toString()
.toLowerCase()
.split(' ')
.where((w) => w.isNotEmpty)
.map((w) => w[0].toUpperCase() + w.substring(1))
.join(' '),
item['enquiry_status'] ?? '-',
style: GoogleFonts.inter(
fontSize: 10,
color: Color(0XFF1e293b),
@ -2645,7 +2693,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
child: InkWell(
onTap: () => apiService.downloadFile(
apiUrl:
'api/policy/downloadPolicyFile?policy_id=${item["policy_id"]}&file_type=policy_pdf',
'api/policy/downloadPolicyFile?policy_id=${item["policy_id"]}&file_type=policy_pdf',
apiId: item["policy_id"],
localFile: null,
fileName: item['policy_pdf_file_name'],
@ -2685,12 +2733,12 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Show policy upload menu
Future<void> _showPolicyUploadMenu(
BuildContext buttonContext,
Map<String, dynamic> item,
) async {
BuildContext buttonContext,
Map<String, dynamic> item,
) async {
final button = buttonContext.findRenderObject() as RenderBox;
final overlay =
Overlay.of(buttonContext).context.findRenderObject() as RenderBox;
Overlay.of(buttonContext).context.findRenderObject() as RenderBox;
final position = button.localToGlobal(Offset.zero, ancestor: overlay);
await showMenu(
@ -2723,7 +2771,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Widget _buildPolicyUploadField(Map<String, dynamic> item) {
return ThemedUploadField(
hintText:
selectedFileNames ??
selectedFileNames ??
item['policy_pdf_file_name'] ??
"Upload Document",
padHorizontal: 4,
@ -2741,10 +2789,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Handle policy file upload
Future<void> _handlePolicyFileUpload(
String? fileName,
PlatformFile? file,
Map<String, dynamic> item,
) async {
String? fileName,
PlatformFile? file,
Map<String, dynamic> item,
) async {
if (lastPickedFile == fileName) {
ToastHelper.showErrorToast(context, 'Please upload a new file.');
setState(() {
@ -2786,7 +2834,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic>? _getSelectedPaymentMode(Map<String, dynamic> item) {
try {
return filteredPaymentModeData.firstWhere(
(mode) => mode['id'].toString() == item['payment_mode_id'].toString(),
(mode) => mode['id'].toString() == item['payment_mode_id'].toString(),
orElse: () => {},
);
} catch (e) {
@ -2797,8 +2845,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic>? _getSelectedInsurancePlan(Map<String, dynamic> item) {
try {
return filteredInsuranceData.firstWhere(
(mode) =>
mode['insurance_plan_type'].toString().trim().toLowerCase() ==
(mode) =>
mode['insurance_plan_type'].toString().trim().toLowerCase() ==
item['insurance_plan_type'].toString().trim().toLowerCase(),
orElse: () => {},
);
@ -2840,8 +2888,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Widget _buildDropdownDisplay(dynamic selectedItem, String key, String hint) {
bool isEmpty =
selectedItem == null ||
selectedItem.isEmpty ||
selectedItem[key] == null;
selectedItem.isEmpty ||
selectedItem[key] == null;
return Container(
padding: EdgeInsets.zero,
@ -3123,7 +3171,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(6),
color: isSelected
// ? Color(0xFFF1F5F9)
// ? Color(0xFFF1F5F9)
? const Color(0xFF2E7D6E).withOpacity(0.08)
: Colors.transparent,
border: Border.all(
@ -3250,9 +3298,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
.split(' ')
.map(
(word) => word.isNotEmpty
? word[0].toUpperCase() + word.substring(1).toLowerCase()
: '',
)
? word[0].toUpperCase() + word.substring(1).toLowerCase()
: '',
)
.join(' ');
}
@ -3460,8 +3508,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
icon: Icon(Icons.last_page, size: 18),
onPressed: completedCurrentPage < totalCompletedPages
? () => setState(
() => completedCurrentPage = totalCompletedPages,
)
() => completedCurrentPage = totalCompletedPages,
)
: null,
color: completedCurrentPage < totalCompletedPages
? Color(0xFF2E7D6E)
@ -3583,8 +3631,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
icon: Icon(Icons.last_page, size: 18),
onPressed: completedCurrentPage < totalCompletedPages
? () => setState(
() => completedCurrentPage = totalCompletedPages,
)
() => completedCurrentPage = totalCompletedPages,
)
: null,
color: completedCurrentPage < totalCompletedPages
? Color(0xFF2E7D6E)
@ -3650,4 +3698,4 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
return pageButtons;
}
}
}

View File

@ -174,22 +174,23 @@ class ExcelExporter {
final rowMap = reversedData[i];
final row = <CellValue?>[];
// Inside ExcelExporter class -> exportToExcel method
for (var key in keys) {
dynamic value;
if (key == 'sno' ||
key.toLowerCase() == 's.no' ||
key.toLowerCase() == 'sno.') {
value = i + 1; // serial number (descending)
if (key == 'sno' || key.toLowerCase() == 's.no' || key.toLowerCase() == 'sno.') {
value = i + 1;
} else if (key.toLowerCase() == 'is_active') {
// Handle Active/Inactive display
final rawVal = rowMap[key];
value = (rawVal == 1 || rawVal == '1') ? 'Active' : 'Inactive';
} else {
// FIX: Ensure we extract the value and check if it's "null" as a string
value = rowMap[key];
if (value == "null") value = null;
}
if (value == null) {
row.add(TextCellValue('-'));
if (value == null || value.toString().trim().isEmpty) {
row.add(TextCellValue('-')); // This ensures the column isn't empty
} else if (value is int) {
row.add(IntCellValue(value));
} else if (value is double) {
@ -198,10 +199,10 @@ class ExcelExporter {
row.add(TextCellValue(value.toString()));
}
}
sheet.appendRow(row);
}
final excelBytes = excel.encode();
if (excelBytes == null) throw Exception('Failed to encode Excel file');

View File

@ -282,7 +282,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
'dd-MM-yyyy',
).format(date);
// controllers['date']?.text = date as String;
Future.microtask(() => widget.onFilter());
// Future.microtask(() => widget.onFilter());
},
),
),