This commit is contained in:
Surendiran 2026-01-06 12:52:37 +05:30
commit 6c92692fa9
23 changed files with 1294 additions and 310 deletions

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,7 @@ import '../../presentation/screens/Enquiry/policy_claims_endros/claims.dart';
import '../../presentation/screens/Enquiry/policy_claims_endros/endrosment.dart'; import '../../presentation/screens/Enquiry/policy_claims_endros/endrosment.dart';
import '../../presentation/screens/Masters/Brokers/brokerList.dart'; import '../../presentation/screens/Masters/Brokers/brokerList.dart';
import '../../presentation/screens/Masters/EndorsementType/endorsementList.dart'; import '../../presentation/screens/Masters/EndorsementType/endorsementList.dart';
import '../../presentation/screens/Masters/VehicleType/vehicleList.dart';
import '../../presentation/screens/StaffAttendance/attendanceAllDetails.dart'; import '../../presentation/screens/StaffAttendance/attendanceAllDetails.dart';
import '../../presentation/screens/StaffAttendance/individual_Attendance.dart'; import '../../presentation/screens/StaffAttendance/individual_Attendance.dart';
import '../../presentation/screens/UserManagement/Agent/agent.dart'; import '../../presentation/screens/UserManagement/Agent/agent.dart';
@ -278,6 +279,10 @@ final GoRouter appRouter = GoRouter(
path: AppRoutes.endorsementTypeLst, path: AppRoutes.endorsementTypeLst,
builder: (context, state) => const EndorsementTypeList(), builder: (context, state) => const EndorsementTypeList(),
), ),
GoRoute(
path: AppRoutes.vehicleTypeLst,
builder: (context, state) => const VehicleTypeList(),
),
GoRoute( GoRoute(
path: AppRoutes.paymentModeLst, path: AppRoutes.paymentModeLst,
builder: (context, state) => const PaymentLsit(), builder: (context, state) => const PaymentLsit(),

View File

@ -32,4 +32,5 @@ class AppRoutes {
static const String brokerLst = '/brokerLst'; static const String brokerLst = '/brokerLst';
static const String paymentModeLst = '/paymentMode'; static const String paymentModeLst = '/paymentMode';
static const String endorsementTypeLst = '/endorsementTypeLst'; static const String endorsementTypeLst = '/endorsementTypeLst';
static const String vehicleTypeLst = '/vehicleTypeLst';
} }

View File

@ -708,6 +708,9 @@ class ApiService {
else if (masterName == 'EndorsementType') { else if (masterName == 'EndorsementType') {
url = Uri.parse('${Env.apiUrl}master/updateEndorsementStatus/$id'); url = Uri.parse('${Env.apiUrl}master/updateEndorsementStatus/$id');
} }
else if (masterName == 'VehicleType') {
url = Uri.parse('${Env.apiUrl}master/updateVehicleTypeStatus/$id');
}
else { else {
url = Uri.parse('${Env.apiUrl}master/updatePaymentModeStatus/$id'); url = Uri.parse('${Env.apiUrl}master/updatePaymentModeStatus/$id');
} }
@ -787,9 +790,12 @@ class ApiService {
} }
final url = Uri.parse( final url = Uri.parse(
'${Env.apiUrl}dashboard/partnerDashboard?manager_id=$id', '${Env.apiUrl}dashboard/partnerDashboard?manager_id=$id',
// 'http://localhost/nhance_partner_be/dashboard/partnerDashboard?manager_id=$id',
); );
// final url = Uri.parse(
// 'http://localhost/nhance_partner_be/dashboard/partnerDashboard?manager_id=$id',
// );
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature, 'app-signature': Env.App_Signature,
@ -1097,6 +1103,10 @@ class ApiService {
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus', '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus',
// '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus', // '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus',
); );
} else if (role == 'agent') {
url = Uri.parse(
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus',
);
} else { } else {
url = Uri.parse( url = Uri.parse(
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus&staff_id=$selectedStaffId', '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus&staff_id=$selectedStaffId',
@ -1689,6 +1699,28 @@ class ApiService {
return response; 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 late String _baseUrl;
static void initialize(String baseUrl) { static void initialize(String baseUrl) {
@ -1991,11 +2023,13 @@ class ApiService {
} }
Future<void> generateEndorsementExcel(managerId) async { Future<void> generateEndorsementExcel(managerId,searchValue) async {
final url = Uri.parse( final url = Uri.parse(
'${Env.apiUrl}reports/endorsement-excel?manager_id=$managerId', '${Env.apiUrl}reports/endorsement-excel?manager_id=$managerId',
); );
// final url = Uri.parse( 'http://localhost/nhance_partner_be/reports/endorsement-excel?manager_id=$managerId&search=${searchValue ?? ''}', );
print('getPdfDownload endorsement-excel - $url'); print('getPdfDownload endorsement-excel - $url');
await _initializeToken(); await _initializeToken();
@ -2062,7 +2096,7 @@ class ApiService {
Future<void> generatePolicyExcel(managerId, fromDate, toDate, searchValue) async { Future<void> generatePolicyExcel(managerId, fromDate, toDate, searchValue) async {
final url = Uri.parse( 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 ?? ''}', ); // 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

@ -229,6 +229,14 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
context.go(AppRoutes.endorsementTypeLst); context.go(AppRoutes.endorsementTypeLst);
}, },
), ),
_buildPopupItem(
label: "Vehicle Type",
onTap: () {
setState(() => _activeMenu = 'Masters');
_hidePopup();
context.go(AppRoutes.vehicleTypeLst);
},
),
SizedBox(height: 2), SizedBox(height: 2),
_buildPopupItem( _buildPopupItem(
label: "Payment Mode", label: "Payment Mode",
@ -400,7 +408,8 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
], ],
if (role != 'Accounts') ...[ // if (role != 'Accounts') ...[
if (!['Accounts', 'agent'].contains(role)) ...[
// Proposal button // Proposal button
Container( Container(
width: 36, width: 36,

View File

@ -732,7 +732,7 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text("End. Premium *", style: _textStyle), Text("End Premium *", style: _textStyle),
SizedBox(height: 10), SizedBox(height: 10),
ThemedFormField( ThemedFormField(
backgroundColor: Color(0xFFEDF6F5), backgroundColor: Color(0xFFEDF6F5),

View File

@ -51,6 +51,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
super.initState(); super.initState();
apiService = ApiService(); apiService = ApiService();
for (String field in tabHeader) { for (String field in tabHeader) {
controllers[field] = TextEditingController(); controllers[field] = TextEditingController();
} }
@ -62,11 +63,6 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
print("A56 => r : $roleId | mId: $id | uId: $userId "); print("A56 => r : $roleId | mId: $id | uId: $userId ");
// Staff - sanjeev.p@venbainfotech.com - T E S T S - 9 evarukku 8th id is manager
// Manager - venbalap08@gmail.com - T E S T M - 8 evarukku 8th id is manager
// Agent - venba2026@gmail.com - T E S T A - 5 evarkku 8th id is manager
// so here i used userId
if (userId != null) { if (userId != null) {
getStaffList(userId, roleId); getStaffList(userId, roleId);
} }
@ -189,6 +185,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
toDt = toDateVal; toDt = toDateVal;
} }
print("ASSS= $SelectedStatus");
try { try {
final response = await apiService.fetchEnquiryList( final response = await apiService.fetchEnquiryList(
managerId, managerId,
@ -1083,7 +1080,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
// validator: (value) => Validators.requiredField(value, "date"), // validator: (value) => Validators.requiredField(value, "date"),
controller: controllers['startDate']!, controller: controllers['startDate']!,
onDateSelected: (date) { onDateSelected: (date) {
print("Picked Date: $date"); print("SPicked Date: $date");
controllers['startDate']?.text = DateFormat( controllers['startDate']?.text = DateFormat(
'dd-MM-yyyy', 'dd-MM-yyyy',
@ -1127,7 +1124,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
controller: controllers['endDate']!, controller: controllers['endDate']!,
lastDate: DateTime.now(), lastDate: DateTime.now(),
onDateSelected: (date) { onDateSelected: (date) {
print("Picked Date: $date"); print("EPicked Date: $date");
controllers['endDate']?.text = DateFormat( controllers['endDate']?.text = DateFormat(
'dd-MM-yyyy', 'dd-MM-yyyy',
).format(date); ).format(date);

View File

@ -227,7 +227,8 @@ class endosementState extends ConsumerState<endosement> {
} }
Future<void> fetchEndorsementExcelReport() async { Future<void> fetchEndorsementExcelReport() async {
final response = await apiService.generateEndorsementExcel(managerId); final String searchValue = _searchStaffController.text;
final response = await apiService.generateEndorsementExcel(managerId,searchValue);
// Map your controllers and IDs to the API parameters // Map your controllers and IDs to the API parameters
// final String fromDate = controllers['startDate']!.text; // "11-01-2025" // final String fromDate = controllers['startDate']!.text; // "11-01-2025"
// final String toDate = controllers['endDate']!.text; // "20-01-2025" // final String toDate = controllers['endDate']!.text; // "20-01-2025"
@ -493,19 +494,19 @@ class endosementState extends ConsumerState<endosement> {
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('S.No.', style: _headerStyle), child: Text('S No ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Policy.From.', style: _headerStyle), child: Text('Policy From ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Status.', style: _headerStyle), child: Text('Status ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Vehicle.No.', style: _headerStyle), child: Text('Vehicle No ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
@ -513,7 +514,7 @@ class endosementState extends ConsumerState<endosement> {
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Policy No.', style: _headerStyle), child: Text('Policy No ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,

View File

@ -0,0 +1,472 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/screens/Masters/VehicleType/vehicleType.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/utils/Pagination.dart';
import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart';
import '../../../themes/indicators/export_btn.dart';
import '../../../themes/indicators/filter_btn.dart';
import '../../../themes/indicators/search_field_theme.dart';
import '../../../themes/indicators/text_field_theme.dart';
import '../../../widgets/custom_action_popup.dart';
class VehicleTypeList extends ConsumerStatefulWidget {
const VehicleTypeList({super.key});
@override
ConsumerState<VehicleTypeList> createState() => VehicleTypeListState();
}
class VehicleTypeListState extends ConsumerState<VehicleTypeList> {
int currentPage = 1;
int itemsPerPage = 10;
late ApiService apiService;
dynamic managerId;
dynamic role;
dynamic prefid;
dynamic userId;
// List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getVehicleTypeData = [];
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
bool isLoading = false;
Map<String, dynamic>? selectedVehicleType;
dynamic selectedId;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
final data1 = ref.read(managerIdProvider);
userId = ref.watch(userIdProvider);
// final data2 = ref.read(handlerIdProvider);
print("Edata1 => mId: $data1 -2 :");
prefid = data1;
role = ref.read(userRoleProvider);
print("E43 => mId: $prefid");
if (prefid != null && role != null) {
getVehicleType();
}
});
// getVehicleTypeList();
}
List<dynamic> get _paginatedData {
// Sort descending by id first
final sortedData = [...filteredData]
..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));
if (sortedData.isEmpty) return [];
// Ensure currentPage is valid
final maxPage = (sortedData.length / itemsPerPage).ceil();
final safePage = currentPage.clamp(1, maxPage);
final startIndex = (safePage - 1) * itemsPerPage;
final endIndex = (startIndex + itemsPerPage).clamp(0, sortedData.length);
return sortedData.sublist(startIndex, endIndex);
}
void handleEdit(Map<String, dynamic> item) {
setState(() {
selectedId = item['id'];
selectedVehicleType = item;
});
}
void filterData(String query) {
setState(() {
final q = query.toLowerCase();
if (q.isEmpty) {
filteredData = getVehicleTypeData;
return;
}
filteredData = getVehicleTypeData.where((item) {
final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
return (item['vehicle_type'] ?? '').toString().toLowerCase().contains(q) ||
isActiveStatus.contains(q);
}).toList();
});
}
final TextEditingController _searchStaffController = TextEditingController();
Future<void> getVehicleType() async {
print('getVehicleType called');
setState(() {
isLoading = true;
});
try {
final response = await apiService.fetchMasterDropDown('vehicleType');
if (response['status'] == 200) {
print('getVehicleType - ${response['data']}');
setState(() {
getVehicleTypeData = List<Map<String, dynamic>>.from(response['data']);
print('API Data - $getVehicleTypeData');
filteredData = List.from(getVehicleTypeData);
print('originalData - $filteredData');
});
} else {
getVehicleTypeData = [];
filteredData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
List<Widget> _buildPopupMenuActions(BuildContext context, dynamic data) {
return [
GestureDetector(
onTap: () {
Navigator.pop(context);
print('EDITStaff - ${data['id']}');
dynamic id = data['id'];
context.go('/staff/$id');
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
SizedBox(width: 10),
Text('Edit'),
],
),
),
];
}
@override
Widget build(BuildContext context) {
managerId = ref.watch(managerIdProvider);
return MainLayout(
title: "Vehicle Type",
body: Container(
// padding: EdgeInsets.all(8.0),
// margin: EdgeInsets.all(10.0),
// color: Colors.yellow.shade50,
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
// height: 30,
// color: Colors.red.shade50,
width: MediaQuery.of(context).size.width,
child: GestureDetector(
onTap: () {
context.go(AppRoutes.dashboard);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Vehicle Type',
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
SizedBox(height: 5),
Expanded(
child: Container(
// color: Colors.green,
// color: Colors.green.shade50,
width: MediaQuery.of(context).size.width,
// margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
// color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
),
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Container(
// height: 40,
// color: Colors.pink,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
VehicleType(
key: ValueKey(selectedId),
data: selectedVehicleType,
id: selectedId,
onSubmit: () {
getVehicleType();
setState(() {
selectedVehicleType = null;
selectedId = null;
}); // reset after save
},
),
Spacer(),
ThemedSearchField(
hintText: 'Search',
// backgroundColor: Color(0xFFF6F8F8),
backgroundColor: Color(0xFFFFFFFF),
txtHeight: 30,
onChanged: filterData,
controller: _searchStaffController,
txtwidth: MediaQuery.of(context).size.width * 0.15,
),
SizedBox(width: 10),
ExportBtn(
sheetName: "VehicleType",
fileName: "vehicle_type_list",
txt: !ResponsiveLayout.isMobile(context)
? true
: false,
data: filteredData,
displayHeaders: ['S.No.', 'Vehicle Type', 'Status'],
keys: ["sno", "vehicle_type", "is_active"],
),
],
),
),
SizedBox(height: 10),
Container(
decoration: BoxDecoration(
color: Color(0xFFF1F5F9),
// color: Color(0xFFEDF6F5),
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
),
child: Row(
children: [
Expanded(
flex: 1,
child: Text('S.No.', style: _headerStyle),
),
Expanded(
flex: 5,
child: Text('Vehicle Type', style: _headerStyle),
),
Expanded(
flex: 2,
child: Text('Status', style: _headerStyle),
),
Expanded(
flex: 2,
child: Text('Action', style: _headerStyle),
),
],
),
),
Expanded(
child: Container(
color: Colors.white,
child: _buildDataTable(context),
),
),
],
),
),
),
Container(
// height: 20,
width: MediaQuery.of(context).size.width,
// color: Colors.green.shade50,
child: PaginationControls(
currentPage: currentPage,
itemsPerPage: itemsPerPage,
// totalItems: dataVal.length,
totalItems: filteredData.length,
// activeColor: layoutColor, // your theme color
onPageChanged: (page) {
setState(() {
currentPage = page;
});
},
onItemsPerPageChanged: (items) {
setState(() {
itemsPerPage = items;
currentPage = 1;
});
},
),
),
],
),
),
);
}
Widget _buildDataTable(BuildContext context) {
if (filteredData.isEmpty) {
return const SizedBox(
height: 50,
child: Center(child: Text('No available data')),
);
}
final sortedData = [..._paginatedData];
return ListView.builder(
// itemCount: filteredData.length + 1, // +1 for header, +1 for pagination
itemCount: sortedData.length + 1, // +1 for header, +1 for pagination
itemBuilder: (context, index) {
if (index == 0) return _buildHeader();
// if (index == dataVal.length + 1)
// return _buildPagination(context);
final startIndex = ((currentPage - 1) * itemsPerPage);
// final item = filteredData[index - 1];
final item = sortedData[index - 1];
final sno = startIndex + index;
return _buildDataRow(item, sno);
},
);
}
Widget _buildHeader() {
return SizedBox.shrink();
}
Widget _buildDataRow(Map<String, dynamic> item, sno) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 16),
// margin: const EdgeInsets.only(top: 10),
decoration: BoxDecoration(
color: Colors.white,
// color: Color(0xFFE0F7F9),
border: const Border(
bottom: BorderSide(color: Colors.blueGrey, width: 0.15),
),
// borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded(flex: 5, child: Text(item['vehicle_type'] ?? '-', style: _dataBold)),
Expanded(flex: 2,
child: Row(
children: [
Container(
// color: Colors.yellow.shade50,
child: Transform.scale(
scale: 0.4, // reduce size (0.70.9 works well)
child: Switch(
value: item['is_active'] == "1",
onChanged: (val) {
setState(() {
item['is_active'] = val ? "1" : "0";
});
final response = apiService.updateStatusMasters(
item['id'],
val ? "0" : "1",
'VehicleType',
userId,
);
print("Response - $response");
},
activeColor: Color(0xFF2E7D6E), // thumb when active
// activeColor: Color(0xFF425B5B), // thumb when active
activeTrackColor: Color(0xFFDCFCE7), // track when active
// activeTrackColor: Color(0xFFB2D8D3), // track when active
inactiveThumbColor:
Colors.grey.shade400, // thumb when inactive
inactiveTrackColor:
Colors.grey.shade300, // track when inactive
),
),
),
],
),
),
Expanded(
flex: 2,
child: Center( // Add Center wrapper
child: Row(
mainAxisSize: MainAxisSize.min, // Add this
children: [
item['is_active'] == "1"
? Tooltip(
message: 'Edit',
child: IconButton(
icon: Image.asset(
"assets/miscellaneous/Edit.png",
height: 12,
width: 15,
),
onPressed: () {
handleEdit(item);
},
splashRadius: 28,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(8),
constraints: const BoxConstraints(),
),
)
: Padding(
padding: const EdgeInsets.all(8.0), // Match IconButton padding
child: Image.asset(
"assets/miscellaneous/Edit_muted.png",
height: 12,
width: 15,
),
),
],
),
),
),
],
),
);
}
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static final _dataBold = GoogleFonts.inter(
fontSize: 11.5,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _headerStyle = GoogleFonts.poppins(
fontSize: 11.2,
fontWeight: FontWeight.w500,
color: Color(0xFF1E293B),
);
}

View File

@ -0,0 +1,346 @@
import 'dart:convert';
// import 'dart:io' as html;
import 'dart:typed_data'; // Import for Uint8List
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:nhance_partner/core/routing/routes.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/presentation/themes/indicators/text_field_theme.dart';
import 'package:nhance_partner/presentation/themes/indicators/text_field_theme_inline_editor.dart';
import '../../../../core/config/env.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/services/auth_service.dart';
import '../../../../data/utils/validators.dart';
import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart';
import 'package:universal_html/html.dart' as html;
import '../../../themes/indicators/input_field_decoration.dart';
class VehicleType extends ConsumerStatefulWidget {
final String? id;
final Map<String, dynamic>? data;
final VoidCallback onSubmit;
const VehicleType({super.key, this.id, this.data, required this.onSubmit});
@override
ConsumerState<VehicleType> createState() => VehicleTypeState();
}
class VehicleTypeState extends ConsumerState<VehicleType> {
final _formKey = GlobalKey<FormState>();
late ApiService apiService;
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyHandler = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> tabHeader = ['vehicle_type'];
late String isActive = "1";
String? selectedFileNames;
dynamic selectedId;
String? _token;
bool isLoading = false;
bool showHandler = false;
String? selectedRole;
List<Map<String, dynamic>> filteredRolesData = [];
List<Map<String, dynamic>> getRolesData = [];
List<dynamic>? selectedHandlerIds = [];
String? selectedHandler;
List<Map<String, dynamic>> filteredHandlersData = [];
List<Map<String, dynamic>> getHandlersData = [];
Map<String, TextEditingController> controllers = {};
dynamic userId;
dynamic managerId;
Map<String, dynamic> dataDetails() {
final data = {
"vehicle_type": controllers["vehicle_type"]?.text,
"is_active": isActive,
};
return data;
}
@override
void initState() {
super.initState();
apiService = ApiService();
for (String field in tabHeader) {
controllers[field] = TextEditingController();
}
_initializeToken();
updateData();
Future.microtask(() {
managerId = ref.watch(managerIdProvider);
userId = ref.watch(userIdProvider);
if (managerId != null) {
print('hansles');
// getHandlers(managerId);
}
});
}
Future<void> _initializeToken() async {
_token = await AuthService.getToken();
print("APISERTOKEN - $_token");
}
void updateData() async {
if (widget.data != null) {
dynamic id = widget.data?['id'];
final data = widget.data;
if (data == null) return;
setState(() {
selectedId = id;
controllers['vehicle_type']?.text = data['vehicle_type'] ?? '';
controllers["is_active"]?.text = data['is_active'].toString();
});
}
}
Future<void> handleSave() async {
if (controllers['vehicle_type'] == null ||
controllers['vehicle_type']!.text.trim().isEmpty) {
ToastHelper.showWarningToast(context, "Vehicle Type is required");
return;
}
if (!_formKey.currentState!.validate()) return;
setState(() {
if (_formKey.currentState!.validate()) {
dataDetails();
final dataSet = dataDetails();
print("dataSetAgent - $dataSet");
print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
print("TYPE of value → ${dataSet['value'].runtimeType}");
createUserData(dataSet);
} else {
// isDisable = false;
}
});
}
// Future<void> handleSave() async {
// // if (controllers['name'] != null && controllers['name'] != '') {
// // return;
// // }
// if (!_formKey.currentState!.validate()) return;
// setState(() {
// if (_formKey.currentState!.validate()) {
// dataDetails();
// final dataSet = dataDetails();
// print("dataSetAgent - $dataSet");
//
// print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
// print("TYPE of vehicle_type → ${dataSet['vehicle_type'].runtimeType}");
// createUserData(dataSet);
// } else {
// // isDisable = false;
// }
// });
// }
void refresh() {
print('REfresj');
widget.onSubmit();
setState(() {
// clear all text controllers
for (var controller in controllers.values) {
controller.clear();
} // 👈 clear selected agent
controllers['vehicle_type']?.clear();
});
}
Future<void> createUserData(data) async {
final bool isUpdating = selectedId != null;
final dynamic id = isUpdating ? int.tryParse(selectedId.toString()) : 0;
final String apiUrldata;
print("TYPE of id → $id - ${id.runtimeType}");
print("TYPE of id → $userId - ${userId.runtimeType}");
apiUrldata = isUpdating
? '${Env.apiUrl}/master/updateVehicleType/$selectedId'
: '${Env.apiUrl}/master/createVehicleType';
// final token = await getToken(); // Fetch token
if (_token == null) {
throw Exception('Token not found. Please log in.');
}
if (isUpdating) {
data['updated_by'] = userId.toString();
} else {
data['created_by'] = userId.toString();
}
print("data------- $data}");
try {
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $_token',
'Content-Type': 'application/json',
'app-signature': Env.App_Signature,
},
body: jsonEncode(data), // Convert map to JSON
);
if (response.statusCode == 200) {
final responseBody = jsonDecode(response.body);
final message = responseBody['message'];
print("VehicleType submitted successfully!");
print("Response: ${response.body}");
if (responseBody['status'] == 200) {
refresh();
isUpdating
? ToastHelper.showSuccessToast(context, message)
: ToastHelper.showSuccessToast(context, message);
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Vehicle Type Creation Failed"),
content: Text(message),
actions: [
TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
} else if (response.statusCode == 403) {
await apiService.clearLocalStorageAndRedirect();
}
} catch (e) {
print(" Error submitting Staff: $e");
}
}
@override
void dispose() {
for (var controller in controllers.values) {
controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
buildFormFields(),
SizedBox(width: 5),
InkWell(
onTap: () {
handleSave();
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Color(0xFF2E7D6E),
),
child: Text(
'Save',
style: GoogleFonts.inter(color: Colors.white, fontSize: 10),
),
),
),
SizedBox(width: 5),
InkWell(
onTap: () {
refresh();
},
child: Container(
padding: EdgeInsets.all(6.0),
decoration: BoxDecoration(
color: const Color(0xFF2E7D6E),
borderRadius: BorderRadius.circular(5.0),
),
child: Icon(Icons.refresh, size: 13, color: Colors.white),
),
),
],
),
);
}
Widget buildFormFields() {
return Form(
key: _formKey,
child: Row(
children: [buildVehicleTypeName()],
),
);
}
Widget buildVehicleTypeName() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Vehicle Type *", style: _textStyle),
SizedBox(width: 10),
SizedBox(
child: ThemedFormInlineField(
controller: controllers['vehicle_type']!,
validator: (value) => Validators.requiredField(value, "vehicle_type"),
txtwidth: MediaQuery.of(context).size.width * 0.15,
inputFormatters: [
// This line now allows letters, numbers, hyphens, underscores, and spaces
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9\-_ ]')),
],
borderColor: Color(0xFFE2E8F0),
highlightColor: Color(0xFF50A398),
// txtheight: 30,
isdense: true,
errFieldHgt: 0,
),
),
],
);
}
static final _textStyle = GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w600,
);
}

View File

@ -749,13 +749,19 @@ class AgentState extends ConsumerState<Agent> {
} }
Widget buildSalesExecutive(BuildContext context) { Widget buildSalesExecutive(BuildContext context) {
Map<String, dynamic>? selectedroleVal = filteredSalesExecutiveData Map<String, dynamic>? selectedSE;
.firstWhere(
(item) => item['id'] == selectedSalesExectv,
orElse: () => {},
);
print('selectedroleVal - $selectedroleVal'); if (selectedSalesExectv != null &&
filteredSalesExecutiveData.isNotEmpty) {
selectedSE = filteredSalesExecutiveData.firstWhere(
(item) =>
item['id'].toString() ==
selectedSalesExectv.toString(),
orElse: () => {}, // MUST be null
);
}
print('selectedSalesExectv = $selectedSalesExectv');
final isReadOnly = false; final isReadOnly = false;
// final isReadOnly = widget.id != null; // final isReadOnly = widget.id != null;
@ -778,7 +784,7 @@ class AgentState extends ConsumerState<Agent> {
absorbing: isReadOnly, absorbing: isReadOnly,
child: DropdownSearch<Map<String, dynamic>>( child: DropdownSearch<Map<String, dynamic>>(
key: dropDownKey, key: dropDownKey,
selectedItem: selectedroleVal.isNotEmpty ? selectedroleVal : null, selectedItem: selectedSE,
items: (filter, infiniteScrollProps) { items: (filter, infiniteScrollProps) {
return filteredSalesExecutiveData; return filteredSalesExecutiveData;
}, },
@ -893,6 +899,7 @@ class AgentState extends ConsumerState<Agent> {
); );
} }
Widget buildUploadDocument() { Widget buildUploadDocument() {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -323,20 +323,21 @@ class AgentListState extends ConsumerState<AgentList> {
data: filteredData, data: filteredData,
displayHeaders: [ displayHeaders: [
'S.No.', 'S.No.',
'Partner Id',
'Partner Name', 'Partner Name',
'Email', 'Email',
'Phone Number', 'Phone Number',
'Id',
'Retention Rate', 'Retention Rate',
'Address', 'Address',
'Status', 'Status',
], ],
keys: [ keys: [
"sno", // handled internally as i + 1 "sno", // handled internally as i + 1
"agent_code",
"name", "name",
"email", "email",
"mobile", "mobile",
"agent_code",
"retention_rate", "retention_rate",
"address", "address",
"is_active", "is_active",
@ -404,6 +405,10 @@ class AgentListState extends ConsumerState<AgentList> {
flex: 1, flex: 1,
child: Text('S.No.', style: _headerStyle), child: Text('S.No.', style: _headerStyle),
), ),
Expanded(
flex: 1,
child: Text('Partner Id', style: _headerStyle),
),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Partner Name', style: _headerStyle), child: Text('Partner Name', style: _headerStyle),
@ -416,10 +421,6 @@ class AgentListState extends ConsumerState<AgentList> {
flex: 2, flex: 2,
child: Text('Phone Number', style: _headerStyle), child: Text('Phone Number', style: _headerStyle),
), ),
Expanded(
flex: 1,
child: Text('Id', style: _headerStyle),
),
Expanded( Expanded(
flex: 1, flex: 1,
child: Text( child: Text(
@ -534,6 +535,7 @@ class AgentListState extends ConsumerState<AgentList> {
child: Row( child: Row(
children: [ children: [
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)), Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded(flex: 1, child: Text(item['agent_code'] ?? '-', style: _dataBold)),
Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)), Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)),
Expanded( Expanded(
flex: 3, flex: 3,
@ -543,10 +545,6 @@ class AgentListState extends ConsumerState<AgentList> {
flex: 2, flex: 2,
child: Text(item['mobile'] ?? '-', style: _dataBold), child: Text(item['mobile'] ?? '-', style: _dataBold),
), ),
Expanded(
flex: 1,
child: Text(item['agent_code'] ?? '-', style: _dataBold),
),
Expanded( Expanded(
flex: 1, flex: 1,
child: Text(item['retention_rate'] ?? '-', style: _dataBold), child: Text(item['retention_rate'] ?? '-', style: _dataBold),

View File

@ -301,7 +301,7 @@ class _DashboardState extends ConsumerState<PartnerDashboard> {
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Column( child: Column(
children: [ children: [
if (role == 'manager' || role == 'handler') if (role == 'manager' || role == 'handler' || role == 'agent')
SizedBox( SizedBox(
height: MediaQuery.of(context).size.height * 0.78, height: MediaQuery.of(context).size.height * 0.78,
// replace Expanded // replace Expanded

View File

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

View File

@ -108,40 +108,44 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
for (String field in tabHeader) { for (String field in tabHeader) {
controllers[field] = TextEditingController(); controllers[field] = TextEditingController();
} }
// invoiceNoController = TextEditingController(text: generateInvoiceNumber());
Future.microtask(() async { Future.microtask(() async {
managerId = ref.watch(managerIdProvider); managerId = ref.read(managerIdProvider);
userId = ref.watch(userIdProvider);
roleId = ref.read(userRoleProvider); roleId = ref.read(userRoleProvider);
userId = ref.read(userIdProvider);
print('PayOutScreen => managerId: $managerId');
if (managerId != null) { if (managerId != null) {
getAgentList(managerId); getAgentList(managerId);
getPosList(managerId); getPosList(managerId);
} }
await getBroker(); await getBroker();
// EDIT MODE (MUST be here)
if (widget.editItem != null) {
print('editItemID ${widget.editItem}');
final invoiceID = widget.editItem!['id'];
final brokerID = widget.editItem!['broker_id'];
controllers['invoiceNo']?.text =
widget.editItem!['invoice_no'];
controllers['invoiceDate']?.text =
widget.editItem!['invoice_date_ui_format'];
controllers['invoiceStatus']?.text =
widget.editItem!['payout_status'];
_loadEditData(invoiceID, brokerID, managerId); // managerId ready
}
}); });
// 👉 CHECK EDIT MODE
if (widget.editItem != null) {
print('editItemID ${widget.editItem}');
final invoiceID = widget.editItem!['id'];
final brokerID = widget.editItem!['broker_id'];
// Invoice No
controllers['invoiceNo']?.text = widget.editItem!['invoice_no'];
// Invoice Date (UI format)
controllers['invoiceDate']?.text =
widget.editItem!['invoice_date_ui_format'];
controllers['invoiceStatus']?.text = widget.editItem!['payout_status'];
print('invoiceID $invoiceID');
print('brokerID $brokerID');
_loadEditData(invoiceID, brokerID);
}
} }
void filterPolicyData(String query) { void filterPolicyData(String query) {
final lowerQuery = query.toLowerCase(); final lowerQuery = query.toLowerCase();
@ -182,7 +186,7 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
} }
Future<void> getPosList(int id) async { Future<void> getPosList(int id) async {
print('E104 => Fns called => $id'); print('H104 => Fns called => $id');
final val = 'dropDown'; final val = 'dropDown';
setState(() { setState(() {
@ -230,14 +234,16 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
}); });
} }
void _loadEditData(String invoiceID, brokerID) async { void _loadEditData(String invoiceID, brokerID, managerID) async {
setState(() => isLoadingEditData = true); setState(() => isLoadingEditData = true);
print("H010 => r : $roleId | mId: $managerID | ParmMID: $managerID | uId: $userId ");
print('_loadEditData'); print('_loadEditData');
final jsondata = { final jsondata = {
// "id": invoiceID, // "id": invoiceID,
"invoice_id": invoiceID, "invoice_id": invoiceID,
"broker_id": int.tryParse(brokerID ?? ''), "broker_id": int.tryParse(brokerID ?? ''),
"manager_id": managerId
// "issued_date": formattedTillDate, // "issued_date": formattedTillDate,
}; };
@ -442,9 +448,32 @@ 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) // Load policies (simulate API)
Future<void> loadPolicies() async { Future<void> loadPolicies() async {
print('loadPolicies'); print('loadPolicies');
print("H13 => r : $roleId | mId: $managerId | uId: $userId ");
try { try {
final List<int> agentIds = (selectedAgentId ?? []) final List<int> agentIds = (selectedAgentId ?? [])
.map((e) => int.parse(e)) .map((e) => int.parse(e))
@ -454,7 +483,9 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
"from_date": controllers['startDate']?.text, "from_date": controllers['startDate']?.text,
"to_date": controllers['endDate']?.text, "to_date": controllers['endDate']?.text,
"broker_id": int.tryParse(selectedBrokerID ?? ''), "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, // "issued_date": formattedTillDate,
}; };
final response = await apiService.getCommissionRateList(jsondata); final response = await apiService.getCommissionRateList(jsondata);
@ -1296,6 +1327,8 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
} }
double _calculateTotalCommission() { double _calculateTotalCommission() {
print("ASD");
print(filteredPolicies);
double total = 0.0; double total = 0.0;
for (var p in filteredPolicies) { for (var p in filteredPolicies) {

View File

@ -1668,7 +1668,7 @@ class CreateProposal_QuickFormState
decoratorProps: DropDownDecoratorProps( decoratorProps: DropDownDecoratorProps(
decoration: decoration:
AppInputDecorations.dropdownDecoration( AppInputDecorations.dropdownDecoration(
label: "Select Staff Member", label: "Select Plan Type",
).copyWith( ).copyWith(
errorStyle: GoogleFonts.poppins(fontSize: 0, height: 0.0), errorStyle: GoogleFonts.poppins(fontSize: 0, height: 0.0),
filled: true, filled: true,

View File

@ -53,7 +53,7 @@ class EnquiryListStaffInline extends ConsumerStatefulWidget {
class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> { class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// bool fromDashboard = false; // bool fromDashboard = false;
bool _dashboardInitHandled = false; bool _dashboardInitHandled = false;
bool _resetKeyEnable = false; bool _resetKeyEnable = false; // very first
int currentPage = 1; int currentPage = 1;
int itemsPerPage = 10; int itemsPerPage = 10;
// int itemsPerPage = 5; // int itemsPerPage = 5;
@ -173,9 +173,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic> dataDetails() { Map<String, dynamic> dataDetails() {
final data = { final data = {
"agent_id": "agent_id":
((roleId == 'handler') || ((roleId == 'handler') ||
(roleId == 'manager') || (roleId == 'manager') ||
(roleId == 'staff')) (roleId == 'staff'))
? selectedAgent ? selectedAgent
: userId, : userId,
"name": controllers["name"]?.text, "name": controllers["name"]?.text,
@ -202,19 +202,19 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey = final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownSelectPaymentModeKey = dropDownSelectPaymentModeKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
//---------------------- Assign Staff starts -------------------------------- // //---------------------- Assign Staff starts -------------------------------- //
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyInsurerEnqAsgn = dropDownKeyInsurerEnqAsgn =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKeyBroker = 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>> getStaffDetailsDataEnqAsgn = [];
List<Map<String, dynamic>> filteredStaffDataEnqAsgn = []; List<Map<String, dynamic>> filteredStaffDataEnqAsgn = [];
@ -322,9 +322,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
getPaymentMode(); getPaymentMode();
refreshSub = ref.listenManual<bool>(enquiryRefreshProvider, ( refreshSub = ref.listenManual<bool>(enquiryRefreshProvider, (
previous, previous,
next, next,
) { ) {
if (next == true) { if (next == true) {
print('refresh triggered Quick Creation'); print('refresh triggered Quick Creation');
autoRefrshfilterDateRange(); autoRefrshfilterDateRange();
@ -630,13 +630,13 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
Future<void> getStaffList( Future<void> getStaffList(
int managerId, int managerId,
role, { role, {
String fromDate = '', String fromDate = '',
String toDate = '', String toDate = '',
String SelectedStatus = '', String SelectedStatus = '',
String SelectedStaffId = '', String SelectedStaffId = '',
}) async { }) async {
print('A613 => Fns called => $managerId | $role'); print('A613 => Fns called => $managerId | $role');
setState(() { setState(() {
isLoadingStaffList = true; isLoadingStaffList = true;
@ -682,6 +682,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
fromDt = _dashboardInitHandled ? controllers['startDate']?.text : ''; fromDt = _dashboardInitHandled ? controllers['startDate']?.text : '';
toDt = _dashboardInitHandled ? controllers['endDate']?.text : ''; toDt = _dashboardInitHandled ? controllers['endDate']?.text : '';
print('End Date: ${controllers['endDate']?.text}');
print('STT Date: ${controllers['startDate']?.text}');
print('PrevPending FROM TO - $fromDt - $toDt'); print('PrevPending FROM TO - $fromDt - $toDt');
} else if (dashboardKey != 'fromDashboard' && } else if (dashboardKey != 'fromDashboard' &&
@ -691,27 +693,28 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
print('A1013 => Fns called => $managerId | $role'); print('A1013 => Fns called => $managerId | $role');
final today = DateTime.now(); final today = DateTime.now();
fromDt = dateFormat.format(today.subtract(Duration(days: 5))); fromDt = dateFormat.format(today.subtract(Duration(days: 4)));
// fromDt = dateFormat.format(today); // fromDt = dateFormat.format(today);
toDt = dateFormat.format(today); toDt = dateFormat.format(today);
print('Enq FROM TO - $fromDt - $toDt'); print('Enq FROM TO - $fromDt - $toDt');
} else { } else {
print('A1113 => Fns called => $managerId | $role'); print('A1113 => Fns called => $managerId | $role');
print('Enq 1- $fromDt - $toDt'); print('Pre Date its User Choosen Enq Inline list - $fromDt - $toDt');
if(_resetKeyEnable = true){ if (_resetKeyEnable) {
final dateFormat = DateFormat('dd-MM-yyyy'); final dateFormat = DateFormat('dd-MM-yyyy');
final today = DateTime.now(); final today = DateTime.now();
final yesterday = today.subtract(Duration(days: 1)); // final yesterday = today.subtract(Duration(days: 1));
// fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15))); // Dont Delete any doubt Ref Suren
fromDt = dateFormat.format(today.subtract(const Duration(days: 4)));
toDt = dateFormat.format(today);
fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15)));
toDt = dateFormat.format(yesterday);
setState(() { setState(() {
controllers['startDate']?.text = fromDt; controllers['startDate']?.text = fromDt;
controllers['endDate']?.text = toDt; controllers['endDate']?.text = toDt;
_resetKeyEnable = false; // ask suren Never forgot
}); });
} else { } else {
fromDt = fromDateVal; fromDt = fromDateVal;
toDt = toDateVal; toDt = toDateVal;
@ -736,7 +739,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// ? finalStatus // ? finalStatus
// : '', // : '',
selectedStatus: selectedStatus:
(SelectedStatus != '' && SelectedStatus != 'PrevPending') (SelectedStatus != '' && SelectedStatus != 'PrevPending')
? SelectedStatus ? SelectedStatus
: '', : '',
selectedStaffId: SelectedStaffId ?? '', selectedStaffId: SelectedStaffId ?? '',
@ -752,10 +755,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
print('A1213 => Fns called => $managerId | $role'); print('A1213 => Fns called => $managerId | $role');
setState(() { setState(() {
_resetKeyEnable = false; _resetKeyEnable = false;
controllers['startDate']?.text = fromDate; controllers['startDate']?.text = fromDate;
controllers['endDate']?.text = toDate; controllers['endDate']?.text = toDate;
@ -827,6 +830,40 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
void _applyFilter(String query) { void _applyFilter(String query) {
setState(() {
final List<dynamic> source = (selectedIndex == 0) ? inProgressData : completedData;
final String q = query.trim().toLowerCase();
completedCurrentPage = 1;
if (q.length < 2) {
filteredData = List<Map<String, dynamic>>.from(source);
return;
}
// 1. Filter the list
List<dynamic> results = source.where((item) {
final map = item as Map<String, dynamic>;
// Get the field values safely
String regNo = safeString(map['reg_no']).toLowerCase().trim();
String agentName = safeString(map['agent_name']).toLowerCase().trim();
// IF CONDITION: Check if query is exactly "new"
if (q == "new") {
// Only return items where the field is EXACTLY "new"
return regNo == "new" || agentName == "new";
} else {
// Regular partial search for any other query
return regNo.contains(q) || agentName.contains(q);
}
}).toList();
// 2. Final Type Casting to fix your "dynamic" error
filteredData = results.map((e) => e as Map<String, dynamic>).toList();
});
}
void _applyFilter_05012026(String query) {
print("FilterData - $query"); print("FilterData - $query");
setState(() { setState(() {
@ -1003,8 +1040,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Search within the current tab's data // Search within the current tab's data
filteredData = sourceList.where((item) { filteredData = sourceList.where((item) {
return (item['agent_name'] ?? '-').toLowerCase().contains( return (item['agent_name'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
(item['agent_code'] ?? '-').toLowerCase().contains( (item['agent_code'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
@ -1070,11 +1107,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
Future<void> handleStaff( Future<void> handleStaff(
BuildContext context, BuildContext context,
dynamic data, dynamic data,
id, id,
regNum, regNum,
) async { ) async {
showDialog( showDialog(
context: context, context: context,
builder: (ctx) => AssignStaffDialog( builder: (ctx) => AssignStaffDialog(
@ -1209,7 +1246,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final bool isNewRow = final bool isNewRow =
int.tryParse(id.toString()) != null && int.tryParse(id.toString()) != null &&
int.parse(id.toString()) > 1000000000000; int.parse(id.toString()) > 1000000000000;
print('isNewRow - $isNewRow'); print('isNewRow - $isNewRow');
@ -1217,20 +1254,20 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
if (isNewRow) { if (isNewRow) {
// Check if this is a new unsaved row // Check if this is a new unsaved row
final row = getStaffData.firstWhere( final row = getStaffData.firstWhere(
(item) => item['id'].toString() == id.toString(), (item) => item['id'].toString() == id.toString(),
orElse: () => {}, orElse: () => {},
); );
// If policy_number is empty, it's a new row - remove it // If policy_number is empty, it's a new row - remove it
if (row.isNotEmpty) { if (row.isNotEmpty) {
getStaffData.removeWhere( getStaffData.removeWhere(
(item) => item['id'].toString() == id.toString(), (item) => item['id'].toString() == id.toString(),
); );
originalData.removeWhere( originalData.removeWhere(
(item) => item['id'].toString() == id.toString(), (item) => item['id'].toString() == id.toString(),
); );
filteredData.removeWhere( filteredData.removeWhere(
(item) => item['id'].toString() == id.toString(), (item) => item['id'].toString() == id.toString(),
); );
rowControllers.remove(id); rowControllers.remove(id);
} }
@ -1350,10 +1387,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Future<void> attachFiles(http.MultipartRequest request) async { Future<void> attachFiles(http.MultipartRequest request) async {
Future<void> addFileOrKeepName( Future<void> addFileOrKeepName(
PlatformFile? file, PlatformFile? file,
String? apiFileName, String? apiFileName,
String fieldName, String fieldName,
) async { ) async {
if (file != null) { if (file != null) {
// User uploaded a new file send as multipart // User uploaded a new file send as multipart
if (file.bytes != null) { if (file.bytes != null) {
@ -1404,8 +1441,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Future<void> createUserData(Map<String, dynamic> userData) async { Future<void> createUserData(Map<String, dynamic> userData) async {
final bool isNewRow = final bool isNewRow =
idPrimary != null && idPrimary != null &&
int.tryParse(idPrimary.toString()) != null && int.tryParse(idPrimary.toString()) != null &&
int.parse(idPrimary.toString()) > 1000000000000; int.parse(idPrimary.toString()) > 1000000000000;
final bool isUpdating = final bool isUpdating =
idPrimary != null && idPrimary != 'null' && !isNewRow; idPrimary != null && idPrimary != 'null' && !isNewRow;
@ -1634,26 +1671,26 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// SizedBox(height: 5), // SizedBox(height: 5),
ResponsiveLayout.isMobile(context) ResponsiveLayout.isMobile(context)
? Container( ? Container(
height: MediaQuery.of(context).size.height * 0.69, height: MediaQuery.of(context).size.height * 0.69,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
padding: EdgeInsets.all(2), padding: EdgeInsets.all(2),
child: _buildContent(context), child: _buildContent(context),
), ),
), ),
) )
: :
// Expanded( // Expanded(
// child: // child:
Container( Container(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.69, height: MediaQuery.of(context).size.height * 0.69,
// padding: EdgeInsets.symmetric( // padding: EdgeInsets.symmetric(
// horizontal: 8.0, // horizontal: 8.0,
// vertical: 2.0, // vertical: 2.0,
// ), // ),
child: _buildContent(context), child: _buildContent(context),
), ),
], ],
), ),
), ),
@ -1672,7 +1709,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final result = await showDialog( final result = await showDialog(
context: context, context: context,
barrierDismissible: barrierDismissible:
false, // optional - prevents closing by tapping outside false, // optional - prevents closing by tapping outside
builder: (context) => TabEnquiryStaffList(showKey: val), builder: (context) => TabEnquiryStaffList(showKey: val),
); );
@ -1683,10 +1720,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
Future<void> buildPolicyCreatedStatusActions( Future<void> buildPolicyCreatedStatusActions(
BuildContext context, BuildContext context,
status, status,
id, id,
) async { ) async {
print("Actionsstatus - $status -$id"); print("Actionsstatus - $status -$id");
dynamic val; dynamic val;
if (status == 'Awaiting Proposal' || status == 'Proposal Created') { if (status == 'Awaiting Proposal' || status == 'Proposal Created') {
@ -1698,7 +1735,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
final result = await showDialog( final result = await showDialog(
context: context, context: context,
barrierDismissible: barrierDismissible:
false, // optional - prevents closing by tapping outside false, // optional - prevents closing by tapping outside
builder: (context) => PolicyStaffEnqList(), builder: (context) => PolicyStaffEnqList(),
); );
@ -1805,7 +1842,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
userPreference = newValue; // Save this as the new "normal" userPreference = newValue; // Save this as the new "normal"
}); });
final prefs = final prefs =
await SharedPreferences.getInstance(); await SharedPreferences.getInstance();
await prefs.setBool( await prefs.setBool(
'isActionable', 'isActionable',
newValue, newValue,
@ -1908,11 +1945,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
txt: !ResponsiveLayout.isMobile(context) ? true : false, txt: !ResponsiveLayout.isMobile(context) ? true : false,
displayHeaders: [ displayHeaders: [
"Received Date & Time", "Received Date & Time",
"Partner",
"Assigned To", "Assigned To",
"Partner",
"Insurer", "Insurer",
"Vehicle.No.",
"Insured Name", "Insured Name",
"Vehicle.No.",
"Assigned Date & Time", "Assigned Date & Time",
"Premium", "Premium",
"Payment Mode", "Payment Mode",
@ -1921,14 +1958,14 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
], ],
keys: [ keys: [
"created_on", "created_on",
"agent_name",
"assigned_to_name", "assigned_to_name",
"agent_name",
"insurer_short_name", "insurer_short_name",
"reg_no",
"insured_name", "insured_name",
"reg_no",
"updated_on", "updated_on",
"premium_amount", "premium_amount",
"payment_mode", "payment_mode_value",
"policy_number", "policy_number",
"status", "status",
], ],
@ -1942,12 +1979,12 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
ResponsiveLayout.isMobile(context) ResponsiveLayout.isMobile(context)
? _buildDataTable(context) ? _buildDataTable(context)
: Container( : Container(
height: MediaQuery.of(context).size.height * 0.55, height: MediaQuery.of(context).size.height * 0.55,
// decoration: BoxDecoration( // decoration: BoxDecoration(
// color: Colors.white // color: Colors.white
// ), // ),
child: _buildDataTable(context), child: _buildDataTable(context),
), ),
], ],
); );
} }
@ -2093,54 +2130,54 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Calculate minimum width based on screen size // Calculate minimum width based on screen size
double minTableWidth = isMobile ? screenWidth * 1.5 : 1300; double minTableWidth = isMobile ? screenWidth * 1.5 : 1300;
return return
// Expanded( // Expanded(
// child: // child:
LayoutBuilder( LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
double tableWidth = constraints.maxWidth > minTableWidth double tableWidth = constraints.maxWidth > minTableWidth
? constraints.maxWidth ? constraints.maxWidth
: minTableWidth; : minTableWidth;
final isDesktop = !ResponsiveLayout.isMobile(context); final isDesktop = !ResponsiveLayout.isMobile(context);
return ScrollConfiguration( return ScrollConfiguration(
behavior: const MaterialScrollBehavior().copyWith( behavior: const MaterialScrollBehavior().copyWith(
dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch}, dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch},
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
controller: _horizontalScrollController, // 👈 Shared controller controller: _horizontalScrollController, // 👈 Shared controller
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: SizedBox( child: SizedBox(
// width: minWidth, // width: minWidth,
width: tableWidth, width: tableWidth,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Fixed Header // Fixed Header
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
// color: Colors.white, // color: Colors.white,
color: Color(0xFFF1F5F9), color: Color(0xFFF1F5F9),
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
),
child: _buildTableHeader(isDesktop),
), ),
child: _buildTableHeader(isDesktop),
),
// Scrollable Data Content // Scrollable Data Content
Expanded( Expanded(
child: Container( child: Container(
decoration: BoxDecoration(color: Colors.white), decoration: BoxDecoration(color: Colors.white),
child: _buildDataTableContent(), // 👈 New method child: _buildDataTableContent(), // 👈 New method
),
), ),
), _buildPaginationControls(),
_buildPaginationControls(), ],
], ),
), ),
), ),
), );
); },
}, );
);
// ); // );
} }
@ -2352,10 +2389,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Build action buttons // Helper: Build action buttons
Widget _buildActionButtons( Widget _buildActionButtons(
Map<String, dynamic> item, Map<String, dynamic> item,
int id, int id,
String selectId, String selectId,
) { ) {
return Row( return Row(
children: [ children: [
_buildInfoTooltip(item), _buildInfoTooltip(item),
@ -2427,8 +2464,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
onTap: () async { onTap: () async {
final button = buttonContext.findRenderObject() as RenderBox; final button = buttonContext.findRenderObject() as RenderBox;
final overlay = final overlay =
Overlay.of(buttonContext).context.findRenderObject() Overlay.of(buttonContext).context.findRenderObject()
as RenderBox; as RenderBox;
final position = button.localToGlobal( final position = button.localToGlobal(
Offset.zero, Offset.zero,
ancestor: overlay, ancestor: overlay,
@ -2476,11 +2513,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Status cell with conditional actions // Helper: Status cell with conditional actions
Widget _buildStatusCell( Widget _buildStatusCell(
Map<String, dynamic> item, Map<String, dynamic> item,
int id, int id,
Color bgColor, Color bgColor,
Color borderColor, Color borderColor,
) { ) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -2497,9 +2534,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
} }
String formatEnquiryStatus(String? status) { String formatEnquiryStatus(String? status) {
if (status == null) return '-'; if (status == null || status.trim().isEmpty) return '-';
switch (status.toLowerCase()) { switch (status.trim().toLowerCase()) {
case 'to be assigned': case 'to be assigned':
return 'To Be Assigned'; return 'To Be Assigned';
case 'in progress': case 'in progress':
@ -2515,11 +2552,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Status display container // Helper: Status display container
Widget _buildStatusContainer( Widget _buildStatusContainer(
Map<String, dynamic> item, Map<String, dynamic> item,
int id, int id,
Color bgColor, Color bgColor,
Color borderColor, Color borderColor,
) { ) {
return Material( return Material(
color: Colors.white, color: Colors.white,
child: InkWell( child: InkWell(
@ -2538,7 +2575,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
item['enquiry_status'] ?? '-', // item['enquiry_status'] ?? '-',
formatEnquiryStatus(item['enquiry_status']),
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 10, fontSize: 10,
color: Color(0XFF1e293b), color: Color(0XFF1e293b),
@ -2693,7 +2731,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
child: InkWell( child: InkWell(
onTap: () => apiService.downloadFile( onTap: () => apiService.downloadFile(
apiUrl: 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"], apiId: item["policy_id"],
localFile: null, localFile: null,
fileName: item['policy_pdf_file_name'], fileName: item['policy_pdf_file_name'],
@ -2733,12 +2771,12 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Show policy upload menu // Helper: Show policy upload menu
Future<void> _showPolicyUploadMenu( Future<void> _showPolicyUploadMenu(
BuildContext buttonContext, BuildContext buttonContext,
Map<String, dynamic> item, Map<String, dynamic> item,
) async { ) async {
final button = buttonContext.findRenderObject() as RenderBox; final button = buttonContext.findRenderObject() as RenderBox;
final overlay = final overlay =
Overlay.of(buttonContext).context.findRenderObject() as RenderBox; Overlay.of(buttonContext).context.findRenderObject() as RenderBox;
final position = button.localToGlobal(Offset.zero, ancestor: overlay); final position = button.localToGlobal(Offset.zero, ancestor: overlay);
await showMenu( await showMenu(
@ -2771,7 +2809,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Widget _buildPolicyUploadField(Map<String, dynamic> item) { Widget _buildPolicyUploadField(Map<String, dynamic> item) {
return ThemedUploadField( return ThemedUploadField(
hintText: hintText:
selectedFileNames ?? selectedFileNames ??
item['policy_pdf_file_name'] ?? item['policy_pdf_file_name'] ??
"Upload Document", "Upload Document",
padHorizontal: 4, padHorizontal: 4,
@ -2789,10 +2827,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
// Helper: Handle policy file upload // Helper: Handle policy file upload
Future<void> _handlePolicyFileUpload( Future<void> _handlePolicyFileUpload(
String? fileName, String? fileName,
PlatformFile? file, PlatformFile? file,
Map<String, dynamic> item, Map<String, dynamic> item,
) async { ) async {
if (lastPickedFile == fileName) { if (lastPickedFile == fileName) {
ToastHelper.showErrorToast(context, 'Please upload a new file.'); ToastHelper.showErrorToast(context, 'Please upload a new file.');
setState(() { setState(() {
@ -2834,7 +2872,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic>? _getSelectedPaymentMode(Map<String, dynamic> item) { Map<String, dynamic>? _getSelectedPaymentMode(Map<String, dynamic> item) {
try { try {
return filteredPaymentModeData.firstWhere( return filteredPaymentModeData.firstWhere(
(mode) => mode['id'].toString() == item['payment_mode_id'].toString(), (mode) => mode['id'].toString() == item['payment_mode_id'].toString(),
orElse: () => {}, orElse: () => {},
); );
} catch (e) { } catch (e) {
@ -2845,8 +2883,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Map<String, dynamic>? _getSelectedInsurancePlan(Map<String, dynamic> item) { Map<String, dynamic>? _getSelectedInsurancePlan(Map<String, dynamic> item) {
try { try {
return filteredInsuranceData.firstWhere( return filteredInsuranceData.firstWhere(
(mode) => (mode) =>
mode['insurance_plan_type'].toString().trim().toLowerCase() == mode['insurance_plan_type'].toString().trim().toLowerCase() ==
item['insurance_plan_type'].toString().trim().toLowerCase(), item['insurance_plan_type'].toString().trim().toLowerCase(),
orElse: () => {}, orElse: () => {},
); );
@ -2888,8 +2926,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
Widget _buildDropdownDisplay(dynamic selectedItem, String key, String hint) { Widget _buildDropdownDisplay(dynamic selectedItem, String key, String hint) {
bool isEmpty = bool isEmpty =
selectedItem == null || selectedItem == null ||
selectedItem.isEmpty || selectedItem.isEmpty ||
selectedItem[key] == null; selectedItem[key] == null;
return Container( return Container(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@ -3171,7 +3209,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
decoration: BoxDecoration( decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(6), // borderRadius: BorderRadius.circular(6),
color: isSelected color: isSelected
// ? Color(0xFFF1F5F9) // ? Color(0xFFF1F5F9)
? const Color(0xFF2E7D6E).withOpacity(0.08) ? const Color(0xFF2E7D6E).withOpacity(0.08)
: Colors.transparent, : Colors.transparent,
border: Border.all( border: Border.all(
@ -3298,9 +3336,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
.split(' ') .split(' ')
.map( .map(
(word) => word.isNotEmpty (word) => word.isNotEmpty
? word[0].toUpperCase() + word.substring(1).toLowerCase() ? word[0].toUpperCase() + word.substring(1).toLowerCase()
: '', : '',
) )
.join(' '); .join(' ');
} }
@ -3508,8 +3546,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
icon: Icon(Icons.last_page, size: 18), icon: Icon(Icons.last_page, size: 18),
onPressed: completedCurrentPage < totalCompletedPages onPressed: completedCurrentPage < totalCompletedPages
? () => setState( ? () => setState(
() => completedCurrentPage = totalCompletedPages, () => completedCurrentPage = totalCompletedPages,
) )
: null, : null,
color: completedCurrentPage < totalCompletedPages color: completedCurrentPage < totalCompletedPages
? Color(0xFF2E7D6E) ? Color(0xFF2E7D6E)
@ -3631,8 +3669,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
icon: Icon(Icons.last_page, size: 18), icon: Icon(Icons.last_page, size: 18),
onPressed: completedCurrentPage < totalCompletedPages onPressed: completedCurrentPage < totalCompletedPages
? () => setState( ? () => setState(
() => completedCurrentPage = totalCompletedPages, () => completedCurrentPage = totalCompletedPages,
) )
: null, : null,
color: completedCurrentPage < totalCompletedPages color: completedCurrentPage < totalCompletedPages
? Color(0xFF2E7D6E) ? Color(0xFF2E7D6E)
@ -3698,4 +3736,4 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
return pageButtons; return pageButtons;
} }
} }

View File

@ -720,7 +720,7 @@ class CreateProposalFormState extends ConsumerState<CreateProposalForm> {
decoratorProps: DropDownDecoratorProps( decoratorProps: DropDownDecoratorProps(
decoration: decoration:
AppInputDecorations.dropdownDecoration( AppInputDecorations.dropdownDecoration(
label: "Select Staff Member", label: "Select Plan Type",
).copyWith( ).copyWith(
filled: true, filled: true,
fillColor: fillColor:

View File

@ -82,8 +82,8 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
final data = { final data = {
"id": widget.enquiryPrimaryId, "id": widget.enquiryPrimaryId,
"assigned_to": selectedStaff, "assigned_to": selectedStaff,
// "insurer_id": selectedInsurer, "insurer_id": selectedInsurer,
// "broker_id": selectedBroker, "broker_id": selectedBroker,
"updated_by": widget.userId, "updated_by": widget.userId,
}; };
return data; return data;
@ -230,8 +230,9 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
dataDetails(); dataDetails();
final dataSet = dataDetails(); final dataSet = dataDetails();
print("dataSetAgent - $dataSet"); print("b4 - $dataSet");
// print("managerId - $managerId ,userId - $userId "); dataSet['from_dashboard_enquiry_status'] = 'Assigned';
print("Atr - $dataSet");
createUserData(dataSet); createUserData(dataSet);
} else { } else {
// isDi sable = false; // isDi sable = false;
@ -244,6 +245,7 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
final String apiUrldata; final String apiUrldata;
apiUrldata = '${Env.apiUrl}enquiry/enquiryAssignUpdate'; apiUrldata = '${Env.apiUrl}enquiry/enquiryAssignUpdate';
// apiUrldata = 'http://localhost/nhance_partner_be/enquiry/enquiryAssignUpdate';
// final token = await getToken(); // Fetch token // final token = await getToken(); // Fetch token
@ -406,8 +408,8 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
children: [ children: [
buildRegistrationNumber(context), buildRegistrationNumber(context),
buildSelectStaffMem(context), buildSelectStaffMem(context),
// buildInsurer(context), buildInsurer(context),
// buildBroker(context), buildBroker(context),
], ],
), ),
); );
@ -514,9 +516,9 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
label: "Select Staff Member", label: "Select Staff Member",
).copyWith( ).copyWith(
filled: true, filled: true,
fillColor: Color( fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
0xFFEDF6F5, isDense: true, // 👈 Makes the field compact
), // 👈 makes the dropdown input white contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
), ),
), ),
@ -619,9 +621,9 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
label: "Select Insurer", label: "Select Insurer",
).copyWith( ).copyWith(
filled: true, filled: true,
fillColor: Color( fillColor: Color(0xFFEDF6F5), // 👈 makes the dropdown input white
0xFFEDF6F5, isDense: true, // 👈 Makes the field compact
), // 👈 makes the dropdown input white contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
), ),
), ),
@ -723,9 +725,9 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
label: "Select Broker", label: "Select Broker",
).copyWith( ).copyWith(
filled: true, filled: true,
fillColor: Color( fillColor: Color(0xFFEDF6F5,), // 👈 makes the dropdown input white
0xFFEDF6F5, isDense: true, // 👈 Makes the field compact
), // 👈 makes the dropdown input white contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
), ),
), ),

View File

@ -584,7 +584,7 @@ class policylistState extends ConsumerState<policylist> {
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Vehicle.No.', style: _headerStyle), child: Text('Vehicle No ', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 3, flex: 3,

View File

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

View File

@ -179,7 +179,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
SizedBox(width: spacing), SizedBox(width: spacing),
if (widget.dataFrom == null && widget.dataFrom != 'Policy') ...[ if (widget.dataFrom == null && widget.dataFrom != 'Policy') ...[
buildStatusSearch(context), buildStatusSearch(context,widget.role),
SizedBox(width: spacing), SizedBox(width: spacing),
], ],
@ -277,12 +277,12 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
// validator: (value) => Validators.requiredField(value, "date"), // validator: (value) => Validators.requiredField(value, "date"),
controller: widget.startController, controller: widget.startController,
onDateSelected: (date) { onDateSelected: (date) {
print("Picked Date: $date"); print("SPicked Date: $date");
widget.startController.text = DateFormat( widget.startController.text = DateFormat(
'dd-MM-yyyy', 'dd-MM-yyyy',
).format(date); ).format(date);
// controllers['date']?.text = date as String; // controllers['date']?.text = date as String;
Future.microtask(() => widget.onFilter()); // Future.microtask(() => widget.onFilter());
}, },
), ),
), ),
@ -322,9 +322,9 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
}, },
controller: widget.endController, controller: widget.endController,
lastDate: DateTime.now(), lastDate: DateTime.now(),
onDateSelected: (date) { onDateSelected: (edate) {
print("Picked Date: $date"); print("EPicked Date: $edate");
widget.endController.text = DateFormat('dd-MM-yyyy').format(date); widget.endController.text = DateFormat('dd-MM-yyyy').format(edate);
Future.microtask(() => widget.onFilter()); Future.microtask(() => widget.onFilter());
// controllers['date']?.text = date as String; // controllers['date']?.text = date as String;
}, },
@ -334,18 +334,27 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
); );
} }
Widget buildStatusSearch(BuildContext context) { Widget buildStatusSearch(BuildContext context,role) {
final List<Map<String, dynamic>> statusOptions = [
// {'id': 1, 'status': 'Awaiting Proposal'}, final List<Map<String, dynamic>> statusOptions;
// {'id': 2, 'status': 'Proposal Created'},
// {'id': 3, 'status': 'Proposal Accepted'}, if (role == "agent") {
// {'id': 4, 'status': 'Proposal Rejected'}, statusOptions = [
// {'id': 5, 'status': 'Policy Created'}, {'id': 1, 'status': 'Awaiting Proposal'},
{'id': 1, 'status': 'To be Assigned'}, {'id': 2, 'status': 'Proposal Created'},
{'id': 2, 'status': 'Assigned'}, {'id': 3, 'status': 'Proposal Accepted'},
{'id': 3, 'status': 'In Progress'}, {'id': 4, 'status': 'Proposal Rejected'},
{'id': 4, 'status': 'Completed'}, {'id': 5, 'status': 'Policy Created'},
]; ];
} else {
statusOptions = [
{'id': 1, 'status': 'To Be Assigned'},
{'id': 2, 'status': 'Assigned'},
{'id': 3, 'status': 'In Progress'},
{'id': 4, 'status': 'Completed'},
];
}
Map<String, dynamic>? selectedStatusMap = statusOptions Map<String, dynamic>? selectedStatusMap = statusOptions
.where((element) => element['status'] == widget.selectedStatusVal) .where((element) => element['status'] == widget.selectedStatusVal)
.cast<Map<String, dynamic>>() .cast<Map<String, dynamic>>()

View File

@ -143,7 +143,8 @@ class _TopBarState extends ConsumerState<TopBar> {
), ),
], ],
SizedBox(width: 10), SizedBox(width: 10),
if (role != 'Accounts') ...[ // if (role != 'Accounts') ...[
if (!['Accounts', 'agent'].contains(role)) ...[
// Proposal button // Proposal button
Container( Container(
width: 36, width: 36,