import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; import 'package:nhance_partner/data/services/auth_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; import '../../data/utils/toastNotification.dart'; import '../../presentation/screens/staff/enquiry_single_page/model/dropdown_option.dart'; import '../../presentation/screens/staff/enquiry_single_page/model/enquiry_model.dart'; import '../config/env.dart'; import 'package:universal_html/html.dart' as html; import 'package:http/http.dart' as http; import '../config/navigation_service.dart'; import '../routing/app_router.dart'; import '../routing/routes.dart'; class ApiService { late final BuildContext context; String? _token; bool _isLoggingOut = false; Future clearLocalStorageAndRedirect() async { if (_isLoggingOut) return; _isLoggingOut = true; await AuthService.clearToken(); final ctx = navigatorKey.currentContext; if (ctx != null) { // ToastHelper.showErrorToast(ctx, 'Session expired'); ctx.go(AppRoutes.login); } else { // fallback (web-safe) appRouter.go(AppRoutes.login); } } Future _initializeToken() async { _token = await AuthService.getToken(); print("APISERTOKEN - $_token"); } // Future clearLocalStorageAndRedirect() async { // // final prefs = await SharedPreferences.getInstance(); // // await prefs.clear(); // // Assuming you have access to the context // ToastHelper.showErrorToast(context, 'Session Out'); // // Navigator.pushNamed(context, 'login'); // AuthService.clearToken(); // context.go(AppRoutes.login); // } Future> _makeGetRequest( Uri url, Map headers, ) async { final response = await http.get(url, headers: headers); return _handleResponse(response); } Future _makeGethttpRequest( Uri url, Map headers, ) async { final response = await http.get(url, headers: headers); if (response.statusCode == 401 || response.statusCode == 403) { await clearLocalStorageAndRedirect(); } return response; } Future> _makePostRequestJson( Uri url, Map body, Map headers, ) async { final response = await http.post( url, headers: headers, body: jsonEncode(body), // ✅ convert to JSON ); return _handleResponse(response); } // --------------------------- COMMON FILES __________________________________________ Future> createUserData(data, path) async { // print('path - $path'); final url = Uri.parse('${Env.apiUrl}$path'); if (_token == null) { await _initializeToken(); } // print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> fetchUploadEnquiryFiles(dynamic enqId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}enquiry/enquiryFiles?enquiry_id=$enqId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> logoutUsingAPI(BuildContext context) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}auth/logout'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // Future> _handleResponse(http.Response response) async { // if (response.statusCode == 200) { // return jsonDecode(response.body); // } else if (response.statusCode == 401 || response.statusCode == 403) { // await clearLocalStorageAndRedirect(); // return {}; // } else { // throw Exception('Failed to load data'); // } // } Future> _handleResponse(http.Response response) async { Map body = {}; try { body = jsonDecode(response.body); } catch (_) {} if (response.statusCode == 200) { return body; } if (response.statusCode == 401 || response.statusCode == 403) { await clearLocalStorageAndRedirect(); throw Exception('Session expired'); } throw Exception('Server Error: ${response.statusCode}'); } Future> softDeletePolicyApi(String policyId) async { // Ensure token is available if (_token == null) { await _initializeToken(); } // Define the endpoint with query parameter final url = Uri.parse('${Env.apiUrl}policy/softdelete?policy_id=$policyId'); final headers = { 'Authorization': 'Bearer $_token', // Removed null-coalesce as _token is checked above 'app-signature': Env.App_Signature, }; // Using your standard helper for consistency and error handling final response = await _makeGetRequest(url, headers); return response; } Future> CheckDuplicate( BuildContext context, String value, ) async { if (_token == null) { await _initializeToken(); } String apiUrldata; final response = await http.get( Uri.parse('${Env.apiUrl}enquiry/checkVehicleDuplicate?reg_no=$value'), headers: { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }, ); if (response.statusCode == 200) { try { final data = json.decode(response.body); // Updated to match actual response structure if (data['status'] == "exists") { final msg = data['message'] ?? "Already exists"; final field = data['field'] ?? ""; // print("$field - $value : $msg"); // print("EXIST REG"); return {"message": msg, "field": field}; } else { print("NOT EXIST REG"); // print("$value : ${data['message'] ?? "is a new value"}"); return {}; } } catch (e) { throw Exception('Error parsing response: $e'); } } else if (response.statusCode == 403) { await clearLocalStorageAndRedirect(); return {}; } else { throw Exception( 'Failed to load checkDuplicate data. Status code: ${response.statusCode}', ); } } Future getPdfDownload1(path, id) async { print('GetDownload'); final url = Uri.parse('${Env.apiUrl}$path'); print('GetDownload - $url'); await _initializeToken(); if (_token == null) { throw Exception('Token not found. Please log in.'); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGethttpRequest(url, headers); if (response.statusCode == 200) { try { print("PDf Dowloaded"); // Create a blob from the response body final blob = html.Blob([response.bodyBytes]); // Generate a download URL for the blob final url = html.Url.createObjectUrlFromBlob(blob); // Create a link element to trigger the download final anchor = html.AnchorElement(href: url) ..setAttribute('download', 'nhancePartner_$id.pdf') ..click(); // Revoke the download URL to free up resources html.Url.revokeObjectUrl(url); } catch (e) { throw Exception('Error parsing response: $e'); } } else if (response.statusCode == 404) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('File not found.'), // content: Text('File not found.'), actions: [ TextButton( child: Text('OK'), onPressed: () { Navigator.of(context).pop(); // Close the dialog }, ), ], ); }, ); } else { throw Exception('Failed to load plans'); } } String extractFileName(String? contentDisposition, String fallback) { if (contentDisposition == null) return fallback; // Check for extended filename first (RFC 5987) final filenameStarMatch = RegExp( r'filename\*\s*=\s*([^;]+)', ).firstMatch(contentDisposition); if (filenameStarMatch != null) { String value = filenameStarMatch.group(1)!; // Remove UTF-8'' prefix if exists value = value.replaceAll(RegExp(r"UTF-8''"), ''); return Uri.decodeFull(value.replaceAll('"', '')); } // Fallback to regular filename= final filenameMatch = RegExp( r'filename\s*=\s*"?([^";]+)"?', ).firstMatch(contentDisposition); if (filenameMatch != null) { return filenameMatch.group(1)!; } // Fallback: use the provided fallback string return fallback; } Future getPdfDownload( // BuildContext context, String path, String id, ) async { print('Sa - getPdfDownload - $path'); // if (path.isEmpty) { // ToastHelper.showInfoToast(context, 'No file path found.'); // return; // } final url = Uri.parse('${Env.apiUrl}$path'); // final url = Uri.parse('${Env.apiUrl}$path'); print('Sb - getPdfDownload - $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('Sc - getPdfDownload - $blobUrl'); // --- filename resolution --- // String fileName = 'download_$id'; // print('getPdfDownloadfileName $fileName'); // final contentDisp = response.headers['content-disposition']; // print('getPdfDownloadcontentDisp $contentDisp'); // if (contentDisp != null && contentDisp.contains('filename=')) { // print('getPdfDownloadcontentDisp..1'); // fileName = contentDisp.split('filename=')[1].replaceAll('"', ''); // print('getPdfDownloadcontentDisp..2'); // } else { // print('getPdfDownloadcontentDisp..3'); // // fallback: URL or id // fileName = path.split('/').last; // if (id != null) fileName = '${id}_$fileName'; // } final contentDisp = response.headers['content-disposition']; print('Sd getPdfDownloadcontentDisp $contentDisp'); String fileName = extractFileName(contentDisp, path.split('/').last); print('Se 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('Sf 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 generateChartExcel( // BuildContext context, String path, String id, String month, dynamic managerId, {DateTime? toDate, DateTime? fromDate} ) async { print('Sq getxl 1 - $path'); print('Sq toDate - $toDate'); print('Sq fromDate - $fromDate'); 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') { pathVal = 'dashboard/downloadExcelInsurer?manager_id=$managerId&month=$month&insurer_id=$id'; } else if (path == 'Broker') { pathVal = 'dashboard/downloadExcelBroker?manager_id=$managerId&month=$month&broker_id=$id'; } else if (path == 'Product') { pathVal = 'dashboard/downloadExcelProduct?manager_id=$managerId&month=$month&vehicle_type=$id'; } else if (path == 'PerformingTop50') { pathVal = 'dashboard/downloadExcelPerformingAgentsTop50?manager_id=$managerId'; } else if (path == 'PerformingAgentsByID') { pathVal = 'dashboard/downloadExcelPerformingAgentsByID?manager_id=$managerId&agent_id=$id'; } else if (path == 'NonPerformingBelow50K') { pathVal = 'dashboard/downloadExcelLowPremium?manager_id=$managerId'; } else if (path == 'staff_pending_summary') { pathVal = 'dashboard/downloadExcelStaffPendingSummary?manager_id=$managerId'; } else if (path == 'staff_pending_summary_by_id') { pathVal = 'dashboard/downloadExcelStaffPendingSummaryByID?manager_id=$managerId&staff_id=$id&status=$month'; } else { //NoBusiness pathVal = 'dashboard/downloadExcelWithoutPolicies?manager_id=$managerId'; } if (fromDate != null && toDate != null) { final from = DateFormat('dd-MM-yyyy').format(fromDate); final to = DateFormat('dd-MM-yyyy').format(toDate); pathVal += '&from_date=$from&to_date=$to'; } // print('Final Excel URL => $pathVal'); final url = Uri.parse('${Env.apiUrl}$pathVal'); // original print('sq1 2 - $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('sq1 3 $blobUrl'); final contentDisp = response.headers['content-disposition']; print('getPdfDownloadcontentDisp $contentDisp'); String fileName = extractFileName(contentDisp, path.split('/').last); print('sq 4 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('sq 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 generatePerformanceDashboardExcel( // BuildContext context, String path, String id, String salesId, String month, dynamic managerId, ) async { print('sm 1 - $path'); dynamic pathVal; pathVal = 'dashboard/downloadExcelStaffAndProduct?manager_id=$managerId&month=$month&sales_executive_id=$salesId&vehicle_type=$id'; final url = Uri.parse('${Env.apiUrl}$pathVal'); print('sm 2 - $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('sm 3 $blobUrl'); final contentDisp = response.headers['content-disposition']; print('sm4 $contentDisp'); String fileName = extractFileName(contentDisp, path.split('/').last); print('sm 5 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('smno 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 downloadFile({ required String? apiUrl, required PlatformFile? localFile, required String? fileName, String? apiId, // optional if your API needs it }) async { try { if (localFile != null) { if (kIsWeb) { final blob = html.Blob([localFile.bytes!]); final url = html.Url.createObjectUrlFromBlob(blob); final anchor = html.AnchorElement(href: url) ..setAttribute('download', localFile.name) ..click(); html.Url.revokeObjectUrl(url); print("Download triggered successfully (web)!"); } else { print("Local file path: ${localFile.path}"); // await OpenFilex.open(localFile.path!); } } else if (apiUrl != null) { print("Download from API: $apiUrl"); print("Download from API: $apiId!"); await getPdfDownload(apiUrl, apiId!); } else { print("⚠️ No file available to download"); } } catch (e) { print("Error during download: $e"); } } Future> updateStatus(id, status, role) async { print('updateStatusupdateStatus'); final Map data = { "id": int.parse(id), "is_active": int.parse(status), }; final url; if (role == 'salesExecutive') { url = Uri.parse('${Env.apiUrl}salesExecutive/changeExecutiveStatus'); } else if (role == 'staff') { url = Uri.parse('${Env.apiUrl}staff/changeStaffStatus'); } else { url = Uri.parse('${Env.apiUrl}agent/changeAgentStatus'); } // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> updateStatusMasters( id, status, masterName, userId, ) async { print('updateStatusMaster $id $status $masterName $userId'); final Map data = { "is_active": int.parse(status), "updated_by": userId, }; final url; if (masterName == 'Broker') { url = Uri.parse('${Env.apiUrl}master/updateBrokerStatus/$id'); } else if (masterName == 'EndorsementType') { url = Uri.parse('${Env.apiUrl}master/updateEndorsementStatus/$id'); } else if (masterName == 'VehicleType') { url = Uri.parse('${Env.apiUrl}master/updateVehicleTypeStatus/$id'); } else if (masterName == 'Insurer') { url = Uri.parse('${Env.apiUrl}master/updateInsurerStatus/$id'); } else { url = Uri.parse('${Env.apiUrl}master/updatePaymentModeStatus/$id'); } // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } // ----------------------------------- Staff Level Count ------------------------------------------------- Future> fetchStaffLevelCount(id, userId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url; url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id&staff_id=$userId'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- Dashboard ------------------------------------------------- Future> fetchDashboard(int id, role, userId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url; if (role == 'manager') { url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id'); } else if (role == 'handler') { url = Uri.parse( '${Env.apiUrl}dashboard/handlerDashboard?manager_id=$id&handler_id=$userId', ); } else if (role == 'staff') { url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$userId'); } else { url = Uri.parse('${Env.apiUrl}dashboard/agentDashboard?agent_id=$userId'); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findBusinessDashboardData(id, broker) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}dashboard/businessDashboard?manager_id=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findPartnerDashboardData(id, fromDate,toDate) async { // print(_token); if (_token == null) { await _initializeToken(); } late Uri url; /// ✅ CASE 1: fromDate OR toDate is null → normal API if (fromDate == null || toDate == null) { url = Uri.parse( '${Env.apiUrl}dashboard/partnerDashboard?manager_id=$id', ); } /// ✅ CASE 2: both dates present → filtered API else { final from = DateFormat('dd-MM-yyyy').format(fromDate); final to = DateFormat('dd-MM-yyyy').format(toDate); url = Uri.parse( '${Env.apiUrl}dashboard/partnerDashboard' '?manager_id=$id' '&from_date=$from' '&to_date=$to', ); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findProductivityDashboardData(id, broker) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}dashboard/productivityDashboard?manager_id=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // -------------------------------- AGENT ---------------------------------------------- Future> fetchAgentIncentiveList( dynamic agentId, { String type = 'incentive', }) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}agent/agentIncentiveFileList?agent_id=$agentId&type=$type', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchGridFileList() async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}grid/fileList'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- PAYOUT GRID ---------------------------------------------- Future> loadPayoutGrid({ String? role, String? fileId, String? insurer, String? vehicleType, String? segment, String? rto, String? search, String? loggedId, }) async { if (_token == null) { await _initializeToken(); } final roleTrimmed = role?.trim(); final fileIdTrimmed = fileId?.trim(); final insurerTrimmed = insurer?.trim(); final vehicleTypeTrimmed = vehicleType?.trim(); final segmentTrimmed = segment?.trim(); final rtoTrimmed = rto?.trim(); final searchTrimmed = search?.trim(); final loggedIdTrimmed = loggedId?.trim(); final endpoint = Uri.parse('${Env.apiUrl}grid'); // final endpoint = Uri.parse('http://localhost/nhance_partner_be/grid'); final roleLower = roleTrimmed?.toLowerCase(); final queryParameters = {}; if (roleTrimmed != null && roleTrimmed.isNotEmpty) { queryParameters['role'] = roleTrimmed; } if (roleLower != 'agent' && fileIdTrimmed != null && fileIdTrimmed.isNotEmpty) { queryParameters['file_id'] = fileIdTrimmed; } if (insurerTrimmed != null && insurerTrimmed.isNotEmpty) { queryParameters['insurer'] = insurerTrimmed; } if (vehicleTypeTrimmed != null && vehicleTypeTrimmed.isNotEmpty) { queryParameters['vehicle_type'] = vehicleTypeTrimmed; } if (segmentTrimmed != null && segmentTrimmed.isNotEmpty) { queryParameters['segment'] = segmentTrimmed; } if (rtoTrimmed != null && rtoTrimmed.isNotEmpty) { queryParameters['rto'] = rtoTrimmed; } if (searchTrimmed != null && searchTrimmed.isNotEmpty) { queryParameters['search'] = searchTrimmed; } if (loggedIdTrimmed != null && loggedIdTrimmed.isNotEmpty) { queryParameters['logged_id'] = loggedIdTrimmed; } final url = endpoint.replace(queryParameters: queryParameters); final headers = { 'Authorization': 'Bearer ${_token ?? ''}', 'app-signature': Env.App_Signature, }; return await _makeGetRequest(url, headers); } Future downloadGridExcel({ String? role, String? fileId, String? insurer, String? vehicleType, String? segment, String? rto, String? search, String? loggedId, }) async { if (_token == null) { await _initializeToken(); } final endpoint = Uri.parse('${Env.apiUrl}grid/download'); final queryParameters = {}; void addQuery(String key, String? value) { final v = value?.trim(); if (v != null && v.isNotEmpty) { queryParameters[key] = v; } } final downloadRoleLc = role?.trim().toLowerCase(); addQuery('role', role); // Manager / Accounts use file_id; Agent uses logged_id only (same as loadPayoutGrid). if (downloadRoleLc != 'agent') { addQuery('file_id', fileId); } addQuery('insurer', insurer); addQuery('vehicle_type', vehicleType); addQuery('segment', segment); addQuery('rto', rto); addQuery('search', search); addQuery('logged_id', loggedId); final url = endpoint.replace(queryParameters: queryParameters); final headers = { 'Authorization': 'Bearer ${_token ?? ''}', 'app-signature': Env.App_Signature, }; final response = await _makeGethttpRequest(url, headers); if (response.statusCode != 200) { throw Exception('Failed to download grid excel'); } final contentType = response.headers['content-type'] ?? ''; if (contentType.contains('application/json')) { throw Exception('No export data available for selected filters'); } final blob = html.Blob([response.bodyBytes]); final blobUrl = html.Url.createObjectUrlFromBlob(blob); final fileName = extractFileName( response.headers['content-disposition'], 'grid_export.xlsx', ); html.AnchorElement(href: blobUrl) ..setAttribute('download', fileName) ..click(); html.Url.revokeObjectUrl(blobUrl); } Future> fetchManagerIncentiveList(mangerId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}staff/managerIncentiveFileList?manager_id=$mangerId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchAgentUserList(int managerId) async { // print(_token); if (_token == null) { await _initializeToken(); } final userId = '1'; final url = Uri.parse( '${Env.apiUrl}agent/agentList?manager_id=${managerId}', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future downloadAgentRetentionRateExcel() async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}agent/exportRetentionRateExcel'); final headers = { 'Authorization': 'Bearer ${_token ?? ''}', 'app-signature': Env.App_Signature, }; final response = await _makeGethttpRequest(url, headers); if (response.statusCode != 200) { throw Exception('Failed to download retention rate excel'); } final contentType = response.headers['content-type'] ?? ''; if (contentType.contains('application/json')) { throw Exception('No export data available'); } final blob = html.Blob([response.bodyBytes]); final blobUrl = html.Url.createObjectUrlFromBlob(blob); final fileName = extractFileName( response.headers['content-disposition'], 'RentationRate.xlsx', ); html.AnchorElement(href: blobUrl) ..setAttribute('download', fileName) ..click(); html.Url.revokeObjectUrl(blobUrl); } Future> importAgentRetentionRateExcel({ required PlatformFile file, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}agent/importRetentionRateExcel'); try { final request = http.MultipartRequest('POST', url); request.headers.addAll({ 'Authorization': 'Bearer ${_token ?? ''}', 'app-signature': Env.App_Signature, }); if (file.bytes == null) { throw Exception('Could not read selected file'); } request.files.add( http.MultipartFile.fromBytes( 'retention_excel', file.bytes!, filename: file.name, ), ); // Backward/forward compatibility: // some backend versions expect `retention_rate_excel`. request.files.add( http.MultipartFile.fromBytes( 'retention_rate_excel', file.bytes!, filename: file.name, ), ); final streamedResponse = await request.send(); final responseBody = await streamedResponse.stream.bytesToString(); if (streamedResponse.statusCode == 401 || streamedResponse.statusCode == 403) { await clearLocalStorageAndRedirect(); return {'status': 'error', 'message': 'Session expired'}; } if (responseBody.trim().isEmpty) { return { 'status': 'error', 'message': 'Empty response from server', 'code': streamedResponse.statusCode, }; } final decoded = jsonDecode(responseBody); if (decoded is Map) { return decoded; } return {'status': 'error', 'message': 'Unexpected response format'}; } catch (e) { return {'status': 'error', 'message': e.toString()}; } } Future> findSingleAgentData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } // final url = Uri.parse('${Env.apiUrl}agent/agentList'); final url = Uri.parse('${Env.apiUrl}agent/findAgent?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchPartnerVehicleTypes() async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}agent/partnerVehicleTypeList'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } Future> updateAgentVehicleRetention({ required String agentId, required String vehicleTypeId, required String segmentId, required String retentionRate, required String updatedBy, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}agent/updateAgentVehicleRetention'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final body = { 'agent_id': agentId, 'vehicle_type_id': vehicleTypeId, 'segment_id': segmentId, 'retention_rate': retentionRate, 'updated_by': updatedBy, }; return _makePostRequestJson(url, body, headers); } /// Bulk upsert retention rows for an agent (Save all in retention table). Future> saveAgentRetentionRatesBulk({ required String agentId, required List> retentionRates, required String updatedBy, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}agent/saveAgentRetentionRatesBulk'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final body = { 'agent_id': agentId, 'updated_by': updatedBy, 'retention_rates': retentionRates, }; return _makePostRequestJson(url, body, headers); } Future> deleteAgentIncentiveFile(id) async { // print(_token); if (_token == null) { await _initializeToken(); } // final url = Uri.parse('${Env.apiUrl}agent/agentList'); final url = Uri.parse('${Env.apiUrl}agent/deleteAgentIncentiveFile?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ------------------------------------ STAFF ----------------------------------------------------- Future> fetchStaffUserList(int managerId, role) async { // print(_token); print('rolemanagerId - $managerId'); if (_token == null) { await _initializeToken(); } dynamic url; if (role == 'manager') { print('manager'); // url = Uri.parse('${Env.apiUrl}staff/staffList'); url = Uri.parse('${Env.apiUrl}staff/staffList?manager_id=${managerId}'); } else if (role == 'Accounts') { print('manager'); // url = Uri.parse('${Env.apiUrl}staff/staffList'); url = Uri.parse('${Env.apiUrl}staff/staffList?manager_id=${managerId}'); } else { print('handler'); url = Uri.parse('${Env.apiUrl}staff/staffList?handler_id=${managerId}'); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findSingleStaffData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } // final url = Uri.parse('${Env.apiUrl}staff/findStaff?id=$id'); final url = Uri.parse('${Env.apiUrl}staff/findStaff?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ------------------------------------ SALES EXECUTIVE ----------------------------------------------------- Future> fetchSalesExecutiveList( int managerId, role, ) async { // print(_token); print('rolemanagerId - $managerId'); if (_token == null) { await _initializeToken(); } dynamic url; if (role == 'manager') { print('manager'); // url = Uri.parse('${Env.apiUrl}staff/staffList'); url = Uri.parse( '${Env.apiUrl}salesExecutive/executiveList?manager_id=${managerId}', ); // url = Uri.parse('${Env.apiUrl}salesExecutive/executiveList'); } else if (role == 'Accounts') { print('manager'); // url = Uri.parse('${Env.apiUrl}staff/staffList'); url = Uri.parse( '${Env.apiUrl}salesExecutive/executiveList?manager_id=${managerId}', ); } else { print('handler'); url = Uri.parse( '${Env.apiUrl}salesExecutive/executiveList?handler_id=${managerId}', ); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findSingleSalesExecutiveData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}salesExecutive/findExecutive?id=$id'); // final url = Uri.parse('${Env.apiUrl}staff/findStaff?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- POS ------------------------------------------------- Future> fetchPosList(int managerId, val) async { // print(_token); print('dropDown - $managerId'); if (_token == null) { await _initializeToken(); } dynamic url; if (val == 'dropDown') { print('dropDown'); url = Uri.parse( '${Env.apiUrl}master/getAllPOS?is_active=1&manager_id=${managerId}', ); } else { print('List'); url = Uri.parse( '${Env.apiUrl}master/getAllPOS?is_active=1&manager_id=${managerId}', ); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- ENQUIRY ------------------------------------------------- Future> fetchEnquiryList( int managerid, int id, String role, { String? fromDate, String? toDate, String? selectedStatus, String? selectedStaffId, }) async { print("selectedStatusselectedStatus - $selectedStatus"); if (_token == null) { await _initializeToken(); } final String query; // if (role == 'manager' || role == 'handler') { // query = 'manager_id=$id'; // } if (role == 'manager') { query = 'manager_id=$managerid'; } else if (role == 'handler') { query = 'handler_id=$id'; } else if (role == 'staff') { query = 'staff_id=$id'; } else { query = 'agent_id=$id'; } // final url = Uri.parse( // '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', // ); final url; if (role == 'staff') { url = Uri.parse( '${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', ); } else if (role == 'agent') { url = Uri.parse( '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus', ); } else { 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 ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId', ); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchAttndanceOFAllStaffList({ required String month, required dynamic mangerId, }) async { if (_token == null) { await _initializeToken(); } final String query; // if (role == 'manager') { // query = 'manager_id=$id'; // } final url = Uri.parse( '${Env.apiUrl}staff/monthlyLoginCount?month=${month ?? ''}&manager_id=$mangerId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchAttndanceOfIndiviualStaffList({ String? month, id, }) async { if (_token == null) { await _initializeToken(); } final String query; final url = Uri.parse( '${Env.apiUrl}staff/staffLoggedDays?month=${month ?? ''}&staff_id=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findSingleEnquiryData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?enquiry_id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> updateEnquiryInProgress(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}enquiry/updateEnquiryInProgress?enquiry_id=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ───────────────────────────────────────────────────────────────────────────── /// GET /partner/{id}/details /// Returns: profile info, policy count, premium totals, commission, clients Future> getPartnerDetails(dynamic id) async { if (_token == null) await _initializeToken(); final url = Uri.parse('${Env.apiUrl}partner/$id/details'); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET /partner/{id}/policies /// Returns: list of policies with policy_no, holder_name, product, premium, status Future> getPartnerPolicies(dynamic id) async { if (_token == null) await _initializeToken(); final url = Uri.parse('${Env.apiUrl}partner/$id/policies'); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET /partner/{id}/renewals?days=N /// Returns: list of policies expiring within [days] days /// [days] default is 20 — pass 10, 20, 30 or 45 from the UI dropdown Future> getPartnerRenewals( dynamic id, { int days = 20, }) async { if (_token == null) await _initializeToken(); final url = Uri.parse('${Env.apiUrl}partner/$id/renewals?days=$days'); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET /partner/{id}/earnings?financial_year=2025-2026 /// Monthly rows for that Indian FY: month_key, month_label, premium, policies, payout. Future> getPartnerEarnings( dynamic id, { String? financialYear, }) async { if (_token == null) await _initializeToken(); final q = (financialYear != null && financialYear.isNotEmpty) ? '?financial_year=${Uri.encodeQueryComponent(financialYear)}' : ''; final url = Uri.parse('${Env.apiUrl}partner/$id/earnings$q'); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ───────────────────────────────────────────────────────────────────────────── Future> findEnqQuotePolicyView(id) async { print('findEnqQuotePolicyVie2w - $id'); if (_token == null) { print('findEnqQuotePolicyVie2w 1'); await _initializeToken(); print('findEnqQuotePolicyVie2w 2'); } final url = Uri.parse( '${Env.apiUrl}enquiry/enquiryQuotePolicyView?enquiry_id=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; print('findEnqQuotePolicyVie2w 3'); final response = await _makeGetRequest(url, headers); if (response.containsKey('error')) { print( '❌ API returned invalid JSON or HTML. Raw response: ${response['raw']}', ); return {}; // return empty map on error } print('findEnqQuotePolicyView 1'); print('findEnqQuotePolicyView 1 - $response'); return response; } Future> deleteEnquiy(id, val) async { final url = Uri.parse( '${Env.apiUrl}/enquiry/updateEnquiryStatus?enquiry_id=$id&is_active=$val', ); // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; // final response = await _makePostRequestJson(url, data, headers); final response = await _makeGetRequest(url, headers); return response; } //------------------------------------ Quotation ------------------------------------------------ Future> fetchQuickQuotationList(int managerId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}enquiry/getQuickQuoteEnquiryList?manager_id=${managerId}', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchQuotationList(int managerId) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}quotation/quotationList?manager_id=${managerId}', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findSingleQuotationData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}quotation/findQuotation?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- POLICY ------------------------------------------------- Future> fetchPolicyList( int id, role, { String? fromDate, String? toDate, String? selectedStatus, String? selectedStaffId, }) async { print("APISERV : A1304"); print(_token); if (_token == null) { await _initializeToken(); } final url; final String query; final String val = 'Proposal Created'; if (role == 'manager') { query = 'manager_id=$id'; } else if (role == 'staff') { query = 'staff_id=$id'; } else { query = 'agent_id=$id'; } // url = Uri.parse( // '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', // ); if (role == 'staff') { url = Uri.parse( '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus', ); } else { url = Uri.parse( '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId', ); } // if (role == 'manager') { // url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?manager_id=$id'); // } else { // url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?staff_id=$id'); // } // else { // url = Uri.parse('${Env.apiUrl}endorsement/endorsementList?agent_id=$id'); // } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchPolicyDataOnlyList( managerId, dynamic id, role, { String? fromDate, String? toDate, String? selectedStaffId, String ? selectedStatus, String ? selectedInsurer, /// Accounts + policy list: filter by partner (agent id). String? selectedAgentId, }) async { print( "fetchPolicyDataOnlyListAPI - mangerID- $managerId - id - $id - role -$role >> selectedInsurer -$selectedInsurer ", ); if (_token == null) { await _initializeToken(); } final userId = '1'; String query = ""; if (role == 'manager') { query = 'manager_id=$managerId'; } else if (role == 'Accounts') { query = 'manager_id=$managerId'; if (selectedStatus != null) { query += '&show_policy_report=${Uri.encodeComponent(selectedStatus)}'; } if (selectedInsurer != null && selectedInsurer.toString().trim().isNotEmpty) { query += '&insurer_id=$selectedInsurer'; } } else if (role == 'staff') { query = 'staff_id=$id'; } else if (role == 'handler') { query = 'handler_id=$id'; } else { query = 'agent_id=$id'; } var listPath = '${Env.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&staff_id=${selectedStaffId ?? ''}'; if (role == 'Accounts' && selectedAgentId != null && selectedAgentId.toString().trim().isNotEmpty) { listPath += '&agent_id=${Uri.encodeComponent(selectedAgentId.toString().trim())}'; } final url = Uri.parse(listPath); // if (role == 'manager') { // url = Uri.parse( // '${Env.apiUrl}enquiry/enquiryList?manager_id=$id&only_policy_data=true', // ); // } else if (role == 'staff') { // url = Uri.parse( // '${Env.apiUrl}enquiry/enquiryList?staff_id=$id&only_policy_data=true', // ); // } else { // url = Uri.parse( // '${Env.apiUrl}enquiry/enquiryList?agent_id=$id&only_policy_data=true', // ); // } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // ----------------------------------- CLAIMS ------------------------------------------------- Future> fetchPolicySearch(val) async { // print(_token); // print('rolemanagerId - $managerId'); if (_token == null) { await _initializeToken(); } dynamic url; url = Uri.parse('${Env.apiUrl}policy/searchThePolicies?policy_number=$val'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchVehicleSearch(val) async { // print(_token); // print('rolemanagerId - $managerId'); if (_token == null) { await _initializeToken(); } dynamic url; url = Uri.parse( '${Env.apiUrl}policy/searchThePolicies?vehicle_number=$val', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET /claims with optional filters (e.g. manager_id, claim_type_id, from_date). Future> fetchClaims({ int? managerId, int? agentId, int? handlerId, int? staffId, int? claimTypeId, int? claimStatusId, int? insurerId, String? policyNumber, String? fromDate, String? toDate, }) async { if (_token == null) { await _initializeToken(); } final query = {}; void addInt(String key, int? value) { if (value != null) query[key] = value.toString(); } void addStr(String key, String? value) { final trimmed = value?.trim(); if (trimmed != null && trimmed.isNotEmpty) { query[key] = trimmed; } } addInt('manager_id', managerId); addInt('agent_id', agentId); addInt('handler_id', handlerId); addInt('staff_id', staffId); addInt('claim_type_id', claimTypeId); addInt('claim_status_id', claimStatusId); addInt('insurer_id', insurerId); addStr('policy_number', policyNumber); addStr('from_date', fromDate); addStr('to_date', toDate); final url = Uri.parse('${Env.apiUrl}claim/ClaimList').replace( queryParameters: query.isEmpty ? null : query, ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } @Deprecated('Use fetchClaims with query parameters') Future> fetchClaimList( managerId, int userId, role, ) async { final roleStr = role?.toString().toLowerCase() ?? ''; return fetchClaims( managerId: (roleStr == 'manager' || roleStr == 'accounts') ? int.tryParse(managerId?.toString() ?? '') : null, agentId: roleStr == 'agent' ? userId : null, handlerId: roleStr == 'handler' ? userId : null, staffId: (roleStr != 'manager' && roleStr != 'accounts' && roleStr != 'agent' && roleStr != 'handler') ? userId : null, ); } Future> findSingleClaimData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}claim/ClaimList?policy_number=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET claim/claimStatusList — active claim statuses for filters & forms. Future> fetchClaimStatusList() async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}claim/claimStatusList'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } Future> fetchClaimById(dynamic id) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}claim/getClaimById', ).replace(queryParameters: {'id': id.toString()}); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } /// GET claim/deleteClaim?id=&updated_by= Future> deleteClaim({ required dynamic id, required dynamic updatedBy, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}claim/deleteClaim').replace( queryParameters: { 'id': id.toString(), 'updated_by': updatedBy.toString(), }, ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } // ----------------------------------- ENDORSEMENT ------------------------------------------------- Future> fetchEndorsementList( managerId, int id, role, { String? fromDate, String? toDate, String? endorsementType, String? insurerId, String? status, String? verification, }) async { print('fetchEndorsementList in'); if (_token == null) { await _initializeToken(); } print('fetchEndorsementList token'); Map queryParams = {}; // 🔹 Role based base params if (role == 'manager' || role == 'Accounts') { queryParams['manager_id'] = managerId.toString(); } else if (role == 'agent') { queryParams['agent_id'] = id.toString(); } else if (role == 'handler') { queryParams['handler_id'] = id.toString(); } else { queryParams['staff_id'] = id.toString(); } queryParams['from_date'] = fromDate ?? ''; queryParams['to_date'] = toDate ?? ''; queryParams['endorsement_type'] = endorsementType ?? ''; queryParams['insurer_id'] = insurerId ?? ''; queryParams['status'] = status ?? ''; queryParams['verification'] = verification ?? ''; print('fetchEndorsementList api'); final url = Uri.parse('${Env.apiUrl}endorsement/endorsementList') .replace(queryParameters: queryParams); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> findSingleEnrosmentData(id) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}endorsement/endorsementList?policy_number=$id', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // --------------------------------- MASTER DATA DROPDOWN---------------------------------------------- Future> fetchMasterDropDown(String val ,[String? type]) async { // print(_token); print("*** MasterDropDown *** "); if (_token == null) { await _initializeToken(); } print('VAl - $val'); dynamic url; if (val == 'staffRole') { url = Uri.parse('${Env.apiUrl}master/getRoleMaster'); } else if (val == 'vehicleType') { // url = Uri.parse('${Env.apiUrl}master/getVehicleTypeMaster'); if(type == 'dropdown'){ url = Uri.parse('${Env.apiUrl}master/getVehicleTypeMaster?value_for=dropdown'); }else{ url = Uri.parse('${Env.apiUrl}master/getVehicleTypeMaster'); } // url = Uri.parse('${Env.apiUrl}master/getVehicleTypeMaster') // .replace(queryParameters: { // if (type != null) 'value_for': type, //}); } else if (val == 'InsuranceType') { url = Uri.parse('${Env.apiUrl}master/getInsurancePlanTypeMaster'); } else if (val == 'Insurers') { url = Uri.parse('${Env.apiUrl}master/getInsurersMaster'); } else if (val == 'Staffs') { url = Uri.parse('${Env.apiUrl}master/getStaffMaster'); } else if (val == 'Claim') { url = Uri.parse('${Env.apiUrl}master/getClaimMaster'); } else if (val == 'Claim Status' || val == 'ClaimStatus') { url = Uri.parse('${Env.apiUrl}master/getClaimStatusMaster'); } else if (val == 'Status') { url = Uri.parse('${Env.apiUrl}master/getStatusMaster'); } else if (val == 'Endorsement') { url = Uri.parse('${Env.apiUrl}master/getEndorsementMaster'); } else if (val == 'Broker') { url = Uri.parse('${Env.apiUrl}master/getAllBrokers'); } else if (val == 'PaymentMode') { url = Uri.parse('${Env.apiUrl}master/getAllPaymentModelist'); } else if (val == 'EndorsementType') { url = Uri.parse('${Env.apiUrl}master/getAllEndorsement'); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> fetchHandlerNameDropDown(id) async { print('fetchHandlerNameDropDown'); if (_token == null) { await _initializeToken(); } dynamic url; print('fetchHandlerNameDropDown 1'); url = Uri.parse( '${Env.apiUrl}staff/handlerListForStaffCreationDropdown?manager_id=$id', ); print('fetchHandlerNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; print('fetchHandlerNameDropDown 3'); final response = await _makeGetRequest(url, headers); print('fetchHandlerNameDropDown 4 - $response'); return response; } Future> fetchStaffListForEnquiryAssignDropDown( managerId, id, role, ) async { print('fetchHandlerNameDropDown'); if (_token == null) { await _initializeToken(); } dynamic url; print('fetchHandlerNameDropDown 1'); if (role == 'manager') { url = Uri.parse( '${Env.apiUrl}staff/staffListForEnquiryAssignDropdown?manager_id=$managerId', ); } else { url = Uri.parse( '${Env.apiUrl}staff/staffListForEnquiryAssignDropdown?handler_id=$id', ); } print('fetchHandlerNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; print('fetchHandlerNameDropDown 3'); final response = await _makeGetRequest(url, headers); print('fetchHandlerNameDropDown 4 - $response'); return response; } Future> fetchAgentNameDropDown(id) async { print('fetchAGENTNameDropDown'); if (_token == null) { await _initializeToken(); } dynamic url; print('fetchAGENTNameDropDown 1'); url = Uri.parse( '${Env.apiUrl}agent/agentListForEnquiryCreationDropdown?manager_id=$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; } Future> fetchAgentUnusedCommissionList( id, { String? fromDate, String? toDate, }) async { print('fetchAGENTNameDropDown'); if (_token == null) { await _initializeToken(); } final queryParameters = { 'manager_id': id.toString(), if (fromDate != null && fromDate.trim().isNotEmpty) 'from_date': fromDate.trim(), if (toDate != null && toDate.trim().isNotEmpty) 'to_date': toDate.trim(), }; dynamic url; print('fetchAGENTNameDropDown 1'); url = Uri.parse( '${Env.apiUrl}invoice/getAgentUnusedCommissionList', ).replace(queryParameters: queryParameters); print('fetchAGENTNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; print('fetchAGENTNameDropDown 3'); final response = await _makeGetRequest(url, headers); print('fetchAGENTNameDropDown 4 - $response'); return response; } static late String _baseUrl; static void initialize(String baseUrl) { _baseUrl = Env.apiUrl; } // Fetch all enquiries static Future> fetchEnquiries() async { try { final response = await http.get( Uri.parse('$_baseUrl/api/enquiries'), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { final List data = json.decode(response.body); return data.map((json) => EnquiryModel.fromJson(json)).toList(); } else { throw Exception('Failed to load enquiries'); } } catch (e) { throw Exception('Error fetching enquiries: $e'); } } // Create new enquiry static Future createEnquiry(EnquiryModel enquiry) async { try { final response = await http.post( Uri.parse('$_baseUrl/api/enquiries'), headers: {'Content-Type': 'application/json'}, body: json.encode(enquiry.toJson()), ); if (response.statusCode == 200 || response.statusCode == 201) { return EnquiryModel.fromJson(json.decode(response.body)); } else { throw Exception('Failed to create enquiry'); } } catch (e) { throw Exception('Error creating enquiry: $e'); } } // Update enquiry static Future updateEnquiry( String id, EnquiryModel enquiry, ) async { try { final response = await http.put( Uri.parse('$_baseUrl/api/enquiries/$id'), headers: {'Content-Type': 'application/json'}, body: json.encode(enquiry.toJson()), ); if (response.statusCode == 200) { return EnquiryModel.fromJson(json.decode(response.body)); } else { throw Exception('Failed to update enquiry'); } } catch (e) { throw Exception('Error updating enquiry: $e'); } } // Fetch dropdown options static Future> fetchDropdownOptions(String type) async { try { final response = await http.get( Uri.parse('$_baseUrl/api/options/$type'), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { final List data = json.decode(response.body); return data.map((json) => DropdownOption.fromJson(json)).toList(); } else { throw Exception('Failed to load options'); } } catch (e) { throw Exception('Error fetching options: $e'); } } // --------------------------------- PayOut Module---------------------------------------------- Future> getCommissionRateList(data) async { print("getCommissionRateList------- $data}"); final url = Uri.parse('${Env.apiUrl}invoice/commission-rate-list'); print("getCommissionRateList 1"); // final token = await getToken(); // Fetch token // if (_token == null) { // throw Exception('Token not found. Please log in.'); // } if (_token == null) { await _initializeToken(); } print("getCommissionRateList 2"); print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> getViewInvoiceList(dynamic data) async { if (_token == null) { await _initializeToken(); } final Map map = data is Map ? Map.from(data) : {}; final invoiceId = map['invoice_id']; final managerId = map['manager_id']; final queryParameters = { if (invoiceId != null) 'invoice_id': invoiceId.toString(), if (managerId != null) 'manager_id': managerId.toString(), }; final url = Uri.parse('${Env.apiUrl}invoice/view').replace( queryParameters: queryParameters, ); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; return _makeGetRequest(url, headers); } Future> getCreateOrUpdate(data) async { final url = Uri.parse('${Env.apiUrl}invoice/create-or-update'); // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> getInvoiceList() async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/list'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> getPayoutList({ String? fromDate, String? toDate, String? agentName, String? agentCode, String? policyNo, }) async { // print(_token); if (_token == null) { await _initializeToken(); } final query = {}; void addParam(String key, String? value) { final trimmed = value?.trim(); if (trimmed != null && trimmed.isNotEmpty) { query[key] = trimmed; } } addParam('from_date', fromDate); addParam('to_date', toDate); addParam('agent_name', agentName); addParam('agent_code', agentCode); addParam('policy_no', policyNo); final url = Uri.parse('${Env.apiUrl}invoice/list').replace( queryParameters: query.isEmpty ? null : query, ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> deleteInvoice(ID) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/delete?id=$ID'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> delete(ID, path) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}$path'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> getInvoiceDetails(ID) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/details?id=$ID'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> addInvoicePayment( Map data, ) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/add-payment'); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> getInvoiceUtrDetails(dynamic invoiceId) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/utrDetails?invoice_id=$invoiceId'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> updateInvoiceUtrDetails( Map data, ) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/updateUtrDetails'); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> addInvoicePaymentHistory(dynamic invoiceId) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}invoice/add-payment-history?invoice_id=$invoiceId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> listInvoiceUtrDetails(dynamic invoiceId) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}invoice/listUtrDetails?invoice_id=$invoiceId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> bulkUploadInvoiceCommission({ required PlatformFile file, required Map data, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/bulk-upload-commission'); try { final request = http.MultipartRequest('POST', url); request.headers.addAll({ 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }); if (file.bytes == null) throw Exception('Could not read file bytes'); request.files.add( http.MultipartFile.fromBytes( 'file_name', file.bytes!, filename: file.name, ), ); data.forEach((key, value) { if (value != null) { request.fields[key] = value.toString(); } }); final streamedResponse = await request.send(); final responseBody = await streamedResponse.stream.bytesToString(); if (streamedResponse.statusCode == 401 || streamedResponse.statusCode == 403) { await clearLocalStorageAndRedirect(); return {'status': 'error', 'message': 'Session expired'}; } if (streamedResponse.statusCode != 200) { return { 'status': 'error', 'message': 'Server Error: ${streamedResponse.statusCode}', }; } final decoded = jsonDecode(responseBody); return decoded is Map ? decoded : {'status': 'error', 'message': 'Unexpected response format'}; } catch (e) { return {'status': 'error', 'message': e.toString()}; } } Future> bulkUploadInvoiceCommissionProceed( Map data, ) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}invoice/bulk-upload-commission/proceed'); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> uploadPolicyCommissionExcel({ required PlatformFile file, bool proceedPartnerMismatch = false, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}policy/uploadCommissionExcel'); try { final request = http.MultipartRequest('POST', url); request.headers.addAll({ 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }); if (file.bytes == null) throw Exception('Could not read file bytes'); request.files.add( http.MultipartFile.fromBytes( 'commission_excel', file.bytes!, filename: file.name, ), ); if (proceedPartnerMismatch) { request.fields['proceed_partner_mismatch'] = '1'; } final streamedResponse = await request.send(); final responseBody = await streamedResponse.stream.bytesToString(); if (streamedResponse.statusCode == 401 || streamedResponse.statusCode == 403) { await clearLocalStorageAndRedirect(); return {'status': 'error', 'message': 'Session expired'}; } if (streamedResponse.statusCode != 200) { try { final decoded = jsonDecode(responseBody); if (decoded is Map) { return { ...decoded, if (!decoded.containsKey('code')) 'code': streamedResponse.statusCode, }; } } catch (_) {} return { 'status': 'failed', 'code': streamedResponse.statusCode, 'message': responseBody.isNotEmpty ? responseBody : 'Server Error: ${streamedResponse.statusCode}', }; } final decoded = jsonDecode(responseBody); return decoded is Map ? decoded : {'status': 'error', 'message': 'Unexpected response format'}; } catch (e) { return {'status': 'error', 'message': e.toString()}; } } Future> findPolicyApi(ID) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}policy/findPolicy?id=$ID'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> policyFilePathApi(ID, file_type) async { // print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( '${Env.apiUrl}policy/PolicyFilePath?policy_id=$ID&file_type=$file_type', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> updatePolicyApi(data) async { final url = Uri.parse('${Env.apiUrl}policy/updatePolicy'); // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> calculateCommissionRequest(data) async { final url = Uri.parse('${Env.apiUrl}policy/calculateCommissionRequest'); // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } print("data------- $data}"); final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> updatePolicyCommissionApi(data) async { final url = Uri.parse('${Env.apiUrl}policy/updatePolicyCommission'); if (_token == null) { throw Exception('Token not found. Please log in.'); } final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }; final response = await _makePostRequestJson(url, data, headers); return response; } Future> fetchPolicyMasterDropDown(String val) async { // print(_token); if (_token == null) { await _initializeToken(); } print('VAl - $val'); dynamic url; if (val == 'fuelType') { url = Uri.parse('${Env.apiUrl}policy/fuelTypeMaster'); } else if (val == 'vehicleType') { url = Uri.parse('${Env.apiUrl}policy/vehicleTypeMaster'); } final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future generateEndorsementExcel( managerId, { String? searchValue, String? fromDate, String? toDate, String? endorsementType, String? insurerId, String? status, String? verification, String? agentId, String? policyNumber, }) async { final queryParams = { 'manager_id': managerId.toString(), 'from_date': fromDate ?? '', 'to_date': toDate ?? '', 'endorsement_type': endorsementType ?? '', 'insurer_id': insurerId ?? '', 'status': status ?? '', 'verification': verification ?? '', 'search': searchValue ?? '', 'agent_id': agentId ?? '', 'policy_number': policyNumber ?? '', }; final url = Uri.parse('${Env.apiUrl}reports/endorsement-excel').replace( queryParameters: queryParams, ); // final url = Uri.parse('http://localhost/nhance_partner_be/reports/endorsement-excel').replace( // queryParameters: queryParams, // ); 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'); } } /// Payout sample: `from_date` / `to_date` as `yyyy-MM-dd`, `agent_code` as partner code (may be empty). Future downloadPendingCommissionExcel({ required String fromDate, required String toDate, required String agentCode, }) async { final query = Uri( queryParameters: { 'from_date': fromDate, 'to_date': toDate, 'agent_code': agentCode, }, ).query; await getPdfDownload( 'policy/downloadPendingCommissionExcel?$query', 'pending_commission', ); } /// Static sample Excel for commission upload (template). Future downloadCommissionUploadSampleExcel() async { await getPdfDownload( 'policy/downloadCommissionUploadSampleExcel', 'commission_upload_sample', ); } /// GET `policy/commissionPayoutReport` — optional query: `from_date`, `to_date` (yyyy-MM-dd), `agent_id`, `payout_raised` (`all` / `yes` / `no`). Future> fetchPayoutReportList({ String? fromDate, String? toDate, String? agentId, String? payoutRaised, }) async { if (_token == null) { await _initializeToken(); } final query = {}; if (fromDate != null && fromDate.isNotEmpty) { query['from_date'] = fromDate; } if (toDate != null && toDate.isNotEmpty) { query['to_date'] = toDate; } if (agentId != null && agentId.trim().isNotEmpty) { query['agent_id'] = agentId.trim(); } if (payoutRaised != null && payoutRaised.isNotEmpty) { query['payout_raised'] = payoutRaised; } final url = Uri.parse('${Env.apiUrl}policy/commissionPayoutReport').replace( queryParameters: query.isEmpty ? null : query, ); final headers = { 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } /// GET `policy/commissionPayoutReportExport` — same optional query as [fetchPayoutReportList]. Future downloadCommissionPayoutReportExport({ String? fromDate, String? toDate, String? agentId, String? payoutRaised, }) async { final query = {}; if (fromDate != null && fromDate.isNotEmpty) { query['from_date'] = fromDate; } if (toDate != null && toDate.isNotEmpty) { query['to_date'] = toDate; } if (agentId != null && agentId.trim().isNotEmpty) { query['agent_id'] = agentId.trim(); } if (payoutRaised != null && payoutRaised.isNotEmpty) { query['payout_raised'] = payoutRaised; } final suffix = query.isEmpty ? '' : '?${Uri(queryParameters: query).query}'; await getPdfDownload( 'policy/commissionPayoutReportExport$suffix', 'commission_payout_report', ); } Future generatePolicyExcel(managerId, fromDate, toDate, searchValue,flag,insurer) async { final url = Uri.parse( '${Env.apiUrl}reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&search=${searchValue ?? ''}&show_policy_report=${flag ?? ''}&insurer_id=${insurer ?? ''}', ); print('getPdfDownload policy-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> fetchAuditHistory(id,table) async { print("fetchAuditHistory - $id "); if (_token == null) { await _initializeToken(); } // final url = Uri.parse('${Env.apiUrl}audit/history?table_name=partner_policy&pk=80',); // final url = Uri.parse( // '${Env.apiUrl}audit/history?table_name=partner_policy&pk=${id ?? ''}', // ); final url = Uri.parse( '${Env.apiUrl}audit/history?table_name=${table ?? ''}&pk=${id ?? ''}', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } // Future> fetchPolicyExcel(managerId,fromDate,toDate) async { // // print( "fetchPolicyExcel - mangerID- $managerId - Dated - $fromDate - $toDate " ); // // if (_token == null) { // await _initializeToken(); // } // // final String query; // // query = 'manager_id=$managerId'; // // final url = Uri.parse('${Env.apiUrl}reports/policy-excel?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}',); // // final headers = { // 'Authorization': 'Bearer $_token' ?? '', // 'app-signature': Env.App_Signature, // }; // // final response = await _makeGetRequest(url, headers); // // return response; // } Future> deleteEndorsement(id) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}endorsement/deleteEndorsement?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; } Future> uploadEndorsementFile({ required PlatformFile file, required Map data, }) async { if (_token == null) { await _initializeToken(); } final url = Uri.parse('${Env.apiUrl}endorsement/uploadEndorsementFile'); try { final request = http.MultipartRequest('POST', url); request.headers.addAll({ 'Authorization': 'Bearer $_token', 'app-signature': Env.App_Signature, }); if (file.bytes == null) throw Exception('Could not read file bytes'); request.files.add( http.MultipartFile.fromBytes( 'endorsement_completion_file', file.bytes!, filename: file.name, ), ); data.forEach((key, value) { if (value != null) { request.fields[key] = value.toString(); } }); print('uploadEndorsementFile url => $url'); print('uploadEndorsementFile fields => ${request.fields}'); print('uploadEndorsementFile fileName => ${file.name}'); final streamedResponse = await request.send(); final responseBody = await streamedResponse.stream.bytesToString(); print('uploadEndorsementFile raw response => $responseBody'); if (streamedResponse.statusCode == 401 || streamedResponse.statusCode == 403) { await clearLocalStorageAndRedirect(); return {'status': 'error', 'message': 'Session expired'}; } if (streamedResponse.statusCode != 200) { return { 'status': 'error', 'message': 'Server Error: ${streamedResponse.statusCode}', }; } try { final decoded = jsonDecode(responseBody); return decoded is Map ? decoded : {'status': 'error', 'message': 'Unexpected response format'}; } catch (_) { return {'status': 'error', 'message': 'Failed to parse response'}; } } catch (e) { print('uploadEndorsementFile exception => $e'); return {'status': 'error', 'message': e.toString()}; } } }