diff --git a/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java b/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java index 4fce47c8e..e910aa6eb 100644 --- a/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java +++ b/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java @@ -506,6 +506,18 @@ public void startOperatorOnboarding(@NonNull BiometricsPigeon.Result res } } + @Override + public void clearBiometricAndDocumentHashmap(@NonNull BiometricsPigeon.Result result) { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + registrationDto.clearBiometricsHashmap(); + registrationDto.clearDocumentsHashmap(); + result.success("Ok"); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + @Override public void saveOperatorBiometrics(@NonNull BiometricsPigeon.Result result) { try{ diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/RegistrationDto.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/RegistrationDto.java index d41ca4324..41687d022 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/RegistrationDto.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/RegistrationDto.java @@ -149,7 +149,20 @@ public void addDemographicField(String fieldId, Object value) { this.demographics.put(fieldId, value); clearAndNotifyAllObservers(); } - + public void clearBiometricsHashmap(){ + this.biometrics.clear(); + clearAttemptsHashmap(); + clearExceptionsHashmap(); + } + public void clearDocumentsHashmap(){ + this.documents.clear(); + } + public void clearAttemptsHashmap(){ + this.ATTEMPTS.clear(); + } + public void clearExceptionsHashmap(){ + this.EXCEPTIONS.clear(); + } public void addDemographicField(String fieldId, String value, String language) { this.demographics.compute(fieldId, (k, v) -> { v = v != null ? v : new ArrayList(); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserDetailRepository.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserDetailRepository.java index b3eabb512..a5c582cb6 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserDetailRepository.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserDetailRepository.java @@ -150,7 +150,9 @@ public void saveUserAuthToken(String userId, String token, String refreshToken, userTokenDao.insert(userToken); } - + public void updateUserDetail(String userId){ + userDetailDao.updateUserDetail(true,userId); + } public String getUserAuthToken(String userId) { UserToken userToken = userTokenDao.findByUsername(userId); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java index e76d3d11b..a9400612c 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java @@ -165,6 +165,7 @@ public void onboardOperator(List biometrics, Runnable onFinish) t if(isIdaResponse()) { Log.i(TAG, "User onboarding success"); isOnboardSuccess = save(biometrics, userId); + userDetailRepository.updateUserDetail(sharedPreferences.getString(PREFERRED_USERNAME,"")); onFinish.run(); } }); diff --git a/assets/svg/Left Eye Exception.svg b/assets/svg/Left Eye Exception.svg new file mode 100644 index 000000000..18997012b --- /dev/null +++ b/assets/svg/Left Eye Exception.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/pigeon.h b/ios/Runner/pigeon.h index ed184bd43..4c6eafa6a 100644 --- a/ios/Runner/pigeon.h +++ b/ios/Runner/pigeon.h @@ -10,30 +10,28 @@ NS_ASSUME_NONNULL_BEGIN -@class DashBoardData; - -@interface DashBoardData : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithUserId:(NSString *)userId - userName:(NSString *)userName - userStatus:(NSNumber *)userStatus - userIsOnboarded:(NSNumber *)userIsOnboarded; -@property(nonatomic, copy) NSString * userId; -@property(nonatomic, copy) NSString * userName; -@property(nonatomic, strong) NSNumber * userStatus; -@property(nonatomic, strong) NSNumber * userIsOnboarded; -@end - -/// The codec used by DashBoardApi. -NSObject *DashBoardApiGetCodec(void); -@protocol DashBoardApi -- (void)getDashBoardDetailsWithCompletion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; -- (void)getPacketUploadedDetailsWithCompletion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; -- (void)getPacketUploadedPendingDetailsWithCompletion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; +/// The codec used by BiometricsApi. +NSObject *BiometricsApiGetCodec(void); + +@protocol BiometricsApi +- (void)invokeDiscoverSbiFieldId:(NSString *)fieldId modality:(NSString *)modality completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)getBestBiometricsFieldId:(NSString *)fieldId modality:(NSString *)modality completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +- (void)getBiometricsFieldId:(NSString *)fieldId modality:(NSString *)modality attempt:(NSNumber *)attempt completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +- (void)extractImageValuesFieldId:(NSString *)fieldId modality:(NSString *)modality completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +- (void)extractImageValuesByAttemptFieldId:(NSString *)fieldId modality:(NSString *)modality attempt:(NSNumber *)attempt completion:(void (^)(NSArray *_Nullable, FlutterError *_Nullable))completion; +- (void)incrementBioAttemptFieldId:(NSString *)fieldId modality:(NSString *)modality completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; +- (void)getBioAttemptFieldId:(NSString *)fieldId modality:(NSString *)modality completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; +- (void)startOperatorOnboardingWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)clearBiometricAndDocumentHashmapWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)saveOperatorBiometricsWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)addBioExceptionFieldId:(NSString *)fieldId modality:(NSString *)modality attribute:(NSString *)attribute completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)removeBioExceptionFieldId:(NSString *)fieldId modality:(NSString *)modality attribute:(NSString *)attribute completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)getMapValueKey:(NSString *)key completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)getAgeGroupWithCompletion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; +- (void)conditionalBioAttributeValidationFieldId:(NSString *)fieldId expression:(NSString *)expression completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @end -extern void DashBoardApiSetup(id binaryMessenger, NSObject *_Nullable api); +extern void BiometricsApiSetup(id binaryMessenger, NSObject *_Nullable api); NS_ASSUME_NONNULL_END diff --git a/ios/Runner/pigeon.m b/ios/Runner/pigeon.m index 04fe85d11..d3557e19e 100644 --- a/ios/Runner/pigeon.m +++ b/ios/Runner/pigeon.m @@ -26,107 +26,260 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { return (result == [NSNull null]) ? nil : result; } -@interface DashBoardData () -+ (DashBoardData *)fromList:(NSArray *)list; -+ (nullable DashBoardData *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@implementation DashBoardData -+ (instancetype)makeWithUserId:(NSString *)userId - userName:(NSString *)userName - userStatus:(NSNumber *)userStatus - userIsOnboarded:(NSNumber *)userIsOnboarded { - DashBoardData* pigeonResult = [[DashBoardData alloc] init]; - pigeonResult.userId = userId; - pigeonResult.userName = userName; - pigeonResult.userStatus = userStatus; - pigeonResult.userIsOnboarded = userIsOnboarded; - return pigeonResult; -} -+ (DashBoardData *)fromList:(NSArray *)list { - DashBoardData *pigeonResult = [[DashBoardData alloc] init]; - pigeonResult.userId = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.userId != nil, @""); - pigeonResult.userName = GetNullableObjectAtIndex(list, 1); - NSAssert(pigeonResult.userName != nil, @""); - pigeonResult.userStatus = GetNullableObjectAtIndex(list, 2); - NSAssert(pigeonResult.userStatus != nil, @""); - pigeonResult.userIsOnboarded = GetNullableObjectAtIndex(list, 3); - NSAssert(pigeonResult.userIsOnboarded != nil, @""); - return pigeonResult; -} -+ (nullable DashBoardData *)nullableFromList:(NSArray *)list { - return (list) ? [DashBoardData fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.userId ?: [NSNull null]), - (self.userName ?: [NSNull null]), - (self.userStatus ?: [NSNull null]), - (self.userIsOnboarded ?: [NSNull null]), - ]; -} -@end - -@interface DashBoardApiCodecReader : FlutterStandardReader -@end -@implementation DashBoardApiCodecReader -- (nullable id)readValueOfType:(UInt8)type { - switch (type) { - case 128: - return [DashBoardData fromList:[self readValue]]; - default: - return [super readValueOfType:type]; - } -} -@end - -@interface DashBoardApiCodecWriter : FlutterStandardWriter -@end -@implementation DashBoardApiCodecWriter -- (void)writeValue:(id)value { - if ([value isKindOfClass:[DashBoardData class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else { - [super writeValue:value]; - } -} -@end - -@interface DashBoardApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation DashBoardApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[DashBoardApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[DashBoardApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *DashBoardApiGetCodec(void) { +NSObject *BiometricsApiGetCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; - static dispatch_once_t sPred = 0; - dispatch_once(&sPred, ^{ - DashBoardApiCodecReaderWriter *readerWriter = [[DashBoardApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); + sSharedObject = [FlutterStandardMessageCodec sharedInstance]; return sSharedObject; } -void DashBoardApiSetup(id binaryMessenger, NSObject *api) { +void BiometricsApiSetup(id binaryMessenger, NSObject *api) { + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.invokeDiscoverSbi" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(invokeDiscoverSbiFieldId:modality:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(invokeDiscoverSbiFieldId:modality:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + [api invokeDiscoverSbiFieldId:arg_fieldId modality:arg_modality completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.getBestBiometrics" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(getBestBiometricsFieldId:modality:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(getBestBiometricsFieldId:modality:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + [api getBestBiometricsFieldId:arg_fieldId modality:arg_modality completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.getBiometrics" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(getBiometricsFieldId:modality:attempt:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(getBiometricsFieldId:modality:attempt:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + NSNumber *arg_attempt = GetNullableObjectAtIndex(args, 2); + [api getBiometricsFieldId:arg_fieldId modality:arg_modality attempt:arg_attempt completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.extractImageValues" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(extractImageValuesFieldId:modality:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(extractImageValuesFieldId:modality:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + [api extractImageValuesFieldId:arg_fieldId modality:arg_modality completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.extractImageValuesByAttempt" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(extractImageValuesByAttemptFieldId:modality:attempt:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(extractImageValuesByAttemptFieldId:modality:attempt:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + NSNumber *arg_attempt = GetNullableObjectAtIndex(args, 2); + [api extractImageValuesByAttemptFieldId:arg_fieldId modality:arg_modality attempt:arg_attempt completion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.incrementBioAttempt" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(incrementBioAttemptFieldId:modality:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(incrementBioAttemptFieldId:modality:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + [api incrementBioAttemptFieldId:arg_fieldId modality:arg_modality completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.getBioAttempt" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(getBioAttemptFieldId:modality:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(getBioAttemptFieldId:modality:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + [api getBioAttemptFieldId:arg_fieldId modality:arg_modality completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.startOperatorOnboarding" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(startOperatorOnboardingWithCompletion:)], @"BiometricsApi api (%@) doesn't respond to @selector(startOperatorOnboardingWithCompletion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api startOperatorOnboardingWithCompletion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.clearBiometricAndDocumentHashmap" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(clearBiometricAndDocumentHashmapWithCompletion:)], @"BiometricsApi api (%@) doesn't respond to @selector(clearBiometricAndDocumentHashmapWithCompletion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api clearBiometricAndDocumentHashmapWithCompletion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.saveOperatorBiometrics" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(saveOperatorBiometricsWithCompletion:)], @"BiometricsApi api (%@) doesn't respond to @selector(saveOperatorBiometricsWithCompletion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + [api saveOperatorBiometricsWithCompletion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.addBioException" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(addBioExceptionFieldId:modality:attribute:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(addBioExceptionFieldId:modality:attribute:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + NSString *arg_attribute = GetNullableObjectAtIndex(args, 2); + [api addBioExceptionFieldId:arg_fieldId modality:arg_modality attribute:arg_attribute completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = + [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.removeBioException" + binaryMessenger:binaryMessenger + codec:BiometricsApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(removeBioExceptionFieldId:modality:attribute:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(removeBioExceptionFieldId:modality:attribute:completion:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_fieldId = GetNullableObjectAtIndex(args, 0); + NSString *arg_modality = GetNullableObjectAtIndex(args, 1); + NSString *arg_attribute = GetNullableObjectAtIndex(args, 2); + [api removeBioExceptionFieldId:arg_fieldId modality:arg_modality attribute:arg_attribute completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.registration_client.DashBoardApi.getDashBoardDetails" + initWithName:@"dev.flutter.pigeon.registration_client.BiometricsApi.getMapValue" binaryMessenger:binaryMessenger - codec:DashBoardApiGetCodec()]; + codec:BiometricsApiGetCodec()]; if (api) { - NSCAssert([api respondsToSelector:@selector(getDashBoardDetailsWithCompletion:)], @"DashBoardApi api (%@) doesn't respond to @selector(getDashBoardDetailsWithCompletion:)", api); + NSCAssert([api respondsToSelector:@selector(getMapValueKey:completion:)], @"BiometricsApi api (%@) doesn't respond to @selector(getMapValueKey:completion:)", api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - [api getDashBoardDetailsWithCompletion:^(NSArray *_Nullable output, FlutterError *_Nullable error) { + NSArray *args = message; + NSString *arg_key = GetNullableObjectAtIndex(args, 0); + [api getMapValueKey:arg_key completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { callback(wrapResult(output, error)); }]; }]; @@ -137,13 +290,13 @@ void DashBoardApiSetup(id binaryMessenger, NSObject binaryMessenger, NSObject _chosenLang = []; - String _operatorOnboardingAttributes=""; + String _operatorOnboardingAttributes = ""; Map _languageMap = { 'English': true, 'Arabic': false, @@ -64,7 +64,7 @@ class GlobalProvider with ChangeNotifier { Map _fieldDisplayValues = {}; Map _fieldInputValue = {}; - Map _completeException={}; + Map _completeException = {}; Map _mvelValues = {}; @@ -73,6 +73,12 @@ class GlobalProvider with ChangeNotifier { String _regId = ""; String _ageGroup = ""; + String _checkAgeGroupChange = ""; + String get checkAgeGroupChange => _checkAgeGroupChange; + set checkAgeGroupChange(String value) { + _checkAgeGroupChange = value; + } + //GettersSetters setScannedPages(String field, List value) { _scannedPages[field] = value; @@ -220,9 +226,9 @@ class GlobalProvider with ChangeNotifier { notifyListeners(); } - Map get completeException=>_completeException; - set completeException(Map value){ - _completeException=value; + Map get completeException => _completeException; + set completeException(Map value) { + _completeException = value; notifyListeners(); } @@ -232,15 +238,15 @@ class GlobalProvider with ChangeNotifier { } //Functions - setCompleteExceptionByKey(String key,dynamic value){ - completeException[key]=value; + setCompleteExceptionByKey(String key, dynamic value) { + completeException[key] = value; notifyListeners(); } - getCompleteExceptionByKey(String key){ - if(completeException.containsKey(key)){ + + getCompleteExceptionByKey(String key) { + if (completeException.containsKey(key)) { return completeException[key]; - } - else{ + } else { return []; } } @@ -349,7 +355,7 @@ class GlobalProvider with ChangeNotifier { } else { commitId = head; } - } catch(e) { + } catch (e) { debugPrint("Failed fetching git info: $e"); } @@ -362,10 +368,12 @@ class GlobalProvider with ChangeNotifier { notifyListeners(); } - removeValidFromMap(String key,Uint8List? item, Map commonMap) { - if(commonMap[key].listofImages!=null && commonMap[key].listofImages.length>=1) { + removeValidFromMap( + String key, Uint8List? item, Map commonMap) { + if (commonMap[key].listofImages != null && + commonMap[key].listofImages.length >= 1) { commonMap[key].listofImages.remove(item); - }else{ + } else { commonMap.remove(key); } notifyListeners(); @@ -495,13 +503,13 @@ class GlobalProvider with ChangeNotifier { await setLanguageConfigData(); await createLanguageCodeMapper(); String mandatoryLang = _mandatoryLanguages[0] ?? "eng"; - if(!isManualSync) { + if (!isManualSync) { await toggleLocale(mandatoryLang); } notifyListeners(); } - set exceptionAttributes(List value){ + set exceptionAttributes(List value) { _exceptionAttributes = value; notifyListeners(); } @@ -617,12 +625,12 @@ class GlobalProvider with ChangeNotifier { } List languageList = []; _codeToLanguageMapper = {}; - for(var element in _mandatoryLanguages) { + for (var element in _mandatoryLanguages) { languageList.add(element!); _codeToLanguageMapper[element] = element; } for (var element in _languageDataList) { - if(_codeToLanguageMapper[element!.code] == null) { + if (_codeToLanguageMapper[element!.code] == null) { languageList.add(element.code); } _codeToLanguageMapper[element.code] = element.name; @@ -716,7 +724,8 @@ class GlobalProvider with ChangeNotifier { await networkService.saveScreenHeaderToGlobalParam(id, value); } - removeProofOfExceptionFieldFromMap(String key, Map commonMap) { + removeProofOfExceptionFieldFromMap( + String key, Map commonMap) { commonMap.remove(key); } } diff --git a/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart b/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart index c365f0214..c173f0af0 100644 --- a/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart +++ b/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart @@ -126,12 +126,33 @@ class _OperatorBiometricCaptureScanBlockViewState Row( mainAxisAlignment: MainAxisAlignment.center, children: [ + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 130.h : 260.h, + ) + : const SizedBox()) + : const SizedBox(), ...temp.map( (e) => Image.memory( e!, height: (isMobileSize) ? 130.h : 260.h, ), ), + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? const SizedBox() + : Transform.flip( + flipX: true, + child: SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 130.h : 260.h, + ), + )) + : const SizedBox(), ], ), // Divider( @@ -201,11 +222,45 @@ class _OperatorBiometricCaptureScanBlockViewState child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? Row( + children: [ + SizedBox( + width: 115.h, + ), + SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 70.h : 130.h, + ), + ], + ) + : const SizedBox()) + : const SizedBox(), ...biometricAttributeData.listofImages .map((e) => Image.memory( e, height: (isMobileSize) ? 70.h : 130.h, - )) + )),(biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? const SizedBox() + : Row( + children: [ + Transform.flip( + flipX: true, + child: SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 70.h : 130.h, + ), + ), + SizedBox( + width: 115.h, + ) + ], + )) + : const SizedBox(), ], ), ), diff --git a/lib/ui/process_ui/new_process.dart b/lib/ui/process_ui/new_process.dart index bfaa0765a..53eb02177 100644 --- a/lib/ui/process_ui/new_process.dart +++ b/lib/ui/process_ui/new_process.dart @@ -319,6 +319,55 @@ class _NewProcessState extends State with WidgetsBindingObserver { return i; } + ageDateChangeValidation(int currentIndex) async { + if (globalProvider.newProcessTabIndex < size) { + Screen screen = newProcess.screens!.elementAt(currentIndex)!; + for (int i = 0; i < screen.fields!.length; i++) { + if (screen.fields!.elementAt(i)!.id == "dateOfBirth") { + if (globalProvider.checkAgeGroupChange == "") { + globalProvider.checkAgeGroupChange = globalProvider.ageGroup; + } else { + if (globalProvider.checkAgeGroupChange + .compareTo(globalProvider.ageGroup) == + 0) { + } else { + List screens = []; + for (int i = 0; + i < registrationTaskProvider.listOfProcesses.length; + i++) { + Process process = Process.fromJson( + jsonDecode( + context + .read() + .listOfProcesses + .elementAt(i) + .toString(), + ), + ); + if (process.id == "NEW") { + screens = process.screens!; + } + } + for (Screen? screen in screens) { + if (screen!.name! == "Documents" || + screen!.name! == "BiometricDetails") { + for (Field? field in screen!.fields!) { + if (globalProvider.fieldInputValue + .containsKey(field!.id!)) { + globalProvider.fieldInputValue.remove(field.id); + } + } + } + } + await BiometricsApi().clearBiometricAndDocumentHashmap(); + globalProvider.checkAgeGroupChange = globalProvider.ageGroup; + } + } + } + } + } + } + customValidation(int currentIndex) async { bool isValid = true; if (globalProvider.newProcessTabIndex < size) { @@ -420,6 +469,27 @@ class _NewProcessState extends State with WidgetsBindingObserver { .conditionalBioAttributes! .first! .validationExpr!); + if (screen.fields!.elementAt(i)!.exceptionPhotoRequired == true) { + List biometricAttributeDataList = + globalProvider + .fieldInputValue[screen.fields!.elementAt(i)!.id!]; + bool isExceptionPresent = false; + bool isExceptionAttributePresent = false; + for (var biometricAttributeData in biometricAttributeDataList) { + if (globalProvider.exceptionAttributes + .contains(biometricAttributeData.title)) { + isExceptionPresent = true; + } + if (biometricAttributeData.title == "Exception") { + isExceptionAttributePresent = true; + } + } + if (isExceptionPresent == true && + isExceptionAttributePresent == false) { + isValid = false; + break; + } + } if (!valid) { isValid = false; break; @@ -433,6 +503,7 @@ class _NewProcessState extends State with WidgetsBindingObserver { continueButtonTap(BuildContext context, int size, newProcess) async { if (globalProvider.newProcessTabIndex < size) { + ageDateChangeValidation(globalProvider.newProcessTabIndex); bool customValidator = await customValidation(globalProvider.newProcessTabIndex); if (customValidator) { @@ -483,8 +554,8 @@ class _NewProcessState extends State with WidgetsBindingObserver { globalProvider.formKey.currentState != null && globalProvider.formKey.currentState!.validate(); - if(globalProvider.newProcessTabIndex >= size) { - continueButton = true; + if (globalProvider.newProcessTabIndex >= size) { + continueButton = true; } }); diff --git a/lib/ui/process_ui/widgets/age_date_control.dart b/lib/ui/process_ui/widgets/age_date_control.dart index ff001598e..a84412fd7 100644 --- a/lib/ui/process_ui/widgets/age_date_control.dart +++ b/lib/ui/process_ui/widgets/age_date_control.dart @@ -5,16 +5,21 @@ * */ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; +import 'package:registration_client/model/process.dart'; import 'package:registration_client/pigeon/biometrics_pigeon.dart'; import 'package:registration_client/provider/registration_task_provider.dart'; import 'package:registration_client/utils/app_config.dart'; import '../../../model/field.dart'; +import '../../../model/screen.dart'; import '../../../provider/global_provider.dart'; import 'custom_cupertino_picker.dart'; import 'custom_label.dart'; @@ -135,82 +140,82 @@ class _AgeDateControlState extends State { builder: (context) { return ListView( primary: false, - physics: const NeverScrollableScrollPhysics(), - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const SizedBox( - width: 50, - ), - Text( - widget.field.label!['eng'] ?? "", - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(fontWeight: FontWeight.bold), + physics: const NeverScrollableScrollPhysics(), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const SizedBox( + width: 50, + ), + Text( + widget.field.label!['eng'] ?? "", + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(fontWeight: FontWeight.bold), + ), + IconButton( + icon: const Icon( + Icons.close, ), - IconButton( - icon: const Icon( - Icons.close, - ), - onPressed: () => Navigator.pop(context), - ) - ], + onPressed: () => Navigator.pop(context), + ) + ], + ), + Container( + height: 2.5, + width: MediaQuery.of(context).size.width, + color: solidPrimary.withOpacity(0.075), + ), + const SizedBox( + height: 16, + ), + CustomCupertinoDatePicker( + maxDate: DateTime.now(), + minDate: DateTime(DateTime.now().year - 125), + selectedDate: dateString != "" + ? DateFormat(widget.field.format ?? "yyyy/MM/dd") + .parse(dateString) + : null, + squeeze: 1, + itemExtent: 50, + diameterRatio: 10, + selectionOverlay: Container( + width: double.infinity, + decoration: BoxDecoration( + color: solidPrimary.withOpacity(0.075), + ), ), - Container( - height: 2.5, - width: MediaQuery.of(context).size.width, - color: solidPrimary.withOpacity(0.075), + selectedStyle: TextStyle( + color: solidPrimary, + fontWeight: FontWeight.w600, + fontSize: 16, ), - const SizedBox( - height: 16, + unselectedStyle: TextStyle( + color: Colors.grey[800], + fontSize: 15, ), - CustomCupertinoDatePicker( - maxDate: DateTime.now(), - minDate: DateTime(DateTime.now().year - 125), - selectedDate: dateString != "" - ? DateFormat(widget.field.format ?? "yyyy/MM/dd") - .parse(dateString) - : null, - squeeze: 1, - itemExtent: 50, - diameterRatio: 10, - selectionOverlay: Container( - width: double.infinity, - decoration: BoxDecoration( - color: solidPrimary.withOpacity(0.075), - ), - ), - selectedStyle: TextStyle( - color: solidPrimary, - fontWeight: FontWeight.w600, - fontSize: 16, - ), - unselectedStyle: TextStyle( - color: Colors.grey[800], - fontSize: 15, - ), - disabledStyle: TextStyle( - color: Colors.grey[400], - fontSize: 15, - ), - onSelectedItemChanged: (selectedDate) { - String targetDateString = widget.field.format ?? - "yyyy/MM/dd" - .replaceAll('dd', - selectedDate.day.toString().padLeft(2, "0")) - .replaceAll('MM', - selectedDate.month.toString().padLeft(2, "0")) - .replaceAll('yyyy', selectedDate.year.toString()); - setState(() { - dateController.text = targetDateString; - }); - _calculateAgeFromDOB(); - saveData(); - }, + disabledStyle: TextStyle( + color: Colors.grey[400], + fontSize: 15, ), - ], + onSelectedItemChanged: (selectedDate) { + String targetDateString = widget.field.format ?? + "yyyy/MM/dd" + .replaceAll( + 'dd', selectedDate.day.toString().padLeft(2, "0")) + .replaceAll('MM', + selectedDate.month.toString().padLeft(2, "0")) + .replaceAll('yyyy', selectedDate.year.toString()); + setState(() { + dateController.text = targetDateString; + }); + _calculateAgeFromDOB(); + saveData(); + }, + ), + ], ); }); } @@ -292,7 +297,7 @@ class _AgeDateControlState extends State { } return null; }, - onChanged: (value) { + onChanged: (value) async { if (value != "") { _getDateFromAge(value); } else { diff --git a/lib/ui/process_ui/widgets/biometric_capture_control.dart b/lib/ui/process_ui/widgets/biometric_capture_control.dart index 2c55bbb96..b59d7962a 100644 --- a/lib/ui/process_ui/widgets/biometric_capture_control.dart +++ b/lib/ui/process_ui/widgets/biometric_capture_control.dart @@ -248,6 +248,13 @@ class BiometricCaptureControlInitialization extends StatelessWidget { context.read().fieldInputValue[field.id], "Exception")); } + } else { + context.read().iris.attemptNo = 0; + context.read().rightHand.attemptNo = 0; + context.read().leftHand.attemptNo = 0; + context.read().thumbs.attemptNo = 0; + context.read().face.attemptNo = 0; + context.read().exception.attemptNo = 0; } } return StatefulWrapper( diff --git a/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart b/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart index f207be785..3ad8e4cc3 100644 --- a/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart +++ b/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart @@ -127,14 +127,37 @@ class _BiometricCaptureScanBlockPortraitState color: secondaryColors.elementAt(22), ), Row( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: (biometricAttributeData.title == "Iris") + ? MainAxisAlignment.spaceEvenly + : MainAxisAlignment.center, children: [ + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 130.h : 260.h, + ) + : const SizedBox()) + : const SizedBox(), ...temp.map( (e) => Image.memory( e!, height: (isMobileSize) ? 130.h : 260.h, ), ), + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? const SizedBox() + : Transform.flip( + flipX: true, + child: SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 130.h : 260.h, + ), + )) + : const SizedBox(), ], ), Divider( @@ -237,11 +260,46 @@ class _BiometricCaptureScanBlockPortraitState child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? Row( + children: [ + SizedBox( + width: 115.h, + ), + SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 70.h : 130.h, + ), + ], + ) + : const SizedBox()) + : const SizedBox(), ...biometricAttributeData.listofImages .map((e) => Image.memory( e, height: (isMobileSize) ? 70.h : 130.h, - )) + )), + (biometricAttributeData.title == "Iris" && + biometricAttributeData.exceptions.contains(true)) + ? ((biometricAttributeData.exceptions.first == true) + ? const SizedBox() + : Row( + children: [ + Transform.flip( + flipX: true, + child: SvgPicture.asset( + "assets/svg/Left Eye Exception.svg", + height: (isMobileSize) ? 70.h : 130.h, + ), + ), + SizedBox( + width: 115.h, + ) + ], + )) + : const SizedBox(), ], ), ), diff --git a/pigeon/biometrics.dart b/pigeon/biometrics.dart index fa24a0d9e..7a6bce709 100644 --- a/pigeon/biometrics.dart +++ b/pigeon/biometrics.dart @@ -27,6 +27,9 @@ abstract class BiometricsApi { @async String startOperatorOnboarding(); + @async + String clearBiometricAndDocumentHashmap(); + @async String saveOperatorBiometrics();