forex calculations
This commit is contained in:
parent
c99ac679a6
commit
42f3f465d5
@ -369,7 +369,7 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
"Welcome To Trip Approval Tools",
|
||||
"Welcome To TripApprovalTool",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
@ -822,55 +822,48 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Future<void> handleMS() async {
|
||||
final url = '$apiUrl/auth/mslogin';
|
||||
print(url);
|
||||
try {
|
||||
final response = await http
|
||||
.get(Uri.parse(url), headers: {'Content-Type': 'application/json'});
|
||||
print("inside try method");
|
||||
if (response.statusCode == 200) {
|
||||
final authUrl = json.decode(response.body)['auth_url'];
|
||||
print("authurl - $authUrl");
|
||||
if (authUrl != '') {
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.setString('auth_token', authUrl);
|
||||
print('i have auth URL');
|
||||
// canLaunchUrl(authUrl);
|
||||
|
||||
final url = '$apiUrl/auth/mslogin';
|
||||
print(url);
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
);
|
||||
print("inside try method");
|
||||
if (response.statusCode == 200) {
|
||||
final authUrl = json.decode(response.body)['auth_url'];
|
||||
print("authurl - $authUrl");
|
||||
if(authUrl != ''){
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.setString('auth_token', authUrl);
|
||||
print('i have auth URL');
|
||||
// canLaunchUrl(authUrl);
|
||||
if (kIsWeb) {
|
||||
print("kIsWeb");
|
||||
// Use web redirect (e.g., via JS interop or window.location.href)
|
||||
// redirectTo(url);
|
||||
|
||||
if (kIsWeb) {
|
||||
print("kIsWeb");
|
||||
// Use web redirect (e.g., via JS interop or window.location.href)
|
||||
// redirectTo(url);
|
||||
|
||||
html.window.location.href = authUrl;
|
||||
} else {
|
||||
// For mobile/desktop, open in external browser
|
||||
// launchUrl(Uri.parse(url),
|
||||
// mode: LaunchMode.externalApplication);
|
||||
}
|
||||
// final result = await FlutterWebAuth.authenticate(
|
||||
// url: authUrl,
|
||||
// callbackUrlScheme: "myapp", // Use a custom scheme you registered
|
||||
// );
|
||||
}else{
|
||||
print('auth URL not Founded');
|
||||
throw Exception('auth URL not Founded');
|
||||
html.window.location.href = authUrl;
|
||||
} else {
|
||||
// For mobile/desktop, open in external browser
|
||||
// launchUrl(Uri.parse(url),
|
||||
// mode: LaunchMode.externalApplication);
|
||||
}
|
||||
}else{
|
||||
final errorMessage = json.decode(response.body)['message'];
|
||||
print(errorMessage);
|
||||
throw Exception(errorMessage);
|
||||
// final result = await FlutterWebAuth.authenticate(
|
||||
// url: authUrl,
|
||||
// callbackUrlScheme: "myapp", // Use a custom scheme you registered
|
||||
// );
|
||||
} else {
|
||||
print('auth URL not Founded');
|
||||
throw Exception('auth URL not Founded');
|
||||
}
|
||||
} else {
|
||||
final errorMessage = json.decode(response.body)['message'];
|
||||
print(errorMessage);
|
||||
throw Exception(errorMessage);
|
||||
}
|
||||
catch (e) {
|
||||
print("Error: $e");
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
print("Error: $e");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ class DepartmentList extends StatefulWidget {
|
||||
|
||||
class DepartmentListState extends State<DepartmentList> {
|
||||
final GlobalKey<DepartmentListState> departmentListKey =
|
||||
GlobalKey<DepartmentListState>();
|
||||
GlobalKey<DepartmentListState>();
|
||||
|
||||
final ApiService apiService = ApiService();
|
||||
late Future<List<dynamic>> futureDepartment;
|
||||
@ -97,7 +97,6 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchGetDepartment() async {
|
||||
|
||||
final String apiUrlData = '$apiUrl/api/getDepartmentList';
|
||||
|
||||
final String? token = await getToken();
|
||||
@ -142,19 +141,18 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
print("all before filtering: $query");
|
||||
final lowerQuery = query.toLowerCase();
|
||||
setState(() {
|
||||
filteredDepartment = allDepartment.where((object) {
|
||||
final isActiveStatus =
|
||||
object['is_active'] == "1" ? "active" : "inactive";
|
||||
return (object['department_id']?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(object['name']?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(object['description']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||
(isActiveStatus.contains(lowerQuery));
|
||||
}).toList();
|
||||
filteredDepartment = allDepartment.where((object) {
|
||||
final isActiveStatus =
|
||||
object['is_active'] == "1" ? "active" : "inactive";
|
||||
return (object['department_id']?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(object['name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||
(object['description']?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(isActiveStatus.contains(lowerQuery));
|
||||
}).toList();
|
||||
});
|
||||
print("filteredDepartment: $filteredDepartment");
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
@ -171,11 +169,11 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
body: Padding(
|
||||
padding: isDesktop
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.1, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0, // 5% of screen height as vertical padding
|
||||
)
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.1, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
children: [
|
||||
@ -297,7 +295,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side:
|
||||
BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20, vertical: 12),
|
||||
@ -317,7 +315,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Add Department",
|
||||
@ -344,46 +342,46 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
isDesktop
|
||||
? SizedBox.shrink()
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: filterDepartment,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Color(0xFF9E9DBD)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF9E9DBD),
|
||||
size: 18,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: filterDepartment,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Color(0xFF9E9DBD)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF9E9DBD),
|
||||
size: 18,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade200,
|
||||
width: 0.5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade200,
|
||||
width: 0.5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
// SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
FutureBuilder<List<dynamic>>(
|
||||
future: futureDepartment,
|
||||
@ -432,8 +430,9 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
);
|
||||
}
|
||||
/* Here collect the list to displayed the data in table or card Used */
|
||||
List<dynamic> object =
|
||||
filteredDepartment.isNotEmpty ? filteredDepartment : allDepartment;
|
||||
List<dynamic> object = filteredDepartment.isNotEmpty
|
||||
? filteredDepartment
|
||||
: allDepartment;
|
||||
|
||||
/* List is Sorting here */
|
||||
object.sort((a, b) {
|
||||
@ -454,7 +453,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
Widget table = LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
double minWidth =
|
||||
isDesktop ? constraints.maxWidth : 1300;
|
||||
isDesktop ? constraints.maxWidth : 1300;
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: minWidth),
|
||||
@ -468,64 +467,67 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Department ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
'Department ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
'Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Description',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
'Description',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedDepartment.map((tableObject) {
|
||||
String departmentId = tableObject['department_id']
|
||||
.toString(); // Get user ID
|
||||
bool isSelected = selectedDepartmentId == departmentId;
|
||||
String departmentId =
|
||||
tableObject['department_id']
|
||||
.toString(); // Get user ID
|
||||
bool isSelected =
|
||||
selectedDepartmentId == departmentId;
|
||||
|
||||
return DataRow(cells: [
|
||||
DataCell(
|
||||
Text("${tableObject['department_id'] ?? ''}",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
))),
|
||||
DataCell(Text(
|
||||
"${tableObject['department_id'] ?? ''}",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
))),
|
||||
DataCell(Text(tableObject['name'] ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
))),
|
||||
DataCell(Text(tableObject['description'] ?? 'N/A',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
DataCell(
|
||||
Text(tableObject['description'] ?? 'N/A',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis)),
|
||||
DataCell(
|
||||
Text(
|
||||
tableObject['is_active'] == "1"
|
||||
@ -534,7 +536,9 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
color: tableObject['is_active'] == "1" ? Colors.green : Colors.red,
|
||||
color: tableObject['is_active'] == "1"
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
),
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@ -558,17 +562,21 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
final departmentId = int.tryParse(
|
||||
tableObject['department_id']
|
||||
.toString());
|
||||
|
||||
if (departmentId != null) {
|
||||
print("Table cell - department Id -- $departmentId");
|
||||
final data = await apiService.getDepartmentDetailsFind(departmentId);
|
||||
print(
|
||||
"Table cell - department Id -- $departmentId");
|
||||
final data = await apiService
|
||||
.getDepartmentDetailsFind(
|
||||
departmentId);
|
||||
print("DepartmentId -- $data");
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => DepartmentData(
|
||||
builder: (context) =>
|
||||
DepartmentData(
|
||||
isDesktop: isDesktop,
|
||||
departmentId: departmentId, // Pass the ID
|
||||
departmentId:
|
||||
departmentId, // Pass the ID
|
||||
departmentData: data,
|
||||
layoutColor: layoutColor!,
|
||||
// fetchGetForex: fetchGetForex,
|
||||
@ -612,7 +620,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
// Status and Employee Code
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
cardObject['department_id'] ?? 'N/A',
|
||||
@ -636,20 +644,25 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
.toString());
|
||||
|
||||
if (departmentId != null) {
|
||||
print("departmentId -- $departmentId");
|
||||
print(
|
||||
"departmentId -- $departmentId");
|
||||
final data = await apiService
|
||||
.getDepartmentDetailsFind(departmentId);
|
||||
.getDepartmentDetailsFind(
|
||||
departmentId);
|
||||
print("DepartmentId -- $data");
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => DepartmentData(
|
||||
builder: (context) =>
|
||||
DepartmentData(
|
||||
isDesktop: isDesktop,
|
||||
departmentId:departmentId, // Pass the ID
|
||||
departmentData:data,
|
||||
layoutColor:layoutColor!,
|
||||
departmentId:
|
||||
departmentId, // Pass the ID
|
||||
departmentData: data,
|
||||
layoutColor: layoutColor!,
|
||||
// fetchGetDepartment: fetchGetDepartment,
|
||||
fetchGetDepartment: refreshData,
|
||||
fetchGetDepartment:
|
||||
refreshData,
|
||||
// role:
|
||||
// "Travel Agent"
|
||||
),
|
||||
@ -742,7 +755,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
cardObject['name'] ?? '',
|
||||
@ -757,7 +770,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
cardObject['description'] ?? '',
|
||||
@ -779,39 +792,39 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return Expanded(
|
||||
child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: isDesktop
|
||||
? (searchController.text.isNotEmpty &&
|
||||
filteredDepartment.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"No matches found",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: Colors.grey),
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: table,
|
||||
))
|
||||
: (searchController.text.isNotEmpty &&
|
||||
filteredDepartment.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"No matches found",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: Colors.grey),
|
||||
),
|
||||
)
|
||||
: buildMobileCardView(paginatedDepartment)),
|
||||
),
|
||||
Expanded(
|
||||
child: isDesktop
|
||||
? (searchController.text.isNotEmpty &&
|
||||
filteredDepartment.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"No matches found",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: Colors.grey),
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: table,
|
||||
))
|
||||
: (searchController.text.isNotEmpty &&
|
||||
filteredDepartment.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"No matches found",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: Colors.grey),
|
||||
),
|
||||
)
|
||||
: buildMobileCardView(
|
||||
paginatedDepartment)),
|
||||
),
|
||||
// Expanded(
|
||||
// child: isDesktop
|
||||
// ? SingleChildScrollView(
|
||||
@ -846,4 +859,4 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -51,11 +52,16 @@ class ForexDataState extends State<ForexData> {
|
||||
int? forexDataId;
|
||||
late String isActive = "1";
|
||||
|
||||
bool isCashEditing = false;
|
||||
bool isCardEditing = false;
|
||||
|
||||
List<String> dataHeader = [
|
||||
"country_code",
|
||||
"country",
|
||||
"currency",
|
||||
"perdiemAmount"
|
||||
"perdiemAmount",
|
||||
"cash",
|
||||
"card"
|
||||
];
|
||||
|
||||
Map<String, dynamic> forex_Detials() {
|
||||
@ -64,6 +70,8 @@ class ForexDataState extends State<ForexData> {
|
||||
"country_code": selectedCountry,
|
||||
"country_name": selectedCountryName,
|
||||
"currency": controllers["currency"]?.text,
|
||||
"cash_percentage": controllers["cash"]?.text,
|
||||
"card_percentage": controllers["card"]?.text,
|
||||
"perdiem_amount": controllers["perdiemAmount"]?.text,
|
||||
"is_active": 1,
|
||||
"created_by": userId,
|
||||
@ -82,6 +90,10 @@ class ForexDataState extends State<ForexData> {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
fetchCountries();
|
||||
|
||||
controllers["cash"]?.addListener(_handleCashChange);
|
||||
controllers["card"]?.addListener(_handleCardChange);
|
||||
|
||||
if (widget.forexId != null) {
|
||||
print('Editing Forex ID: ${widget.forexId}');
|
||||
updateForexDetails();
|
||||
@ -116,6 +128,8 @@ class ForexDataState extends State<ForexData> {
|
||||
selectedCurrency = data['currency']; // Optional if used elsewhere
|
||||
|
||||
controllers['currency']?.text = data['currency'] ?? '';
|
||||
controllers['cash']?.text = data['cash_percentage'] ?? '';
|
||||
controllers['card']?.text = data['card_percentage'] ?? '';
|
||||
controllers['perdiemAmount']?.text = data['perdiem_amount'].toString();
|
||||
isActive = data["is_active"];
|
||||
final forexId = int.tryParse(data['forex_perdiem_id'].toString());
|
||||
@ -140,6 +154,31 @@ class ForexDataState extends State<ForexData> {
|
||||
});
|
||||
}
|
||||
|
||||
void _handleCashChange() {
|
||||
if (isCardEditing) return; // Prevent circular update
|
||||
|
||||
isCashEditing = true;
|
||||
final cashText = controllers["cash"]?.text ?? '';
|
||||
final cash = int.tryParse(cashText) ?? 0;
|
||||
|
||||
final card = 100 - cash;
|
||||
controllers["card"]?.text = card.toString();
|
||||
isCashEditing = false;
|
||||
}
|
||||
|
||||
void _handleCardChange() {
|
||||
if (isCashEditing) return; // Prevent circular update
|
||||
|
||||
final cash = int.tryParse(controllers["cash"]?.text ?? '') ?? 0;
|
||||
final card = int.tryParse(controllers["card"]?.text ?? '') ?? 0;
|
||||
|
||||
if (cash + card != 100) {
|
||||
errorMessages["cash_percentage"] = "Cash and card must total 100%";
|
||||
} else {
|
||||
errorMessages.remove("cash_percentage");
|
||||
}
|
||||
}
|
||||
|
||||
bool validateData() {
|
||||
errorMessages.clear();
|
||||
|
||||
@ -147,6 +186,8 @@ class ForexDataState extends State<ForexData> {
|
||||
"country_code": selectedCountry,
|
||||
"country": selectedCountryName,
|
||||
"currency": controllers["currency"]?.text,
|
||||
"cash_percentage": controllers["cash"]?.text,
|
||||
"card_percentage": controllers["card"]?.text,
|
||||
"perdiemAmount": controllers["perdiemAmount"]?.text,
|
||||
};
|
||||
|
||||
@ -154,7 +195,9 @@ class ForexDataState extends State<ForexData> {
|
||||
"country_code",
|
||||
"country",
|
||||
"currency",
|
||||
"perdiemAmount"
|
||||
"perdiemAmount",
|
||||
"cash_percentage",
|
||||
"card_percentage"
|
||||
];
|
||||
|
||||
// Check validation for each field
|
||||
@ -164,6 +207,13 @@ class ForexDataState extends State<ForexData> {
|
||||
}
|
||||
}
|
||||
|
||||
final cash = int.tryParse(data["cash_percentage"] ?? '') ?? 0;
|
||||
final card = int.tryParse(data["card_percentage"] ?? '') ?? 0;
|
||||
|
||||
if (cash + card != 100) {
|
||||
errorMessages["card_percentage"] = "Total must be 100%";
|
||||
}
|
||||
|
||||
return errorMessages.isEmpty;
|
||||
}
|
||||
|
||||
@ -431,6 +481,107 @@ class ForexDataState extends State<ForexData> {
|
||||
),
|
||||
// if (isDesktop)SizedBox(width: 8,) else SizedBox(height: 8,),
|
||||
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Cash",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
color: Colors.transparent,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.09
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["cash"],
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Cash",
|
||||
labelStyle:
|
||||
TextStyle(fontSize: 11, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
)),
|
||||
),
|
||||
if (errorMessages["cash_percentage"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["cash_percentage"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Card",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
color: Colors.transparent,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.09
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["card"],
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Card",
|
||||
labelStyle:
|
||||
TextStyle(fontSize: 11, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
)),
|
||||
),
|
||||
if (errorMessages["card_percentage"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["card_percentage"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
|
||||
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/Screens/group/group.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -209,9 +210,14 @@ class _GroupListState extends State<GroupList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text('Group List',
|
||||
style:
|
||||
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
Text(
|
||||
'Group List',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
onPressed: () {},
|
||||
@ -234,7 +240,7 @@ class _GroupListState extends State<GroupList> {
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Text('New Group'),
|
||||
Text('New Group', style: GoogleFonts.poppins(fontSize: 12)),
|
||||
SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
@ -300,9 +306,24 @@ class _GroupListState extends State<GroupList> {
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text("Group Name: ${group['name']}",
|
||||
style: TextStyle(
|
||||
fontSize: 13, fontWeight: FontWeight.bold)),
|
||||
child: Text("Group Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5, fontWeight: FontWeight.w400)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text("Domestic Policy",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5, fontWeight: FontWeight.w400)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text("International Policy",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5, fontWeight: FontWeight.w400)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text("Description",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5, fontWeight: FontWeight.w400)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -311,9 +332,23 @@ class _GroupListState extends State<GroupList> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Policy: ${group['domestic_policy_name'] ?? group['international_policy_name']}")),
|
||||
Expanded(child: Text("${group['description'] ?? 'N/A'}")),
|
||||
child: Text("${group['name']}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text("${group['domestic_policy_name'] ?? 'N/A'}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text("${group['international_policy_name']}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600))),
|
||||
Expanded(
|
||||
child: Text("${group['description'] ?? 'N/A'}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600))),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
||||
@ -42,8 +42,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
|
||||
late ValueNotifier<String?> flightFirstTripDateNotifier;
|
||||
late ValueNotifier<String?> flightLastTripDateNotifier;
|
||||
// late final tripuserId;
|
||||
String? tripuserId;
|
||||
|
||||
late String? userCardNumber;
|
||||
// late String? userCardNumber;
|
||||
|
||||
Map<String, String?> selectedValues = {};
|
||||
bool isChecked = false; // State variable for checkbox
|
||||
@ -97,6 +99,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
String? selectedPerdiemAmount;
|
||||
String? CalculatedOtherExpenses;
|
||||
String? selectedQuotedAmount;
|
||||
int? selectedCashPercent;
|
||||
int? selectedCardPercent;
|
||||
|
||||
bool userEdited = false;
|
||||
|
||||
Map<String, dynamic> get forexData {
|
||||
Map<String, dynamic> data = {
|
||||
@ -116,6 +122,8 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
"delivery_location": textControllers["_deliveryLocation"]?.text,
|
||||
"comments": textControllers["_comments"]?.text,
|
||||
"total": selectedQuotedAmount,
|
||||
"card_percentage": selectedCardPercent,
|
||||
"cash_percentage": selectedCashPercent,
|
||||
"created_by": widget.loginUser,
|
||||
"updated_by": widget.loginUser,
|
||||
};
|
||||
@ -138,6 +146,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
"country_code": selectedCountry,
|
||||
"start_date": _formatDate(textControllers["_forexStartDate"]?.text),
|
||||
"end_date": _formatDate(textControllers["_forexEndDate"]?.text),
|
||||
"user_id": tripuserId
|
||||
// "currency": selectedCurrency ?? "",
|
||||
};
|
||||
}
|
||||
@ -186,6 +195,13 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
selectedDuration = responseData["duration"]?.toString() ?? "";
|
||||
selectedQuotedAmount =
|
||||
responseData["perdiem_amount"]?.toString() ?? "";
|
||||
selectedCardPercent =
|
||||
int.tryParse(responseData["card_percentage"]?.toString() ?? "");
|
||||
selectedCashPercent =
|
||||
int.tryParse(responseData["cash_percentage"]?.toString() ?? "");
|
||||
|
||||
textControllers["_cardNumber"]?.text =
|
||||
responseData["forex_card_no"]?.toString() ?? "";
|
||||
});
|
||||
_onFieldChangedForOthers();
|
||||
_divideQuotedAmount();
|
||||
@ -325,7 +341,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
flightFirstTripDateNotifier = ValueNotifier<String?>(null);
|
||||
flightLastTripDateNotifier = ValueNotifier<String?>(null);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
tripuserId = await getTripUserId();
|
||||
|
||||
print("tripuserId - $tripuserId");
|
||||
final result = getFlightTripDateRange(widget.flightData);
|
||||
flightFirstTripDateNotifier.value = result['firstTripDate'];
|
||||
flightLastTripDateNotifier.value = result['lastTripDate'];
|
||||
@ -351,15 +370,15 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
|
||||
void handleUpdatedField() async {
|
||||
// Set the selected value if available
|
||||
|
||||
userCardNumber = await getForexCardNumber();
|
||||
// userCardNumber = "CD7909043";
|
||||
print("userCardNumber - $userCardNumber");
|
||||
//
|
||||
// userCardNumber = await getForexCardNumber();
|
||||
// // userCardNumber = "CD7909043";
|
||||
// print("userCardNumber - $userCardNumber");
|
||||
|
||||
if (widget.selectedItem == null &&
|
||||
textControllers["_cardNumber"]?.text == "") {
|
||||
print("userCardNumber11 - $userCardNumber");
|
||||
textControllers["_cardNumber"]?.text = userCardNumber ?? "";
|
||||
// print("userCardNumber11 - $userCardNumber");
|
||||
// textControllers["_cardNumber"]?.text = userCardNumber ?? "";
|
||||
}
|
||||
|
||||
if (widget.selectedItem != null) {
|
||||
@ -381,13 +400,20 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
selectedCountry = widget.selectedItem!["country_code"] as String?;
|
||||
selectedCurrency = widget.selectedItem!["currency"] as String?;
|
||||
selectedDuration = widget.selectedItem!["duration"] as String?;
|
||||
selectedCardPercent = int.tryParse(
|
||||
widget.selectedItem!["card_percentage"]?.toString() ?? "");
|
||||
selectedCashPercent = int.tryParse(
|
||||
widget.selectedItem!["cash_percentage"]?.toString() ?? "");
|
||||
selectedPerdiemAmount = widget.selectedItem!["perdiem_amount"] as String?;
|
||||
isChecked =
|
||||
widget.selectedItem!["have_card"] == "1"; // Convert string to bool
|
||||
textControllers["_cardNumber"]?.text =
|
||||
widget.selectedItem!["card_number"]?.toString() ?? "";
|
||||
|
||||
// if (textControllers["_cardNumber"] != null) {
|
||||
// print("userCardNumber11 - $userCardNumber");
|
||||
// textControllers["_cardNumber"]!.text = userCardNumber ?? '';
|
||||
//
|
||||
// }
|
||||
|
||||
_onFieldChangedForOthers();
|
||||
@ -431,7 +457,11 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
}
|
||||
|
||||
if (_isForexDataComplete()) {
|
||||
postgetForexData(getForexData);
|
||||
if (tripuserId != null) {
|
||||
postgetForexData(getForexData);
|
||||
} else {
|
||||
print("tripuserId is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,35 +533,42 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
selectedQuotedAmount =
|
||||
((perdiemAmount + calclateVal).toString() ?? 0) as String?;
|
||||
});
|
||||
_divideQuotedAmount();
|
||||
|
||||
if (userEdited) {
|
||||
_divideQuotedAmount();
|
||||
}
|
||||
errorMessages.clear();
|
||||
}
|
||||
|
||||
void _divideQuotedAmount() {
|
||||
int? quotedAmount = int.tryParse(selectedQuotedAmount!);
|
||||
print("quotedAmount - $selectedQuotedAmount");
|
||||
|
||||
print("DIVIDREFD - $selectedQuotedAmount -$quotedAmount");
|
||||
if (quotedAmount != null) {
|
||||
fifteenPercent =
|
||||
(quotedAmount * 15) ~/ 100; // Calculate 15% (integer division)
|
||||
// fifteenPercent = (quotedAmount * 15) ~/ 100;
|
||||
print("selectedCardPercent - $selectedCashPercent");
|
||||
fifteenPercent = (quotedAmount * selectedCashPercent!) ~/
|
||||
100; // Calculate 15% (integer division)
|
||||
remainingAmount = quotedAmount - fifteenPercent; // Subtract from total
|
||||
|
||||
// Only set text if the field is empty (user hasn't typed)
|
||||
if (textControllers["_cash"] != null &&
|
||||
textControllers["_cash"]!.text.trim().isEmpty) {
|
||||
textControllers["_cash"]!.text = fifteenPercent.toString();
|
||||
} else {
|
||||
print("_cash already has user input, not overwriting");
|
||||
}
|
||||
// // Only set text if the field is empty (user hasn't typed)
|
||||
// if (textControllers["_cash"] != null &&
|
||||
// textControllers["_cash"]!.text.trim().isEmpty) {
|
||||
// textControllers["_cash"]!.text = fifteenPercent.toString();
|
||||
// } else {
|
||||
// print("_cash already has user input, not overwriting");
|
||||
// }
|
||||
//
|
||||
// if (textControllers["_card"] != null &&
|
||||
// textControllers["_card"]!.text.trim().isEmpty) {
|
||||
// textControllers["_card"]!.text = remainingAmount.toString();
|
||||
// } else {
|
||||
// print("_card already has user input, not overwriting");
|
||||
// }
|
||||
|
||||
if (textControllers["_card"] != null &&
|
||||
textControllers["_card"]!.text.trim().isEmpty) {
|
||||
textControllers["_card"]!.text = remainingAmount.toString();
|
||||
} else {
|
||||
print("_card already has user input, not overwriting");
|
||||
}
|
||||
|
||||
// textControllers["_cash"]?.text = fifteenPercent.toString();
|
||||
// textControllers["_card"]?.text = remainingAmount.toString();
|
||||
textControllers["_cash"]?.text = fifteenPercent.toString();
|
||||
textControllers["_card"]?.text = remainingAmount.toString();
|
||||
print("15% Amount: $fifteenPercent");
|
||||
print("Remaining Amount: $remainingAmount");
|
||||
} else {
|
||||
@ -588,13 +625,13 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
print('CardAmount - $cardAmount');
|
||||
textControllers["_card"]?.text = difference.toString();
|
||||
|
||||
if (enteredAmount == null || enteredAmount > fifteenPercent) {
|
||||
errorMessages["deposit_on_cash"] = "Amount cannot exceed $fifteenPercent";
|
||||
} else if (checkValidAmount == quotedAmount) {
|
||||
errorMessages["deposit_on_card"] = " "; // Clear error if valid
|
||||
} else {
|
||||
errorMessages["deposit_on_cash"] = ""; // Clear error if valid
|
||||
}
|
||||
// if (enteredAmount > fifteenPercent) {
|
||||
// errorMessages["deposit_on_cash"] = "Amount cannot exceed $fifteenPercent";
|
||||
// } else if (checkValidAmount == quotedAmount) {
|
||||
// errorMessages["deposit_on_card"] = " "; // Clear error if valid
|
||||
// } else {
|
||||
// errorMessages["deposit_on_cash"] = ""; // Clear error if valid
|
||||
// }
|
||||
|
||||
// Refresh UI if using StatefulWidget
|
||||
setState(() {});
|
||||
@ -1253,7 +1290,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_transport"],
|
||||
controller: textControllers["_transport"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
userEdited = true;
|
||||
});
|
||||
_onFieldChangedForOthers();
|
||||
},
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
@ -1324,7 +1366,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_accomodation"],
|
||||
controller: textControllers["_accomodation"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
userEdited = true;
|
||||
});
|
||||
_onFieldChangedForOthers();
|
||||
},
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
@ -1396,7 +1443,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_telephone"],
|
||||
controller: textControllers["_telephone"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
userEdited = true;
|
||||
});
|
||||
_onFieldChangedForOthers();
|
||||
},
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
@ -1536,6 +1588,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
style: const TextStyle(fontSize: 12),
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (value) {
|
||||
// errorMessages["deposit_on_cash"] = "";
|
||||
_validateCashAmount(
|
||||
value); // Call validation when text changes
|
||||
},
|
||||
|
||||
@ -610,13 +610,13 @@ class TemplatesListState extends State<TemplatesList> {
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Attributes',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
// DataColumn(
|
||||
// label: Text(
|
||||
// 'Attributes',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 13,
|
||||
// fontWeight: FontWeight.w600),
|
||||
// )),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Actions',
|
||||
@ -640,12 +640,12 @@ class TemplatesListState extends State<TemplatesList> {
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
))),
|
||||
DataCell(Text(
|
||||
getPlaceholderNames(forex['placeholder']),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
))),
|
||||
// DataCell(Text(
|
||||
// getPlaceholderNames(forex['placeholder']),
|
||||
// style: TextStyle(
|
||||
// fontSize: 13,
|
||||
// fontFamily: "Inter",
|
||||
// ))),
|
||||
DataCell(
|
||||
// UserActionsMenu(
|
||||
// user: forex,
|
||||
@ -661,14 +661,14 @@ class TemplatesListState extends State<TemplatesList> {
|
||||
// final userId = getUserId(user['user_id']);
|
||||
// final usersData = await getUserDetails(userId);
|
||||
//
|
||||
final forexId = int.tryParse(
|
||||
final templateId = int.tryParse(
|
||||
forex['forex_perdiem_id']
|
||||
.toString());
|
||||
|
||||
if (forexId != null) {
|
||||
print("ForexId -- $forexId");
|
||||
if (templateId != null) {
|
||||
print("templateId -- $templateId");
|
||||
final data = await apiService
|
||||
.getForexDetailsFind(forexId);
|
||||
.getTemplateFind(templateId);
|
||||
print("ForexId -- $data");
|
||||
} else {
|
||||
print("Invalid Forex ID");
|
||||
@ -725,24 +725,24 @@ class TemplatesListState extends State<TemplatesList> {
|
||||
|
||||
SizedBox(height: 2),
|
||||
// Trip Id and Trip Name
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
getPlaceholderNames(
|
||||
forex['placeholder']),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// Row(
|
||||
// children: [
|
||||
// Column(
|
||||
// crossAxisAlignment:
|
||||
// CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// getPlaceholderNames(
|
||||
// forex['placeholder']),
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// color: Colors.black87,
|
||||
// fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
|
||||
// Actions
|
||||
// Actions
|
||||
|
||||
@ -680,7 +680,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
}
|
||||
}
|
||||
|
||||
void getSelectedPlanFor() {
|
||||
Future<void> getSelectedPlanFor() async {
|
||||
var userTripId;
|
||||
// if (!mounted) return;
|
||||
print("getSelectedPlanFor");
|
||||
setState(() {
|
||||
@ -689,18 +690,24 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
if (selectedIstravelUser!) {
|
||||
planUsrId = "";
|
||||
planTravlrId = selectedplanUserId;
|
||||
userTripId = selectedplanUserId;
|
||||
} else {
|
||||
planUsrId = selectedplanUserId;
|
||||
planTravlrId = "";
|
||||
userTripId = selectedplanUserId;
|
||||
}
|
||||
} else {
|
||||
print("Is USER ID - $planUsrId ");
|
||||
planUsrId = selfId;
|
||||
planTravlrId = "";
|
||||
_selectedOption = "Option 1";
|
||||
userTripId = selfId;
|
||||
}
|
||||
});
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('trip_planned_user', userTripId);
|
||||
|
||||
print("USER ID - $planUsrId , TRAVELLER ID - $planTravlrId");
|
||||
}
|
||||
|
||||
|
||||
@ -2416,7 +2416,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Country...",
|
||||
hintText: "Search Airline...",
|
||||
hintStyle: GoogleFonts.poppins(fontSize: 11.5),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
@ -2435,7 +2435,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Country",
|
||||
selectedItem ?? "Select Airline",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
|
||||
@ -887,6 +887,51 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
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.get(
|
||||
Uri.parse(apiUrldata),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
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<bool> showCancelConfirmationDialog(
|
||||
BuildContext context, Color? layoutColor) async {
|
||||
return await showDialog<bool>(
|
||||
|
||||
@ -7,6 +7,11 @@ Future<String?> getToken() async {
|
||||
return prefs.getString("auth_token");
|
||||
}
|
||||
|
||||
Future<String?> getTripUserId() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("trip_planned_user");
|
||||
}
|
||||
|
||||
Future<String?> getLayoutColor() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("layout_color");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user