fix: new condition flag for idCardType
This commit is contained in:
parent
dd2bb57e42
commit
a7652aadfb
|
@ -3,11 +3,13 @@ import 'dart:io';
|
|||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:sigap/src/cores/services/azure_ocr_service.dart';
|
||||
import 'package:sigap/src/features/auth/data/models/face_model.dart';
|
||||
import 'package:sigap/src/features/auth/data/models/kta_model.dart';
|
||||
import 'package:sigap/src/features/auth/data/models/ktp_model.dart';
|
||||
import 'package:sigap/src/features/auth/data/repositories/authentication_repository.dart';
|
||||
|
||||
class IdCardVerificationController extends GetxController {
|
||||
// Singleton instance
|
||||
|
@ -16,12 +18,49 @@ class IdCardVerificationController extends GetxController {
|
|||
// Services
|
||||
final AzureOCRService _ocrService = AzureOCRService();
|
||||
|
||||
final bool isOfficer;
|
||||
// Store isOfficer as a reactive variable instead of a final field
|
||||
final RxBool _isOfficer = RxBool(false);
|
||||
bool get isOfficer => _isOfficer.value;
|
||||
|
||||
// Maximum allowed file size in bytes (4MB)
|
||||
final int maxFileSizeBytes = 4 * 1024 * 1024; // 4MB in bytes
|
||||
|
||||
IdCardVerificationController({required this.isOfficer});
|
||||
// Constructor that accepts initial isOfficer value but will be updated from user data
|
||||
IdCardVerificationController({bool isOfficer = false}) {
|
||||
_isOfficer.value = isOfficer;
|
||||
Logger().i(
|
||||
'IdCardVerificationController initialized with isOfficer: $_isOfficer',
|
||||
);
|
||||
// Fetch current user role when controller is created
|
||||
fetchCurrentUserRole();
|
||||
}
|
||||
|
||||
// Method to fetch current user role and update isOfficer flag
|
||||
Future<void> fetchCurrentUserRole() async {
|
||||
try {
|
||||
final metadata = AuthenticationRepository.instance.authUser?.userMetadata;
|
||||
|
||||
if (metadata == null) {
|
||||
Logger().w('User metadata is null, cannot determine role');
|
||||
return;
|
||||
}
|
||||
|
||||
// Ambil nilai is_officer
|
||||
final bool isOfficer = metadata['is_officer'] == true;
|
||||
|
||||
// Simpan ke variabel observasi jika perlu
|
||||
_isOfficer.value = isOfficer;
|
||||
|
||||
Logger().i('Updated isOfficer flag from user role: $isOfficer');
|
||||
|
||||
// Tampilkan jenis kartu identitas yang perlu diverifikasi
|
||||
final String idCardType = isOfficer ? 'KTA' : 'KTP';
|
||||
Logger().i('User should verify $idCardType based on role');
|
||||
} catch (e) {
|
||||
Logger().e('Error fetching current user role: $e');
|
||||
// Keep the initial value if there's an error
|
||||
}
|
||||
}
|
||||
|
||||
// Local storage keys
|
||||
static const String _kOcrResultsKey = 'ocr_results';
|
||||
|
@ -64,26 +103,34 @@ class IdCardVerificationController extends GetxController {
|
|||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String jsonData = jsonEncode(results);
|
||||
final String idCardType = isOfficer ? 'KTA' : 'KTP';
|
||||
|
||||
Logger().i(
|
||||
'Saving to local storage for ID card type: $idCardType (isOfficer=$isOfficer)',
|
||||
);
|
||||
|
||||
await prefs.setString(_kOcrResultsKey, jsonData);
|
||||
await prefs.setString(_kIdCardTypeKey, isOfficer ? 'KTA' : 'KTP');
|
||||
await prefs.setString(_kIdCardTypeKey, idCardType);
|
||||
|
||||
// Also save the model
|
||||
if (isOfficer && ktaModel.value != null) {
|
||||
Logger().i('Saving KTA model to storage');
|
||||
await prefs.setString(
|
||||
_kOcrModelKey,
|
||||
jsonEncode(ktaModel.value!.toJson()),
|
||||
);
|
||||
} else if (!isOfficer && ktpModel.value != null) {
|
||||
Logger().i('Saving KTP model to storage');
|
||||
await prefs.setString(
|
||||
_kOcrModelKey,
|
||||
jsonEncode(ktpModel.value!.toJson()),
|
||||
);
|
||||
}
|
||||
|
||||
print('OCR results saved to local storage: ${results.length} items');
|
||||
print('ID Card Type saved: ${isOfficer ? 'KTA' : 'KTP'}');
|
||||
Logger().i('OCR results saved to local storage: ${results.length} items');
|
||||
Logger().i('ID Card Type saved: $idCardType');
|
||||
} catch (e) {
|
||||
print('Error saving OCR results to local storage: $e');
|
||||
Logger().e('Error saving OCR results to local storage: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +144,7 @@ class IdCardVerificationController extends GetxController {
|
|||
return decodedData.map((key, value) => MapEntry(key, value.toString()));
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error loading OCR results from local storage: $e');
|
||||
Logger().e('Error loading OCR results from local storage: $e');
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -191,41 +238,72 @@ class IdCardVerificationController extends GetxController {
|
|||
}
|
||||
|
||||
try {
|
||||
// Make sure we have the latest user role before proceeding
|
||||
await fetchCurrentUserRole();
|
||||
|
||||
isVerifying.value = true;
|
||||
final idCardType = isOfficer ? 'KTA' : 'KTP';
|
||||
|
||||
Logger().i(
|
||||
'Starting ID card validation for ${isOfficer ? "KTA (Officer)" : "KTP (Citizen)"} - isOfficer flag: $isOfficer',
|
||||
);
|
||||
|
||||
// Basic validation to check if the image is clear enough for OCR
|
||||
bool isImageValid = false;
|
||||
|
||||
try {
|
||||
// Process the ID card with OCR (still using Azure OCR)
|
||||
Logger().i(
|
||||
'About to process ID card image with OCR service - isOfficer flag: $isOfficer',
|
||||
);
|
||||
|
||||
// Process the ID card with OCR
|
||||
final result = await _ocrService.processIdCard(
|
||||
idCardImage.value!,
|
||||
isOfficer,
|
||||
);
|
||||
|
||||
Logger().i(
|
||||
'OCR processing completed for $idCardType - Data received: ${result.length} fields',
|
||||
);
|
||||
|
||||
// Store the extraction results
|
||||
extractedInfo.assignAll(result);
|
||||
hasExtractedInfo.value = result.isNotEmpty;
|
||||
|
||||
// Save the OCR results to local storage
|
||||
if (result.isNotEmpty) {
|
||||
print('Saving OCR results to local storage...');
|
||||
Logger().i('Saving $idCardType OCR results to local storage...');
|
||||
await _saveOcrResultsToLocalStorage(result);
|
||||
}
|
||||
|
||||
// Debug the extracted data
|
||||
Logger().i('Card type being validated: $idCardType');
|
||||
Logger().i('isOfficer flag: $isOfficer');
|
||||
Logger().i('Extracted data: $result');
|
||||
|
||||
// Check if the extracted information is valid using our validation methods
|
||||
if (isOfficer) {
|
||||
Logger().i('Validating as KTA (Officer card)');
|
||||
isImageValid = _ocrService.isKtaValid(result);
|
||||
} else {
|
||||
isImageValid = _ocrService.isKtpValid(result);
|
||||
}
|
||||
Logger().i('KTA validation result: $isImageValid');
|
||||
|
||||
// Create model from extracted data
|
||||
if (isOfficer) {
|
||||
// Create KTA model from extracted data
|
||||
ktaModel.value = _ocrService.createKtaModel(result);
|
||||
Logger().i('KTA model created: ${ktaModel.value != null}');
|
||||
|
||||
// Ensure KTP model is null
|
||||
ktpModel.value = null;
|
||||
} else {
|
||||
Logger().i('Validating as KTP (Citizen card)');
|
||||
isImageValid = _ocrService.isKtpValid(result);
|
||||
Logger().i('KTP validation result: $isImageValid');
|
||||
|
||||
// Create KTP model from extracted data
|
||||
ktpModel.value = _ocrService.createKtpModel(result);
|
||||
Logger().i('KTP model created: ${ktpModel.value != null}');
|
||||
|
||||
// Ensure KTA model is null
|
||||
ktaModel.value = null;
|
||||
}
|
||||
|
||||
if (isImageValid) {
|
||||
|
@ -233,10 +311,14 @@ class IdCardVerificationController extends GetxController {
|
|||
isIdCardValid.value = true;
|
||||
idCardValidationMessage.value =
|
||||
'$idCardType image looks valid. Please confirm this is your $idCardType.';
|
||||
Logger().i('$idCardType validation successful');
|
||||
} else {
|
||||
isIdCardValid.value = false;
|
||||
idCardValidationMessage.value =
|
||||
'Unable to verify your $idCardType clearly. Please ensure all text is visible and try again.';
|
||||
Logger().i(
|
||||
'$idCardType validation failed - unable to verify clearly',
|
||||
);
|
||||
}
|
||||
} on SocketException catch (e) {
|
||||
isIdCardValid.value = false;
|
||||
|
@ -248,10 +330,16 @@ class IdCardVerificationController extends GetxController {
|
|||
idCardValidationMessage.value =
|
||||
'Network error occurred. Please try again later.';
|
||||
}
|
||||
Logger().e(
|
||||
'Network error during $idCardType validation: ${e.toString()}',
|
||||
);
|
||||
} catch (processingError) {
|
||||
isIdCardValid.value = false;
|
||||
idCardValidationMessage.value =
|
||||
'We\'re having trouble processing your $idCardType. Please try again with a clearer image.';
|
||||
Logger().e(
|
||||
'Processing error during $idCardType validation: ${processingError.toString()}',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
isIdCardValid.value = false;
|
||||
|
@ -265,14 +353,22 @@ class IdCardVerificationController extends GetxController {
|
|||
'The verification is taking too long. Please try again later when the connection is better.';
|
||||
} else {
|
||||
// Generic but still user-friendly error message
|
||||
final idCardType = isOfficer ? 'KTA' : 'KTP';
|
||||
idCardValidationMessage.value =
|
||||
'We encountered an issue during verification. Please try again later.';
|
||||
'We encountered an issue during $idCardType verification. Please try again later.';
|
||||
}
|
||||
|
||||
// Log the actual error for debugging (wouldn't be shown to the user)
|
||||
print('ID Card validation error: ${e.toString()}');
|
||||
Logger().e('ID Card validation error: ${e.toString()}');
|
||||
} finally {
|
||||
isVerifying.value = false;
|
||||
|
||||
// Final verification of which model is set
|
||||
Logger().i(
|
||||
'Final verification - Card type: ${isOfficer ? "KTA" : "KTP"}',
|
||||
);
|
||||
Logger().i('KTP model is null: ${ktpModel.value == null}');
|
||||
Logger().i('KTA model is null: ${ktaModel.value == null}');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +400,7 @@ class IdCardVerificationController extends GetxController {
|
|||
await prefs.remove(_kOcrModelKey);
|
||||
await prefs.remove(_kIdCardTypeKey);
|
||||
} catch (e) {
|
||||
print('Error clearing OCR results from local storage: $e');
|
||||
Logger().e('Error clearing OCR results from local storage: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,14 +411,14 @@ class IdCardVerificationController extends GetxController {
|
|||
|
||||
// Log storage data for debugging
|
||||
SharedPreferences.getInstance().then((prefs) {
|
||||
print('Storage check on confirmation:');
|
||||
print(
|
||||
Logger().i('Storage check on confirmation:');
|
||||
Logger().i(
|
||||
'OCR results: ${prefs.getString(_kOcrResultsKey)?.substring(0, 50)}...',
|
||||
);
|
||||
print(
|
||||
Logger().i(
|
||||
'OCR model: ${prefs.getString(_kOcrModelKey)?.substring(0, 50)}...',
|
||||
);
|
||||
print('ID card type: ${prefs.getString(_kIdCardTypeKey)}');
|
||||
Logger().i('ID card type: ${prefs.getString(_kIdCardTypeKey)}');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -331,4 +427,25 @@ class IdCardVerificationController extends GetxController {
|
|||
dynamic get verifiedIdCardModel {
|
||||
return isOfficer ? ktaModel.value : ktpModel.value;
|
||||
}
|
||||
|
||||
// Debug helper method - can be called from UI for troubleshooting
|
||||
void debugControllerState() {
|
||||
Logger().i('======= ID CARD VERIFICATION CONTROLLER STATE =======');
|
||||
Logger().i('isOfficer: $isOfficer');
|
||||
Logger().i('Current ID card type: ${isOfficer ? "KTA" : "KTP"}');
|
||||
Logger().i('Has ID card image: ${idCardImage.value != null}');
|
||||
Logger().i('Is ID card valid: ${isIdCardValid.value}');
|
||||
Logger().i('Has confirmed ID card: ${hasConfirmedIdCard.value}');
|
||||
Logger().i('Has extracted info: ${hasExtractedInfo.value}');
|
||||
Logger().i('Extracted info fields: ${extractedInfo.length}');
|
||||
Logger().i('KTP model null: ${ktpModel.value == null}');
|
||||
Logger().i('KTA model null: ${ktaModel.value == null}');
|
||||
Logger().i('================================================');
|
||||
}
|
||||
|
||||
// Method to force update the isOfficer flag (useful for testing or if user role changes)
|
||||
void updateIsOfficerFlag(bool value) {
|
||||
Logger().i('Manually updating isOfficer flag from $isOfficer to $value');
|
||||
_isOfficer.value = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:sigap/src/features/auth/data/models/kta_model.dart';
|
||||
import 'package:sigap/src/features/auth/data/models/ktp_model.dart';
|
||||
import 'package:sigap/src/features/auth/presentasion/controllers/signup/main/registration_form_controller.dart';
|
||||
|
@ -25,8 +26,25 @@ class IdCardVerificationStep extends StatelessWidget {
|
|||
mainController.formKey = formKey;
|
||||
|
||||
final isOfficer = mainController.selectedRole.value?.isOfficer ?? false;
|
||||
|
||||
// Ensure controller's isOfficer flag matches mainController's selected role
|
||||
if (controller.isOfficer != isOfficer) {
|
||||
controller.updateIsOfficerFlag(isOfficer);
|
||||
Logger().i(
|
||||
'Updated controller isOfficer flag to match selected role: $isOfficer',
|
||||
);
|
||||
}
|
||||
|
||||
final String idCardType = isOfficer ? 'KTA' : 'KTP';
|
||||
|
||||
Logger().i(
|
||||
'Building IdCardVerificationStep with isOfficer: $isOfficer (Card type: $idCardType)',
|
||||
);
|
||||
Logger().i('Controller isOfficer flag: ${controller.isOfficer}');
|
||||
|
||||
// Call the debug method to print full controller state
|
||||
controller.debugControllerState();
|
||||
|
||||
return Form(
|
||||
key: formKey,
|
||||
child: Column(
|
||||
|
|
Loading…
Reference in New Issue