report completed 2

This commit is contained in:
venba-Inspriron-3558 2025-06-18 16:26:09 +05:30
parent 25239c6e62
commit ce9bcb113b
12 changed files with 5167 additions and 2108 deletions

View File

@ -94,6 +94,8 @@ class _PolicyListState extends State<PolicyList> {
futurePolicy.then((object) { futurePolicy.then((object) {
setState(() { setState(() {
allPolicy = object; allPolicy = object;
filteredPolicy = object;
searchController.text = "";
}); });
}); });
// Wait for futurePlans to be fetched and update allPlans // Wait for futurePlans to be fetched and update allPlans

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:core'; import 'dart:core';
import 'dart:typed_data';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -8,23 +10,23 @@ import 'package:frontend/config/apiUrl.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
import '../../routes/custom_appBar.dart'; import '../../routes/custom_appBar.dart';
import '../../routes/custom_drawer.dart'; import '../../routes/custom_drawer.dart';
import '../../routes/mainLayout.dart';
import '../../services/apiService.dart'; import '../../services/apiService.dart';
import '../../utils/auth_utils.dart'; import '../../utils/auth_utils.dart';
import '../../utils/pagination.dart'; import '../../utils/pagination.dart';
import '../../widgets/custom_text_field.dart'; import '../../widgets/custom_text_field.dart';
class AdvancePurchase extends StatefulWidget { class MIShotel extends StatefulWidget {
const AdvancePurchase({super.key}); const MIShotel({super.key});
@override @override
_AdvancePurchaseState createState() => _AdvancePurchaseState(); _MIShotelState createState() => _MIShotelState();
} }
class _AdvancePurchaseState extends State<AdvancePurchase> class _MIShotelState extends State<MIShotel>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final ApiService apiService = ApiService(); final ApiService apiService = ApiService();
@ -42,12 +44,12 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
int currentPage2 = 0; int currentPage2 = 0;
int itemsPerPage2 = 10; int itemsPerPage2 = 10;
late TabController _tabController; late TabController _tabController;
final List<String> tabNames = ['Domestic', 'International']; String selectedTabName = 'domestic';
Map<String, FocusNode> focusNodes = {}; Map<String, FocusNode> focusNodes = {};
Map<String, bool> focusStates = {}; Map<String, bool> focusStates = {};
Map<String, TextEditingController> textControllers = {}; Map<String, TextEditingController> textControllers = {};
Map<String, String> errorMessages = {}; Map<String, String> errorMessages = {};
// Map<String, dynamic> advancePurchaseReport = {}; // Map<String, dynamic> MIShotelReport = {};
List<Map<String, dynamic>> domesticData = []; List<Map<String, dynamic>> domesticData = [];
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
@ -59,6 +61,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
void initState() { void initState() {
super.initState(); super.initState();
loadInitialData(); loadInitialData();
_checkAuthAndLoadData();
if (!textControllers.containsKey("from_date")) { if (!textControllers.containsKey("from_date")) {
textControllers["from_date"] = TextEditingController(); textControllers["from_date"] = TextEditingController();
} }
@ -83,6 +86,9 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
_tabController.addListener(() { _tabController.addListener(() {
if (_tabController.indexIsChanging == false) { if (_tabController.indexIsChanging == false) {
// Only fire when tab change is complete // Only fire when tab change is complete
setState(() {
selectedTabName = getTabName(_tabController.index);
});
print(" :) :X Selected Tab: ${getTabName(_tabController.index)}"); print(" :) :X Selected Tab: ${getTabName(_tabController.index)}");
} }
}); });
@ -97,17 +103,18 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
}); });
getToken(); getToken();
// fetchAdvancePurchaseReport(); // fetchMIShotelReport();
} }
String getTabName(int index) { String getTabName(int index) {
switch (index) { switch (index) {
case 0: case 0:
return "Domestic"; return "domestic";
case 1: case 1:
return "International"; return "international";
default: default:
return "Unknown"; // return "Unknown";
return "domestic";
} }
} }
@ -118,7 +125,26 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
}); });
}); });
} }
void _checkAuthAndLoadData() async {
final String? token = await getToken(); // Your async function to get token
if (token == null || token.isEmpty) {
// Token doesn't exist → redirect to login
context.go(
"/",
); // or use: router.go("/") if you're using `GoRouter` directly
return;
}
if (!mounted) return;
try {
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
} catch (e) {
print("service report : $e");
}
}
void loadInitialData() async { void loadInitialData() async {
String? layoutString = await getLayoutColor(); String? layoutString = await getLayoutColor();
String? bodyStringColor = await getBodyColor(); String? bodyStringColor = await getBodyColor();
@ -190,14 +216,18 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
setState(() { setState(() {
domesticData = []; domesticData = [];
internationalData = []; internationalData = [];
currentPage1 = 0;
itemsPerPage1 = 10;
currentPage2 = 0;
itemsPerPage2 = 10;
}); });
final fromDateText = textControllers["from_date"]?.text; final fromDateText = textControllers["from_date"]?.text;
final toDateText = textControllers["to_date"]?.text; final toDateText = textControllers["to_date"]?.text;
if (fromDateText == null || fromDateText.isEmpty || if (fromDateText == null || fromDateText.isEmpty ||
toDateText == null || toDateText.isEmpty) { toDateText == null || toDateText.isEmpty) {
errorMessages["from_date"] = "Required"; fromDateText == null || fromDateText.isEmpty ? errorMessages["from_date"] = "Required" : errorMessages.remove("from_date");
errorMessages["to_date"] = "Required"; toDateText == null || toDateText.isEmpty ? errorMessages["to_date"] = "Required" : errorMessages.remove("to_date");
setState(() {}); setState(() {});
return; return;
} }
@ -224,13 +254,18 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
loaderFlag = true; loaderFlag = true;
try { try {
final result = await apiService.CallReports( final result = await apiService.CallReports(
'advancePurchaseReport', 'misHotelReport',
formattedfromDate, jsonEncode({"fromDate":'$formattedfromDate',"toDate":'$formattedtoDate'}),
formattedtoDate,
); );
setState(() { setState(() {
domesticData = List<Map<String, dynamic>>.from(result['data']['domestic'] ?? []); // domesticData = List<Map<String, dynamic>>.from(result['data']['domestic'] ?? []);
internationalData = List<Map<String, dynamic>>.from(result['data']['international'] ?? []); domesticData = List<Map<String, dynamic>>.from(
result['status'] == 'success' ? result['data']['domestic'] ?? [] : []
);
internationalData = List<Map<String, dynamic>>.from(
result['status'] == 'success' ? result['data']['international'] ?? [] : []
);
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -243,6 +278,51 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
} }
} }
Future<void> handleDownload() async {
final dateFormat = DateFormat('dd-MM-yyyy');
if (textControllers["from_date"]!.text.isEmpty || textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
);
return;
}
final DateTime fromDate = dateFormat.parse(textControllers["from_date"]!.text);
final DateTime toDate = dateFormat.parse(textControllers["to_date"]!.text);
final formattedFromDate = DateFormat('yyyy-MM-dd').format(fromDate);
final formattedToDate = DateFormat('yyyy-MM-dd').format(toDate);
final name =
'MIS Hotel - $selectedTabName Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})';
final safeName = name.replaceAll(RegExp(r'[^\w\s-]'), '');
final excelName = '$safeName';
final result = await apiService.reportExcelDownload(
'misHotelReport',
jsonEncode({
"fromDate": formattedFromDate,
"toDate": formattedToDate,
"export": selectedTabName,
}),
excelName,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.green,
content: Text(result as String),
behavior: SnackBarBehavior.floating,
),
);
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -274,7 +354,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
children: [ children: [
// if (isDesktop) CustomDrawer(isDesktop: true), // if (isDesktop) CustomDrawer(isDesktop: true),
// const Expanded(child: Center(child: Text("User Page Content"))), // const Expanded(child: Center(child: Text("User Page Content"))),
Expanded(child: buildAdvancePurchaseLayout(isDesktop)) Expanded(child: buildMIShotelLayout(isDesktop))
], ],
), ),
), ),
@ -283,11 +363,11 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
); );
} }
Widget buildAdvancePurchaseLayout(bool isDesktop) { Widget buildMIShotelLayout(bool isDesktop) {
return Container( child: buildAdvancePurchaseFormLayout(isDesktop) ); return Container( child: buildMIShotelFormLayout(isDesktop) );
} }
Widget buildAdvancePurchaseFormLayout(bool isDesktop) { Widget buildMIShotelFormLayout(bool isDesktop) {
return Container( return Container(
margin: isDesktop ? EdgeInsets.all(10.0) : null, margin: isDesktop ? EdgeInsets.all(10.0) : null,
padding: const EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20), padding: const EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20),
@ -309,7 +389,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Advance Purchase', 'Mis Hotel Report',
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: isDesktop ? 16 : 14, fontSize: isDesktop ? 16 : 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -327,9 +407,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
), ),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), ),
onPressed: () { onPressed: handleDownload,
// Your Excel export logic here
},
child: Row( child: Row(
children: [ children: [
Text( Text(
@ -344,33 +422,33 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
], ],
), ),
), ),
SizedBox(width: 10), // SizedBox(width: 10),
ElevatedButton( // ElevatedButton(
style: ElevatedButton.styleFrom( // style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF114D8B), // backgroundColor: Color(0xFF114D8B),
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8), // borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Color(0xFF114D8B), width: 2), // side: BorderSide(color: Color(0xFF114D8B), width: 2),
), // ),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), // padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), // ),
onPressed: () { // onPressed: () {
// Your PDF export logic here // // Your PDF export logic here
}, // },
child: Row( // child: Row(
children: [ // children: [
Text( // Text(
"PDF", // "PDF",
style: GoogleFonts.poppins( // style: GoogleFonts.poppins(
fontSize: isDesktop ? 13 : 11, // fontSize: isDesktop ? 13 : 11,
color: Colors.white, // color: Colors.white,
), // ),
), // ),
SizedBox(width: 8), // SizedBox(width: 8),
Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white), // Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
], // ],
), // ),
), // ),
], ],
), ),
], ],
@ -519,8 +597,11 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
], ],
), ),
if (isDesktop) Spacer() else SizedBox(height: 8), if (isDesktop) Spacer() else SizedBox(height: 8),
SizedBox( Padding(
padding: EdgeInsets.only(top: 10, left: 4),
child : SizedBox(
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF114D8B), backgroundColor: Color(0xFF114D8B),
foregroundColor: Colors.white, foregroundColor: Colors.white,
@ -556,6 +637,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
), ),
), ),
), ),
)
], ],
), ),
SizedBox(height: 5), SizedBox(height: 5),
@ -616,65 +698,61 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
), ),
), ),
SizedBox(width: 16), // SizedBox(width: 16),
/// Buttons on the right // /// Buttons on the right
Row( // Row(
children: [ // children: [
ElevatedButton( // ElevatedButton(
style: ElevatedButton.styleFrom( // style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF114D8B), // backgroundColor: Color(0xFF114D8B),
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8), // borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Color(0xFF114D8B), width: 2), // side: BorderSide(color: Color(0xFF114D8B), width: 2),
), // ),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), // padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), // ),
onPressed: () { // onPressed: handleDownload,
// Excel export logic // child: Row(
}, // children: [
child: Row( // Text(
children: [ // "Excel",
Text( // style: GoogleFonts.poppins(
"Excel", // fontSize: isDesktop ? 13 : 11,
style: GoogleFonts.poppins( // color: Colors.white,
fontSize: isDesktop ? 13 : 11, // ),
color: Colors.white, // ),
), // SizedBox(width: 8),
), // Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
SizedBox(width: 8), // ],
Icon(Icons.file_present_outlined, size: 15, color: Colors.white), // ),
], // ),
), // SizedBox(width: 10),
), // ElevatedButton(
SizedBox(width: 10), // style: ElevatedButton.styleFrom(
ElevatedButton( // backgroundColor: Color(0xFF114D8B),
style: ElevatedButton.styleFrom( // shape: RoundedRectangleBorder(
backgroundColor: Color(0xFF114D8B), // borderRadius: BorderRadius.circular(8),
shape: RoundedRectangleBorder( // side: BorderSide(color: Color(0xFF114D8B), width: 2),
borderRadius: BorderRadius.circular(8), // ),
side: BorderSide(color: Color(0xFF114D8B), width: 2), // padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), // ),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), // onPressed: handleDownload,
), // child: Row(
onPressed: () { // children: [
// PDF export logic // Text(
}, // "PDF",
child: Row( // style: GoogleFonts.poppins(
children: [ // fontSize: isDesktop ? 13 : 11,
Text( // color: Colors.white,
"PDF", // ),
style: GoogleFonts.poppins( // ),
fontSize: isDesktop ? 13 : 11, // SizedBox(width: 8),
color: Colors.white, // Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
), // ],
), // ),
SizedBox(width: 8), // ),
Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white), // ],
], // ),
),
),
],
),
], ],
), ),
), ),
@ -748,26 +826,40 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
color: Colors.grey.shade200, color: Colors.grey.shade200,
), ),
), ),
// rows: paginatedDomestic
columns: [ columns: [
DataColumn(label: Text('Plan Id', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Plan Id', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Employee Name', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Flight Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Hotel Name', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Hotel City', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Check In Date', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Check Out Date', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
], ],
rows: paginatedDomestic.map((entry) { rows: paginatedDomestic.map((entry) {
final checkInDate = DateFormat('dd-MM-yyyy').format(DateTime.parse(entry['check_in_date']));
final checkOutDate = DateFormat('dd-MM-yyyy').format(DateTime.parse(entry['check_out_date']));
return DataRow(cells: [ return DataRow(cells: [
DataCell(Text('${entry['plan_id']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['plan_id']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['employee_name']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['flight_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['hotel_name']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['hotel_city']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text(checkInDate, style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text(checkOutDate, style: GoogleFonts.poppins(fontSize: 12))),
]); ]);
}).toList(), }).toList(),
), ),
), ),
), ),
@ -971,24 +1063,35 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
color: Colors.grey.shade200, color: Colors.grey.shade200,
), ),
), ),
// rows: paginatedInternational
columns: [ columns: [
DataColumn(label: Text('Plan Id', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Plan Id', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Employee Name', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Flight Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))), DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Hotel Name', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Hotel City', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Check In Date', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
DataColumn(label: Text('Check Out Date', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
], ],
rows: paginatedInternational.map((entry) { rows: paginatedInternational.map((entry) {
final checkInDate = DateFormat('dd-MM-yyyy').format(DateTime.parse(entry['check_in_date']));
final checkOutDate = DateFormat('dd-MM-yyyy').format(DateTime.parse(entry['check_out_date']));
return DataRow(cells: [ return DataRow(cells: [
DataCell(Text('${entry['plan_id']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['plan_id']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['employee_name']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['flight_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))), DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['hotel_name']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text('${entry['hotel_city']}', style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text(checkInDate, style: GoogleFonts.poppins(fontSize: 12))),
DataCell(Text(checkOutDate, style: GoogleFonts.poppins(fontSize: 12))),
]); ]);
}).toList(), }).toList(),
), ),

