ts-tat/lib/services/apiService.dart
2025-08-21 14:57:52 +05:30

1722 lines
49 KiB
Dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js.dart';
import '../../config/apiUrl.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class ApiService {
Future<void> getOrganizationData() async {
try {
print("ORG getUpdatedServices");
final result = await fetchOrganization();
print("UUPdatedServices - $result");
// ✅ Save to local storage
final prefs = await SharedPreferences.getInstance();
final jsonString = jsonEncode(result);
await prefs.setString('org_data', jsonString);
print("✅ Organization data saved to SharedPreferences.");
print("selectedOrg - $result");
} catch (e) {
print('Error fetching updatedServices list: $e');
}
}
Future<List<dynamic>> fetchCountryList() async {
final String apiUrldata = '$apiUrl/api/getcountryMaster';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("Country - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load country list');
}
}
Future<List<dynamic>> fetchHotelsList() async {
final String apiUrldata = '$apiUrl/api/getHotels';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("Hotelss - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load country list');
}
}
Future<List<dynamic>> fetchAirlineList() async {
final String apiUrldata = '$apiUrl/api/getAirlineMaster';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("Airline - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load country list');
}
}
Future<List<dynamic>> fetchUsers() async {
String? ordId = await getOrgId();
final String apiUrlData = '$apiUrl/api/users?org_id=$ordId';
final String? token = await getToken();
print("Fetch Users");
print("TOEKRWE: $token");
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrlData),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['data']; // Returning raw JSON list
} else {
throw Exception('Failed to load users');
}
}
Future<List> fetchCostCenter() async {
final String apiUrldata = '$apiUrl/api/getCostCenterMaster';
final token = await getToken();
final userId = await getUserId();
// print("SUSRTRT- $userId");
//
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
List<dynamic> plansJson = data['data']; // 'data' is a Map, not a List
// setState(() {
// apiCostData = plansJson; // Store API response in state
// if(apiCostData!.isNotEmpty){
// selectedCostCenterId =apiCostData?.first['department_id'];
// }
// if (apiCostData != null && apiCostData!.isNotEmpty) {
// selectedCostCenterId ??= apiCostData!.first['department_id']?.toString();
// }
// });
print('plansJSON');
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<List> fetchDepartmentCostCenter() async {
final String apiUrldata = '$apiUrl/api/getDepartmentList';
final token = await getToken();
final userId = await getUserId();
// print("SUSRTRT- $userId");
//
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
List<dynamic> plansJson = data['data']; // 'data' is a Map, not a List
// setState(() {
// apiCostData = plansJson; // Store API response in state
// if(apiCostData!.isNotEmpty){
// selectedCostCenterId =apiCostData?.first['department_id'];
// }
// if (apiCostData != null && apiCostData!.isNotEmpty) {
// selectedCostCenterId ??= apiCostData!.first['department_id']?.toString();
// }
// });
print('plansJSON');
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<Map<String, dynamic>> fetchMasterDropdown() async {
final String apiUrldata = '$apiUrl/api/getDropdownMaster';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
Map<String, dynamic> plansJson =
data['data']; // 'data' is a Map, not a List
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<List<dynamic>> fetchAllServices() async {
final String apiUrldata = '$apiUrl/api/service';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<List<dynamic>> fetchAllGroup() async {
String? orgId = await getOrgId();
final String apiUrldata = '$apiUrl/api/groups?for=table_view&org_id=$orgId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<List<dynamic>> fetchFindGroup() async {
String? orgId = await getOrgId();
final String apiUrldata = '$apiUrl/api/groups/find/$orgId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<List<dynamic>> fetchAllPolicy() async {
String? orgId = await getOrgId();
final String apiUrldata = '$apiUrl/api/policy?for=table_view&org_id=$orgId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<Map<String, dynamic>> getSinglePolicy(int policyId) async {
final String apiUrldata = '$apiUrl/api/policy/find/${policyId}';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
Map<String, dynamic> plansJson =
data['data']; // 'data' is a Map, not a List
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<Map<String, dynamic>> fetchOrganization() async {
String? orgId = await getOrgId();
// final String apiUrldata = '$apiUrl/api/organizations';
final String apiUrldata = '$apiUrl/api/organizations/find/$orgId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
// Make sure each item is a Map<String, dynamic>
// final List<Map<String, dynamic>> orgList =
// List<Map<String, dynamic>>.from(data['data']);
// return orgList;
return Map<String, dynamic>.from(data['data']);
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load organizations');
}
}
static Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/cancle_plan?plan_id=$planId';
// final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
final token = await getToken();
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token', // Add token here
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
final Map<String, dynamic>? resData = json.decode(response.body);
return resData?["data"];
} else {
throw Exception('Failed to load plans');
}
}
static Future<Map<String, dynamic>> getViewPlanEdit(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
final token = await getToken();
final response = await http.put(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token', // Add token here
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
final Map<String, dynamic>? resData = json.decode(response.body);
return resData?["data"];
} else {
throw Exception('Failed to load plans');
}
}
static Future<void> viewPlan(
BuildContext context,
String planId, {
bool isViewMode = false,
bool isMyTrips = false,
}) async {
try {
Map<String, dynamic> planData = await getViewPlanEdit(planId);
print("ViewAAA - $planData");
context.go(
isMyTrips ? '/createPlan' : '/allTrips/trips',
extra: {'planData': planData, 'isViewMode': isViewMode},
);
} catch (e) {
print("Error fetching plan: $e");
}
}
static Future<void> viewPlanForApprover(
BuildContext context,
String planId,
String? approverId,
String? delegaterId,
String? approver_status, {
bool isViewMode = false,
bool isApprover = true,
}) async {
try {
Map<String, dynamic> planData = await getViewPlanEdit(planId);
print("ViewAAA - $planData");
context.replace(
'/approver/plans',
extra: {
'planData': planData,
'approver_status': approver_status,
'approverId': approverId,
'delegaterId': delegaterId,
'isViewMode': isViewMode,
'isApprover': isApprover,
},
);
} catch (e) {
print("Error fetching plan: $e");
}
}
Future<Map<String, dynamic>> fetchUserApprovalList() async {
String? orgId = await getOrgId();
String? userId = await getUserId();
// final String apiUrldata = '$apiUrl/api/organizations';
final String apiUrldata =
'$apiUrl/api/plans/findApprovalList?user_id=$userId&org_id=$orgId';
// '$apiUrl/api/findApprovalList?user_id=$userId&org_id=$orgId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
// Make sure each item is a Map<String, dynamic>
// final List<Map<String, dynamic>> orgList =
// List<Map<String, dynamic>>.from(data['data']);
// return orgList;
return Map<String, dynamic>.from(data['data']);
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load organizations');
}
}
// Flight From - To
Future<List<dynamic>> fetchFlightsCountryList(String? tripType) async {
print("FlightTripType- $tripType");
final String apiUrldata =
'$apiUrl/api/getAirportCodeMaster?trip_type=$tripType';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("Country - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load country list');
}
}
Future<List<dynamic>> fetchTrainCountryList() async {
final String apiUrldata = '$apiUrl/api/getTrainCodeMaster';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("Country - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
return data['data'];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load country list');
}
}
Future<void> getPdfDownload(planId) async {
final String apiUrldata = '$apiUrl/api/plans/download?plan_id=$planId';
// final String apiUrldata = '$apiUrl/auth/googlelogin';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
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', 'trip_plan_$planId.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');
}
}
Future<void> getForexPdfDownload(forexId) async {
final String apiUrldata =
'$apiUrl/api/plans/forexDownload?forex_id=$forexId';
// final String apiUrldata = '$apiUrl/auth/googlelogin';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
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', 'Forex_$forexId.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');
}
}
// download the Template for bulk upload the user
Future<Map<String, dynamic>> getDownloadUserTemplateForUpload() async {
final String apiUrldata =
'$apiUrl/api/user/userUploadTemplate'; // download the Template for bulk upload user => api
// final String apiUrldata = '$apiUrl/auth/googlelogin';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
print("XL 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', 'user_file.xlsx')
..click();
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url);
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) {
return {'status': false, 'message': 'Download error: $e'};
}
} else if (response.statusCode == 404) {
return {'status': false, 'message': 'File not found (404).'};
} else {
return {'status': false, 'message': 'Failed to download. Try again.'};
}
}
//---------------------------------------User Management-----------------------------------
Future<Map<String, dynamic>> getSingleUser(int userId) async {
print('Single USer 1 - $userId');
final String apiUrldata = '$apiUrl/api/users/find/$userId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
print('Single USer 1');
Map<String, dynamic> plansJson =
data['data']; // 'data' is a Map, not a List
print('Single USer 2');
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<Map<String, dynamic>> getForexDetailsFind(int userId) async {
print('Single Forez 1 - $userId');
// final String apiUrldata = '$apiUrl/api/users/find/$userId';
final String apiUrldata =
'$apiUrl/api/findForexPerdiem?forex_perdiem_id=$userId';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print("forexDat - $data");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<dynamic> forexList = data['data'];
if (forexList.isEmpty) {
throw Exception('No forex data found.');
}
return forexList.first as Map<String, dynamic>;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
// ---
Future<Map<String, dynamic>> getDepartmentDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findDepartment?id=$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
// print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No department found with ID $id");
}
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load department details');
}
}
Future<Map<String, dynamic>> getPurposeOfTravelDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findPurposeOfTravel?id=$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
// print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No department found with ID $id");
}
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load department details');
}
}
Future<Map<String, dynamic>> getTemplateFind(int id) async {
final String apiUrldata = '$apiUrl/api/template/find/$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.put(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
// print(data);
// if (!data.containsKey('data') || data['data'] is! List) {
// throw Exception(
// "Invalid response format: 'data' field is missing or not a List");
// }
//
// final List<Map<String, dynamic>> listData =
// List<Map<String, dynamic>>.from(data['data']);
//
// if (listData.isEmpty) {
// throw Exception("No department found with ID $id");
// }
//
// return listData[0];
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
return Map<String, dynamic>.from(data['data']);
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load department details');
}
}
Future<Map<String, dynamic>> getForexTemplate() async {
final String apiUrldata =
'$apiUrl/api/getForexTemplate?template_name=forex';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
print(data);
// if (!data.containsKey('data') || data['data'] is! List) {
// throw Exception(
// "Invalid response format: 'data' field is missing or not a List");
// }
//
// final List<Map<String, dynamic>> listData =
// List<Map<String, dynamic>>.from(data['data']);
//
// if (listData.isEmpty) {
// throw Exception("No department found with ID $id");
// }
//
// return listData[0];
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
return Map<String, dynamic>.from(data['data']);
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load department details');
}
}
Future<bool> showCancelConfirmationDialog(
BuildContext context,
Color? layoutColor,
) async {
return await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
'Cancel Confirmation',
style: GoogleFonts.poppins(
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
content: Text(
'Do you want to cancel?',
style: GoogleFonts.poppins(
fontSize: 14.5,
fontWeight: FontWeight.w500,
),
),
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: layoutColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: layoutColor ?? Colors.grey,
width: 2,
),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text(
"Cancel",
style: GoogleFonts.poppins(fontSize: 12),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: layoutColor, // Keep original color
foregroundColor: Colors.white, // Keep original color
disabledBackgroundColor:
layoutColor, // Ensure color remains when disabled
disabledForegroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: layoutColor ?? Colors.grey,
width: 1,
),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed:
() => Navigator.of(
context,
).pop(true), // Disable when in view mode
child: Text("OK", style: GoogleFonts.poppins(fontSize: 12)),
),
],
);
},
) ??
false; // Default to false if dismissed
}
static Future<void> viewPlanTravelAgent(
BuildContext context,
String planId, {
bool isViewMode = false,
bool isMyTrips = false,
}) async {
try {
Map<String, dynamic> planData = await getViewPlanEdit(planId);
print("ViewAAA - $planData");
context.go(
'/travelagent/trips',
extra: {'planData': planData, 'isViewMode': isViewMode},
);
} catch (e) {
print("Error fetching plan: $e");
}
}
Future<Map<String, dynamic>> getCostCenterDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findCostCenter?cost_center_id=$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
// print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No CostCenter found with ID $id");
}
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load CostCenter details');
}
}
Future<Map<String, dynamic>> getHotelsDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findHotels?hotel_id=$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// print('findout the result');
// print(data.runtimeType);
// print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No Hotel data found with ID $id");
}
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load Hotel details');
}
}
Future<Map<String, dynamic>> getGroupDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/groups/find/$id';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
print(data);
if (!data.containsKey('data') || data['data'] is! Map) {
throw Exception(
"Invalid response format: 'data' field is missing or not a Map",
);
}
print('Single USer 1');
Map<String, dynamic> plansJson =
data['data']; // 'data' is a Map, not a List
print('Single USer 2');
return plansJson;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load plans');
}
}
Future<Map<String, dynamic>> getTravellerDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/travellers/find?traveller_id=$id';
//c
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List",
);
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No Traveller data found with ID $id");
}
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception('Failed to load Hotel details');
}
}
// ----------------------- User Management - CheckDuplicate ---------------
Future<Map<String, dynamic>> CheckDuplicate(
String label,
String field,
String value,
String? userId,
) async {
String apiUrldata;
if (userId == null || userId.isEmpty) {
apiUrldata = '$apiUrl/api/checkDuplicate?$field=$value';
} else {
apiUrldata = '$apiUrl/api/checkDuplicate?$field=$value&user_id=$userId';
}
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// Updated to match actual response structure
if (data['status'] == "exists") {
print("${data['field']} - $value already exists");
return {"message": "$label already exists", "field": data['field']};
} else {
print("$label - $value is a new value");
return {};
}
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception(
'Failed to load checkDuplicate data. Status code: ${response.statusCode}',
);
}
}
// ----------------------- User Management - CheckDuplicate end here ----------------------------------
// ----------------------- Report -------------------------
Future<Map<String, dynamic>> CallReports(String apiRoute, String body) async {
String apiUrldata = '$apiUrl/api/$apiRoute';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
body: body,
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
return data;
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else {
throw Exception(
'Failed to load data. Status code: ${response.statusCode}',
);
}
}
Future<Map<String, dynamic>> reportExcelDownload(
String apiRoute,
String body,
String name,
) async {
final String apiUrldata = '$apiUrl/api/$apiRoute';
// Sanitize name for filename (optional)
final safeName = name.replaceAll(
RegExp(r'[^\w\s-]'),
'',
); // remove any special chars if needed
final excelName = '$safeName.xlsx';
final token = await getToken();
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
body: body,
);
if (response.statusCode == 200) {
try {
print("report XL Dowloaded");
print(excelName);
// 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', excelName)
..click();
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url);
// throw Exception('Sucessfully Downloaded');
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) {
// throw Exception('Error parsing response: $e');
return {'status': false, 'message': 'Download error: $e'};
}
} else if (response.statusCode == 404) {
// throw Exception('File not found.');
return {'status': false, 'message': 'File not found (404).'};
} else {
// throw Exception('Failed to Download');
return {'status': false, 'message': 'Failed to download. Try again.'};
}
}
// ----------------------- Report -------------------------
Future<List<dynamic>> fetchGetHotels() async {
// return [];
final orgId = await getOrgId();
final String apiUrlData = '$apiUrl/api/getHotels';
final String? token = await getToken();
print("Fetch Hotels 2KN : $token");
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrlData),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'app-signature': 'ts-traveltool-2025-signature-123456',
},
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['data']; // Returning raw JSON list
} else {
throw Exception('Failed to load users');
}
}
}