diff --git a/android/app/src/main/java/io/mosip/registration_client/MainActivity.java b/android/app/src/main/java/io/mosip/registration_client/MainActivity.java index f67cc7785..439a02fd9 100644 --- a/android/app/src/main/java/io/mosip/registration_client/MainActivity.java +++ b/android/app/src/main/java/io/mosip/registration_client/MainActivity.java @@ -98,6 +98,8 @@ import io.mosip.registration_client.model.TransliterationPigeon; import io.mosip.registration_client.model.UserPigeon; import io.mosip.registration_client.model.DocumentDataPigeon; +import io.mosip.registration_client.utils.BatchJob; +import io.mosip.registration_client.utils.CustomToast; import android.net.Uri; @@ -167,7 +169,6 @@ public class MainActivity extends FlutterActivity { @Inject DocumentDetailsApi documentDetailsApi; - @Inject DynamicDetailsApi dynamicDetailsApi; @@ -188,16 +189,19 @@ public class MainActivity extends FlutterActivity { @Inject DashBoardDetailsApi dashBoardDetailsApi; + @Inject + BatchJob batchJob; + private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals("REGISTRATION_PACKET_UPLOAD")) { - syncRegistrationPackets(context); - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - scheduler.schedule(()-> { - createBackgroundTask("registrationPacketUploadJob"); - }, 1, TimeUnit.MINUTES); - } + if (intent.getAction().equals("REGISTRATION_PACKET_UPLOAD")) { + batchJob.syncRegistrationPackets(context); + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + scheduler.schedule(()-> { + createBackgroundTask("registrationPacketUploadJob"); + }, 1, TimeUnit.MINUTES); + } } }; @@ -240,7 +244,7 @@ void createBackgroundTask(String api){ permissionIntent.setData(Uri.fromParts("package", getPackageName(), null)); startActivity(permissionIntent); } - long alarmTime = getIntervalMillis(api); + long alarmTime = batchJob.getIntervalMillis(api); long currentTime = System.currentTimeMillis(); long delay = alarmTime > currentTime ? alarmTime - currentTime : alarmTime - currentTime; Log.d(getClass().getSimpleName(), String.valueOf(delay)+ " Next Execution"); @@ -256,91 +260,6 @@ void createBackgroundTask(String api){ } } - private void syncRegistrationPackets(Context context) { - if(NetworkUtils.isNetworkConnected(context)){ - Log.d(getClass().getSimpleName(), "Sync Packets in main activity"); - Integer batchSize = getBatchSize(); - List registrationList = packetService.getRegistrationsByStatus(PacketClientStatus.APPROVED.name(), batchSize); - -// Variable is accessed within inner class. Needs to be declared final also it is modified too in the inner class -// Solution: using final array variable with one element that can be altered - final Integer[] remainingPack = {registrationList.size()}; - - if(registrationList.isEmpty()){ - uploadRegistrationPackets(context); - return; - } - for (Registration value : registrationList) { - try { - Log.d(getClass().getSimpleName(), "Syncing " + value.getPacketId()); - auditManagerService.audit(AuditEvent.SYNC_PACKET, Components.REG_PACKET_LIST); - packetService.syncRegistration(value.getPacketId(), new AsyncPacketTaskCallBack() { - @Override - public void inProgress(String RID) { - //Do nothing - } - - @Override - public void onComplete(String RID, PacketTaskStatus status) { - remainingPack[0] -= 1; - Log.d(getClass().getSimpleName(), "Remaining pack"+ remainingPack[0]); - if(remainingPack[0] == 0){ - Log.d(getClass().getSimpleName(), "Last Packet"+RID); - uploadRegistrationPackets(context); - } - } - }); - } catch (Exception e) { - Log.e(getClass().getSimpleName(), e.getMessage()); - } - } - } - } - - private void uploadRegistrationPackets(Context context) { - if(NetworkUtils.isNetworkConnected(context)){ - Log.d(getClass().getSimpleName(), "Upload Packets in main activity"); - Integer batchSize = getBatchSize(); - List registrationList = packetService.getRegistrationsByStatus(PacketClientStatus.SYNCED.name(), batchSize); - for (Registration value : registrationList) { - try { - Log.d(getClass().getSimpleName(), "Uploading " + value.getPacketId()); - auditManagerService.audit(AuditEvent.UPLOAD_PACKET, Components.REG_PACKET_LIST); - packetService.uploadRegistration(value.getPacketId()); - } catch (Exception e) { - Log.e(getClass().getSimpleName(), e.getMessage()); - } - } - } - } - - private Integer getBatchSize(){ - // Default batch size is 4 - List globalParams = globalParamDao.getGlobalParams(); - for (GlobalParam value : globalParams) { - if (Objects.equals(value.getId(), "mosip.registration.packet_upload_batch_size")) { - return Integer.parseInt(value.getValue()); - } - } - return ClientManagerConstant.DEFAULT_BATCH_SIZE; - } - - private long getIntervalMillis(String api){ - // Default everyday at Noon - 12pm - String cronExp = ClientManagerConstant.DEFAULT_UPLOAD_CRON; - List syncJobs = syncJobDefRepository.getAllSyncJobDefList(); - for (SyncJobDef value : syncJobs) { - if (Objects.equals(value.getApiName(), api)) { - Log.d(getClass().getSimpleName(), api + " Cron Expression : " + String.valueOf(value.getSyncFreq())); - cronExp = String.valueOf(value.getSyncFreq()); - break; - } - } - long nextExecution = CronParserUtil.getNextExecutionTimeInMillis(cronExp); - Log.d(getClass().getSimpleName(), " Next Execution : " + String.valueOf(nextExecution)); - return nextExecution; - } - public void initializeAppComponent() { AppComponent appComponent = DaggerAppComponent.builder() .application(getApplication()) @@ -349,7 +268,6 @@ public void initializeAppComponent() { .appModule(new AppModule(getApplication())) .hostApiModule(new HostApiModule(getApplication())) .build(); - appComponent.inject(this); } @@ -367,6 +285,7 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { biometricsDetailsApi.setCallbackActivity(this); RegistrationDataPigeon.RegistrationDataApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), registrationApi); PacketAuthPigeon.PacketAuthApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), packetAuthenticationApi); + packetAuthenticationApi.setCallbackActivity(this); DemographicsDataPigeon.DemographicsApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), demographicsDetailsApi); DocumentDataPigeon.DocumentApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), documentDetailsApi); DocumentCategoryPigeon.DocumentCategoryApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), documentCategoryApi); @@ -374,9 +293,9 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { TransliterationPigeon.TransliterationApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(),new TransliterationApi(new TransliterationServiceImpl())); DynamicResponsePigeon.DynamicResponseApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), dynamicDetailsApi); + batchJob.setCallbackActivity(this); MasterDataSyncPigeon.SyncApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), masterDataSyncApi); - masterDataSyncApi.setCallbackActivity(this); - + masterDataSyncApi.setCallbackActivity(this, batchJob); AuditResponsePigeon.AuditResponseApi.setup(flutterEngine.getDartExecutor().getBinaryMessenger(), auditDetailsApi); } diff --git a/android/app/src/main/java/io/mosip/registration_client/api_services/MasterDataSyncApi.java b/android/app/src/main/java/io/mosip/registration_client/api_services/MasterDataSyncApi.java index 0d82162ef..38ba8b9de 100644 --- a/android/app/src/main/java/io/mosip/registration_client/api_services/MasterDataSyncApi.java +++ b/android/app/src/main/java/io/mosip/registration_client/api_services/MasterDataSyncApi.java @@ -25,24 +25,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.List; -import java.util.Objects; - import javax.inject.Inject; import javax.inject.Singleton; -import io.mosip.registration.clientmanager.constant.AuditEvent; -import io.mosip.registration.clientmanager.constant.ClientManagerConstant; -import io.mosip.registration.clientmanager.constant.Components; -import io.mosip.registration.clientmanager.constant.PacketClientStatus; -import io.mosip.registration.clientmanager.constant.PacketTaskStatus; import io.mosip.registration.clientmanager.dao.FileSignatureDao; import io.mosip.registration.clientmanager.dao.GlobalParamDao; import io.mosip.registration.clientmanager.dto.CenterMachineDto; + import io.mosip.registration.clientmanager.entity.GlobalParam; import io.mosip.registration.clientmanager.entity.Registration; import io.mosip.registration.clientmanager.entity.SyncJobDef; import io.mosip.registration.clientmanager.exception.ClientCheckedException; + import io.mosip.registration.clientmanager.repository.ApplicantValidDocRepository; import io.mosip.registration.clientmanager.repository.BlocklistedWordRepository; import io.mosip.registration.clientmanager.repository.DocumentTypeRepository; @@ -56,7 +50,6 @@ import io.mosip.registration.clientmanager.repository.SyncJobDefRepository; import io.mosip.registration.clientmanager.repository.TemplateRepository; import io.mosip.registration.clientmanager.repository.UserDetailRepository; -import io.mosip.registration.clientmanager.spi.AsyncPacketTaskCallBack; import io.mosip.registration.clientmanager.spi.AuditManagerService; import io.mosip.registration.clientmanager.spi.JobManagerService; import io.mosip.registration.clientmanager.spi.MasterDataService; @@ -65,9 +58,8 @@ import io.mosip.registration.clientmanager.spi.SyncRestService; import io.mosip.registration.keymanager.spi.CertificateManagerService; import io.mosip.registration.keymanager.spi.ClientCryptoManagerService; -import io.mosip.registration_client.CronParserUtil; +import io.mosip.registration_client.utils.BatchJob; import io.mosip.registration_client.MainActivity; -import io.mosip.registration_client.NetworkUtils; import io.mosip.registration_client.UploadBackgroundService; import io.mosip.registration_client.model.MasterDataSyncPigeon; @@ -105,7 +97,7 @@ public class MasterDataSyncApi implements MasterDataSyncPigeon.SyncApi { private Activity activity; - boolean syncAndUploadInProgressStatus = false; + BatchJob batchJob; @Inject public MasterDataSyncApi(ClientCryptoManagerService clientCryptoManagerService, MachineRepository machineRepository, RegistrationCenterRepository registrationCenterRepository, SyncRestService syncRestService, CertificateManagerService certificateManagerService, GlobalParamRepository globalParamRepository, ObjectMapper objectMapper, UserDetailRepository userDetailRepository, IdentitySchemaRepository identitySchemaRepository, Context context, DocumentTypeRepository documentTypeRepository, @@ -148,8 +140,9 @@ public MasterDataSyncApi(ClientCryptoManagerService clientCryptoManagerService, this.preRegistrationDataSyncService = preRegistrationDataSyncService; } - public void setCallbackActivity(MainActivity mainActivity){ + public void setCallbackActivity(MainActivity mainActivity, BatchJob batchJob){ this.activity=mainActivity; + this.batchJob = batchJob; } @Override @@ -255,7 +248,7 @@ public void getCaCertsSync(@NonNull Boolean isManualSync, @NonNull MasterDataSyn @Override public void batchJob(@NonNull MasterDataSyncPigeon.Result result) { - syncRegistrationPackets(this.context); + batchJob.syncRegistrationPackets(this.context); result.success("Registration Packet Sync Completed."); } @@ -290,7 +283,7 @@ public void getKernelCertsSync(@NonNull Boolean isManualSync, @NonNull MasterDat @Override public void getSyncAndUploadInProgressStatus(@NonNull MasterDataSyncPigeon.Result result) { - result.success(syncAndUploadInProgressStatus); + result.success(batchJob.getInProgressStatus()); } void resetAlarm(String api){ @@ -318,7 +311,7 @@ void resetAlarm(String api){ permissionIntent.setData(Uri.fromParts("package", activity.getPackageName(), null)); activity.startActivity(permissionIntent); } - long alarmTime = getIntervalMillis(api); + long alarmTime = batchJob.getIntervalMillis(api); long currentTime = System.currentTimeMillis(); long delay = alarmTime > currentTime ? alarmTime - currentTime : alarmTime - currentTime; Log.d(getClass().getSimpleName(), String.valueOf(delay)+ " Next Execution"); @@ -333,95 +326,4 @@ void resetAlarm(String api){ } } } - - private void syncRegistrationPackets(Context context) { - if (NetworkUtils.isNetworkConnected(context)) { - Log.d(getClass().getSimpleName(), "Sync Packets in main activity"); - Integer batchSize = getBatchSize(); - List registrationList = packetService.getRegistrationsByStatus(PacketClientStatus.APPROVED.name(), batchSize); - -// Variable is accessed within inner class. Needs to be declared final also it is modified too in the inner class -// Solution: using final array variable with one element that can be altered - final Integer[] remainingPack = {registrationList.size()}; - - if (registrationList.isEmpty()) { - uploadRegistrationPackets(context); - return; - } - for (Registration value : registrationList) { - try { - syncAndUploadInProgressStatus = true; - Log.d(getClass().getSimpleName(), "Syncing " + value.getPacketId()); - auditManagerService.audit(AuditEvent.SYNC_PACKET, Components.REG_PACKET_LIST); - packetService.syncRegistration(value.getPacketId(), new AsyncPacketTaskCallBack() { - @Override - public void inProgress(String RID) { - //Do nothing - } - - @Override - public void onComplete(String RID, PacketTaskStatus status) { - remainingPack[0] -= 1; - Log.d(getClass().getSimpleName(), "Remaining pack" + remainingPack[0]); - if (remainingPack[0] == 0) { - Log.d(getClass().getSimpleName(), "Last Packet" + RID); - uploadRegistrationPackets(context); - } - syncAndUploadInProgressStatus = false; - } - }); - } catch (Exception e) { - syncAndUploadInProgressStatus = false; - Log.e(getClass().getSimpleName(), e.getMessage()); - } - } - } - } - - private void uploadRegistrationPackets(Context context) { - if (NetworkUtils.isNetworkConnected(context)) { - Log.d(getClass().getSimpleName(), "Upload Packets in main activity"); - Integer batchSize = getBatchSize(); - List registrationList = packetService.getRegistrationsByStatus(PacketClientStatus.SYNCED.name(), batchSize); - for (Registration value : registrationList) { - try { - syncAndUploadInProgressStatus = true; - Log.d(getClass().getSimpleName(), "Uploading " + value.getPacketId()); - auditManagerService.audit(AuditEvent.UPLOAD_PACKET, Components.REG_PACKET_LIST); - packetService.uploadRegistration(value.getPacketId()); - syncAndUploadInProgressStatus = false; - } catch (Exception e) { - syncAndUploadInProgressStatus = false; - Log.e(getClass().getSimpleName(), e.getMessage()); - } - } - } - } - - private Integer getBatchSize() { - // Default batch size is 4 - List globalParams = globalParamDao.getGlobalParams(); - for (GlobalParam value : globalParams) { - if (Objects.equals(value.getId(), "mosip.registration.packet_upload_batch_size")) { - return Integer.parseInt(value.getValue()); - } - } - return ClientManagerConstant.DEFAULT_BATCH_SIZE; - } - - private long getIntervalMillis(String api){ - // Default everyday at Noon - 12pm - String cronExp = ClientManagerConstant.DEFAULT_UPLOAD_CRON; - List syncJobs = syncJobDefRepository.getAllSyncJobDefList(); - for (SyncJobDef value : syncJobs) { - if (Objects.equals(value.getApiName(), api)) { - Log.d(getClass().getSimpleName(), api + " Cron Expression : " + String.valueOf(value.getSyncFreq())); - cronExp = String.valueOf(value.getSyncFreq()); - break; - } - } - long nextExecution = CronParserUtil.getNextExecutionTimeInMillis(cronExp); - Log.d(getClass().getSimpleName(), " Next Execution : " + String.valueOf(nextExecution)); - return nextExecution; - } } diff --git a/android/app/src/main/java/io/mosip/registration_client/api_services/PacketAuthenticationApi.java b/android/app/src/main/java/io/mosip/registration_client/api_services/PacketAuthenticationApi.java index 85e4834cd..cdf75e9b6 100644 --- a/android/app/src/main/java/io/mosip/registration_client/api_services/PacketAuthenticationApi.java +++ b/android/app/src/main/java/io/mosip/registration_client/api_services/PacketAuthenticationApi.java @@ -8,13 +8,13 @@ package io.mosip.registration_client.api_services; import com.fasterxml.jackson.databind.ObjectMapper; +import android.app.Activity; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.inject.Inject; @@ -22,17 +22,18 @@ import io.mosip.registration.clientmanager.constant.AuditEvent; import io.mosip.registration.clientmanager.constant.Components; -import io.mosip.registration.clientmanager.constant.PacketClientStatus; import io.mosip.registration.clientmanager.constant.PacketTaskStatus; import io.mosip.registration.clientmanager.entity.Registration; import io.mosip.registration.clientmanager.repository.RegistrationRepository; import io.mosip.registration.clientmanager.service.LoginService; -import io.mosip.registration.clientmanager.service.PacketServiceImpl; import io.mosip.registration.clientmanager.spi.AsyncPacketTaskCallBack; import io.mosip.registration.clientmanager.spi.AuditManagerService; import io.mosip.registration.clientmanager.spi.PacketService; import io.mosip.registration.clientmanager.spi.SyncRestService; import io.mosip.registration.clientmanager.util.SyncRestUtil; +import io.mosip.registration_client.utils.CustomToast; +import io.mosip.registration_client.MainActivity; +import io.mosip.registration_client.R; import io.mosip.registration_client.model.PacketAuthPigeon; @Singleton @@ -44,6 +45,12 @@ public class PacketAuthenticationApi implements PacketAuthPigeon.PacketAuthApi { PacketService packetService; RegistrationRepository registrationRepository; + private Activity activity; + + public void setCallbackActivity(MainActivity mainActivity){ + this.activity=mainActivity; + } + @Inject public PacketAuthenticationApi(SyncRestService syncRestService, SyncRestUtil syncRestFactory, LoginService loginService, PacketService packetService,RegistrationRepository registrationRepository , @@ -84,34 +91,19 @@ public void authenticate(@NonNull String username, @NonNull String password, @No offlineAuthentication(username, password, result); } - @Override - public void syncPacket(@NonNull String packetId, @NonNull PacketAuthPigeon.Result result) { - auditManagerService.audit(AuditEvent.SYNC_PACKET, Components.REG_PACKET_LIST); - try{ - packetService.syncRegistration(packetId); - }catch(Exception e){ - Log.e(getClass().getSimpleName(), "Error packet Sync", e); - } - } - - @Override - public void uploadPacket(@NonNull String packetId, @NonNull PacketAuthPigeon.Result result) { - auditManagerService.audit(AuditEvent.UPLOAD_PACKET, Components.REG_PACKET_LIST); - try{ - packetService.uploadRegistration(packetId); - }catch(Exception e){ - Log.e(getClass().getSimpleName(), "Error packet Upload", e); - } - } - @Override public void syncPacketAll(@NonNull List packetIds, @NonNull PacketAuthPigeon.Result result) { - Log.e(getClass().getSimpleName(), packetIds.toString()); - final Integer[] remainingPack = {packetIds.size()}; + Integer packetSize = packetIds.size(); + final Integer[] remainingPack = {packetSize, 0}; + CustomToast newToast = new CustomToast(activity); for (String value: packetIds){ try { - Log.d(getClass().getSimpleName(), "Syncing " + value); auditManagerService.audit(AuditEvent.SYNC_PACKET, Components.REG_PACKET_LIST); + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Sync Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + newToast.showToast(); + packetService.syncRegistration(value, new AsyncPacketTaskCallBack() { @Override public void inProgress(String RID) { @@ -120,10 +112,26 @@ public void inProgress(String RID) { @Override public void onComplete(String RID, PacketTaskStatus status) { + if(status.equals(PacketTaskStatus.SYNC_COMPLETED) || status.equals(PacketTaskStatus.SYNC_ALREADY_COMPLETED)){ + remainingPack[1] += 1; + } remainingPack[0] -= 1; - Log.d(getClass().getSimpleName(), "Remaining pack"+ remainingPack[0]); + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Sync Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + if(remainingPack[0] == 0){ - Log.d(getClass().getSimpleName(), "Last Packet"+RID); + Integer failed = packetSize - remainingPack[1]; + newToast.setIcon(R.drawable.done); + String message = "Sync Packet Status :"; + if(remainingPack[1] != 0){ + message = message + String.format(" %s/%s Success", remainingPack[1], packetSize); + } + if(failed != 0){ + message = message + String.format(" %s/%s Failed", failed, packetSize); + } + newToast.setText(message); + newToast.showToast(); result.success(null); } } @@ -136,24 +144,45 @@ public void onComplete(String RID, PacketTaskStatus status) { @Override public void uploadPacketAll(@NonNull List packetIds, @NonNull PacketAuthPigeon.Result result) { - Log.e(getClass().getSimpleName(), packetIds.toString()); - final Integer[] remainingPack = {packetIds.size()}; + Integer packetSize = packetIds.size(); + final Integer[] remainingPack = {packetSize, 0}; + CustomToast newToast = new CustomToast(activity); for (String value: packetIds){ try { - Log.d(getClass().getSimpleName(), "Uploading " + value); auditManagerService.audit(AuditEvent.UPLOAD_PACKET, Components.REG_PACKET_LIST); + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Upload Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + newToast.showToast(); + packetService.uploadRegistration(value, new AsyncPacketTaskCallBack() { @Override public void inProgress(String RID) { + newToast.showToast(); //Do nothing } @Override public void onComplete(String RID, PacketTaskStatus status) { + if(status.equals(PacketTaskStatus.UPLOAD_COMPLETED) || status.equals(PacketTaskStatus.UPLOAD_ALREADY_COMPLETED)){ + remainingPack[1] += 1; + } remainingPack[0] -= 1; - Log.d(getClass().getSimpleName(), "Remaining pack"+ remainingPack[0]); + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Upload Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + if(remainingPack[0] == 0){ - Log.d(getClass().getSimpleName(), "Last Packet"+RID); + Integer failed = packetSize - remainingPack[1]; + newToast.setIcon(R.drawable.done); + String message = "Upload Packet Status :"; + if(remainingPack[1] != 0){ + message = message + String.format(" %s/%s Success", remainingPack[1], packetSize); + } + if(failed != 0){ + message = message + String.format(" %s/%s Failed", failed, packetSize); + } + newToast.setText(message); + newToast.showToast(); result.success(null); } } @@ -168,7 +197,7 @@ public void onComplete(String RID, PacketTaskStatus status) { public void getAllRegistrationPacket(@NonNull PacketAuthPigeon.Result> result) { List packets = new ArrayList(); try{ - List allRegistration = packetService.getAllRegistrations(1,20); + List allRegistration = packetService.getAllNotUploadedRegistrations(1,20); ObjectMapper mapper = new ObjectMapper(); for (Registration element : allRegistration) { String json = mapper.writeValueAsString(element); diff --git a/android/app/src/main/java/io/mosip/registration_client/utils/BatchJob.java b/android/app/src/main/java/io/mosip/registration_client/utils/BatchJob.java new file mode 100644 index 000000000..18bf4932b --- /dev/null +++ b/android/app/src/main/java/io/mosip/registration_client/utils/BatchJob.java @@ -0,0 +1,218 @@ +package io.mosip.registration_client.utils; + +import android.app.Activity; +import android.content.Context; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import javax.inject.Inject; + +import io.mosip.registration.clientmanager.constant.AuditEvent; +import io.mosip.registration.clientmanager.constant.ClientManagerConstant; +import io.mosip.registration.clientmanager.constant.Components; +import io.mosip.registration.clientmanager.constant.PacketClientStatus; +import io.mosip.registration.clientmanager.constant.PacketTaskStatus; +import io.mosip.registration.clientmanager.dao.GlobalParamDao; +import io.mosip.registration.clientmanager.entity.GlobalParam; +import io.mosip.registration.clientmanager.entity.Registration; +import io.mosip.registration.clientmanager.entity.SyncJobDef; +import io.mosip.registration.clientmanager.repository.SyncJobDefRepository; +import io.mosip.registration.clientmanager.spi.AsyncPacketTaskCallBack; +import io.mosip.registration.clientmanager.spi.AuditManagerService; +import io.mosip.registration.clientmanager.spi.PacketService; +import io.mosip.registration_client.MainActivity; +import io.mosip.registration_client.R; + +public class BatchJob { + + PacketService packetService; + AuditManagerService auditManagerService; + GlobalParamDao globalParamDao; + SyncJobDefRepository syncJobDefRepository; + Activity activity; + boolean syncAndUploadInProgressStatus = false; + + @Inject + public BatchJob(PacketService packetService, AuditManagerService auditManagerService, + GlobalParamDao globalParamDao, SyncJobDefRepository syncJobDefRepository) { + this.packetService = packetService; + this.auditManagerService = auditManagerService; + this.globalParamDao = globalParamDao; + this.syncJobDefRepository = syncJobDefRepository; + } + + public void setCallbackActivity(MainActivity mainActivity){ + this.activity=mainActivity; + } + + public boolean getInProgressStatus(){ + return syncAndUploadInProgressStatus; + } + + private List getRegistrationList(List statusList){ + Integer batchSize = getBatchSize(); + List registrationList = new ArrayList(); + for(String status: statusList){ + if(registrationList.size() >= batchSize){ + break; + } + List newList = packetService.getRegistrationsByStatus(status, (batchSize - registrationList.size())); + registrationList.addAll(newList); + } + return registrationList; + } + + public void syncRegistrationPackets(Context context) { + Log.d(getClass().getSimpleName(), "Sync Packets in Batch Job"); + List registrationList = getRegistrationList(Arrays.asList(PacketClientStatus.APPROVED.name(), PacketClientStatus.EXPORTED.name())); + final Integer[] remainingPack = {registrationList.size(), 0}; + + Integer packetSize = registrationList.size(); + CustomToast newToast = new CustomToast(activity); + + if(registrationList.isEmpty()){ + uploadRegistrationPackets(context); + return; + } + for (Registration value : registrationList) { + try { + syncAndUploadInProgressStatus = true; + Log.d(getClass().getSimpleName(), "Syncing " + value.getPacketId()); + auditManagerService.audit(AuditEvent.SYNC_PACKET, Components.REG_PACKET_LIST); + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Sync Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + newToast.showToast(); + + packetService.syncRegistration(value.getPacketId(), new AsyncPacketTaskCallBack() { + @Override + public void inProgress(String RID) { + //Do nothing + newToast.showToast(); + } + + @Override + public void onComplete(String RID, PacketTaskStatus status) { + if(status.equals(PacketTaskStatus.SYNC_COMPLETED) || status.equals(PacketTaskStatus.SYNC_ALREADY_COMPLETED)){ + remainingPack[1] += 1; + } + remainingPack[0] -= 1; + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Sync Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + + if(remainingPack[0] == 0){ + syncAndUploadInProgressStatus = false; + Integer failed = packetSize- remainingPack[1]; + newToast.setIcon(R.drawable.done); + String message = "Sync Packet Status :"; + if(remainingPack[1] != 0){ + message = message + String.format(" %s/%s Success", remainingPack[1], packetSize); + } + if(failed != 0){ + message = message + String.format(" %s/%s Failed", failed, packetSize); + } + newToast.setText(message); + newToast.showToast(); + + Log.d(getClass().getSimpleName(), "Last Packet"+RID); + uploadRegistrationPackets(context); + } + } + }); + } catch (Exception e) { + syncAndUploadInProgressStatus = false; + Log.e(getClass().getSimpleName(), e.getMessage()); + } + } + } + + public void uploadRegistrationPackets(Context context) { + Log.d(getClass().getSimpleName(), "Upload Packets in Batch Job"); + List registrationList = getRegistrationList(Arrays.asList(PacketClientStatus.SYNCED.name(), PacketClientStatus.EXPORTED.name())); + + Integer packetSize = registrationList.size(); + final Integer[] remainingPack = {packetSize, 0}; + CustomToast newToast = new CustomToast(activity); + + for (Registration value : registrationList) { + try { + syncAndUploadInProgressStatus = true; + Log.d(getClass().getSimpleName(), "Uploading " + value.getPacketId()); + auditManagerService.audit(AuditEvent.UPLOAD_PACKET, Components.REG_PACKET_LIST); + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Upload Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + newToast.showToast(); + + packetService.uploadRegistration(value.getPacketId(), new AsyncPacketTaskCallBack() { + @Override + public void inProgress(String RID) { + //Do nothing + newToast.showToast(); + } + + @Override + public void onComplete(String RID, PacketTaskStatus status) { + if(status.equals(PacketTaskStatus.UPLOAD_COMPLETED) || status.equals(PacketTaskStatus.UPLOAD_ALREADY_COMPLETED)){ + remainingPack[1] += 1; + } + remainingPack[0] -= 1; + + Integer remaining = packetSize - remainingPack[0]; + newToast.setText(String.format("Upload Packet Status : %s/%s Processed", remaining.toString(), packetSize.toString())); + + if(remainingPack[0] == 0){ + syncAndUploadInProgressStatus = false; + Integer failed = packetSize- remainingPack[1]; + newToast.setIcon(R.drawable.done); + String message = "Upload Packet Status :"; + if(remainingPack[1] != 0){ + message = message + String.format(" %s/%s Success", remainingPack[1], packetSize); + } + if(failed != 0){ + message = message + String.format(" %s/%s Failed", failed, packetSize); + } + newToast.setText(message); + newToast.showToast(); + } + } + }); + } catch (Exception e) { + syncAndUploadInProgressStatus = false; + Log.e(getClass().getSimpleName(), e.getMessage()); + } + } + } + + public Integer getBatchSize(){ + // Default batch size is 4 + List globalParams = globalParamDao.getGlobalParams(); + for (GlobalParam value : globalParams) { + if (Objects.equals(value.getId(), "mosip.registration.packet_upload_batch_size")) { + return Integer.parseInt(value.getValue()); + } + } + return ClientManagerConstant.DEFAULT_BATCH_SIZE; + } + + public long getIntervalMillis(String api){ + // Default everyday at Noon - 12pm + String cronExp = ClientManagerConstant.DEFAULT_UPLOAD_CRON; + List syncJobs = syncJobDefRepository.getAllSyncJobDefList(); + for (SyncJobDef value : syncJobs) { + if (Objects.equals(value.getApiName(), api)) { + Log.d(getClass().getSimpleName(), api + " Cron Expression : " + String.valueOf(value.getSyncFreq())); + cronExp = String.valueOf(value.getSyncFreq()); + break; + } + } + long nextExecution = CronParserUtil.getNextExecutionTimeInMillis(cronExp); + Log.d(getClass().getSimpleName(), " Next Execution : " + String.valueOf(nextExecution)); + return nextExecution; + } +} diff --git a/android/app/src/main/java/io/mosip/registration_client/CronParserUtil.java b/android/app/src/main/java/io/mosip/registration_client/utils/CronParserUtil.java similarity index 95% rename from android/app/src/main/java/io/mosip/registration_client/CronParserUtil.java rename to android/app/src/main/java/io/mosip/registration_client/utils/CronParserUtil.java index 8bea9c52e..f506605ef 100644 --- a/android/app/src/main/java/io/mosip/registration_client/CronParserUtil.java +++ b/android/app/src/main/java/io/mosip/registration_client/utils/CronParserUtil.java @@ -5,7 +5,7 @@ * */ -package io.mosip.registration_client; +package io.mosip.registration_client.utils; import com.cronutils.model.Cron; import com.cronutils.model.CronType; diff --git a/android/app/src/main/java/io/mosip/registration_client/utils/CustomToast.java b/android/app/src/main/java/io/mosip/registration_client/utils/CustomToast.java new file mode 100644 index 000000000..be10ccf60 --- /dev/null +++ b/android/app/src/main/java/io/mosip/registration_client/utils/CustomToast.java @@ -0,0 +1,51 @@ +package io.mosip.registration_client.utils; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Toast; + +import io.mosip.registration_client.R; + +public class CustomToast{ + + private Toast toast = null; + private View layout = null; + private Activity activity; + + public CustomToast(Activity activity){ + this.activity = activity; + final LayoutInflater inflater = LayoutInflater.from(activity); + layout = inflater.inflate(R.layout.toast_layout, null); + // Show the toast + toast = new Toast(activity); + toast.setView(layout); + toast.setDuration(Toast.LENGTH_LONG); + } + + public void showToast(){ + toast.show(); + } + + public void setText(String text){ + if(layout!=null){ + EditText parent = layout.findViewById(R.id.toast_message); + parent.setText(text); + } + } + + public void setIcon(int icon){ + if(layout!=null){ + ImageView imageView = layout.findViewById(R.id.toast_icon); + imageView.setImageResource(icon); + } + } + + public void hideToast(){ + if(toast!=null){ + toast.cancel(); + } + } +} diff --git a/android/app/src/main/java/io/mosip/registration_client/NetworkUtils.java b/android/app/src/main/java/io/mosip/registration_client/utils/NetworkUtils.java similarity index 94% rename from android/app/src/main/java/io/mosip/registration_client/NetworkUtils.java rename to android/app/src/main/java/io/mosip/registration_client/utils/NetworkUtils.java index da3d203f4..e94be79a6 100644 --- a/android/app/src/main/java/io/mosip/registration_client/NetworkUtils.java +++ b/android/app/src/main/java/io/mosip/registration_client/utils/NetworkUtils.java @@ -5,7 +5,7 @@ * */ -package io.mosip.registration_client; +package io.mosip.registration_client.utils; import android.content.Context; import android.net.ConnectivityManager; diff --git a/android/app/src/main/res/drawable/done.png b/android/app/src/main/res/drawable/done.png new file mode 100644 index 000000000..c0baf18bc Binary files /dev/null and b/android/app/src/main/res/drawable/done.png differ diff --git a/android/app/src/main/res/drawable/loader.gif b/android/app/src/main/res/drawable/loader.gif new file mode 100644 index 000000000..05cd7a260 Binary files /dev/null and b/android/app/src/main/res/drawable/loader.gif differ diff --git a/android/app/src/main/res/drawable/rounded_bg.xml b/android/app/src/main/res/drawable/rounded_bg.xml new file mode 100644 index 000000000..0f4de9076 --- /dev/null +++ b/android/app/src/main/res/drawable/rounded_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/toast_layout.xml b/android/app/src/main/res/layout/toast_layout.xml new file mode 100644 index 000000000..47a2bddac --- /dev/null +++ b/android/app/src/main/res/layout/toast_layout.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/PacketClientStatus.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/PacketClientStatus.java index 96a8ca5b3..8bf8b44bf 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/PacketClientStatus.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/PacketClientStatus.java @@ -6,5 +6,6 @@ public enum PacketClientStatus { APPROVED, REJECTED, SYNCED, + EXPORTED, UPLOADED; } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/RegistrationDao.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/RegistrationDao.java index 0496f6d8a..311dc0d1b 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/RegistrationDao.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/RegistrationDao.java @@ -17,6 +17,9 @@ public interface RegistrationDao { @Query("SELECT * FROM registration order by cr_dtimes desc") List findAll(); + @Query("SELECT * FROM registration where client_status!='UPLOADED' order by cr_dtimes desc") + List findAllNotUploaded(); + @Query("SELECT * FROM registration where client_status = :status order by cr_dtimes desc limit :batchSize") List findRegistrationByStatus(String status, Integer batchSize); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/RegistrationRepository.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/RegistrationRepository.java index bc2a2dcf3..273878b1e 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/RegistrationRepository.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/RegistrationRepository.java @@ -26,6 +26,10 @@ public List getAllRegistrations() { return this.registrationDao.findAll(); } + public List getAllNotUploadedRegistrations() { + return this.registrationDao.findAllNotUploaded(); + } + public List getRegistrationsByStatus(String status, Integer batchSize) { return this.registrationDao.findRegistrationByStatus(status, batchSize); } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/PacketServiceImpl.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/PacketServiceImpl.java index c1397902a..b1520cfb8 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/PacketServiceImpl.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/PacketServiceImpl.java @@ -67,7 +67,7 @@ public class PacketServiceImpl implements PacketService { public static final String PACKET_SYNC_VERSION = "1.0"; public static final String PACKET_UPLOAD_FIELD = "file"; public static final List PACKET_UNSYNCED_STATUS = Arrays.asList(PacketClientStatus.CREATED.name(), - PacketClientStatus.APPROVED.name(), PacketClientStatus.REJECTED.name()); + PacketClientStatus.APPROVED.name(), PacketClientStatus.REJECTED.name(), PacketClientStatus.EXPORTED.name()); public static final List PACKET_UPLOAD_STATUS = Arrays.asList(PacketServerStatus.RESEND.name(), PacketServerStatus.UPLOAD_PENDING.name()); @@ -166,16 +166,18 @@ public void onResponse(Call>> call, if (response.isSuccessful()) { ServiceError error = SyncRestUtil.getServiceError(response.body()); if (error == null && response.body().getResponse().get(0).getStatus().equalsIgnoreCase("SUCCESS")) { - registrationRepository.updateStatus(packetId, null, PacketClientStatus.SYNCED.name()); + if(!PacketClientStatus.EXPORTED.name().equals(registration.getClientStatus())){ + registrationRepository.updateStatus(packetId, null, PacketClientStatus.SYNCED.name()); + } callBack.onComplete(packetId, PacketTaskStatus.SYNC_COMPLETED); - Toast.makeText(context, "Packet synced successfully", Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet synced successfully", Toast.LENGTH_LONG).show(); } else { callBack.onComplete(packetId, PacketTaskStatus.SYNC_FAILED); - Toast.makeText(context, "Packet sync failed : " + error, Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet sync failed : " + error, Toast.LENGTH_LONG).show(); } } else { callBack.onComplete(packetId, PacketTaskStatus.SYNC_FAILED); - Toast.makeText(context, "Packet sync failed with Status Code : " + response.code(), Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet sync failed with Status Code : " + response.code(), Toast.LENGTH_LONG).show(); } } @@ -183,7 +185,7 @@ public void onResponse(Call>> call, public void onFailure(Call>> call, Throwable t) { Log.e(TAG, "Packet sync failed", t); callBack.onComplete(packetId, PacketTaskStatus.SYNC_FAILED); - Toast.makeText(context, "Packet sync failed", Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet sync failed", Toast.LENGTH_LONG).show(); } }); callBack.inProgress(packetId); @@ -229,14 +231,14 @@ public void onResponse(Call> call, Respon registrationRepository.updateStatus(packetId, response.body().getResponse().getStatus(), PacketClientStatus.UPLOADED.name()); callBack.onComplete(packetId, PacketTaskStatus.UPLOAD_COMPLETED); - Toast.makeText(context, "Packet uploaded successfully", Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet uploaded successfully", Toast.LENGTH_LONG).show(); } else { callBack.onComplete(packetId, PacketTaskStatus.UPLOAD_FAILED); - Toast.makeText(context, "Packet uploaded failed : " + error.getMessage(), Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet uploaded failed : " + error.getMessage(), Toast.LENGTH_LONG).show(); } } else { callBack.onComplete(packetId, PacketTaskStatus.UPLOAD_FAILED); - Toast.makeText(context, "Packet uploaded failed with Status Code : " + response.code(), Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet uploaded failed with Status Code : " + response.code(), Toast.LENGTH_LONG).show(); } } @@ -244,7 +246,7 @@ public void onResponse(Call> call, Respon public void onFailure(Call> call, Throwable t) { Log.e(TAG, "Packet uploaded failed", t); callBack.onComplete(packetId, PacketTaskStatus.UPLOAD_FAILED); - Toast.makeText(context, "Packet uploaded failed", Toast.LENGTH_LONG).show(); +// Toast.makeText(context, "Packet uploaded failed", Toast.LENGTH_LONG).show(); } }); callBack.inProgress(packetId); @@ -255,6 +257,11 @@ public List getAllRegistrations(int page, int pageLimit) { return this.registrationRepository.getAllRegistrations(); } + @Override + public List getAllNotUploadedRegistrations(int page, int pageLimit) { + return this.registrationRepository.getAllNotUploadedRegistrations(); + } + @Override public List getRegistrationsByStatus(String status, Integer batchSize) { return this.registrationRepository.getRegistrationsByStatus(status, batchSize); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/PacketService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/PacketService.java index b3a30002a..523e85835 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/PacketService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/PacketService.java @@ -45,6 +45,14 @@ public interface PacketService { */ List getAllRegistrations(int page, int pageLimit); + /** + * + * @param page + * @param pageLimit + * @return + */ + List getAllNotUploadedRegistrations(int page, int pageLimit); + /** * * @param status diff --git a/android/clientmanager/src/main/res/values/strings.xml b/android/clientmanager/src/main/res/values/strings.xml index 9ad0ae83f..fdcc03d4e 100644 --- a/android/clientmanager/src/main/res/values/strings.xml +++ b/android/clientmanager/src/main/res/values/strings.xml @@ -39,6 +39,8 @@ Registration Center Important Guidelines Acknowledgement + Loading... + Loader Face diff --git a/assets/l10n/app_ar.arb b/assets/l10n/app_ar.arb index 411525e51..5347944c5 100644 --- a/assets/l10n/app_ar.arb +++ b/assets/l10n/app_ar.arb @@ -138,6 +138,50 @@ }, "synchronize_data": "مزامنة البيانات", "registration_tasks": "مهام التسجيل", + + + "manage_applications": "إدارة التطبيقات", + "search_application": "البحث عن طريق معرف التطبيق", + "upload": "رفع", + "export": "يصدّر", + "number_of_application": "عرض {number} تطبيقات", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} تم تحديد التطبيقات", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": " حالة العميل", + "server_status": "حالة الملقم", + "clear_filter": "مرشح واضح", + "serial_number": "س.ن", + "application_id": "رقم الاستمارة", + "reg_date":"ريج. تاريخ", + "reg_type":"ريج. يكتب", + "operator_id": "معرف المشغل", + + + + + + "operation_tasks": "المهام التشغيلية", "system_storage_usage": "استخدام تخزين النظام", "download_pre_registration_data": "تنزيل بيانات التسجيل المسبق", diff --git a/assets/l10n/app_en.arb b/assets/l10n/app_en.arb index 445fab04e..715f12783 100644 --- a/assets/l10n/app_en.arb +++ b/assets/l10n/app_en.arb @@ -138,6 +138,47 @@ }, "synchronize_data": "Synchronize Data", "registration_tasks": "Registration Tasks", + + + "manage_applications": "Manage Applications", + "search_application": "Search by Application ID", + "upload": "UPLOAD", + "export": "EXPORT", + "number_of_application": "Displaying {number} Applications", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} Applications Selected", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": "Client Status", + "server_status": "Server Status", + "clear_filter": "Clear Filter", + "serial_number": "S.no", + "application_id": "Application ID", + "reg_date":"Reg. Date", + "reg_type":"Reg. Type", + "operator_id": "Operator ID", + + + "operation_tasks": "Operational Tasks", "system_storage_usage": "System Storage Usage", "download_pre_registration_data": "Download Pre-Registration Data", diff --git a/assets/l10n/app_fr.arb b/assets/l10n/app_fr.arb index e27bbe3ae..afc4e45b0 100644 --- a/assets/l10n/app_fr.arb +++ b/assets/l10n/app_fr.arb @@ -138,6 +138,50 @@ }, "synchronize_data": "Synchroniser les données", "registration_tasks": "Tâches d'inscription", + + + + "manage_applications": "Gérer des applications", + "search_application": "Rechercher par ID d'application", + "upload": "TÉLÉCHARGER", + "export": "EXPORTER", + "number_of_application": "Affichage de {number} applications", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} Applications sélectionnées", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": "Statut du client", + "server_status": "État du serveur", + "clear_filter": "Effacer le filtre", + "serial_number": "S.non", + "application_id": "ID d'application", + "reg_date":"Rég. Date", + "reg_type":"Rég. Taper", + "operator_id": "ID de l'opérateur", + + + + + "operation_tasks": "Tâches opérationnelles", "system_storage_usage": "Utilisation du stockage système", "download_pre_registration_data": "Télécharger les données de pré-inscription", diff --git a/assets/l10n/app_hi.arb b/assets/l10n/app_hi.arb index 6aaf060eb..1310357d5 100644 --- a/assets/l10n/app_hi.arb +++ b/assets/l10n/app_hi.arb @@ -138,6 +138,51 @@ }, "synchronize_data": "डेटा सिंक्रनाइज़ करें", "registration_tasks": "पंजीकरण कार्य", + + + + "manage_applications": "अनुप्रयोगों का प्रबंधन", + "search_application": "एप्लिकेशन आईडी द्वारा खोजें", + "upload": "डालना", + "export": "निर्यात", + "number_of_application": "{number} एप्लिकेशन प्रदर्शित हो रहे हैं", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} आवेदन चयनित", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": "ग्राहक स्थिति", + "server_status": "सर्वर की स्थिति", + "clear_filter": "फ़िल्टर साफ़ करें", + "serial_number": "क्र.सं", + "application_id": "आवेदन पहचान पत्र", + "reg_date":"रजि. तारीख", + "reg_type":"रजि. प्रकार", + "operator_id": "ऑपरेटर आईडी", + + + + + + "operation_tasks": "परिचालन कार्य", "system_storage_usage": "सिस्टम संग्रहण उपयोग", "download_pre_registration_data": "पूर्व-पंजीकरण डेटा डाउनलोड करें", diff --git a/assets/l10n/app_kn.arb b/assets/l10n/app_kn.arb index 8314e9419..4d3c964f5 100644 --- a/assets/l10n/app_kn.arb +++ b/assets/l10n/app_kn.arb @@ -138,6 +138,49 @@ }, "synchronize_data": "ಡೇಟಾವನ್ನು ಸಿಂಕ್ರೊನೈಸ್ ಮಾಡಿ", "registration_tasks": "ನೋಂದಣಿ ಕಾರ್ಯಗಳು", + + + + "manage_applications": "ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ", + "search_application": "ಅಪ್ಲಿಕೇಶನ್ ಐಡಿ ಮೂಲಕ ಹುಡುಕಿ", + "upload": "ಅಪ್ಲೋಡ್ ಮಾಡಿ", + "export": "ರಫ್ತು ಮಾಡಿ", + "number_of_application": "{number} ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತಿದೆ", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} ಅಪ್ಲಿಕೇಶನ್\u200Cಗಳನ್ನು ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": "ಕ್ಲೈಂಟ್ ಸ್ಥಿತಿ", + "server_status": "ಸರ್ವರ್ ಸ್ಥಿತಿ", + "clear_filter": "Clear Filter", + "serial_number": "ಎಸ್.ಎನ್", + "application_id": "ಅಪ್ಲಿಕೇಶನ್ ಐಡಿ", + "reg_date":"ರೆಗ್. ದಿನಾಂಕ", + "reg_type":"ರೆಗ್. ಪ್ರಕಾರ", + "operator_id": "ಆಪರೇಟರ್ ಐಡಿ", + + + + "operation_tasks": "ಕಾರ್ಯಾಚರಣೆಯ ಕಾರ್ಯಗಳು", "system_storage_usage": "ಸಿಸ್ಟಮ್ ಶೇಖರಣಾ ಬಳಕೆ", "download_pre_registration_data": "ಪೂರ್ವ-ನೋಂದಣಿ ಡೇಟಾವನ್ನು ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ", diff --git a/assets/l10n/app_ta.arb b/assets/l10n/app_ta.arb index bfac1838b..8513dd886 100644 --- a/assets/l10n/app_ta.arb +++ b/assets/l10n/app_ta.arb @@ -129,6 +129,51 @@ "upload_document": "ஆவணத்தைப் பதிவேற்றவும்", "synchronize_data": "தரவை ஒத்திசைக்கவும்", "registration_tasks": "பதிவு பணிகள்", + + + + + "manage_applications": "பயன்பாடுகளை நிர்வகிக்கவும்", + "search_application": "விண்ணப்ப ஐடி மூலம் தேடவும்", + "upload": "பதிவேற்றம்", + "export": "ஏற்றுமதி", + "number_of_application": "{number} பயன்பாடுகளைக் காட்டுகிறது", + "@number_of_application": { + "description": "A message with a single parameter", + "placeholders": { + "number": { + "type": "int", + "example": "0" + } + } + }, + "total_selected_application": "{selected}/{total} விண்ணப்பங்கள் தேர்ந்தெடுக்கப்பட்டன", + "@total_selected_application": { + "description": "A message with a two parameter", + "placeholders": { + "selected": { + "type": "int", + "example": "0" + }, + "total": { + "type": "int", + "example": "0" + } + } + }, + "client_status": "வாடிக்கையாளர் நிலை", + "server_status": "சேவையக நிலை", + "clear_filter": "Clear Filter", + "serial_number": "எஸ்.என்", + "application_id": "விண்ணப்ப ஐடி", + "reg_date":"ரெஜி. தேதி", + "reg_type":"ரெஜி. வகை", + "operator_id": "ஆபரேட்டர் ஐடி", + + + + + "operation_tasks": "செயல்பாட்டு பணிகள்", "system_storage_usage": "கணினி சேமிப்பக பயன்பாடு", "download_pre_registration_data": "முன் பதிவுத் தரவைப் பதிவிறக்கவும்", diff --git a/lib/platform_android/packet_service_impl.dart b/lib/platform_android/packet_service_impl.dart index a290c5b67..5b811131e 100644 --- a/lib/platform_android/packet_service_impl.dart +++ b/lib/platform_android/packet_service_impl.dart @@ -15,29 +15,6 @@ import 'package:registration_client/pigeon/packet_auth_pigeon.dart'; import 'package:registration_client/platform_spi/packet_service.dart'; class PacketServiceImpl implements PacketService { - @override - Future packetSync(String packetId) async { - try { - await PacketAuthApi().syncPacket(packetId); - log("Sucess Sync packet"); - } on PlatformException { - debugPrint('PacketAuthenticationApi call failed!'); - } catch (e) { - debugPrint(e.toString()); - } - } - - @override - Future packetUpload(String packetId) async { - try { - await PacketAuthApi().uploadPacket(packetId); - log("Sucess Upload packet"); - } on PlatformException { - debugPrint('PacketAuthenticationApi call failed!'); - } catch (e) { - debugPrint(e.toString()); - } - } @override Future> getAllRegistrationPacket() async { diff --git a/lib/platform_spi/packet_service.dart b/lib/platform_spi/packet_service.dart index f8f3b4a0e..f6c26ee8d 100644 --- a/lib/platform_spi/packet_service.dart +++ b/lib/platform_spi/packet_service.dart @@ -8,8 +8,6 @@ import '../platform_android/packet_service_impl.dart'; abstract class PacketService { - Future packetSync(String packetId); - Future packetUpload(String packetId); Future packetSyncAll(List packetIds); Future packetUploadAll(List packetIds); Future> getAllRegistrationPacket(); diff --git a/lib/provider/export_packet_provider.dart b/lib/provider/export_packet_provider.dart index 7ddae5d2b..8ee778d2c 100644 --- a/lib/provider/export_packet_provider.dart +++ b/lib/provider/export_packet_provider.dart @@ -35,24 +35,6 @@ class ExportPacketsProvider with ChangeNotifier { notifyListeners(); } - Future refreshPackets() async{ - List allPackets = await PacketServiceImpl().getAllRegistrationPacket(); - packetsList.clear(); - - for (var element in allPackets) { - Registration newRegistration = Registration.fromJson(json.decode(element?? "")); - packetsList.add(newRegistration); - for(int i=0;i allPackets = await PacketServiceImpl().getAllRegistrationPacket(); @@ -138,11 +120,9 @@ class ExportPacketsProvider with ChangeNotifier { notifyListeners(); } - void uploadSelected() async { - await packetSyncAll(); - + Future uploadSelected() async { List toBeUploaded = []; - List uploadStatus = [ClientStatus.EXPORTED.name,ClientStatus.SYNCED.name,]; + List uploadStatus = [ClientStatus.SYNCED.name, ClientStatus.EXPORTED.name,]; for(int i=0; i exportSelected() async{ List sourceFiles = []; List toBeExported = []; - List exportStatus = [ClientStatus.EXPORTED.name, ClientStatus.SYNCED.name, ]; - + List exportStatus = [ ClientStatus.APPROVED.name, ClientStatus.SYNCED.name, ClientStatus.EXPORTED.name, ]; for(int i=0;i packetSyncAll() async { - // Exported packets show packet already synced - List syncStatus = [ClientStatus.APPROVED.name,]; + List syncStatus = [ClientStatus.APPROVED.name,ClientStatus.EXPORTED.name,]; List toBeSynced = []; - for(int i=0; i refreshPackets() async{ + List allPackets = await PacketServiceImpl().getAllRegistrationPacket(); + packetsList.clear(); + + for (var element in allPackets) { + Registration newRegistration = Registration.fromJson(json.decode(element?? "")); + packetsList.add(newRegistration); + for(int i=0;i _preRegistrationData = {}; + int _numberOfPackets = 0; + List get listOfProcesses => _listOfProcesses; String get stringValueGlobalParam => _stringValueGlobalParam; String get uiSchema => _uiSchema; @@ -45,6 +52,7 @@ class RegistrationTaskProvider with ChangeNotifier { String get registrationStartError => _registrationStartError; bool get isRegistrationSaved => _isRegistrationSaved; String get lastSuccessfulUpdatedTime => _lastSuccessfulUpdatedTime; + int get numberOfPackets => _numberOfPackets; Map get preRegistrationData => _preRegistrationData; set listOfProcesses(List value) { @@ -52,6 +60,11 @@ class RegistrationTaskProvider with ChangeNotifier { notifyListeners(); } + setNumberOfPackets(int value) { + _numberOfPackets = value; + notifyListeners(); + } + setStringValueGlobalParam(String value) { _stringValueGlobalParam = value; notifyListeners(); @@ -231,6 +244,12 @@ class RegistrationTaskProvider with ChangeNotifier { return await dashBoard.getPacketUploadedPendingDetails(); } + void getApplicationUploadNumber() async{ + List packets = await PacketServiceImpl().getAllRegistrationPacket(); + log("Number of Packets: ${packets.length}"); + setNumberOfPackets(packets.length); + } + Future getCreatedPacketDetails() async { return await dashBoard.getCreatedPacketDetails(); } diff --git a/lib/ui/export_packet/export_packet_ui.dart b/lib/ui/export_packet/export_packet_ui.dart index 96f6c10fd..8eac84029 100644 --- a/lib/ui/export_packet/export_packet_ui.dart +++ b/lib/ui/export_packet/export_packet_ui.dart @@ -9,8 +9,10 @@ import 'package:registration_client/utils/app_config.dart'; import '../../provider/export_packet_provider.dart'; +import '../../provider/registration_task_provider.dart'; import 'widgets/clear_dropdown_filter.dart'; import 'widgets/client_status_dropdown.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ExportPacketsPage extends StatelessWidget { const ExportPacketsPage({super.key}); @@ -31,11 +33,12 @@ class ExportPacketsPage extends StatelessWidget { style: ElevatedButton.styleFrom(backgroundColor: Colors.white.withOpacity(0.2), padding: const EdgeInsets.all(4)), child: const Icon(Icons.arrow_back, size: 32,), onPressed: (){ + context.read().getApplicationUploadNumber(); Navigator.of(context).pop(); }, ), ), - title: const Text('Manage Applications'), + title: Text(AppLocalizations.of(context)!.manage_applications), ), backgroundColor: backgroundColor, body: Padding( @@ -46,7 +49,7 @@ class ExportPacketsPage extends StatelessWidget { const Row( children: [ Flexible( - flex: 3, + flex: 2, child: SearchBoxExport(), ), SizedBox(width: 10), @@ -69,22 +72,29 @@ class ExportPacketsPage extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24), child: - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - context.watch().countSelected>0 - ? Text("${context.watch().countSelected}/${context.watch().matchingPackets.length} Applications Selected", style: Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 20),) - : Text("Displaying ${context.watch().matchingPackets.length} Applications", style: Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 20),), - const Row( + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: ConstrainedBox( + constraints: BoxConstraints(minWidth: MediaQuery.of(context)!.size.width-90), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - ClientStatusDropdown(), - SizedBox(width: 16,), - ServerStatusDropdown(), - SizedBox(width: 10,), - ClearDropdownFilter(), + context.watch().countSelected>0 + ? Text(AppLocalizations.of(context)!.total_selected_application(context.watch().countSelected, context.watch().matchingPackets.length), style: Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 20),) + : Text(AppLocalizations.of(context)!.number_of_application(context.watch().matchingPackets.length), style: Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 20),), + const SizedBox(width: 50,), + const Row( + children: [ + ClientStatusDropdown(), + SizedBox(width: 16,), + ServerStatusDropdown(), + SizedBox(width: 8,), + ClearDropdownFilter(), + ], + ), ], ), - ], + ), ), ), ), diff --git a/lib/ui/export_packet/widgets/clear_dropdown_filter.dart b/lib/ui/export_packet/widgets/clear_dropdown_filter.dart index 939f53298..14a0d1db4 100644 --- a/lib/ui/export_packet/widgets/clear_dropdown_filter.dart +++ b/lib/ui/export_packet/widgets/clear_dropdown_filter.dart @@ -3,7 +3,7 @@ import 'package:provider/provider.dart'; import '../../../provider/export_packet_provider.dart'; import '../../../utils/app_config.dart'; - +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ClearDropdownFilter extends StatelessWidget { const ClearDropdownFilter({super.key}); @@ -16,6 +16,6 @@ class ClearDropdownFilter extends StatelessWidget { context.read().changeServerStatus(null); context.read().filterSearchList(); }, - child: Text("Clear Filter",style: Theme.of(context).textTheme.titleMedium?.copyWith(fontSize: 16, fontWeight: FontWeight.w500, color: (context.watch().serverStatus==null && context.watch().clientStatus==null)? Colors.black54: solidPrimary),),); + child: Text(AppLocalizations.of(context)!.clear_filter ,style: Theme.of(context).textTheme.titleMedium?.copyWith(fontSize: 16, fontWeight: FontWeight.w500, color: (context.watch().serverStatus==null && context.watch().clientStatus==null)? Colors.black54: solidPrimary),),); } } diff --git a/lib/ui/export_packet/widgets/client_status_dropdown.dart b/lib/ui/export_packet/widgets/client_status_dropdown.dart index c084042e7..2b69ecc90 100644 --- a/lib/ui/export_packet/widgets/client_status_dropdown.dart +++ b/lib/ui/export_packet/widgets/client_status_dropdown.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import '../../../provider/export_packet_provider.dart'; import '../../../utils/constants.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ClientStatusDropdown extends StatelessWidget { const ClientStatusDropdown({super.key}); @@ -23,12 +24,11 @@ class ClientStatusDropdown extends StatelessWidget { dropdownColor: Colors.white, padding: const EdgeInsets.all(16), items: [ - const DropdownMenuItem(value: null, child: Text("Client Status")), + DropdownMenuItem(value: null, child: Text(AppLocalizations.of(context)!.client_status)), DropdownMenuItem(value: ClientStatus.CREATED.name, child: const Text("Created")), DropdownMenuItem(value: ClientStatus.APPROVED.name, child: const Text("Approved")), DropdownMenuItem(value: ClientStatus.REJECTED.name, child: const Text("Rejected")), DropdownMenuItem(value: ClientStatus.SYNCED.name, child: const Text("Synced")), - DropdownMenuItem(value: ClientStatus.UPLOADED.name, child: const Text("Uploaded")), DropdownMenuItem(value: ClientStatus.EXPORTED.name, child: const Text("Exported")), // Add more items as needed ], diff --git a/lib/ui/export_packet/widgets/export_button.dart b/lib/ui/export_packet/widgets/export_button.dart index 51bd83ff5..c0257d47e 100644 --- a/lib/ui/export_packet/widgets/export_button.dart +++ b/lib/ui/export_packet/widgets/export_button.dart @@ -1,20 +1,54 @@ -import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../../provider/connectivity_provider.dart'; import '../../../provider/export_packet_provider.dart'; import '../../../utils/app_config.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -class ExportButton extends StatelessWidget { +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class ExportButton extends StatefulWidget { const ExportButton({super.key}); + @override + State createState() => _ExportButtonState(); +} + +class _ExportButtonState extends State { + late ConnectivityProvider connectivityProvider; + late ExportPacketsProvider exportPacketsProvider; + late AppLocalizations appLocalizations = AppLocalizations.of(context)!; + + @override + void initState() { + connectivityProvider = Provider.of(context, listen: false); + exportPacketsProvider = Provider.of(context, listen: false); + super.initState(); + } + + void _showInSnackBar(String value) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(value), + ), + ); + } + + @override Widget build(BuildContext context) { return OutlinedButton( - onPressed: () { - context.read().exportSelected(); - log(context.read().countSelected.toString()); + onPressed: () async { + await connectivityProvider.checkNetworkConnection(); + if (!connectivityProvider.isConnected) { + _showInSnackBar(appLocalizations.network_error); + }else{ + await exportPacketsProvider.packetSyncAll(); + } + await exportPacketsProvider.exportSelected(); + exportPacketsProvider.searchedList(); }, style: OutlinedButton.styleFrom(side: BorderSide(width: 1.5, color: solidPrimary),backgroundColor: Colors.white), child: SizedBox( @@ -24,7 +58,7 @@ class ExportButton extends StatelessWidget { children: [ const Icon(Icons.upload_sharp, size: 26,), const SizedBox(width: 4,), - Text('EXPORT', style:Theme.of(context).textTheme.titleLarge?.copyWith(color: solidPrimary, fontSize: 17),), + Text(AppLocalizations.of(context)!.export, style:Theme.of(context).textTheme.titleLarge?.copyWith(color: solidPrimary, fontSize: 17),), ], ), ), diff --git a/lib/ui/export_packet/widgets/export_table.dart b/lib/ui/export_packet/widgets/export_table.dart index 3071c50ff..833cc9838 100644 --- a/lib/ui/export_packet/widgets/export_table.dart +++ b/lib/ui/export_packet/widgets/export_table.dart @@ -4,6 +4,7 @@ import 'package:provider/provider.dart'; import '../../../provider/export_packet_provider.dart'; import '../../../utils/app_config.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ExportTable extends StatelessWidget { const ExportTable({super.key}); @@ -39,13 +40,13 @@ class ExportTable extends StatelessWidget { title: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - SizedBox(width: tableWidth/35, child: Text("S.no", textAlign: TextAlign.center, style: textTheme)) , - SizedBox(width: tableWidth/5.5, child: Text("Application ID", textAlign: TextAlign.center, style: textTheme)), - SizedBox(width: tableWidth/9, child: Text("Reg. Date", textAlign: TextAlign.center, style: textTheme)), - SizedBox(width: tableWidth/15, child: Text("Reg. Type",textAlign: TextAlign.center, style: textTheme)), - SizedBox(width: tableWidth/9, child: Text("Client Status",textAlign: TextAlign.center, style: textTheme)), - SizedBox(width: tableWidth/9, child: Text("Server Status",textAlign: TextAlign.center, style: textTheme)), - SizedBox(width: tableWidth/15, child: Text("Operator ID",textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/35, child: Text(AppLocalizations.of(context)!.serial_number, textAlign: TextAlign.center, style: textTheme)) , + SizedBox(width: tableWidth/5.5, child: Text(AppLocalizations.of(context)!.application_id, textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/9, child: Text(AppLocalizations.of(context)!.reg_date, textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/15, child: Text(AppLocalizations.of(context)!.reg_type,textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/9, child: Text(AppLocalizations.of(context)!.client_status,textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/9, child: Text(AppLocalizations.of(context)!.server_status,textAlign: TextAlign.center, style: textTheme)), + SizedBox(width: tableWidth/15, child: Text(AppLocalizations.of(context)!.operator_id,textAlign: TextAlign.center, style: textTheme)), ], ), onTap: () { diff --git a/lib/ui/export_packet/widgets/search_box.dart b/lib/ui/export_packet/widgets/search_box.dart index b5e5be0ff..dca393418 100644 --- a/lib/ui/export_packet/widgets/search_box.dart +++ b/lib/ui/export_packet/widgets/search_box.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../provider/export_packet_provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SearchBoxExport extends StatelessWidget { const SearchBoxExport({super.key}); @@ -13,10 +14,10 @@ class SearchBoxExport extends StatelessWidget { color: Colors.white, child: TextField( onTapOutside: (pointer){FocusScope.of(context).unfocus();}, - decoration: const InputDecoration( - labelText: "Search by Application ID", - prefixIcon: Icon(Icons.search), - border: OutlineInputBorder(), + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.search_application, + prefixIcon: const Icon(Icons.search), + border: const OutlineInputBorder(), ), onChanged: (value) { context.read().setSearchList(value); diff --git a/lib/ui/export_packet/widgets/server_status_dropdown.dart b/lib/ui/export_packet/widgets/server_status_dropdown.dart index 4f02d8d8a..23627530e 100644 --- a/lib/ui/export_packet/widgets/server_status_dropdown.dart +++ b/lib/ui/export_packet/widgets/server_status_dropdown.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../provider/export_packet_provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ServerStatusDropdown extends StatelessWidget { const ServerStatusDropdown({super.key}); @@ -22,12 +23,12 @@ class ServerStatusDropdown extends StatelessWidget { underline: const SizedBox.shrink(), dropdownColor: Colors.white, padding: const EdgeInsets.all(16), - items: const [ - DropdownMenuItem(value: null, child: Text("Server Status")), - DropdownMenuItem(value: "Packet has reached Packet Receiver", child: Text("Received")), - DropdownMenuItem(value: "Processing", child: Text("Processing")), - DropdownMenuItem(value: "Accepted", child: Text("Accepted")), - DropdownMenuItem(value: "Considered for deletion", child: Text("Deletion")), + items: [ + DropdownMenuItem(value: null, child: Text(AppLocalizations.of(context)!.server_status)), + const DropdownMenuItem(value: "Packet has reached Packet Receiver", child: Text("Received")), + const DropdownMenuItem(value: "Processing", child: Text("Processing")), + const DropdownMenuItem(value: "Accepted", child: Text("Accepted")), + const DropdownMenuItem(value: "Considered for deletion", child: Text("Deletion")), ], onChanged: (String? newValue) { context.read().changeServerStatus(newValue); diff --git a/lib/ui/export_packet/widgets/upload_button.dart b/lib/ui/export_packet/widgets/upload_button.dart index 05a5d16d2..151b09cfa 100644 --- a/lib/ui/export_packet/widgets/upload_button.dart +++ b/lib/ui/export_packet/widgets/upload_button.dart @@ -1,17 +1,51 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../../provider/connectivity_provider.dart'; import '../../../provider/export_packet_provider.dart'; import '../../../utils/app_config.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -class UploadButton extends StatelessWidget { +class UploadButton extends StatefulWidget { const UploadButton({super.key}); + @override + State createState() => _UploadButtonState(); +} + +class _UploadButtonState extends State { + late ConnectivityProvider connectivityProvider; + late ExportPacketsProvider exportPacketsProvider; + late AppLocalizations appLocalizations = AppLocalizations.of(context)!; + + @override + void initState() { + connectivityProvider = Provider.of(context, listen: false); + exportPacketsProvider = Provider.of(context, listen: false); + super.initState(); + } + + void _showInSnackBar(String value) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(value), + ), + ); + } + @override Widget build(BuildContext context) { + return OutlinedButton( - onPressed:(context.watch().countSelected==0)?null: () { - context.read().uploadSelected(); + onPressed:(context.watch().countSelected==0)?null: () async { + await connectivityProvider.checkNetworkConnection(); + if (!connectivityProvider.isConnected) { + _showInSnackBar(appLocalizations.network_error); + return; + } + await exportPacketsProvider.packetSyncAll(); + await exportPacketsProvider.uploadSelected(); + exportPacketsProvider.searchedList(); }, style: OutlinedButton.styleFrom(side:(context.watch().countSelected==0)?const BorderSide(width: 1.5, color: Colors.grey): BorderSide(width: 1.5, color: solidPrimary), backgroundColor: Colors.white), child: SizedBox( @@ -21,7 +55,7 @@ class UploadButton extends StatelessWidget { children: [ const Icon(Icons.cloud_upload_outlined, size: 28,), const SizedBox(width: 6,), - Text('UPLOAD', style:Theme.of(context).textTheme.titleLarge?.copyWith(color: (context.watch().countSelected==0)? Colors.grey : solidPrimary, fontSize: 17),), + Text(AppLocalizations.of(context)!.upload, style:Theme.of(context).textTheme.titleLarge?.copyWith(color: (context.watch().countSelected==0)? Colors.grey : solidPrimary, fontSize: 17),), ], ), ), diff --git a/lib/ui/onboard/home_page.dart b/lib/ui/onboard/home_page.dart index 8cee6834a..4648dc5fb 100644 --- a/lib/ui/onboard/home_page.dart +++ b/lib/ui/onboard/home_page.dart @@ -150,11 +150,11 @@ class _HomePageState extends State { ), "title": appLocalizations.synchronize_data, "onTap": syncData, - "subtitle": DateFormat("EEEE d MMMM, hh:mma") + "subtitle": context.watch().lastSuccessfulSyncTime!="" ? DateFormat("EEEE d MMMM, hh:mma") .format(DateTime.parse( context.watch().lastSuccessfulSyncTime) .toLocal()) - .toString(), + .toString(): "Last Sync time not found", }, // { // "icon": SvgPicture.asset( @@ -178,7 +178,7 @@ class _HomePageState extends State { builder: (context) => OperatorOnboardingBiometricsCaptureControl())); }, - "subtitle": lastOperatorUpdateBiometricTime.toString(), + "subtitle": lastOperatorUpdateBiometricTime.toString() == "" ? "Not updated yet" :"Last Updated on ${lastOperatorUpdateBiometricTime.toString()}", }, { "icon": SvgPicture.asset( @@ -191,7 +191,7 @@ class _HomePageState extends State { MaterialPageRoute( builder: (context) => const ExportPacketsPage())); }, - "subtitle": "3 application(s)" + "subtitle": "${context.watch().numberOfPackets} application(s)" }, { "icon": SvgPicture.asset( diff --git a/lib/ui/onboard/portrait/operational_tasks.dart b/lib/ui/onboard/portrait/operational_tasks.dart index 7f22f67f7..e42d751fc 100644 --- a/lib/ui/onboard/portrait/operational_tasks.dart +++ b/lib/ui/onboard/portrait/operational_tasks.dart @@ -9,10 +9,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:provider/provider.dart'; import 'package:registration_client/ui/onboard/portrait/task_card.dart'; import 'package:registration_client/ui/onboard/widgets/home_page_card.dart'; import 'package:registration_client/utils/app_config.dart'; +import '../../../provider/registration_task_provider.dart'; + class OperationalTasks extends StatefulWidget { const OperationalTasks({ super.key, @@ -25,6 +28,14 @@ class OperationalTasks extends StatefulWidget { } class _OperationalTasksState extends State { + + + @override + void initState() { + context.read().getApplicationUploadNumber(); + super.initState(); + } + @override Widget build(BuildContext context) { return Column( diff --git a/lib/ui/onboard/portrait/registration_tasks.dart b/lib/ui/onboard/portrait/registration_tasks.dart index 67707dfa9..00ba8779b 100644 --- a/lib/ui/onboard/portrait/registration_tasks.dart +++ b/lib/ui/onboard/portrait/registration_tasks.dart @@ -135,12 +135,12 @@ class _RegistrationTasksState extends State { const Expanded( child: SizedBox(), ), - Text( + Text(context.watch().lastSuccessfulSyncTime!="" ? DateFormat("EEEE d MMMM, hh:mma") .format(DateTime.parse( context.watch().lastSuccessfulSyncTime) .toLocal()) - .toString(), + .toString(): "Last Sync time not found", style: const TextStyle( fontSize: 18, color: appBlackShade2, diff --git a/pigeon/packet_auth.dart b/pigeon/packet_auth.dart index d983570bf..152ac1462 100644 --- a/pigeon/packet_auth.dart +++ b/pigeon/packet_auth.dart @@ -15,12 +15,6 @@ abstract class PacketAuthApi { @async PacketAuth authenticate(String username, String password); - @async - void syncPacket(String packetId); - - @async - void uploadPacket(String packetId); - @async void syncPacketAll(List packetIds);