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