issues fixes
This commit is contained in:
parent
1005ff962d
commit
5d7faf309a
@ -1012,6 +1012,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
return OfficeDetails(
|
||||
isDesktop: isDesktop, // pass isDesktop as a named argument
|
||||
isViewMode: isViewMode,
|
||||
userIdApi:userIdApi,
|
||||
controllers: controllers,
|
||||
errorMessages: errorMessages,
|
||||
selectedLevel: selectedLevel,
|
||||
@ -1062,12 +1063,14 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
errorMessages: errorMessages,
|
||||
travelDetails: travelDetailsDataFromAPI, // 👈 Pass this down
|
||||
passportFileUrlFromApi: passportFileUrlFromApi,
|
||||
userIdApi:userIdApi,
|
||||
);
|
||||
default:
|
||||
return PersonalDetails(
|
||||
personalDetailsKey: personalDetailsKey,
|
||||
isDesktop: isDesktop, // pass isDesktop as a named argument
|
||||
isViewMode: isViewMode,
|
||||
userIdApi:userIdApi,
|
||||
controllers: controllers,
|
||||
errorMessages: errorMessages,
|
||||
selectedGender: selectedGender,
|
||||
|
||||
@ -15,6 +15,8 @@ class OfficeDetails extends StatefulWidget {
|
||||
final Map<String, String> errorMessages;
|
||||
final bool isDesktop;
|
||||
final bool isViewMode;
|
||||
final String? userIdApi;
|
||||
|
||||
|
||||
final ValueChanged<String?>? onLevelChanged;
|
||||
final ValueChanged<String?>? onDepartmentChanged;
|
||||
@ -48,6 +50,7 @@ class OfficeDetails extends StatefulWidget {
|
||||
this.onThirdApproverChanged,
|
||||
this.selectedSubstituteApprover,
|
||||
this.onFirstSubsApproverChanged,
|
||||
this.userIdApi,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -154,6 +157,28 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
fetchFindGroup();
|
||||
}
|
||||
|
||||
Future<void> apiCheckDuplicate(String label, String field, String value, String? userId) async {
|
||||
try {
|
||||
|
||||
if (field == "employeeCode") {
|
||||
field = "employee_code";
|
||||
}
|
||||
|
||||
final response = await apiService.CheckDuplicate(label, field, value, userId);
|
||||
if (response.isNotEmpty) {
|
||||
_clearError(field);
|
||||
widget.errorMessages[field] = response['message'] ?? "$label already exists";
|
||||
print("Duplicate found: ${response['message']}");
|
||||
return;
|
||||
} else {
|
||||
_clearError(field);
|
||||
print("No duplicates found.");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error in checkDuplicate: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _clearError(String field) {
|
||||
setState(() {
|
||||
widget.errorMessages.remove(field);
|
||||
@ -412,6 +437,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("employeeCode");
|
||||
apiCheckDuplicate("Employee Code", "employeeCode",value,widget.userIdApi);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "Employee Code",
|
||||
|
||||
@ -157,6 +157,34 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> apiCheckDuplicate(String label, String field, String value, String? userId) async {
|
||||
try {
|
||||
// Basic validation: Check mobile number length
|
||||
if (field == "mobile_no" && value.length != 10) {
|
||||
_clearError(field);
|
||||
widget.errorMessages[field] = "$label is invalid";
|
||||
print("Validation failed: $label is too short.");
|
||||
return; // Skip the API call if input is invalid
|
||||
}
|
||||
|
||||
final response = await apiService.CheckDuplicate(label, field, value, userId);
|
||||
if (response.isNotEmpty) {
|
||||
_clearError(field);
|
||||
widget.errorMessages[field] = response['message'] ?? "$label already exists";
|
||||
print("Duplicate found: ${response['message']}");
|
||||
return;
|
||||
} else {
|
||||
_clearError(field);
|
||||
print("No duplicates found.");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error in checkDuplicate: $e");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void _clearError(String field) {
|
||||
setState(() {
|
||||
widget.errorMessages.remove(field);
|
||||
@ -1004,6 +1032,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
controller: widget.controllers["email"],
|
||||
onChanged: (value) {
|
||||
_clearError("email");
|
||||
apiCheckDuplicate("Email", "email",value,widget.userIdApi);
|
||||
},
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
@ -1054,6 +1083,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("mobile_no");
|
||||
apiCheckDuplicate("Mobile Number", "mobile_no",value,widget.userIdApi);
|
||||
},
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
|
||||
@ -31,6 +31,8 @@ class TravellerDetails extends StatefulWidget {
|
||||
final bool isViewMode;
|
||||
final Map<String, dynamic>? travelDetails;
|
||||
final String? passportFileUrlFromApi;
|
||||
final String? userIdApi;
|
||||
|
||||
|
||||
const TravellerDetails({
|
||||
Key? key,
|
||||
@ -40,6 +42,7 @@ class TravellerDetails extends StatefulWidget {
|
||||
required this.isViewMode,
|
||||
this.travelDetails,
|
||||
this.passportFileUrlFromApi,
|
||||
this.userIdApi,
|
||||
}) : super(key: key);
|
||||
@override
|
||||
TravellerDetailsState createState() => TravellerDetailsState();
|
||||
@ -146,6 +149,26 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> apiCheckDuplicate(String label, String field, String value, String? userId) async {
|
||||
try {
|
||||
if(field == "forex_card_num"){
|
||||
field = "forex_pre_paid_card_number";
|
||||
}
|
||||
final response = await apiService.CheckDuplicate(label, field, value, userId);
|
||||
if (response.isNotEmpty) {
|
||||
_clearError(field);
|
||||
widget.errorMessages[field] = response['message'] ?? "$label already exists";
|
||||
print("Duplicate found: ${response['message']}");
|
||||
return;
|
||||
} else {
|
||||
_clearError(field);
|
||||
print("No duplicates found.");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error in checkDuplicate: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _clearError(String field) {
|
||||
setState(() {
|
||||
widget.errorMessages.remove(field);
|
||||
@ -2308,6 +2331,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("forex_card_num");
|
||||
apiCheckDuplicate("Forex Pre-Paid Card Number", "forex_card_num",value,widget.userIdApi);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "Card Number",
|
||||
@ -2439,14 +2463,24 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
SizedBox(width: 25),
|
||||
buildFrequentFlierInformation(entry),
|
||||
SizedBox(width: 15),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeFrequentFlierEntry(entry);
|
||||
});
|
||||
},
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 8), // 👈 Add top padding here
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeFrequentFlierEntry(entry);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
@ -2457,7 +2491,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildFrequentFlierInformation(entry),
|
||||
SizedBox(width: 15),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeFrequentFlierEntry(entry);
|
||||
@ -2738,22 +2773,30 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child:
|
||||
widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildHotel(entry),
|
||||
SizedBox(width: 25),
|
||||
buildHotelMembershipNum(entry),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
// removeHotelLoyaltyEntry(localId);
|
||||
removeHotelLoyaltyEntry(entry);
|
||||
});
|
||||
},
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildHotel(entry),
|
||||
SizedBox(width: 25),
|
||||
buildHotelMembershipNum(entry),
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 8), // 👈 Add top padding here
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeHotelLoyaltyEntry(entry);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -2761,7 +2804,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
SizedBox(height: 8),
|
||||
buildHotelMembershipNum(entry),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
// removeHotelLoyaltyEntry(localId);
|
||||
@ -2987,13 +3031,22 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildVisaValidFrom(entry),
|
||||
SizedBox(width: 15),
|
||||
buildVisaValidUpTo(entry),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeVisaEntry(entry);
|
||||
});
|
||||
},
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 8), // 👈 Add top padding here
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
removeVisaEntry(entry);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -3008,7 +3061,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
SizedBox(height: 8),
|
||||
buildVisaValidUpTo(entry),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel, color: Colors.red, size: 15),
|
||||
icon: Icon(Icons.horizontal_rule, color: Colors.red, size: 15),
|
||||
tooltip: 'Cancel the Details',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
// visaRowIds.remove(id);
|
||||
|
||||
@ -1234,4 +1234,52 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------- User Management - CheckDuplicate ---------------
|
||||
Future<Map<String, dynamic>> CheckDuplicate(String label, String field, String value, String? userId) async {
|
||||
String apiUrldata;
|
||||
if (userId == null || userId.isEmpty) {
|
||||
apiUrldata = '$apiUrl/api/checkDuplicate?$field=$value';
|
||||
} else {
|
||||
apiUrldata = '$apiUrl/api/checkDuplicate?$field=$value&user_id=$userId';
|
||||
}
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(apiUrldata),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
try {
|
||||
final data = json.decode(response.body);
|
||||
|
||||
// Updated to match actual response structure
|
||||
if (data['status'] == "exists") {
|
||||
print("${data['field']} - $value already exists");
|
||||
return {
|
||||
"message": "$label already exists",
|
||||
"field": data['field']
|
||||
};
|
||||
} else {
|
||||
print("$label - $value is a new value");
|
||||
return {};
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Error parsing response: $e');
|
||||
}
|
||||
} else {
|
||||
throw Exception('Failed to load checkDuplicate data. Status code: ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------- User Management - CheckDuplicate end here ----------------------------------
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user