View File

@ -30,6 +30,7 @@ class _ReportListState extends State<ReportList> {
void initState() { void initState() {
super.initState(); super.initState();
loadInitialData(); loadInitialData();
_checkAuthAndLoadData();
} }
void loadInitialData() async { void loadInitialData() async {
@ -41,10 +42,29 @@ class _ReportListState extends State<ReportList> {
layoutString != null layoutString != null
? Color(int.parse(layoutString)) ? Color(int.parse(layoutString))
: Colors.redAccent; : Colors.redAccent;
}); });
} }
void _checkAuthAndLoadData() async {
final String? token = await getToken(); // Your async function to get token
if (token == null || token.isEmpty) {
// Token doesn't exist → redirect to login
context.go(
"/",
); // or use: router.go("/") if you're using `GoRouter` directly
return;
}
if (!mounted) return;
try {
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
} catch (e) {
print("service report : $e");
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ResponsiveBuilder( return ResponsiveBuilder(
@ -97,38 +117,37 @@ class _ReportListState extends State<ReportList> {
{ {
'value': '/misServicesAnalysis', 'value': '/misServicesAnalysis',
'icon': Icons.miscellaneous_services, 'icon': Icons.miscellaneous_services,
'label': 'Miscellaneous Services Analysis', 'label': 'MIS Services Analysis',
'description': 'View Miscellaneous Services Analysis', 'description': 'View MIS Services Analysis',
}, },
{ {
'value': '/misAirReport', 'value': '/misAirReport',
'icon': Icons.flight, 'icon': Icons.flight,
'label': 'Miscellaneous Air Report', 'label': 'MIS Air Report',
'description': 'View Miscellaneous Air Report', 'description': 'View MIS Air Report',
}, },
{ {
'value': '/misHotelReport', 'value': '/misHotelReport',
'icon': Icons.add_business, 'icon': Icons.add_business,
'label': 'Miscellaneous Hotel Report', 'label': 'MIS Hotel Report',
'description': 'View Miscellaneous Hotel Report', 'description': 'View MIS Hotel Report',
}, },
{ {
'value': '/misForexReport', 'value': '/misForexReport',
'icon': Icons.credit_card, 'icon': Icons.credit_card,
'label': 'Miscellaneous Forex Report', 'label': 'MIS Forex Report',
'description': 'View Miscellaneous Forex Report', 'description': 'View MIS Forex Report',
}, },
{ {
'value': '/guestHouseReport', 'value': '/guestHouseReport',
'icon': Icons.add_home_work_sharp, 'icon': Icons.home_work,
'label': 'Guest House Report', 'label': 'Guest House Report',
'description': 'View Guest House Report', 'description': 'View Guest House Report',
} },
]; ];
return Container( return Container(
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 12), padding: EdgeInsets.symmetric(vertical: 16, horizontal: 12),
child: Column( child: Column(

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
//api url //api url
// const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be'; const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be'; // const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';

View File

@ -632,11 +632,11 @@ final List<Map<String, dynamic>> menuItems = [
// 'label': 'Template List' // 'label': 'Template List'
// }, // },
// {'value': '/template', 'icon': Icons.ac_unit_sharp, 'label': 'Template'}, // {'value': '/template', 'icon': Icons.ac_unit_sharp, 'label': 'Template'},
// { {
// 'value': '/report', 'value': '/report',
// 'icon': Icons.auto_graph, 'icon': Icons.auto_graph,
// 'label': 'Reports', 'label': 'Reports',
// }, },
{ {
'value': '/CreateUserDetails', 'value': '/CreateUserDetails',
'icon': Icons.account_circle, 'icon': Icons.account_circle,

View File

@ -35,9 +35,9 @@ import '../Screens/traveller/travellerList.dart';
import '../Screens/reports/reportList.dart'; import '../Screens/reports/reportList.dart';
import '../Screens/reports/advancePurchase.dart'; import '../Screens/reports/advancePurchase.dart';
import '../Screens/reports/servicesAnalysis.dart'; import '../Screens/reports/servicesAnalysis.dart';
import '../Screens/reports/miscellaneousAir.dart'; import '../Screens/reports/misAir.dart';
import '../Screens/reports/miscellaneousHotel.dart'; import '../Screens/reports/misHotel.dart';
import '../Screens/reports/miscellaneousForex.dart'; import '../Screens/reports/misForex.dart';
import '../Screens/reports/guestHouse.dart'; import '../Screens/reports/guestHouse.dart';
import 'mainLayout.dart'; import 'mainLayout.dart';
@ -164,15 +164,15 @@ final GoRouter router = GoRouter(
), ),
GoRoute( GoRoute(
path: '/misAirReport', path: '/misAirReport',
builder: (context, state) => MiscellaneousAir(), builder: (context, state) => MISair(),
), ),
GoRoute( GoRoute(
path: '/misHotelReport', path: '/misHotelReport',
builder: (context, state) => MiscellaneousHotel(), builder: (context, state) => MIShotel(),
), ),
GoRoute( GoRoute(
path: '/misForexReport', path: '/misForexReport',
builder: (context, state) => MiscellaneousForex(), builder: (context, state) => MISforex(),
), ),
GoRoute( GoRoute(
path: '/guestHouseReport', path: '/guestHouseReport',

View File

@ -1511,11 +1511,9 @@ class ApiService {
// ----------------------- User Management - CheckDuplicate end here ---------------------------------- // ----------------------- User Management - CheckDuplicate end here ----------------------------------
// ----------------------- Report ------------------------- // ----------------------- Report -------------------------
Future<Map<String, dynamic>> CallReports(String apiRoute,String FromDate,String ToDate) async { Future<Map<String, dynamic>> CallReports(String apiRoute,String body) async {
String apiUrldata = '$apiUrl/api/$apiRoute'; String apiUrldata = '$apiUrl/api/$apiRoute';
final token = await getToken(); final token = await getToken();
final body = jsonEncode({"fromDate":'$FromDate',"toDate":'$ToDate'});
if (token == null) { if (token == null) {
throw Exception('Token not found. Please log in.'); throw Exception('Token not found. Please log in.');
@ -1536,9 +1534,58 @@ class ApiService {
} }
} else { } else {
throw Exception( throw Exception(
'Failed to load checkDuplicate data. Status code: ${response.statusCode}', 'Failed to load data. Status code: ${response.statusCode}',
); );
} }
} }
Future<void> 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'},
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');
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else if (response.statusCode == 404) {
throw Exception('File not found.');
} else {
throw Exception('Failed to Download');
}
}
// ----------------------- Report ------------------------- // ----------------------- Report -------------------------
} }