FIX_Helpdesk Fixes
This commit is contained in:
parent
ae238f8812
commit
5d3bf2c917
File diff suppressed because one or more lines are too long
@ -5,8 +5,8 @@ class Env {
|
|||||||
);
|
);
|
||||||
static const String apiUrl = String.fromEnvironment(
|
static const String apiUrl = String.fromEnvironment(
|
||||||
'API_URL',
|
'API_URL',
|
||||||
// defaultValue: 'https://partner.nhanceindia.in/partner_api/api/',
|
// defaultValue: 'https://partner.nhanceindia.in/partner_api/api/', /* when test build uncomment this. but below line should in comment */
|
||||||
defaultValue: 'https://venbait.in/nhance/partner/dev/api/',
|
defaultValue: 'https://venbait.in/nhance/partner/dev/api/', /* when live build uncomment . but above line should in comment */
|
||||||
);
|
);
|
||||||
// static const String baseUrl = String.fromEnvironment(
|
// static const String baseUrl = String.fromEnvironment(
|
||||||
// 'BASE_URL',
|
// 'BASE_URL',
|
||||||
|
|||||||
@ -440,33 +440,61 @@ class ApiService {
|
|||||||
print('getPdfDownload 1 - $path');
|
print('getPdfDownload 1 - $path');
|
||||||
|
|
||||||
dynamic pathVal;
|
dynamic pathVal;
|
||||||
|
// if (path == 'Insurer') {
|
||||||
|
// pathVal =
|
||||||
|
// 'dashboard/downloadInsurerPoliciesExcel?manager_id=$managerId&month=$month&insurer_id=$id';
|
||||||
|
// } else if (path == 'Broker') {
|
||||||
|
// pathVal =
|
||||||
|
// 'dashboard/downloadBrokerPoliciesExcel?manager_id=$managerId&month=$month&broker_id=$id';
|
||||||
|
// } else if (path == 'Product') {
|
||||||
|
// pathVal =
|
||||||
|
// 'dashboard/downloadProductPoliciesExcel?manager_id=$managerId&month=$month&vehicle_type=$id';
|
||||||
|
// } else if (path == 'PerformingTop50') {
|
||||||
|
// pathVal =
|
||||||
|
// 'dashboard/downloadAgentMonthlyPoliciesExcel?manager_id=$managerId&agent_id=$id';
|
||||||
|
// } else if (path == 'PerformingAgentAll50') {
|
||||||
|
// pathVal = 'dashboard/downloadT50AgentPoliciesExcel?manager_id=$managerId';
|
||||||
|
// } else if (path == 'NonPerformingBelow50K') {
|
||||||
|
// pathVal = 'dashboard/downloadLowPremiumAgentExcel?manager_id=$managerId';
|
||||||
|
// } else if (path == 'staff_pending_summary') {
|
||||||
|
// pathVal = 'dashboard/downloadStaffPendingSummaryExcel?manager_id=$managerId';
|
||||||
|
// } else if (path == 'staff_pending_summary_by_id') {
|
||||||
|
// pathVal = 'dashboard/downloadStaffPendingSummaryExcelByID?manager_id=$managerId&staff_id=$id&status=$month';
|
||||||
|
// } else {
|
||||||
|
// //NoBusiness
|
||||||
|
// pathVal =
|
||||||
|
// 'dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=$managerId';
|
||||||
|
// }
|
||||||
|
|
||||||
if (path == 'Insurer') {
|
if (path == 'Insurer') {
|
||||||
pathVal =
|
pathVal =
|
||||||
'dashboard/downloadInsurerPoliciesExcel?manager_id=$managerId&month=$month&insurer_id=$id';
|
'dashboard/downloadExcelInsurer?manager_id=$managerId&month=$month&insurer_id=$id';
|
||||||
} else if (path == 'Broker') {
|
} else if (path == 'Broker') {
|
||||||
pathVal =
|
pathVal =
|
||||||
'dashboard/downloadBrokerPoliciesExcel?manager_id=$managerId&month=$month&broker_id=$id';
|
'dashboard/downloadExcelBroker?manager_id=$managerId&month=$month&broker_id=$id';
|
||||||
} else if (path == 'Product') {
|
} else if (path == 'Product') {
|
||||||
pathVal =
|
pathVal =
|
||||||
'dashboard/downloadProductPoliciesExcel?manager_id=$managerId&month=$month&vehicle_type=$id';
|
'dashboard/downloadExcelProduct?manager_id=$managerId&month=$month&vehicle_type=$id';
|
||||||
} else if (path == 'PerformingTop50') {
|
} else if (path == 'PerformingTop50') {
|
||||||
|
pathVal = 'dashboard/downloadExcelPerformingAgentsTop50?manager_id=$managerId';
|
||||||
|
} else if (path == 'PerformingAgentsByID') {
|
||||||
pathVal =
|
pathVal =
|
||||||
'dashboard/downloadAgentMonthlyPoliciesExcel?manager_id=$managerId&agent_id=$id';
|
'dashboard/downloadExcelPerformingAgentsByID?manager_id=$managerId&agent_id=$id';
|
||||||
} else if (path == 'PerformingAgentAll50') {
|
|
||||||
pathVal = 'dashboard/downloadT50AgentPoliciesExcel?manager_id=$managerId';
|
|
||||||
} else if (path == 'NonPerformingBelow50K') {
|
} else if (path == 'NonPerformingBelow50K') {
|
||||||
pathVal = 'dashboard/downloadLowPremiumAgentExcel?manager_id=$managerId';
|
pathVal = 'dashboard/downloadExcelLowPremium?manager_id=$managerId';
|
||||||
} else if (path == 'staff_pending_summary') {
|
} else if (path == 'staff_pending_summary') {
|
||||||
pathVal = 'dashboard/downloadStaffPendingSummaryExcel?manager_id=$managerId';
|
pathVal = 'dashboard/downloadExcelStaffPendingSummaryExcel?manager_id=$managerId';
|
||||||
} else if (path == 'staff_pending_summary_by_id') {
|
} else if (path == 'staff_pending_summary_by_id') {
|
||||||
pathVal = 'dashboard/downloadStaffPendingSummaryExcelByID?manager_id=$managerId&staff_id=$id&status=$month';
|
pathVal = 'dashboard/downloadExcelStaffPendingSummaryExcelByID?manager_id=$managerId&staff_id=$id&status=$month';
|
||||||
} else {
|
} else {
|
||||||
//NoBusiness
|
//NoBusiness
|
||||||
pathVal =
|
pathVal =
|
||||||
'dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=$managerId';
|
'dashboard/downloadExcelWithoutPolicies?manager_id=$managerId';
|
||||||
}
|
}
|
||||||
|
|
||||||
final url = Uri.parse('${Env.apiUrl}$pathVal');
|
final url = Uri.parse('${Env.apiUrl}$pathVal'); // original
|
||||||
|
// final url = Uri.parse('http://localhost/nhance_partner_be/$pathVal'); //LocalHost
|
||||||
|
|
||||||
// final url = 'http://localhost/nhance_partner_be/dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=1';
|
// final url = 'http://localhost/nhance_partner_be/dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=1';
|
||||||
// final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
|
// final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
|
||||||
print('getPdfDownload 2 - $url');
|
print('getPdfDownload 2 - $url');
|
||||||
@ -781,6 +809,7 @@ 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 headers = {
|
final headers = {
|
||||||
@ -1071,7 +1100,7 @@ class ApiService {
|
|||||||
// query = 'manager_id=$id';
|
// query = 'manager_id=$id';
|
||||||
// }
|
// }
|
||||||
if (role == 'manager') {
|
if (role == 'manager') {
|
||||||
query = 'manager_id=$id';
|
query = 'manager_id=$managerid';
|
||||||
} else if (role == 'handler') {
|
} else if (role == 'handler') {
|
||||||
query = 'handler_id=$id';
|
query = 'handler_id=$id';
|
||||||
} else if (role == 'staff') {
|
} else if (role == 'staff') {
|
||||||
@ -1301,7 +1330,8 @@ class ApiService {
|
|||||||
String? selectedStatus,
|
String? selectedStatus,
|
||||||
String? selectedStaffId,
|
String? selectedStaffId,
|
||||||
}) async {
|
}) async {
|
||||||
// print(_token);
|
print("APISERV : A1304");
|
||||||
|
print(_token);
|
||||||
if (_token == null) {
|
if (_token == null) {
|
||||||
await _initializeToken();
|
await _initializeToken();
|
||||||
}
|
}
|
||||||
@ -1982,6 +2012,76 @@ class ApiService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> generateEndorsementExcel(managerId) async {
|
||||||
|
final url = Uri.parse(
|
||||||
|
'${Env.apiUrl}reports/endorsement-excel?manager_id=$managerId',
|
||||||
|
);
|
||||||
|
|
||||||
|
print('getPdfDownload endorsement-excel - $url');
|
||||||
|
await _initializeToken();
|
||||||
|
|
||||||
|
if (_token == null) throw Exception('Token not found. Please log in.');
|
||||||
|
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $_token',
|
||||||
|
// 'App-Signature': Env.App_Signature,
|
||||||
|
'app-signature': Env.App_Signature,
|
||||||
|
};
|
||||||
|
|
||||||
|
final response = await _makeGethttpRequest(url, headers);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final contentType = response.headers['content-type'] ?? '';
|
||||||
|
if (contentType.contains('application/json')) {
|
||||||
|
final jsonResponse = jsonDecode(response.body);
|
||||||
|
if (jsonResponse['code'] == 404 || jsonResponse['code'] == 500) {
|
||||||
|
ToastHelper.show('File Not Found', Colors.red);
|
||||||
|
} else {
|
||||||
|
ToastHelper.show('No File Found', Colors.red);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
final blob = html.Blob([response.bodyBytes]);
|
||||||
|
final blobUrl = html.Url.createObjectUrlFromBlob(blob);
|
||||||
|
print('getPdfDownload $blobUrl');
|
||||||
|
final contentDisp = response.headers['content-disposition'];
|
||||||
|
print('getPdfDownloadcontentDisp $contentDisp');
|
||||||
|
|
||||||
|
String fileName = extractFileName(contentDisp, "policy_excel");
|
||||||
|
print('Resolved fileName: $fileName');
|
||||||
|
final anchor = html.AnchorElement(href: blobUrl)
|
||||||
|
..setAttribute('download', fileName)
|
||||||
|
..click();
|
||||||
|
|
||||||
|
html.Url.revokeObjectUrl(blobUrl);
|
||||||
|
}
|
||||||
|
} else if (response.statusCode == 404) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('File not found.'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: const Text('OK'),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (response.statusCode == 403) {
|
||||||
|
await clearLocalStorageAndRedirect();
|
||||||
|
} else if (response.statusCode == 500) {
|
||||||
|
ToastHelper.show('No File Found', Colors.red);
|
||||||
|
} else if (response.statusCode == 302) {
|
||||||
|
print('getPdfDownload 3-PP-302');
|
||||||
|
ToastHelper.show('No File Found', Colors.red);
|
||||||
|
} else {
|
||||||
|
ToastHelper.show('No File Found', Colors.red);
|
||||||
|
throw Exception('Failed to download file');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> generatePolicyExcel(managerId, fromDate, toDate) async {
|
Future<void> generatePolicyExcel(managerId, fromDate, toDate) 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 ?? ''}',
|
||||||
|
|||||||
@ -83,6 +83,7 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
|
|
||||||
String? selectedClaimsType;
|
String? selectedClaimsType;
|
||||||
String? selectedEndorsement;
|
String? selectedEndorsement;
|
||||||
|
String? selectedEndrosementPolicyFrom;
|
||||||
|
|
||||||
dynamic roleId;
|
dynamic roleId;
|
||||||
|
|
||||||
@ -98,6 +99,11 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
List<Map<String, dynamic>> originalVehicleData = [];
|
List<Map<String, dynamic>> originalVehicleData = [];
|
||||||
List<Map<String, dynamic>> filteredVehicleData = [];
|
List<Map<String, dynamic>> filteredVehicleData = [];
|
||||||
|
|
||||||
|
final List<Map<String, dynamic>> policyFromOptions = [
|
||||||
|
{"policy_from": "Internal"},
|
||||||
|
{"policy_from": "External"},
|
||||||
|
];
|
||||||
|
|
||||||
Map<String, dynamic> claimsDetails() {
|
Map<String, dynamic> claimsDetails() {
|
||||||
final data = {
|
final data = {
|
||||||
"policy_number": controllers["policyNum"]?.text,
|
"policy_number": controllers["policyNum"]?.text,
|
||||||
@ -114,8 +120,9 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
"policy_number": controllers["policyNum"]?.text,
|
"policy_number": controllers["policyNum"]?.text,
|
||||||
"endorsement_description": controllers["remarks"]?.text,
|
"endorsement_description": controllers["remarks"]?.text,
|
||||||
"endorsement_type": selectedEndorsement,
|
"endorsement_type": selectedEndorsement,
|
||||||
// "manager_id": managerId,
|
"manager_id": widget.managerId,
|
||||||
"created_by": widget.userId,
|
"created_by": widget.userId,
|
||||||
|
"policy_from": selectedEndrosementPolicyFrom,
|
||||||
};
|
};
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -424,7 +431,8 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
// isDi sable = false;
|
// isDi sable = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (!_formKeyEndrosment.currentState!.validate()) return;
|
if (!_formKeyEndrosment.currentState!.validate()) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_formKeyEndrosment.currentState!.validate()) {
|
if (_formKeyEndrosment.currentState!.validate()) {
|
||||||
@ -441,9 +449,15 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createUserData(data, val) async {
|
Future<void> createUserData(data, val) async {
|
||||||
final Uri uri = (val == 'Claims')
|
|
||||||
? Uri.parse('${Env.apiUrl}claim/createClaim')
|
final endpoints = {
|
||||||
: Uri.parse('${Env.apiUrl}endorsement/createEndorsement');
|
'Claims': 'claim/createClaim',
|
||||||
|
'Endorsement': 'endorsement/createEndorsement',
|
||||||
|
};
|
||||||
|
|
||||||
|
final String? path = endpoints[val];
|
||||||
|
|
||||||
|
final Uri uri = Uri.parse('${Env.apiUrl}$path');
|
||||||
|
|
||||||
if (_token == null) {
|
if (_token == null) {
|
||||||
throw Exception('Token not found. Please log in.');
|
throw Exception('Token not found. Please log in.');
|
||||||
@ -808,7 +822,7 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
children: [
|
children: [
|
||||||
buildEndrosType(context),
|
buildEndrosType(context),
|
||||||
SizedBox(width: 15),
|
SizedBox(width: 15),
|
||||||
buildPolicyNumber(context),
|
buildEndrosPolicyFrom(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
@ -819,7 +833,17 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
children: [
|
children: [
|
||||||
buildUploadDocumentClaims(context),
|
buildUploadDocumentClaims(context),
|
||||||
SizedBox(width: 15),
|
SizedBox(width: 15),
|
||||||
|
buildPolicyNumber(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
buildEndrosRemarks(context),
|
buildEndrosRemarks(context),
|
||||||
|
SizedBox(width: 15),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1132,6 +1156,94 @@ class _AddDialogState extends State<AddDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildEndrosPolicyFrom(context) {
|
||||||
|
// Find the selected item from the static list based on your variable
|
||||||
|
Map<String, dynamic> selectedEndorsementPF = policyFromOptions.firstWhere(
|
||||||
|
(item) => item['policy_from'].toString() == selectedEndrosementPolicyFrom,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Policy From *", style: _textStyle),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
|
// Use a unique key for this dropdown
|
||||||
|
key: const ValueKey("policyFromDropdown"),
|
||||||
|
selectedItem: selectedEndorsementPF.isNotEmpty
|
||||||
|
? selectedEndorsementPF
|
||||||
|
: null,
|
||||||
|
items: (filter, infiniteScrollProps) {
|
||||||
|
return policyFromOptions; // Use the static list
|
||||||
|
},
|
||||||
|
itemAsString: (val) => val['policy_from'].toString(),
|
||||||
|
compareFn: (item, selectedItem) =>
|
||||||
|
item['policy_from'] == selectedItem['policy_from'],
|
||||||
|
|
||||||
|
// --- REQUIRED VALIDATOR ---
|
||||||
|
validator: (val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return "Required";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
decoratorProps: DropDownDecoratorProps(
|
||||||
|
decoration: AppInputDecorations.dropdownDecoration(
|
||||||
|
label: "Select Policy From",
|
||||||
|
).copyWith(
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color(0xFFEDF6F5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
popupProps: PopupProps.menu(
|
||||||
|
fit: FlexFit.loose,
|
||||||
|
constraints: const BoxConstraints(maxHeight: 150), // Shorter for 2 items
|
||||||
|
menuProps: const MenuProps(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
showSearchBox: true, // Disabled search as there are only 2 items
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
hintText: "Search Policy From...",
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
), // 👈 Normal border
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
width: 1.5,
|
||||||
|
), // 👈 Focused border
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
onChanged: (val) {
|
||||||
|
if (val != null) {
|
||||||
|
setState(() {
|
||||||
|
print("Selected Policy From: ${val['policy_from']}");
|
||||||
|
selectedEndrosementPolicyFrom = val['policy_from'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildEndrosRemarks(context) {
|
Widget buildEndrosRemarks(context) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|||||||
@ -0,0 +1,712 @@
|
|||||||
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:http/http.dart' as ref;
|
||||||
|
import 'package:toastification/toastification.dart';
|
||||||
|
|
||||||
|
import '../../../../core/config/env.dart';
|
||||||
|
import '../../../../core/services/api_service.dart';
|
||||||
|
import '../../../../data/services/auth_service.dart';
|
||||||
|
import '../../../../data/utils/toastNotification.dart';
|
||||||
|
import '../../../../data/utils/validators.dart';
|
||||||
|
import '../../../layouts/responsive_layout.dart';
|
||||||
|
import '../../../themes/indicators/customizd_file_upload.dart';
|
||||||
|
import '../../../themes/indicators/input_field_decoration.dart';
|
||||||
|
import '../../../themes/indicators/search_field_theme.dart';
|
||||||
|
import '../../../themes/indicators/text_field_theme.dart';
|
||||||
|
import '../../../providers/manager_provider.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateEndorsementDialog extends StatefulWidget {
|
||||||
|
final Map<String, dynamic> item;
|
||||||
|
final dynamic userId;
|
||||||
|
final dynamic managerId;
|
||||||
|
final Function(String) onSubmit;
|
||||||
|
|
||||||
|
const UpdateEndorsementDialog({
|
||||||
|
super.key,
|
||||||
|
required this.item,
|
||||||
|
required this.userId,
|
||||||
|
required this.managerId,
|
||||||
|
required this.onSubmit,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<UpdateEndorsementDialog> createState() => _UpdateEndorsementDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
|
||||||
|
late ApiService apiService;
|
||||||
|
String? _token;
|
||||||
|
final _formKeyUpdate = GlobalKey<FormState>();
|
||||||
|
Map<String, TextEditingController> controllers = {};
|
||||||
|
List<Map<String, dynamic>> getEndrosmentType = [];
|
||||||
|
List<Map<String, dynamic>> filteredEndrosmentData = [];
|
||||||
|
String? selectedEndorsement;
|
||||||
|
String? selectedPolicyFrom;
|
||||||
|
String? selectedStatus; // "Pending" or "Completed"
|
||||||
|
String? selectedFileNames;
|
||||||
|
bool isLoading = false;
|
||||||
|
PlatformFile? docUploadedFile;
|
||||||
|
|
||||||
|
final List<Map<String, dynamic>> statusOptions = [
|
||||||
|
{"status_value": "Open"},
|
||||||
|
{"status_value": "Pending"},
|
||||||
|
{"status_value": "Completed"},
|
||||||
|
];
|
||||||
|
|
||||||
|
final List<Map<String, dynamic>> policyFromOptions = [
|
||||||
|
{"policy_from": "Internal"},
|
||||||
|
{"policy_from": "External"},
|
||||||
|
];
|
||||||
|
|
||||||
|
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
|
||||||
|
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||||
|
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
|
||||||
|
dropDownKeyEndorsement =
|
||||||
|
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
apiService = ApiService();
|
||||||
|
super.initState();
|
||||||
|
_initializeToken();
|
||||||
|
|
||||||
|
print("secondpage");
|
||||||
|
// 1. Initialize Controllers
|
||||||
|
controllers['endorsement_no'] = TextEditingController(text: widget.item['endorsement_no']);
|
||||||
|
controllers['remarks'] = TextEditingController(text: widget.item['endorsement_description']);
|
||||||
|
|
||||||
|
selectedEndorsement = widget.item['endorsement_type']?.toString();
|
||||||
|
selectedStatus = widget.item['status']?.toString();
|
||||||
|
selectedFileNames = widget.item['endorsement_completion_file'];
|
||||||
|
getEnroementType();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initializeToken() async {
|
||||||
|
_token = await AuthService.getToken();
|
||||||
|
print("APISERTOKEN - $_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Call logic
|
||||||
|
// Future<void> updateData() async {
|
||||||
|
// if (!_formKeyUpdate.currentState!.validate()) return;
|
||||||
|
//
|
||||||
|
// // VALIDATION: If Status is Completed, File is Mandatory
|
||||||
|
// if (selectedStatus == "Completed" && docUploadedFile == null) {
|
||||||
|
// ToastHelper.showErrorToast(context,"Document is required for Completed status",);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// setState(() => isLoading = true);
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// final Uri uri = Uri.parse('${Env.apiUrl}endorsement/updateEndorsement');
|
||||||
|
//
|
||||||
|
// if (_token == null) {
|
||||||
|
// throw Exception('Token not found. Please log in.');
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Use MultipartRequest (POST only)
|
||||||
|
// final request = http.MultipartRequest('POST', uri);
|
||||||
|
// request.headers['Authorization'] = 'Bearer $_token';
|
||||||
|
// request.headers['app-signature'] = Env.App_Signature;
|
||||||
|
//
|
||||||
|
// // Mapping fields to API Table
|
||||||
|
// request.fields['endorsement_type'] = selectedEndorsement ?? "";
|
||||||
|
// request.fields['endorsement_description'] = controllers['remarks']?.text ?? "";
|
||||||
|
// request.fields['endorsement_no'] = widget.item['endorsement_no'] ?? "";
|
||||||
|
// // request.fields['updated_by'] = userId;
|
||||||
|
// request.fields['status'] = selectedStatus ?? "";
|
||||||
|
//
|
||||||
|
// if (docUploadedFile != null) {
|
||||||
|
// try {
|
||||||
|
// if (docUploadedFile!.bytes != null) {
|
||||||
|
// final multipartFile = http.MultipartFile.fromBytes(
|
||||||
|
// 'endorsement_completion_file',
|
||||||
|
// docUploadedFile!.bytes!,
|
||||||
|
// filename: docUploadedFile!.name,
|
||||||
|
// );
|
||||||
|
// request.files.add(multipartFile);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// print("📎 File attached: ${docUploadedFile!.name}");
|
||||||
|
// } catch (e) {
|
||||||
|
// print("❌ Failed to attach file: $e");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final response = await request.send();
|
||||||
|
// if (response.statusCode == 200) {
|
||||||
|
// ToastHelper.showSuccessToast(context, 'Updated Successfully');
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// widget.onSubmit("success");
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Error: $e");
|
||||||
|
// } finally {
|
||||||
|
// setState(() => isLoading = false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<void> updateData() async {
|
||||||
|
// 1. Basic Form Validation
|
||||||
|
if (!_formKeyUpdate.currentState!.validate()) return;
|
||||||
|
|
||||||
|
// 2. Business Validation: File mandatory for 'Completed' status
|
||||||
|
if (selectedStatus == "Completed" && docUploadedFile == null) {
|
||||||
|
ToastHelper.showErrorToast(context, "Document is required for Completed status");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() => isLoading = true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Uri uri = Uri.parse('${Env.apiUrl}endorsement/updateEndorsement');
|
||||||
|
|
||||||
|
if (_token == null) throw Exception('Token not found. Please log in.');
|
||||||
|
|
||||||
|
// Create Multipart Request
|
||||||
|
final request = http.MultipartRequest('POST', uri);
|
||||||
|
request.headers['Authorization'] = 'Bearer $_token';
|
||||||
|
request.headers['app-signature'] = Env.App_Signature;
|
||||||
|
|
||||||
|
// --- MAPPING FIELDS ---
|
||||||
|
// Use widget.item['id'] to identify the unique record
|
||||||
|
request.fields['id'] = widget.item['id'].toString();
|
||||||
|
request.fields['endorsement_type'] = selectedEndorsement ?? "";
|
||||||
|
request.fields['endorsement_description'] = controllers['remarks']?.text ?? "";
|
||||||
|
request.fields['endorsement_no'] = controllers['endorsement_no']?.text ?? "";
|
||||||
|
|
||||||
|
// Set updated_by from the widget parameter
|
||||||
|
request.fields['updated_by'] = widget.userId.toString();
|
||||||
|
request.fields['status'] = selectedStatus ?? "";
|
||||||
|
|
||||||
|
// --- FILE UPLOAD LOGIC ---
|
||||||
|
if (docUploadedFile != null) {
|
||||||
|
if (docUploadedFile!.bytes != null) {
|
||||||
|
// For Web/Bytes
|
||||||
|
request.files.add(http.MultipartFile.fromBytes(
|
||||||
|
'endorsement_completion_file', // Key must match Backend
|
||||||
|
docUploadedFile!.bytes!,
|
||||||
|
filename: docUploadedFile!.name,
|
||||||
|
));
|
||||||
|
} else if (docUploadedFile!.path != null) {
|
||||||
|
// For Mobile/Desktop path
|
||||||
|
request.files.add(await http.MultipartFile.fromPath(
|
||||||
|
'endorsement_completion_file',
|
||||||
|
docUploadedFile!.path!,
|
||||||
|
filename: docUploadedFile!.name,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
print("📎 Attached: ${docUploadedFile!.name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Send Request
|
||||||
|
final response = await request.send();
|
||||||
|
final responseData = await http.Response.fromStream(response);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
ToastHelper.showSuccessToast(context, 'Updated Successfully');
|
||||||
|
Navigator.pop(context);
|
||||||
|
widget.onSubmit("success");
|
||||||
|
} else {
|
||||||
|
print("Server Error: ${responseData.body}");
|
||||||
|
ToastHelper.showErrorToast(context, "Update failed: ${response.statusCode}");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error during update: $e");
|
||||||
|
ToastHelper.showErrorToast(context, "An error occurred");
|
||||||
|
} finally {
|
||||||
|
setState(() => isLoading = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
// Add shape for a cleaner look
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
|
content: SizedBox(
|
||||||
|
// Set a width to prevent layout jumping
|
||||||
|
width: MediaQuery.of(context).size.width * 0.6,
|
||||||
|
child: SingleChildScrollView( // 👈 Fix 1: Prevent Overflow
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// Header row
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Update Endorsement",
|
||||||
|
style: GoogleFonts.inter(
|
||||||
|
color: const Color(0xFF374141),
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Navigator.pop(context),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFF1F1F1),
|
||||||
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
|
),
|
||||||
|
child: const Tooltip(
|
||||||
|
message: 'Close',
|
||||||
|
child: Icon(Icons.close, size: 18),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
// Your form content
|
||||||
|
endorsement(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// 👈 Fix 2: Remove "onPressed:" label. Just call the function.
|
||||||
|
updateData();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
color: const Color(0xFF425B5B),
|
||||||
|
),
|
||||||
|
child: isLoading
|
||||||
|
? const SizedBox(height: 15, width: 15, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
|
||||||
|
: const Text('Save', style: TextStyle(color: Colors.white)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget endorsement(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: _formKeyUpdate,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
// Wrap children in Expanded so they know how much space to take in the Row
|
||||||
|
Expanded(child: buildEndrosType(context)),
|
||||||
|
const SizedBox(width: 15),
|
||||||
|
Expanded(child: buildStatusDropdown(context)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(child: buildPolicyNumber(context)),
|
||||||
|
const SizedBox(width: 15),
|
||||||
|
Expanded(child: buildUploadDocumentEndorsment(context)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: buildEndrosRemarks(context)),
|
||||||
|
const SizedBox(width: 15),
|
||||||
|
const Spacer(), // Keeps the remark field to the left
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> getEnroementType() async {
|
||||||
|
print('Insurers called');
|
||||||
|
setState(() {
|
||||||
|
isLoading = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await apiService.fetchMasterDropDown('Endorsement');
|
||||||
|
|
||||||
|
if (response['status'] == 200) {
|
||||||
|
print('getEnroementType - ${response['data']}');
|
||||||
|
setState(() {
|
||||||
|
getEndrosmentType = List<Map<String, dynamic>>.from(response['data']);
|
||||||
|
print('API Data - $getEndrosmentType');
|
||||||
|
|
||||||
|
filteredEndrosmentData = List.from(getEndrosmentType);
|
||||||
|
print('originalData - $filteredEndrosmentData');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getEndrosmentType = [];
|
||||||
|
filteredEndrosmentData = [];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception occurred: $e');
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Specialized Widgets ---
|
||||||
|
Widget buildEndrosType(context) {
|
||||||
|
Map<String, dynamic>? selectedEndorsementd = filteredEndrosmentData
|
||||||
|
.firstWhere(
|
||||||
|
(item) => item['id'].toString() == selectedEndorsement,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Endorsement Type *", style: _textStyle),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
// height: 40,
|
||||||
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
|
key: dropDownKeyEndorsement,
|
||||||
|
selectedItem: selectedEndorsementd.isNotEmpty
|
||||||
|
? selectedEndorsementd
|
||||||
|
: null,
|
||||||
|
items: (filter, infiniteScrollProps) {
|
||||||
|
return filteredEndrosmentData;
|
||||||
|
},
|
||||||
|
|
||||||
|
itemAsString: (val) =>
|
||||||
|
val['endorsement_type'].toString(), // what to show
|
||||||
|
compareFn: (item, selectedItem) =>
|
||||||
|
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||||
|
validator: (val) {
|
||||||
|
if (val == null) {
|
||||||
|
return "Required"; // ✅ error message
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
decoratorProps: DropDownDecoratorProps(
|
||||||
|
decoration:
|
||||||
|
AppInputDecorations.dropdownDecoration(
|
||||||
|
label: "Select Endorsement Type",
|
||||||
|
).copyWith(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Color(
|
||||||
|
0xFFEDF6F5,
|
||||||
|
), // 👈 makes the dropdown input white
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
popupProps: PopupProps.menu(
|
||||||
|
fit: FlexFit.loose,
|
||||||
|
constraints: BoxConstraints(maxHeight: 250),
|
||||||
|
menuProps: MenuProps(
|
||||||
|
backgroundColor:
|
||||||
|
Colors.white, // 👈 sets dropdown background to white
|
||||||
|
),
|
||||||
|
showSearchBox: true,
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
hintText: "Search Endorsement Type...",
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
), // 👈 Normal border
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
width: 1.5,
|
||||||
|
), // 👈 Focused border
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// constraints: BoxConstraints(),
|
||||||
|
),
|
||||||
|
|
||||||
|
onChanged: (val) {
|
||||||
|
if (val != null) {
|
||||||
|
print("Selected Endorsement : ${val['endorsement_type']}");
|
||||||
|
print("Id: ${val['id']}");
|
||||||
|
selectedEndorsement = val['id'];
|
||||||
|
// controllers['agentId']?.text = val['agent_code'];
|
||||||
|
// agentId = agent['id'];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildPolicyNumber(context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Endorsement Number *", style: _textStyle),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
ThemedFormField(
|
||||||
|
backgroundColor: Color(0xFFEDF6F5),
|
||||||
|
controller: controllers['endorsement_no']!,
|
||||||
|
validator: (value) => Validators.requiredField(value, "endorsement_no"),
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9\-_]')),
|
||||||
|
],
|
||||||
|
txtwidth: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
// keyboardType: TextInputType.multiline,
|
||||||
|
// txtheight: 45,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildStatusDropdown(context) {
|
||||||
|
// Find the selected item from the static list based on your variable
|
||||||
|
Map<String, dynamic> selectedEndorsementST = statusOptions.firstWhere(
|
||||||
|
(item) => item['status_value'].toString() == selectedStatus,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Status *", style: _textStyle),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
width: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
|
// Use a unique key for this dropdown
|
||||||
|
key: const ValueKey("statusDropdown"),
|
||||||
|
selectedItem: selectedEndorsementST.isNotEmpty
|
||||||
|
? selectedEndorsementST
|
||||||
|
: null,
|
||||||
|
items: (filter, infiniteScrollProps) {
|
||||||
|
return statusOptions; // Use the static list
|
||||||
|
},
|
||||||
|
itemAsString: (val) => val['status_value'].toString(),
|
||||||
|
compareFn: (item, selectedItem) =>
|
||||||
|
item['status_value'] == selectedItem['status_value'],
|
||||||
|
|
||||||
|
// --- REQUIRED VALIDATOR ---
|
||||||
|
validator: (val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return "Required";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
decoratorProps: DropDownDecoratorProps(
|
||||||
|
decoration: AppInputDecorations.dropdownDecoration(
|
||||||
|
label: "Select Status",
|
||||||
|
).copyWith(
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color(0xFFEDF6F5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
popupProps: PopupProps.menu(
|
||||||
|
fit: FlexFit.loose,
|
||||||
|
constraints: const BoxConstraints(maxHeight: 150), // Shorter for 2 items
|
||||||
|
menuProps: const MenuProps(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
showSearchBox: true, // Disabled search as there are only 2 items
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
hintText: "Search Status...",
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
), // 👈 Normal border
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
width: 1.5,
|
||||||
|
), // 👈 Focused border
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
onChanged: (val) {
|
||||||
|
if (val != null) {
|
||||||
|
setState(() {
|
||||||
|
print("Selected Status: ${val['status_value']}");
|
||||||
|
selectedStatus = val['status_value'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildEndrosRemarks(context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Remarks *", style: _textStyle),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
ThemedFormField(
|
||||||
|
backgroundColor: Color(0xFFEDF6F5),
|
||||||
|
controller: controllers['remarks']!,
|
||||||
|
validator: (value) => Validators.requiredField(value, "remarks"),
|
||||||
|
txtwidth: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
// keyboardType: TextInputType.multiline,
|
||||||
|
// txtheight: 45,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildUploadDocumentEndorsment(context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Upload Document", style: _textStyle),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
ThemedUploadField(
|
||||||
|
backgroundColor: Color(0xFFEDF6F5),
|
||||||
|
hintText: selectedFileNames ?? "Upload Document",
|
||||||
|
txtwidth: ResponsiveLayout.isMobile(context)
|
||||||
|
? null
|
||||||
|
: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
onFileSelected: (fileName, file) {
|
||||||
|
setState(() {
|
||||||
|
docUploadedFile = file; // This 'file' is a PlatformFile
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
// children: [
|
||||||
|
// ThemedUploadField(
|
||||||
|
// hintText: selectedFileNames ?? "Upload Document",
|
||||||
|
// txtwidth: MediaQuery.of(context).size.width * 0.26,
|
||||||
|
// onFileSelected: (fileName, file) {
|
||||||
|
// print("Picked file: $fileName (${file.size} bytes)");
|
||||||
|
// setState(() {
|
||||||
|
// docUploadedEndorsFile = file;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// // const SizedBox(height: 5),
|
||||||
|
// //
|
||||||
|
// // if (docUploadedFile != null || passportEndorsFileUrlFromApi != null)
|
||||||
|
// // Container(
|
||||||
|
// // // color: Colors.white,
|
||||||
|
// // child: Row(
|
||||||
|
// // children: [
|
||||||
|
// //
|
||||||
|
// // GestureDetector(
|
||||||
|
// // onTap: () => apiService.downloadFile(
|
||||||
|
// // apiUrl:
|
||||||
|
// // 'api/agent/downloadAgentCertificateFile?agent_id=$selectedEndorsId',
|
||||||
|
// // apiId: selectedEndorsId,
|
||||||
|
// // localFile: docUploadedFile,
|
||||||
|
// // fileName: selectedFileNames,
|
||||||
|
// // ),
|
||||||
|
// // child: Container(
|
||||||
|
// // padding: const EdgeInsets.all(5),
|
||||||
|
// // decoration: BoxDecoration(
|
||||||
|
// // borderRadius: BorderRadius.circular(5),
|
||||||
|
// // color: Color(0xFF425B5B),
|
||||||
|
// // // color: Colors.green.shade300,
|
||||||
|
// // ),
|
||||||
|
// // child: Row(
|
||||||
|
// // children: const [
|
||||||
|
// // Text(
|
||||||
|
// // "Download",
|
||||||
|
// // style: TextStyle(
|
||||||
|
// // fontSize: 12,
|
||||||
|
// // fontWeight: FontWeight.w200,
|
||||||
|
// // color: Colors.white,
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// // SizedBox(width: 5),
|
||||||
|
// // Icon(Icons.download, size: 13, color: Colors.white),
|
||||||
|
// // ],
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// // ],
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static final TextStyle _textStyle = TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
);
|
||||||
|
static final TextStyle _textStyle1 = TextStyle(
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _dataBold = GoogleFonts.inter(
|
||||||
|
fontSize: 11,
|
||||||
|
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Color(0xFF000000),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _dataSub = GoogleFonts.inter(
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
color: Color(0xFF585757),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _headerStyle = GoogleFonts.poppins(
|
||||||
|
fontSize: 11.2,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Color(0xFF1E293B),
|
||||||
|
);
|
||||||
|
static final _cardheaderStyle = GoogleFonts.inter(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 12,
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _cardBodyStyle = GoogleFonts.inter(
|
||||||
|
color: const Color(0xFF545454),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 12,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import '../../../themes/indicators/export_btn.dart';
|
|||||||
import '../../../themes/indicators/search_field_theme.dart';
|
import '../../../themes/indicators/search_field_theme.dart';
|
||||||
import '../../../widgets/custom_action_popup.dart';
|
import '../../../widgets/custom_action_popup.dart';
|
||||||
import '../enquiry/policy_popup.dart';
|
import '../enquiry/policy_popup.dart';
|
||||||
|
import '../enquiry/updateEndorsementDialog.dart';
|
||||||
|
|
||||||
class endosement extends ConsumerStatefulWidget {
|
class endosement extends ConsumerStatefulWidget {
|
||||||
const endosement({super.key});
|
const endosement({super.key});
|
||||||
@ -128,6 +129,12 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
return (item['reg_no'] ?? '-').toLowerCase().contains(
|
return (item['reg_no'] ?? '-').toLowerCase().contains(
|
||||||
query.toLowerCase(),
|
query.toLowerCase(),
|
||||||
) ||
|
) ||
|
||||||
|
(item['policy_from'] ?? '-').toLowerCase().contains(
|
||||||
|
query.toLowerCase(),
|
||||||
|
) ||
|
||||||
|
(item['status'] ?? '-').toLowerCase().contains(
|
||||||
|
query.toLowerCase(),
|
||||||
|
) ||
|
||||||
(item['insurer_short_name'] ?? '-').toLowerCase().contains(
|
(item['insurer_short_name'] ?? '-').toLowerCase().contains(
|
||||||
query.toLowerCase(),
|
query.toLowerCase(),
|
||||||
) ||
|
) ||
|
||||||
@ -176,6 +183,30 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> fetchEndorsementExcelReport() async {
|
||||||
|
final response = await apiService.generateEndorsementExcel(managerId);
|
||||||
|
// Map your controllers and IDs to the API parameters
|
||||||
|
// final String fromDate = controllers['startDate']!.text; // "11-01-2025"
|
||||||
|
// final String toDate = controllers['endDate']!.text; // "20-01-2025"
|
||||||
|
// print("fetchPolicyExcelReport function called here.");
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// // Assuming you have a generic _makeGetRequest method
|
||||||
|
// final response = await apiService.fetchPolicyExcel(managerId,fromDate,toDate);
|
||||||
|
//
|
||||||
|
// if (response != null && response['status'] == 200) {
|
||||||
|
// setState(() {
|
||||||
|
// // Store the list of data in your variable
|
||||||
|
// excelResponseData = response['data'];
|
||||||
|
// });
|
||||||
|
// print("Data fetched. Ready to export.");
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// debugPrint("Export Error: $e");
|
||||||
|
// print("Failed to fetch report data.");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MainLayout(
|
return MainLayout(
|
||||||
@ -266,31 +297,60 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
|
Tooltip(
|
||||||
ExportBtn(
|
message: 'Export Excel',
|
||||||
sheetName: "Endorsement",
|
child: InkWell(
|
||||||
fileName: "endorsement_list",
|
onTap: () async {
|
||||||
data: filteredData,
|
await fetchEndorsementExcelReport();
|
||||||
txt: !ResponsiveLayout.isMobile(context)
|
},
|
||||||
? true
|
child: Container(
|
||||||
: false,
|
padding: const EdgeInsets.all(7.0),
|
||||||
displayHeaders: [
|
decoration: BoxDecoration(
|
||||||
"S.No.",
|
color: const Color(0xFF2E7D6E),
|
||||||
"Vehicle.No.",
|
// color: const Color(0xFF425B5B),
|
||||||
"Insurer",
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
"Policy No.",
|
),
|
||||||
"Endorsement Type",
|
child: Row(
|
||||||
"Endorsement No.",
|
mainAxisSize: MainAxisSize.min,
|
||||||
],
|
children: [
|
||||||
keys: [
|
Image.asset(
|
||||||
"sno", // handled internally as i + 1
|
"assets/miscellaneous/export.png",
|
||||||
"reg_no",
|
height: 13,
|
||||||
"insurer_short_name",
|
width: 13,
|
||||||
"policy_number",
|
),
|
||||||
"endorsement_type_value",
|
|
||||||
"endorsement_no",
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// ExportBtn(
|
||||||
|
// sheetName: "Endorsement",
|
||||||
|
// fileName: "endorsement_list",
|
||||||
|
// data: filteredData,
|
||||||
|
// txt: !ResponsiveLayout.isMobile(context)
|
||||||
|
// ? true
|
||||||
|
// : false,
|
||||||
|
// displayHeaders: [
|
||||||
|
// "S.No.",
|
||||||
|
// "Policy From.",
|
||||||
|
// "Status",
|
||||||
|
// "Vehicle.No.",
|
||||||
|
// "Insurer",
|
||||||
|
// "Policy No.",
|
||||||
|
// "Endorsement Type",
|
||||||
|
// "Endorsement No.",
|
||||||
|
// ],
|
||||||
|
// keys: [
|
||||||
|
// "sno", // handled internally as i + 1
|
||||||
|
// "policy_from",
|
||||||
|
// "status",
|
||||||
|
// "reg_no",
|
||||||
|
// "insurer_short_name",
|
||||||
|
// "policy_number",
|
||||||
|
// "endorsement_type_value",
|
||||||
|
// "endorsement_no",
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -392,6 +452,14 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text('S.No.', style: _headerStyle),
|
child: Text('S.No.', style: _headerStyle),
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text('Policy.From.', style: _headerStyle),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text('Status.', style: _headerStyle),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text('Vehicle.No.', style: _headerStyle),
|
child: Text('Vehicle.No.', style: _headerStyle),
|
||||||
@ -418,10 +486,10 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
style: _headerStyle,
|
style: _headerStyle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Expanded(
|
Expanded(
|
||||||
// flex: 1,
|
flex: 1,
|
||||||
// child: Text('Action', style: _headerStyle),
|
child: Text('Action', style: _headerStyle),
|
||||||
// ),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -515,6 +583,20 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(flex: 2, child: Text('$sno' ?? '-', style: _dataBold)),
|
Expanded(flex: 2, child: Text('$sno' ?? '-', style: _dataBold)),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
item['policy_from'] ?? '-',
|
||||||
|
style: _dataBold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
item['status'] ?? '-',
|
||||||
|
style: _dataBold,
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -522,6 +604,13 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
style: _dataBold,
|
style: _dataBold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
item['endorsement_type_value'] ?? '-',
|
||||||
|
style: _dataBold,
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -545,6 +634,62 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text(item['endorsement_no'] ?? '-', style: _dataBold),
|
child: Text(item['endorsement_no'] ?? '-', style: _dataBold),
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: item['is_active'] == "1"
|
||||||
|
? Row(
|
||||||
|
children: [
|
||||||
|
Tooltip(
|
||||||
|
message: 'Edit',
|
||||||
|
child: IconButton(
|
||||||
|
icon: Image.asset(
|
||||||
|
"assets/miscellaneous/Edit.png",
|
||||||
|
height: 12,
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
|
// onPressed: () {
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) => UpdateEndorsementDialog(
|
||||||
|
// item: item, // Passing the whole row map
|
||||||
|
// userId: userId,
|
||||||
|
// onSubmit: (val) => refresh(),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
onPressed: () {
|
||||||
|
// Ensure we are using the correct context
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true, // Allows clicking outside to close
|
||||||
|
builder: (BuildContext dialogContext) {
|
||||||
|
return UpdateEndorsementDialog(
|
||||||
|
item: item,
|
||||||
|
userId: userId,
|
||||||
|
managerId: managerId,
|
||||||
|
onSubmit: (val) => refresh(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
splashRadius: 28,
|
||||||
|
hoverColor: Colors.black12,
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
"assets/miscellaneous/Edit_muted.png",
|
||||||
|
height: 12,
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
// Expanded(
|
// Expanded(
|
||||||
// flex: 1,
|
// flex: 1,
|
||||||
// child: Row(
|
// child: Row(
|
||||||
@ -621,6 +766,43 @@ class endosementState extends ConsumerState<endosement> {
|
|||||||
),
|
),
|
||||||
const Divider(color: Color(0xffD9EBE8), thickness: 0.8),
|
const Divider(color: Color(0xffD9EBE8), thickness: 0.8),
|
||||||
|
|
||||||
|
// Policy From + Status
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
//date and time
|
||||||
|
Text("policy From", style: _cardheaderStyle),
|
||||||
|
Text(
|
||||||
|
item['policy_from'] ?? '-',
|
||||||
|
style: _cardBodyStyle,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
//remarks
|
||||||
|
Text("Status", style: _cardheaderStyle),
|
||||||
|
Text(
|
||||||
|
item['status'] ?? '-',
|
||||||
|
style: _cardBodyStyle,
|
||||||
|
maxLines: 3,
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
|
||||||
// Company + Vehicle Reg No
|
// Company + Vehicle Reg No
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
|||||||
@ -86,31 +86,57 @@ class BrokerListState extends ConsumerState<BrokerList> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void filterData(String query) {
|
void filterData(String query) {
|
||||||
setState(() {
|
setState(() {
|
||||||
final q = query.toLowerCase();
|
final q = query.toLowerCase().trim();
|
||||||
|
|
||||||
if (q.isEmpty) {
|
if (q.isEmpty) {
|
||||||
filteredData = getBrokerData;
|
filteredData = List.from(getBrokerData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredData = getBrokerData.where((item) {
|
filteredData = getBrokerData.where((item) {
|
||||||
final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
|
final name =
|
||||||
|
(item['name'] ?? '').toString().toLowerCase();
|
||||||
|
final code =
|
||||||
|
(item['short_name'] ?? '').toString().toLowerCase();
|
||||||
|
final status =
|
||||||
|
item['is_active'] == "1" ? "active" : "inactive";
|
||||||
|
|
||||||
return (item['name'] ?? '').toString().toLowerCase().contains(q) ||
|
return name.contains(q) ||
|
||||||
(item['email'] ?? '').toString().toLowerCase().contains(q) ||
|
code.contains(q) ||
|
||||||
(item['mobile'] ?? '').toString().toLowerCase().contains(q) ||
|
status.contains(q);
|
||||||
(item['address'] ?? '').toString().toLowerCase().contains(q) ||
|
|
||||||
(item['emp_id'] ?? item['agent_code'] ?? '')
|
|
||||||
.toString()
|
|
||||||
.toLowerCase()
|
|
||||||
.contains(q) ||
|
|
||||||
isActiveStatus.contains(q);
|
|
||||||
}).toList();
|
}).toList();
|
||||||
|
// currentPage = 1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void filterData(String query) {
|
||||||
|
// setState(() {
|
||||||
|
// final q = query.toLowerCase();
|
||||||
|
//
|
||||||
|
// if (q.isEmpty) {
|
||||||
|
// filteredData = getBrokerData;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// filteredData = getBrokerData.where((item) {
|
||||||
|
// final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
|
||||||
|
//
|
||||||
|
// return (item['name'] ?? '').toString().toLowerCase().contains(q) ||
|
||||||
|
// (item['email'] ?? '').toString().toLowerCase().contains(q) ||
|
||||||
|
// (item['mobile'] ?? '').toString().toLowerCase().contains(q) ||
|
||||||
|
// (item['address'] ?? '').toString().toLowerCase().contains(q) ||
|
||||||
|
// (item['emp_id'] ?? item['agent_code'] ?? '')
|
||||||
|
// .toString()
|
||||||
|
// .toLowerCase()
|
||||||
|
// .contains(q) ||
|
||||||
|
// isActiveStatus.contains(q);
|
||||||
|
// }).toList();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
final TextEditingController _searchStaffController = TextEditingController();
|
final TextEditingController _searchStaffController = TextEditingController();
|
||||||
|
|
||||||
Future<void> getBroker() async {
|
Future<void> getBroker() async {
|
||||||
|
|||||||
@ -311,6 +311,28 @@ class EndorsementTypeState extends ConsumerState<EndorsementType> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildPolicyFrom() {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Policy Type *", style: _textStyle),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
SizedBox(
|
||||||
|
child: ThemedFormInlineField(
|
||||||
|
controller: controllers['policy_from']!,
|
||||||
|
validator: (value) => Validators.requiredField(value, "policy_from"),
|
||||||
|
txtwidth: MediaQuery.of(context).size.width * 0.15,
|
||||||
|
borderColor: Color(0xFFE2E8F0),
|
||||||
|
highlightColor: Color(0xFF50A398),
|
||||||
|
// txtheight: 30,
|
||||||
|
isdense: true,
|
||||||
|
errFieldHgt: 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static final _textStyle = GoogleFonts.inter(
|
static final _textStyle = GoogleFonts.inter(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@ -144,7 +144,7 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
|
|||||||
try {
|
try {
|
||||||
final response = await apiService.fetchAttndanceOFAllStaffList(
|
final response = await apiService.fetchAttndanceOFAllStaffList(
|
||||||
month: monthForApi,
|
month: monthForApi,
|
||||||
mangerId: managerId,
|
mangerId: ref.read(managerIdProvider),
|
||||||
// toDate: controllers['endDate']?.text ?? '',
|
// toDate: controllers['endDate']?.text ?? '',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
dynamic role;
|
dynamic role;
|
||||||
|
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
String? selectedSalesExectv;
|
dynamic selectedSalesExectv;
|
||||||
List<Map<String, dynamic>> filteredSalesExecutiveData = [];
|
List<Map<String, dynamic>> filteredSalesExecutiveData = [];
|
||||||
List<Map<String, dynamic>> getSalesExecutiveData = [];
|
List<Map<String, dynamic>> getSalesExecutiveData = [];
|
||||||
|
|
||||||
@ -170,7 +170,10 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
controllers['address']?.text = data['address'] ?? '';
|
controllers['address']?.text = data['address'] ?? '';
|
||||||
controllers['retenRate']?.text = data['retention_rate'] ?? '';
|
controllers['retenRate']?.text = data['retention_rate'] ?? '';
|
||||||
isActive = data["is_active"];
|
isActive = data["is_active"];
|
||||||
selectedSalesExectv = data['sales_executive_id'] ?? '';
|
selectedSalesExectv = data['sales_executive_id'] != null
|
||||||
|
? int.parse(data['sales_executive_id'].toString())
|
||||||
|
: null;
|
||||||
|
|
||||||
print('selectedSalesExectv - $selectedSalesExectv');
|
print('selectedSalesExectv - $selectedSalesExectv');
|
||||||
|
|
||||||
String? apiDocPath = data["certificate_file_name"];
|
String? apiDocPath = data["certificate_file_name"];
|
||||||
@ -205,9 +208,10 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("Debug: current selectedSalesExectv is $selectedSalesExectv");
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
dataDetails();
|
|
||||||
final dataSet = dataDetails();
|
final dataSet = dataDetails();
|
||||||
print("dataSetAgent - $dataSet");
|
print("dataSetAgent - $dataSet");
|
||||||
print("managerId - $managerId ,userId - $userId ");
|
print("managerId - $managerId ,userId - $userId ");
|
||||||
@ -602,6 +606,10 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
ThemedFormField(
|
ThemedFormField(
|
||||||
controller: controllers['name']!,
|
controller: controllers['name']!,
|
||||||
validator: (value) => Validators.requiredField(value, "name"),
|
validator: (value) => Validators.requiredField(value, "name"),
|
||||||
|
inputFormatters: [
|
||||||
|
// This line now allows letters, numbers, hyphens, and underscores
|
||||||
|
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9\-_]')),
|
||||||
|
],
|
||||||
borderColor: Color(0xFFE2E8F0),
|
borderColor: Color(0xFFE2E8F0),
|
||||||
highlightColor: Color(0xFF50A398),
|
highlightColor: Color(0xFF50A398),
|
||||||
txtwidth: MediaQuery.of(context).size.width * 0.18,
|
txtwidth: MediaQuery.of(context).size.width * 0.18,
|
||||||
@ -872,17 +880,11 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
// constraints: BoxConstraints(),
|
// constraints: BoxConstraints(),
|
||||||
),
|
),
|
||||||
|
|
||||||
onChanged: widget.id != null
|
onChanged: (val) {
|
||||||
? null
|
setState(() {
|
||||||
: (val) {
|
selectedSalesExectv = val?['id']?.toString();
|
||||||
if (val != null) {
|
});
|
||||||
print("Selected Role : ${val['role']}");
|
print("UI Updated with ID: $selectedSalesExectv");
|
||||||
print("Id: ${val['id']}");
|
|
||||||
selectedSalesExectv = val['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// controllers['agentId']?.text = val['agent_code'];
|
|
||||||
// agentId = agent['id'];
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -147,9 +147,9 @@ class _DashboardState extends ConsumerState<PartnerDashboard> {
|
|||||||
if (data is Map<String, dynamic>) {
|
if (data is Map<String, dynamic>) {
|
||||||
setState(() {
|
setState(() {
|
||||||
// agents_performance Policy
|
// agents_performance Policy
|
||||||
if (data['monthlyPolicyCount'] != null) {
|
if (data['agentsPerformanceList'] != null) {
|
||||||
agentsPerformanceList = List<Map<String, dynamic>>.from(
|
agentsPerformanceList = List<Map<String, dynamic>>.from(
|
||||||
(data['monthlyPolicyCount'] as List).map(
|
(data['agentsPerformanceList'] as List).map(
|
||||||
(item) => Map<String, dynamic>.from(item),
|
(item) => Map<String, dynamic>.from(item),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -163,17 +163,17 @@ class _DashboardState extends ConsumerState<PartnerDashboard> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data['noPolicyTimeRange'] != null) {
|
if (data['nonAgentsPerformanceList'] != null) {
|
||||||
nonAgentsPerformanceList = List<Map<String, dynamic>>.from(
|
nonAgentsPerformanceList = List<Map<String, dynamic>>.from(
|
||||||
(data['noPolicyTimeRange'] as List).map(
|
(data['nonAgentsPerformanceList'] as List).map(
|
||||||
(item) => Map<String, dynamic>.from(item),
|
(item) => Map<String, dynamic>.from(item),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} // agents_performance Premium
|
} // agents_performance Premium
|
||||||
|
|
||||||
if (data['below50tPremiumTimeRange'] != null) {
|
if (data['nonAgentsPerformanceListPremium'] != null) {
|
||||||
nonAgentsPerformanceListPremium = List<Map<String, dynamic>>.from(
|
nonAgentsPerformanceListPremium = List<Map<String, dynamic>>.from(
|
||||||
(data['below50tPremiumTimeRange'] as List).map(
|
(data['nonAgentsPerformanceListPremium'] as List).map(
|
||||||
(item) => Map<String, dynamic>.from(item),
|
(item) => Map<String, dynamic>.from(item),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -345,7 +345,7 @@ class _DashboardState extends ConsumerState<PartnerDashboard> {
|
|||||||
InkWell(
|
InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final path =
|
final path =
|
||||||
"PerformingAgentAll50";
|
"PerformingTop50";
|
||||||
final id = '';
|
final id = '';
|
||||||
final month = 'current';
|
final month = 'current';
|
||||||
|
|
||||||
@ -714,7 +714,7 @@ class _PerformanceState extends State<Performance> {
|
|||||||
if (widget.title == 'Performing Partner') ...[
|
if (widget.title == 'Performing Partner') ...[
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final path1 = 'PerformingTop50';
|
final path1 = 'PerformingAgentsByID';
|
||||||
final path2 = widget.isPerfomingAgntPolicy
|
final path2 = widget.isPerfomingAgntPolicy
|
||||||
? "NoBusiness"
|
? "NoBusiness"
|
||||||
: "NonPerformingBelow50K";
|
: "NonPerformingBelow50K";
|
||||||
|
|||||||
@ -190,7 +190,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
"assigned_to": selectedStaff,
|
"assigned_to": selectedStaff,
|
||||||
"insurer_id": selectedInsurer,
|
"insurer_id": selectedInsurer,
|
||||||
"broker_id": selectedBroker,
|
"broker_id": selectedBroker,
|
||||||
"manager_id": managerId,
|
"manager_id": ref.read(managerIdProvider),
|
||||||
"created_by": userId,
|
"created_by": userId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -610,10 +610,11 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
String SelectedStatus = '',
|
String SelectedStatus = '',
|
||||||
String SelectedStaffId = '',
|
String SelectedStaffId = '',
|
||||||
}) async {
|
}) async {
|
||||||
print('DAJJshA72 => Fns called => $managerId | $role');
|
print('A613 => Fns called => $managerId | $role');
|
||||||
setState(() {
|
setState(() {
|
||||||
isLoadingStaffList = true;
|
isLoadingStaffList = true;
|
||||||
});
|
});
|
||||||
|
print('A713 => Fns called => $managerId | $role');
|
||||||
|
|
||||||
dynamic fromDt;
|
dynamic fromDt;
|
||||||
dynamic toDt;
|
dynamic toDt;
|
||||||
@ -625,7 +626,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
if (dashboardKey == 'fromDashboard' && SelectedStatus == "PrevPending") {
|
if (dashboardKey == 'fromDashboard' && SelectedStatus == "PrevPending") {
|
||||||
// For PREV PENDING → set date range until yesterday
|
// For PREV PENDING → set date range until yesterday
|
||||||
final today = DateTime.now();
|
final today = DateTime.now();
|
||||||
|
print('A813 => Fns called => $managerId | $role');
|
||||||
// Change to dd-MM-yyyy
|
// Change to dd-MM-yyyy
|
||||||
final dateFormat = DateFormat('dd-MM-yyyy');
|
final dateFormat = DateFormat('dd-MM-yyyy');
|
||||||
|
|
||||||
@ -640,7 +641,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
SelectedStatus != '') {
|
SelectedStatus != '') {
|
||||||
// For PREV PENDING → set date range until yesterday
|
// For PREV PENDING → set date range until yesterday
|
||||||
final today = DateTime.now();
|
final today = DateTime.now();
|
||||||
|
print('A913 => Fns called => $managerId | $role');
|
||||||
// Change to dd-MM-yyyy
|
// Change to dd-MM-yyyy
|
||||||
final dateFormat = DateFormat('dd-MM-yyyy');
|
final dateFormat = DateFormat('dd-MM-yyyy');
|
||||||
|
|
||||||
@ -652,6 +653,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
fromDateVal == '' &&
|
fromDateVal == '' &&
|
||||||
toDateVal == '') {
|
toDateVal == '') {
|
||||||
print("ENQ LIST PAGE");
|
print("ENQ LIST PAGE");
|
||||||
|
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: 5)));
|
||||||
@ -660,6 +662,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
|
|
||||||
print('Enq FROM TO - $fromDt - $toDt');
|
print('Enq FROM TO - $fromDt - $toDt');
|
||||||
} else {
|
} else {
|
||||||
|
print('A1113 => Fns called => $managerId | $role');
|
||||||
print('Enq 1- $fromDt - $toDt');
|
print('Enq 1- $fromDt - $toDt');
|
||||||
fromDt = fromDateVal;
|
fromDt = fromDateVal;
|
||||||
toDt = toDateVal;
|
toDt = toDateVal;
|
||||||
@ -668,6 +671,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
String finalStatus = SelectedStatus;
|
String finalStatus = SelectedStatus;
|
||||||
print('finalStatus1 - $finalStatus');
|
print('finalStatus1 - $finalStatus');
|
||||||
|
|
||||||
|
print('A1213 => Fns called => $managerId | $role');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await apiService.fetchEnquiryList(
|
final response = await apiService.fetchEnquiryList(
|
||||||
managerId,
|
managerId,
|
||||||
@ -692,6 +697,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
|
|
||||||
print('FromDate : $fromDate');
|
print('FromDate : $fromDate');
|
||||||
print('ToDate : $toDate');
|
print('ToDate : $toDate');
|
||||||
|
print('A1213 => Fns called => $managerId | $role');
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
controllers['startDate']?.text = fromDate;
|
controllers['startDate']?.text = fromDate;
|
||||||
|
|||||||
@ -534,7 +534,7 @@ class policylistState extends ConsumerState<policylist> {
|
|||||||
await fetchPolicyExcelReport();
|
await fetchPolicyExcelReport();
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: const EdgeInsets.all(7.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFF2E7D6E),
|
color: const Color(0xFF2E7D6E),
|
||||||
// color: const Color(0xFF425B5B),
|
// color: const Color(0xFF425B5B),
|
||||||
@ -545,8 +545,8 @@ class policylistState extends ConsumerState<policylist> {
|
|||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Image.asset(
|
||||||
"assets/miscellaneous/export.png",
|
"assets/miscellaneous/export.png",
|
||||||
height: 15,
|
height: 13,
|
||||||
width: 15,
|
width: 13,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user