diff --git a/app/build.gradle b/app/build.gradle index ce40f92d..e991e41d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ apply from: "$project.rootDir/script-git-version.gradle" // Load keystore def keystorePropertiesFile = file("keystore.properties") def keystoreProperties = new Properties() -if ( keystorePropertiesFile.exists() ) { +if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } @@ -20,9 +20,9 @@ static def getDate() { } android { - compileSdkVersion 30 - buildToolsVersion '30.0.3' - if ( keystorePropertiesFile.exists() ) { + compileSdkVersion 33 + buildToolsVersion '33.0.0' + if (keystorePropertiesFile.exists()) { signingConfigs { releaseConfig { storeFile file(keystoreProperties['storeFile']) @@ -35,11 +35,10 @@ android { defaultConfig { applicationId "org.openimis.imispolicies" minSdkVersion 19 - targetSdkVersion 30 + targetSdkVersion 33 versionCode gitVersionCode versionName gitVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - useLibrary('org.apache.http.legacy') vectorDrawables { useSupportLibrary = true } @@ -50,7 +49,7 @@ android { shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' debuggable = false - if ( keystorePropertiesFile.exists() ) { + if (keystorePropertiesFile.exists()) { signingConfig signingConfigs.releaseConfig } buildConfigField "boolean", "LOGGING_ENABLED", "false" @@ -66,7 +65,7 @@ android { // Refer to https://developer.android.com/reference/android/util/Log for the log level values buildConfigField "int", "CONSOLE_LOG_LEVEL", '2' //Verbose - buildConfigField "int", "FILE_LOG_LEVEL", '2' //Verbose + buildConfigField "int", "FILE_LOG_LEVEL", '5' //Warn } flavorDimensions 'std' } @@ -77,7 +76,7 @@ android { buildConfigField "boolean", "SHOW_BULK_CN_MENU", 'false' buildConfigField "String", "RAR_PASSWORD", '")(#$1HsD"' buildConfigField "String", "API_VERSION", '"3"' - buildConfigField "String", "APP_DIR", '"IMIS"' + buildConfigField "String", "DEFAULT_LANGUAGE_CODE", '"en"' resValue "string", "app_name_policies", "Policies" resValue "string", "ReleaseDateValue", getDate() } @@ -85,22 +84,21 @@ android { demoProd { applicationId "org.openimis.imispolicies.demoProd" buildConfigField "String", "API_BASE_URL", '"https://demo.openimis.org/rest/"' - buildConfigField "String", "APP_DIR", '"IMIS-DEMOPROD"' resValue "string", "app_name_policies", "Policies Demo" dimension = 'std' } demoRelease { applicationId "org.openimis.imispolicies.demoRelease" - buildConfigField "String", "API_BASE_URL", '"https://legacy-release.s1.openimis.org/rest/"' - buildConfigField "String", "APP_DIR", '"IMIS-DEMORELEASE"' + buildConfigField "String", "API_BASE_URL", '"https://release.openimis.org/rest/"' resValue "string", "app_name_policies", "Policies Release" + dimension = 'std' } chfDev { applicationId "org.openimis.imispolicies.chfdev" buildConfigField "String", "API_BASE_URL", '"http://chf-dev.swisstph-mis.ch/rest/"' buildConfigField "boolean", "SHOW_PAYMENT_MENU", 'true' buildConfigField "boolean", "SHOW_BULK_CN_MENU", 'true' - buildConfigField "String", "APP_DIR", '"IMIS-CHFDEV"' + buildConfigField "String", "DEFAULT_LANGUAGE_CODE", '"en-tz"' resValue "string", "app_name_policies", "Policies CHF DEV" dimension = 'std' } @@ -108,7 +106,6 @@ android { applicationId "org.openimis.imispolicies.mv" buildConfigField "String", "API_BASE_URL", '"http://imis-mv.swisstph-mis.ch/rest/"' buildConfigField "boolean", "SHOW_PAYMENT_MENU", 'true' - buildConfigField "String", "APP_DIR", '"IMIS-MVDEV"' buildConfigField "String", "API_VERSION", '"3"' resValue "string", "app_name_policies", "Policies MV DEV" dimension = 'std' @@ -116,21 +113,19 @@ android { bephaDev { applicationId "org.openimis.imispolicies.bepha" buildConfigField "String", "API_BASE_URL", '"http://149.210.235.40/devupgrade/rest/"' - buildConfigField "String", "APP_DIR", '"IMIS-BEPHADEV"' + buildConfigField "String", "DEFAULT_LANGUAGE_CODE", '"en-cm"' resValue "string", "app_name_policies", "Policies BEPHA DEV" dimension = 'std' } tchadDev { applicationId "org.openimis.imispolicies.tchadDev" buildConfigField "String", "API_BASE_URL", '"http://imis-tchad-dev.swisstph-mis.ch/rest/"' - buildConfigField "String", "APP_DIR", '"IMIS-TCHADDEV"' resValue "string", "app_name_policies", "Policies TCHAD DEV" dimension = 'std' } local { applicationId "org.openimis.imispolicies.local" buildConfigField "String", "API_BASE_URL", '"http://10.0.2.2:35787/"' - buildConfigField "String", "APP_DIR", '"IMIS-LOCAL"' buildConfigField "boolean", "SHOW_PAYMENT_MENU", 'true' resValue "string", "app_name_policies", "Policies Local" dimension = 'std' @@ -139,13 +134,12 @@ android { niger { applicationId "org.openimis.imispolicies.niger" buildConfigField "String", "API_BASE_URL", '"' + (System.getenv("API_BASE_URL") ?: 'http://192.168.0.100/') + '"' - buildConfigField "String", "APP_DIR", '"' + (System.getenv("CLI_APP_DIR") ?: 'IMIS-POL') + '"' resValue "string", "app_name_policies", System.getenv("CLI_APP_NAME") ?: "Polices Niger" + dimension = 'std' } cli { applicationIdSuffix System.getenv("APPLICATION_ID") ?: "org.openimis.imispolicies.cli" buildConfigField "String", "API_BASE_URL", '"' + (System.getenv("API_BASE_URL") ?: 'http://10.0.2.2:35787/') + '"' - buildConfigField "String", "APP_DIR", '"' + (System.getenv("CLI_APP_DIR") ?: 'IMIS-CLI') + '"' resValue "string", "app_name_policies", System.getenv("CLI_APP_NAME") ?: "Policies CLI" dimension 'std' } @@ -154,23 +148,22 @@ android { buildConfigField "String", "API_BASE_URL", '"https://formation.cnass-mauritanie.swisstph-mis.ch/rest/"' buildConfigField "boolean", "SHOW_PAYMENT_MENU", 'false' buildConfigField "boolean", "SHOW_BULK_CN_MENU", 'false' - buildConfigField "String", "APP_DIR", '"IMIS-MAURITANIA-TRAIN"' resValue "string", "app_name_policies", "Policies CNASS TRAIN" dimension = 'std' } } sourceSets { chfDev.java.srcDir 'src/chf/java' - chfDev.res.srcDir 'src/chf/res' + chfDev.res.srcDirs = ['src/chf/res', 'src/localeChf/res'] mvDev.java.srcDir 'src/master/java' - mvDev.res.srcDirs 'src/master/res' + mvDev.res.srcDirs = ['src/master/res', 'src/localeMv/res'] local.java.srcDir 'src/master/java' - local.res.srcDir 'src/master/res' + local.res.srcDirs = ['src/master/res', 'src/localeMv/res'] bephaDev.java.srcDir 'src/bepha/java' - bephaDev.res.srcDir 'src/bepha/res' + bephaDev.res.srcDirs = ['src/bepha/res', 'src/localeBepha/res'] niger.java.srcDir 'src/niger/java' niger.res.srcDir 'src/niger/res' @@ -180,10 +173,10 @@ android { tchadDev.res.srcDir 'src/tchad/res' demoProd.java.srcDir 'src/master/java' - demoProd.res.srcDir 'src/demoProd/res' + demoProd.res.srcDirs = ['src/demoProd/res', 'src/localeMv/res'] demoRelease.java.srcDir 'src/master/java' - demoRelease.res.srcDir 'src/demoRelease/res' + demoRelease.res.srcDirs = ['src/demoRelease/res', 'src/localeMv/res'] cli.java.srcDir System.getenv("CLI_JAVA_DIR") ?: 'src/master/java' cli.res.srcDir System.getenv("CLI_RES_DIR") ?: 'src/demoProd/res' @@ -194,8 +187,8 @@ android { mauritaniaTrain.java.srcDir 'src/master/java' } -// Apply custom flavours - if(file('custom-flavours.gradle').exists()){ + // Apply custom flavours + if (file('custom-flavours.gradle').exists()) { apply from: 'custom-flavours.gradle' } @@ -203,10 +196,16 @@ android { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } + + packagingOptions { + resources { + excludes += ['META-INF/DEPENDENCIES'] + } + } } dependencies { - implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs') + implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:design:28.0.0' implementation 'com.android.support.constraint:constraint-layout:2.0.4' @@ -215,11 +214,11 @@ dependencies { implementation 'com.android.support:support-v4:28.0.0' implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'org.apache.commons:commons-lang3:3.12.0' - + implementation 'org.jetbrains:annotations:15.0' + implementation 'cz.msebera.android:httpclient:4.5.8' androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - testImplementation 'junit:junit:4.13.1' - //compile 'com.android.support:support-annotations:27.1.1' + testImplementation 'junit:junit:4.13.2' } diff --git a/app/custom-flavours.gradle.dist b/app/custom-flavours.gradle.dist index 9eae42e4..885e1633 100644 --- a/app/custom-flavours.gradle.dist +++ b/app/custom-flavours.gradle.dist @@ -6,7 +6,6 @@ android { buildConfigField "String", "API_BASE_URL", [API_BASE_URL] buildConfigField "boolean", "SHOW_PAYMENT_MENU", [SHOW_PAYMENT_MENU] buildConfigField "boolean", "SHOW_BULK_CN_MENU", [SHOW_BULK_CN_MENU] - buildConfigField "String", "APP_DIR", [APP_DIR_NAME] buildConfigField "String", "API_VERSION", [API_VERSION] buildConfigField "String", "RAR_PASSWORD", [RAR_PASSWORD] resValue "string", "app_name_policies", [APP_NAME] diff --git a/app/src/debug/java/org/openimis/imispolicies/tools/Log.java b/app/src/debug/java/org/openimis/imispolicies/tools/Log.java index 61222eb9..31313260 100644 --- a/app/src/debug/java/org/openimis/imispolicies/tools/Log.java +++ b/app/src/debug/java/org/openimis/imispolicies/tools/Log.java @@ -1,11 +1,14 @@ package org.openimis.imispolicies.tools; +import android.content.Context; import android.net.Uri; import android.support.v4.content.FileProvider; import org.openimis.imispolicies.AppInformation; import org.openimis.imispolicies.BuildConfig; import org.openimis.imispolicies.Global; +import org.openimis.imispolicies.util.FileUtils; +import org.openimis.imispolicies.util.ZipUtils; import java.io.File; import java.io.FileOutputStream; @@ -88,26 +91,30 @@ private static void log(String tag, String msg, int level) { } } - public static void zipLogFiles() { - File cacheDir = Global.getContext().getExternalCacheDir(); - File[] logFiles = cacheDir.listFiles((dir, filename) -> filename.startsWith(logFilePrefix)); - File targetFile = new File(cacheDir, logExportFileName); + public static void zipLogFiles(Context context) { + File cacheDir = Global.getContext().getCacheDir(); + File logsDir = new File(cacheDir, "logs"); + FileUtils.createDirectoryWithSubdirectories(logsDir); + File[] logFiles = logsDir.listFiles((dir, filename) -> filename.startsWith(logFilePrefix)); + File targetFile = new File(logsDir, logExportFileName); if (logFiles != null) { ArrayList filesToZip = new ArrayList<>(Arrays.asList(logFiles)); - Compressor.zip(filesToZip, targetFile, ""); + ZipUtils.zipFiles(filesToZip, targetFile, ""); } Uri logExportUri = FileProvider.getUriForFile(Global.getContext(), String.format("%s.fileprovider", BuildConfig.APPLICATION_ID), targetFile); - Global.getGlobal().sendFile(logExportUri, "application/zip"); + Global.getGlobal().sendFile(context, logExportUri, "application/octet-stream"); } public static void deleteLogFiles() { - File cacheDir = Global.getContext().getExternalCacheDir(); - File[] logFiles = cacheDir.listFiles((dir, filename) -> filename.startsWith(logFilePrefix)); + File cacheDir = Global.getContext().getCacheDir(); + File logsDir = new File(cacheDir, "logs"); + FileUtils.createDirectoryWithSubdirectories(logsDir); + File[] logFiles = logsDir.listFiles((dir, filename) -> filename.startsWith(logFilePrefix)); if (logFiles != null) { for (File f : logFiles) { f.delete(); @@ -129,10 +136,12 @@ private synchronized static void storeLog(String tag, String msg, int level) { private static void initializeLogFile(Date date) { if (logFile == null || !logFile.exists()) { - File cacheDir = Global.getContext().getExternalCacheDir(); + File cacheDir = Global.getContext().getCacheDir(); + File logsDir = new File(cacheDir, "logs"); + FileUtils.createDirectoryWithSubdirectories(logsDir); String filename = String.format("%s%s.txt",logFilePrefix, AppInformation.DateTimeInfo.getDefaultFileDatetimeFormatter().format(date)); - logFile = new File(cacheDir, filename); + logFile = new File(logsDir, filename); try { if (!logFile.createNewFile()) diff --git a/app/src/bepha/res/values/strings.xml b/app/src/localeBepha/res/values-en-rCM/strings.xml similarity index 92% rename from app/src/bepha/res/values/strings.xml rename to app/src/localeBepha/res/values-en-rCM/strings.xml index 1ceb386c..4ae7a116 100644 --- a/app/src/bepha/res/values/strings.xml +++ b/app/src/localeBepha/res/values-en-rCM/strings.xml @@ -1,5 +1,4 @@ - Open navigation drawer Close navigation drawer @@ -445,4 +444,37 @@ Wait %1$s seconds Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. CN limit reached + No control numbers received from the server + You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en_CM + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/bepha/res/values-fr/strings.xml b/app/src/localeBepha/res/values-fr-rCM/strings.xml similarity index 92% rename from app/src/bepha/res/values-fr/strings.xml rename to app/src/localeBepha/res/values-fr-rCM/strings.xml index f4c0a5c2..1deddc82 100644 --- a/app/src/bepha/res/values-fr/strings.xml +++ b/app/src/localeBepha/res/values-fr-rCM/strings.xml @@ -1,5 +1,4 @@ - Ouvrir le menu de navigation Fermer le menu de navigation @@ -243,7 +242,7 @@ Suppression échouée Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. Contrat avec date d\'adhésion : - \" Modifié \" + " Modifié " Voulez-vous activer cet assuré ?]]> Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : Acquérir @@ -257,7 +256,7 @@ Photos envoyées avec succès Aucune photo trouvée Envoyer les photos - \"Recherche \" + "Recherche " Modifier la famille Télécharger la famille Familles éditées @@ -445,4 +444,37 @@ Wait %1$s seconds Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. CN limit reached + No control numbers received from the server + You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + fr_CM + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/main/res/values-en-rCM/strings.xml b/app/src/localeBepha/res/values/strings.xml similarity index 92% rename from app/src/main/res/values-en-rCM/strings.xml rename to app/src/localeBepha/res/values/strings.xml index 42a33996..4ae7a116 100644 --- a/app/src/main/res/values-en-rCM/strings.xml +++ b/app/src/localeBepha/res/values/strings.xml @@ -444,4 +444,37 @@ Wait %1$s seconds Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. CN limit reached + No control numbers received from the server + You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en_CM + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/main/res/values-en-rTZ/strings.xml b/app/src/localeChf/res/values-en-rTZ/strings.xml similarity index 93% rename from app/src/main/res/values-en-rTZ/strings.xml rename to app/src/localeChf/res/values-en-rTZ/strings.xml index cbbc41a2..886901ae 100644 --- a/app/src/main/res/values-en-rTZ/strings.xml +++ b/app/src/localeChf/res/values-en-rTZ/strings.xml @@ -446,4 +446,35 @@ CN limit reached No control numbers received from the server You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en_TZ + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/localeChf/res/values-sw/strings.xml similarity index 93% rename from app/src/main/res/values-sw/strings.xml rename to app/src/localeChf/res/values-sw/strings.xml index cac32a8c..64e3e991 100644 --- a/app/src/main/res/values-sw/strings.xml +++ b/app/src/localeChf/res/values-sw/strings.xml @@ -446,4 +446,35 @@ Kikomo cha namba za malipo kimefikiwa Hakuna namba za malipo zilizopokelewa kwenye kompyuta kuu Huwezi pata namba ya malipo kwa bidhaa hizi + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + sw + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/chf/res/values/strings.xml b/app/src/localeChf/res/values/strings.xml similarity index 93% rename from app/src/chf/res/values/strings.xml rename to app/src/localeChf/res/values/strings.xml index 2c3c9799..886901ae 100644 --- a/app/src/chf/res/values/strings.xml +++ b/app/src/localeChf/res/values/strings.xml @@ -1,5 +1,4 @@ - Open navigation drawer Close navigation drawer @@ -447,4 +446,35 @@ CN limit reached No control numbers received from the server You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en_TZ + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/localeMv/res/values-en/strings.xml b/app/src/localeMv/res/values-en/strings.xml new file mode 100644 index 00000000..9d113651 --- /dev/null +++ b/app/src/localeMv/res/values-en/strings.xml @@ -0,0 +1,480 @@ + + + Open navigation drawer + Close navigation drawer + Settings + Please wait + Page is loading + openIMIS Policies + admin@imis.com + Home + Enrolment + Renewal + Feedback + Sync + About + Quit + Region + District + Municipality + Village + Poverty Status + Confirmation Type + Confirmation No. + Group Type + Ethnicity + Permanent Address Details + Next + Select Region + Select District + Select Municipality + Select Village + Yes + No + Select Poverty Status + Select confirmation type + Select Group type + OK + Please verify all the required fields marked in red border + Insuree number + Other Names + Last Name + Birth Date + Gender + Marital Status + Beneficiary Card + Current District + Current Municipality + Current Village + Current Address Details + Profession + Education + Phone number + Email + Identification Type + Identification Number + District of FSP + Level of FSP + First Service Point + Select Gender + Male + Female + Other + Select marital status + Married + Single + Divorced + Widowed + Not specified + Select card status + Select profession + Select education + Select identification type + Select HF level + Dispensary + Health Centre + Hospital + Select Health facility + Save + Relationship + Select Relationship + Family saved successfully + Error occurred while processing data + Error while inserting data + Error while updating data + Member with this Insuree number already exists + Add + New + Select Enrolment Officer + Select Product + Select Month + Enrolment date + Product + Effective Date + Start Date + Expire Date + Enrolment Officer + Policy Status : + Policy Value : + Balance : + Contribution : + Enquire + Payer + Payment Date + Contribution Category + Receipt No + Contribution Paid + Payment Type + Select Payer + Select Level + Contribution and Others + Photo Fee + Select Payment Type + Cash + Mobile Phone + Bank Transfer + Receipt No : + Expired + Active + Idle + Suspended + Receipt number must be unique + Policy has contribution. Please delete contributions first + Policy deleted successfully + Contribution deleted successfully + Insuree deleted successfully + You can not delete the head of the family. + Family has policy please delete the policy first + Insuree has not deleted + Family deleted + Scan + Insuree Name + SD Card is set to readonly mode. Please set the mode to read/write and restart the application. + openIMIS Policies needs external memory card to run. Please insert memory card and restart the application. + Force Close + Please enter the Insuree number + Invalid Insuree number + Getting insuree info… + Getting Snap Shots Report… + Getting Cumulative Report… + Member with this Insuree number does not exist. + No renewal found + Please check your internet connection. + Process Failed, Wrong File or Enrolment Officer code. + Submit + Discontinue this policy + Do you want to discontinue this policy? + Product Code + loading + Data uploaded on the server successfully. + Data is rejected by the server. Data is moved to the rejected folder of the phone. + Data has been uploaded successfully. Please check your Rejected/Accepted folders to verify the server response. + Please enter Enrolment Officer code + File is saved on external storage. + Uploading… + No feedback found + Internet connection is required to view the statistics. + Preview + No data found + Statistics + Claim Code + Have you been treated at the facility on the said date? + Have you been asked for a payment to the facility or staff? + Have drugs been prescribed to you? + Did you get drugs from the facility? + How satisfied are you with the care you received at the health facility? Rate on a scale 1–5 (1= not satisfied; 5= very satisfied) + Uploading feedback… + Upload all feedback + Please enter Enrolment Officer Code + Please enter Claim ID + Please enter the Insuree number + All the questions must be answered. + End Date + Please enter End Date + In Progress + Please enter Start Date + Please enter Receipt No. + Please enter product code + Please enter amount + This receipt number is already used. + No file found. + Of + Login Name + Login Failed + Password + Enter Rar Password + Enrolment Officer Code: + Incorrect Enrolment Officer code + Login + Unable to connect the server. Operation aborted. + Something went wrong on the server. + Family could not be inserted. + Family uploaded successfully + Given family has no HOF + Family with this Insuree number already exists + Duplicate Insuree number found + Duplicate receipt number found + Could not download master data. + Downloading master data + Data downloaded successfully + Delete + Edit + Payment + Master data not found, would you like to Download? + Enrolment Application + Version + Name + Release Date + Total Families + Total Insurees + Total Policies + Total Contributions + Upload Enrolments + Create Enrolments XML + Upload Renewals + Upload FeedBacks + Download Master Data + Please Wait… + Language + Families + Add new family + Family and Insurees + Family and Policies + Add/Edit Insuree + Add/Edit Policy + Contributions + Add/Edit Contribution + Do you want to quit openIMIS Policies? + Upload report + Go + Insuree + Date To + Full Name + HF Name + Date From And To + Updated time + Cancel + Feedback could not be uploaded please, try again later + Renewal could not be uploaded please, try again later + Region of FSP + Current Region + Upload successful please check Accepted/Rejected folders + Delete Failed + This Family has been deleted only offline because it has a policy online. + Value of policy with the enrolment date : + Changed + Do you want to activate this Insuree?]]> + Policies with the following enrolment dates have reached to their maximum number of members count and therefore this insuree will not be covered by these policies however the insuree is added to the family : + Acquire + Data has been saved on the external memory card. + Data could not be sent to the server. Saved on the external memory card. + Photo uploaded successfully. + Photo saved successfully. + No images found. + Please capture an Image + Upload all Images + Photos uploaded successfully + No photos found + Upload Photos + Search + Modify family + Downloading family + Edited Families + Edited Insurees + Edited Policies + Edited Contributions + Insuree number not found + Insuree number required + Deleting… + Internet connection is required to delete online data. + Please login first, to delete online data + Deleting policy will also delete premium on it + Deleting of family will also Delete all Insurees, Policies and Premiums of this Family + Confirm + Logout + Family already exists in phone + New release of openIMIS Policies is now available. + Click here to download. + Saving… + Process has been interrupted. Please check your internet connection. + No Family was uploaded + No data available + XML has been created + Failed to create XML + No data was created + Please Enter the Insuree number + without a policy/a contribution + without a photo + Failed to upload + Deleted successfully + Invalid Email + Something went wrong on the server. Failed to upload data. + Price of the policy is covered. Do you still want to add contribution? + Contribution exceeds the price of the policy + Price of the policy not covered yet. Please select action to perform. + Price of the policy not covered yet. Please select action to perform.]]> + Reports + Snapshot Indicators + Cumulative Indicators + Number of Families with Active Policies + Number of Families with Expired Policies + Number of Families with Idle Policies + Number of Families with Suspended Polices + Number of New Policies + Number of renewed Policies + Number of Expired Policies + Number of Suspended Polices + Amount of collected contribution + Today\'s Statistics + Create Feedback XML + Create Renewals XML + Double head of family found on server. Please contact your IT manager. + Unlisted Renewal Policies + Renew Your Policy + Username + Claim Code + Type here + Please enter username and password + Login Successful + Invalid input + Total Amount + Control Numbers + Overview Policies + Overview Control Numbers + Control Numbers + Overview policies + Overview control numbers + Product Name: + Uploaded Date: + Requested Date: + Product Code: + Names: + Renewal: + Insurance No. + Requested To + Requested From + Uploaded To + TO + Uploaded From + Insurance product + Clear + Requested + Number of found policies + Amount of contribution + Process Complete + Please select a policy/policies to request + Successfully + Not authorized + OK + No data was selected to delete + Get Control Number + policies where not deleted because they are not uploaded + of + Request has been sent successfully + This policy can\'t be deleted because it has not been uploaded yet. + Type of payment + Request + NO INTERNET CONNECTION + Do you want to import .txt file from your DATABASE folder? + There are no file explorer clients installed. + Load file: + Incomplete! + Check Commission + Year + Paid + Check + Get Commissions + Commissions Report + Amount + commissions + Search enrolled Policies + Search Control Numbers + Overviews + Policies + No data + Please fill the year + Deleting of family will also Delete all Insurees, Policies and Premiums of this Family + Last Installment + Enrolled Policies + Not Enrolled Policies + Request for Not Enrolled Policies + Phone number not provided + Insurance products of the selected policies are not unique + Amount of contribution + Pick Date + Get + Date From + Date To + Send SMS + Requested SMS + TotalAdmissionsLeft + TotalVisitsLeft + TotalConsultationsLeft + TotalSurgeriesLeft + TotalDeliveriesLeft + TotalAntenatalLeft + ConsultationAmountLeft + SurgeryAmountLeft + HospitalizationAmountLeft + AntenatalAmountLeft + DeliveryAmountLeft + Please login first, to check receipt number. + IMIS Directory could not be created. + Cumulative Indicators + Language Of SMS + Approval Of SMS + Payment Overview + Get payment CN for enrolled policies + Get payment CN for not enrolled policies + Overview payment CN + Please login first, to download renewals. + Select All + Deselect All + Synchronization processing + Vulnerability + Select Vulnerability + Bulk Control Numbers + Assigned Control Numbers: + Free Control Numbers: + Fetch Bulk Control Numbers + Fetch + Please log in first, to fetch control numbers. + No control numbers left for this product. Please fetch control numbers or provide control number from other source. + Control Number : + No control number assigned to this policy. Please fetch control numbers or provide control number from other source. + Master Data + External Storage Access + To work correctly, %1$s requires external storage access. Please allow it for %1$s in next screen in order to use the application. + Permissions + To work correctly, %1$s requires multiple permissions. Please allow them in next screen in order to use the application. + Please fill the month + Renewal accepted + Renewal already accepted + Renewal rejected + Grace period expired + Control number error + Unexpected exception + Invalid renewal file + Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. + Do you want to select renewal file to import? + RAR Password + Save RAR Password + Set the default RAR password + Default RAR Password + Wait %1$s seconds + Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. + CN limit reached + No control numbers received from the server + You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/localeMv/res/values-fr/strings.xml similarity index 93% rename from app/src/main/res/values-fr/strings.xml rename to app/src/localeMv/res/values-fr/strings.xml index 182aadcc..e0675292 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/localeMv/res/values-fr/strings.xml @@ -242,7 +242,7 @@ Suppression échouée Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. Contrat avec date d\'adhésion : - \" Modifié \" + " Modifié " Voulez-vous activer cet assuré ?]]> Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : Acquérir @@ -256,7 +256,7 @@ Photos téléversées avec succès Aucune photo trouvée Téléverser les photos - \"Recherche \" + "Recherche " Modifier la famille Télécharger la famille Familles éditées @@ -446,4 +446,35 @@ Limite CN atteinte Aucun numéro de contrôle reçu du serveur Vous ne pouvez pas recevoir plus de numéros de contrôle pour ce produit + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + fr + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s diff --git a/app/src/localeMv/res/values/strings.xml b/app/src/localeMv/res/values/strings.xml new file mode 100644 index 00000000..9d113651 --- /dev/null +++ b/app/src/localeMv/res/values/strings.xml @@ -0,0 +1,480 @@ + + + Open navigation drawer + Close navigation drawer + Settings + Please wait + Page is loading + openIMIS Policies + admin@imis.com + Home + Enrolment + Renewal + Feedback + Sync + About + Quit + Region + District + Municipality + Village + Poverty Status + Confirmation Type + Confirmation No. + Group Type + Ethnicity + Permanent Address Details + Next + Select Region + Select District + Select Municipality + Select Village + Yes + No + Select Poverty Status + Select confirmation type + Select Group type + OK + Please verify all the required fields marked in red border + Insuree number + Other Names + Last Name + Birth Date + Gender + Marital Status + Beneficiary Card + Current District + Current Municipality + Current Village + Current Address Details + Profession + Education + Phone number + Email + Identification Type + Identification Number + District of FSP + Level of FSP + First Service Point + Select Gender + Male + Female + Other + Select marital status + Married + Single + Divorced + Widowed + Not specified + Select card status + Select profession + Select education + Select identification type + Select HF level + Dispensary + Health Centre + Hospital + Select Health facility + Save + Relationship + Select Relationship + Family saved successfully + Error occurred while processing data + Error while inserting data + Error while updating data + Member with this Insuree number already exists + Add + New + Select Enrolment Officer + Select Product + Select Month + Enrolment date + Product + Effective Date + Start Date + Expire Date + Enrolment Officer + Policy Status : + Policy Value : + Balance : + Contribution : + Enquire + Payer + Payment Date + Contribution Category + Receipt No + Contribution Paid + Payment Type + Select Payer + Select Level + Contribution and Others + Photo Fee + Select Payment Type + Cash + Mobile Phone + Bank Transfer + Receipt No : + Expired + Active + Idle + Suspended + Receipt number must be unique + Policy has contribution. Please delete contributions first + Policy deleted successfully + Contribution deleted successfully + Insuree deleted successfully + You can not delete the head of the family. + Family has policy please delete the policy first + Insuree has not deleted + Family deleted + Scan + Insuree Name + SD Card is set to readonly mode. Please set the mode to read/write and restart the application. + openIMIS Policies needs external memory card to run. Please insert memory card and restart the application. + Force Close + Please enter the Insuree number + Invalid Insuree number + Getting insuree info… + Getting Snap Shots Report… + Getting Cumulative Report… + Member with this Insuree number does not exist. + No renewal found + Please check your internet connection. + Process Failed, Wrong File or Enrolment Officer code. + Submit + Discontinue this policy + Do you want to discontinue this policy? + Product Code + loading + Data uploaded on the server successfully. + Data is rejected by the server. Data is moved to the rejected folder of the phone. + Data has been uploaded successfully. Please check your Rejected/Accepted folders to verify the server response. + Please enter Enrolment Officer code + File is saved on external storage. + Uploading… + No feedback found + Internet connection is required to view the statistics. + Preview + No data found + Statistics + Claim Code + Have you been treated at the facility on the said date? + Have you been asked for a payment to the facility or staff? + Have drugs been prescribed to you? + Did you get drugs from the facility? + How satisfied are you with the care you received at the health facility? Rate on a scale 1–5 (1= not satisfied; 5= very satisfied) + Uploading feedback… + Upload all feedback + Please enter Enrolment Officer Code + Please enter Claim ID + Please enter the Insuree number + All the questions must be answered. + End Date + Please enter End Date + In Progress + Please enter Start Date + Please enter Receipt No. + Please enter product code + Please enter amount + This receipt number is already used. + No file found. + Of + Login Name + Login Failed + Password + Enter Rar Password + Enrolment Officer Code: + Incorrect Enrolment Officer code + Login + Unable to connect the server. Operation aborted. + Something went wrong on the server. + Family could not be inserted. + Family uploaded successfully + Given family has no HOF + Family with this Insuree number already exists + Duplicate Insuree number found + Duplicate receipt number found + Could not download master data. + Downloading master data + Data downloaded successfully + Delete + Edit + Payment + Master data not found, would you like to Download? + Enrolment Application + Version + Name + Release Date + Total Families + Total Insurees + Total Policies + Total Contributions + Upload Enrolments + Create Enrolments XML + Upload Renewals + Upload FeedBacks + Download Master Data + Please Wait… + Language + Families + Add new family + Family and Insurees + Family and Policies + Add/Edit Insuree + Add/Edit Policy + Contributions + Add/Edit Contribution + Do you want to quit openIMIS Policies? + Upload report + Go + Insuree + Date To + Full Name + HF Name + Date From And To + Updated time + Cancel + Feedback could not be uploaded please, try again later + Renewal could not be uploaded please, try again later + Region of FSP + Current Region + Upload successful please check Accepted/Rejected folders + Delete Failed + This Family has been deleted only offline because it has a policy online. + Value of policy with the enrolment date : + Changed + Do you want to activate this Insuree?]]> + Policies with the following enrolment dates have reached to their maximum number of members count and therefore this insuree will not be covered by these policies however the insuree is added to the family : + Acquire + Data has been saved on the external memory card. + Data could not be sent to the server. Saved on the external memory card. + Photo uploaded successfully. + Photo saved successfully. + No images found. + Please capture an Image + Upload all Images + Photos uploaded successfully + No photos found + Upload Photos + Search + Modify family + Downloading family + Edited Families + Edited Insurees + Edited Policies + Edited Contributions + Insuree number not found + Insuree number required + Deleting… + Internet connection is required to delete online data. + Please login first, to delete online data + Deleting policy will also delete premium on it + Deleting of family will also Delete all Insurees, Policies and Premiums of this Family + Confirm + Logout + Family already exists in phone + New release of openIMIS Policies is now available. + Click here to download. + Saving… + Process has been interrupted. Please check your internet connection. + No Family was uploaded + No data available + XML has been created + Failed to create XML + No data was created + Please Enter the Insuree number + without a policy/a contribution + without a photo + Failed to upload + Deleted successfully + Invalid Email + Something went wrong on the server. Failed to upload data. + Price of the policy is covered. Do you still want to add contribution? + Contribution exceeds the price of the policy + Price of the policy not covered yet. Please select action to perform. + Price of the policy not covered yet. Please select action to perform.]]> + Reports + Snapshot Indicators + Cumulative Indicators + Number of Families with Active Policies + Number of Families with Expired Policies + Number of Families with Idle Policies + Number of Families with Suspended Polices + Number of New Policies + Number of renewed Policies + Number of Expired Policies + Number of Suspended Polices + Amount of collected contribution + Today\'s Statistics + Create Feedback XML + Create Renewals XML + Double head of family found on server. Please contact your IT manager. + Unlisted Renewal Policies + Renew Your Policy + Username + Claim Code + Type here + Please enter username and password + Login Successful + Invalid input + Total Amount + Control Numbers + Overview Policies + Overview Control Numbers + Control Numbers + Overview policies + Overview control numbers + Product Name: + Uploaded Date: + Requested Date: + Product Code: + Names: + Renewal: + Insurance No. + Requested To + Requested From + Uploaded To + TO + Uploaded From + Insurance product + Clear + Requested + Number of found policies + Amount of contribution + Process Complete + Please select a policy/policies to request + Successfully + Not authorized + OK + No data was selected to delete + Get Control Number + policies where not deleted because they are not uploaded + of + Request has been sent successfully + This policy can\'t be deleted because it has not been uploaded yet. + Type of payment + Request + NO INTERNET CONNECTION + Do you want to import .txt file from your DATABASE folder? + There are no file explorer clients installed. + Load file: + Incomplete! + Check Commission + Year + Paid + Check + Get Commissions + Commissions Report + Amount + commissions + Search enrolled Policies + Search Control Numbers + Overviews + Policies + No data + Please fill the year + Deleting of family will also Delete all Insurees, Policies and Premiums of this Family + Last Installment + Enrolled Policies + Not Enrolled Policies + Request for Not Enrolled Policies + Phone number not provided + Insurance products of the selected policies are not unique + Amount of contribution + Pick Date + Get + Date From + Date To + Send SMS + Requested SMS + TotalAdmissionsLeft + TotalVisitsLeft + TotalConsultationsLeft + TotalSurgeriesLeft + TotalDeliveriesLeft + TotalAntenatalLeft + ConsultationAmountLeft + SurgeryAmountLeft + HospitalizationAmountLeft + AntenatalAmountLeft + DeliveryAmountLeft + Please login first, to check receipt number. + IMIS Directory could not be created. + Cumulative Indicators + Language Of SMS + Approval Of SMS + Payment Overview + Get payment CN for enrolled policies + Get payment CN for not enrolled policies + Overview payment CN + Please login first, to download renewals. + Select All + Deselect All + Synchronization processing + Vulnerability + Select Vulnerability + Bulk Control Numbers + Assigned Control Numbers: + Free Control Numbers: + Fetch Bulk Control Numbers + Fetch + Please log in first, to fetch control numbers. + No control numbers left for this product. Please fetch control numbers or provide control number from other source. + Control Number : + No control number assigned to this policy. Please fetch control numbers or provide control number from other source. + Master Data + External Storage Access + To work correctly, %1$s requires external storage access. Please allow it for %1$s in next screen in order to use the application. + Permissions + To work correctly, %1$s requires multiple permissions. Please allow them in next screen in order to use the application. + Please fill the month + Renewal accepted + Renewal already accepted + Renewal rejected + Grace period expired + Control number error + Unexpected exception + Invalid renewal file + Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. + Do you want to select renewal file to import? + RAR Password + Save RAR Password + Set the default RAR password + Default RAR Password + Wait %1$s seconds + Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. + CN limit reached + No control numbers received from the server + You cannot receive more control numbers for this product + Export all logs: + Export logs + Do you want to export logs? + Export canceled. Export file can be found in external cache directory. + Clear all logs: + Clear logs + Do you want to clear logs? + Wait + Suspend + Enforce + without a policy + without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c82445e7..56cb49d2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,7 +14,6 @@ - + - @@ -82,10 +81,8 @@ android:screenOrientation="portrait" /> + + + + + + + + + + + - \ No newline at end of file + diff --git a/app/src/main/assets/pages/Insuree.js b/app/src/main/assets/pages/Insuree.js index d3744785..e70883e6 100644 --- a/app/src/main/assets/pages/Insuree.js +++ b/app/src/main/assets/pages/Insuree.js @@ -98,19 +98,18 @@ $(document).ready(function () { var ExceedThreshold = -1; if (PolicyId > 0 && IsNewIns == 0) { - var PolicyStatus = Android.getPolicyStatus(PolicyId); if (TotalIns >= MemberCount) { ExceedThreshold = 0; Android.ShowDialog(Android.getString('ExceedMemberCount')); } else if (TotalIns >= Threshold) { ExceedThreshold = 1; - } else if (PolicyStatus == 2) { + } else { ExceedThreshold = 0; } } var InsureeId = Android.SaveInsuree(jsonInsuree, FamilyId, 0, parseInt(ExceedThreshold), PolicyId); - if (InsureeId == 7 || InsureeId == 6) { + if (PolicyId > 0 && TotalIns >= MemberCount) { $("#divProgress").hide(); } else { $("#divProgress").hide(); @@ -193,15 +192,7 @@ $(document).ready(function () { }); $('#btnScan').click(function () { - var InsuranceNo = Android.getScannedNumber(); - var ans = Android.isValidInsuranceNumber(InsuranceNo); - if (ans != true) { - $('#txtInsuranceNumber').val(""); - $('#txtInsuranceNumber').focus(); - } else { - $('#txtInsuranceNumber').val(InsuranceNo); - getImage(); - } + Android.getScannedNumber(); }); if ($('#hfIsOffline').val() == "0") { @@ -235,6 +226,18 @@ function selectImageCallback(imagePath) { } } +// called from java after the image was selected by the user +function scanQrCallback(insureeNumber) { + var ans = Android.isValidInsuranceNumber(insureeNumber); + if (ans) { + $('#txtInsuranceNumber').val(insureeNumber); + getImage(); + } else { + $('#txtInsuranceNumber').val(""); + $('#txtInsuranceNumber').focus(); + } +} + function fillRelationship() { $textLanguage = "Relation"; if (Android.getSelectedLanguage() != "en") { diff --git a/app/src/main/assets/pages/Search.js b/app/src/main/assets/pages/Search.js index 132a6641..2f49c3c3 100644 --- a/app/src/main/assets/pages/Search.js +++ b/app/src/main/assets/pages/Search.js @@ -11,22 +11,9 @@ $(document).ready(function () { if (InsuranceNumber.length > 0) { $("#divProgress").show(); setTimeout(function () { - var Result = Android.ModifyFamily(InsuranceNumber); - //alert(Result); - if (Result == 1) { - //Android.ShowDialog(Android.getString('DataDownloadedSuccess')); + if (Android.ModifyFamily(InsuranceNumber) == 1) { window.open("Enrollment.html", "_self"); } - else if (Result == 2) { - Android.ShowDialog(Android.getString('FamilyExists')); - //window.open("Enrollment.html", "_self"); - } - else if (Result == 0) { - Android.ShowDialog(Android.getString('InsuranceNumberNotFound')); - } - else if (Result == 3) { - Android.ShowDialog(Android.getString('NoInternet')); - } $("#divProgress").hide(); }, 500) } diff --git a/app/src/main/assets/pages/Sync.js b/app/src/main/assets/pages/Sync.js index 305ce367..736e77a4 100644 --- a/app/src/main/assets/pages/Sync.js +++ b/app/src/main/assets/pages/Sync.js @@ -38,17 +38,17 @@ $(document).ready(function () { break; case "liCreateRenewalXML": - Android.zipFeedBackRenewal('Renewal'); + Android.CreateRenewalExport(); break; case "liUploadFeedback": if (!Android.isLoggedIn()) { window.open("Login.html?s=0", "_self"); } else { - Android.UploadOfflineFeedbackRenewal('feedback'); + Android.uploadFeedbacks(); } break; case "liCreateFeedbackXML": - Android.zipFeedBackRenewal('Feedback'); + Android.CreateFeedbackExport(); break; case "liDownloadMasterData": diff --git a/app/src/main/java/org/openimis/imispolicies/Acquire.java b/app/src/main/java/org/openimis/imispolicies/Acquire.java index 4d7a9189..90ba2296 100644 --- a/app/src/main/java/org/openimis/imispolicies/Acquire.java +++ b/app/src/main/java/org/openimis/imispolicies/Acquire.java @@ -48,7 +48,12 @@ import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextWatcher; + +import org.openimis.imispolicies.tools.ImageManager; import org.openimis.imispolicies.tools.Log; +import org.openimis.imispolicies.tools.StorageManager; +import org.openimis.imispolicies.util.FileUtils; + import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -64,15 +69,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; -import java.util.Locale; public class Acquire extends AppCompatActivity { private static final String LOG_TAG = "ACQUIRE"; private static final int SCAN_QR_REQUEST_CODE = 0; private static final int TAKE_PHOTO_REQUEST_CODE = 1; + private static final String TEMP_PHOTO_PATH = "images/acquireTemp.jpg"; private Global global; @@ -85,17 +88,15 @@ public class Acquire extends AppCompatActivity { private String Path = null; private int result = 0; - private String msg = ""; private double Longitude, Latitude; private LocationManager lm; private String towers; private ClientAndroidInterface ca; private SQLHandler sqlHandler; - - private File tempPhotoFile; private Uri tempPhotoUri; private Picasso picasso; + private StorageManager storageManager; private final Target imageTarget = new Target() { @Override @@ -127,37 +128,26 @@ public void onCreate(Bundle savedInstanceState) { global = (Global) getApplicationContext(); ca = new ClientAndroidInterface(this); - picasso = new Picasso.Builder(this).build(); + storageManager = StorageManager.of(this); + sqlHandler = new SQLHandler(this); - Path = global.getSubdirectory("Images") + "/"; - tempPhotoFile = new File(Path, "temp.jpg"); - try { - if (tempPhotoFile.delete()) { - Log.v(LOG_TAG, "Leftover temp image deleted"); - } + etCHFID = findViewById(R.id.etCHFID); + iv = findViewById(R.id.imageView); + btnTakePhoto = findViewById(R.id.btnTakePhoto); + btnScan = findViewById(R.id.btnScan); + btnSubmit = findViewById(R.id.btnSubmit); - if (!tempPhotoFile.createNewFile()) { - Log.w(LOG_TAG, "Temp photo file already exists"); - } + File tempPhotoFile = FileUtils.createTempFile(this, TEMP_PHOTO_PATH); + if (tempPhotoFile != null) { tempPhotoUri = FileProvider.getUriForFile(this, String.format("%s.fileprovider", BuildConfig.APPLICATION_ID), tempPhotoFile); if (tempPhotoUri == null) { Log.w(LOG_TAG, "Failed to create temp photo URI"); } - } catch (IOException e) { - Log.e(LOG_TAG, "Temp photo file creation failed", e); } - etCHFID = findViewById(R.id.etCHFID); - iv = findViewById(R.id.imageView); - btnTakePhoto = findViewById(R.id.btnTakePhoto); - btnScan = findViewById(R.id.btnScan); - btnSubmit = findViewById(R.id.btnSubmit); - - sqlHandler = new SQLHandler(this); - etCHFID.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -168,14 +158,14 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override - public void afterTextChanged(Editable InsNo) { - String path = null; - if (!InsNo.toString().isEmpty()) { - path = ca.GetListOfImagesContain(InsNo.toString()); + public void afterTextChanged(Editable text) { + File photoFile = null; + String insureeNumber = text.toString(); + if (!insureeNumber.isEmpty()) { + photoFile = ImageManager.of(Acquire.this).getNewestInsureeImage(insureeNumber); } - if (path != null && !"".equals(path)) { - File file = new File(path); - picasso.load(file) + if (photoFile != null) { + picasso.load(photoFile) .placeholder(R.drawable.person) .error(R.drawable.person) .into(iv); @@ -217,13 +207,17 @@ public void afterTextChanged(Editable InsNo) { }); btnTakePhoto.setOnClickListener(v -> { - try { - Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, tempPhotoUri); - global.grantUriPermissions(this, tempPhotoUri, intent, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - startActivityForResult(intent, TAKE_PHOTO_REQUEST_CODE); - } catch (ActivityNotFoundException e) { - Log.e(LOG_TAG, "Image capture activity not found", e); + if (!etCHFID.getText().toString().isEmpty()) { + try { + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + intent.putExtra(MediaStore.EXTRA_OUTPUT, tempPhotoUri); + global.grantUriPermissions(this, tempPhotoUri, intent, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivityForResult(intent, TAKE_PHOTO_REQUEST_CODE); + } catch (ActivityNotFoundException e) { + Log.e(LOG_TAG, "Image capture activity not found", e); + } + } else { + Toast.makeText(this, R.string.MissingCHFID, Toast.LENGTH_LONG).show(); } }); @@ -256,15 +250,6 @@ public void afterTextChanged(Editable InsNo) { } runOnUiThread(() -> { - switch (result) { - case 1: - msg = getResources().getString(R.string.PhotoSaved); - break; - default: - msg = getResources().getString(R.string.CouldNotUpload); - break; - } - Toast.makeText(Acquire.this, getResources().getString(R.string.PhotoSaved), Toast.LENGTH_LONG).show(); etCHFID.setText(""); @@ -280,10 +265,7 @@ public void afterTextChanged(Editable InsNo) { @Override protected void onDestroy() { super.onDestroy(); - - if (!tempPhotoFile.delete()) { - Log.w(LOG_TAG, "Temp photo file deletion failed"); - } + FileUtils.removeTempFile(this, TEMP_PHOTO_PATH); } @Override @@ -331,6 +313,8 @@ private int SubmitData() throws IOException, UserException { String date = AppInformation.DateTimeInfo.getDefaultFileDatetimeFormatter().format(new Date()); String fName = etCHFID.getText() + "_" + global.getOfficerCode() + "_" + date + "_" + Latitude + "_" + Longitude + ".jpg"; + File[] oldInsureeImages = ImageManager.of(this).getInsureeImages(etCHFID.getText().toString()); + File file = new File(global.getSubdirectory("Images"), fName); if (file.exists()) { Log.w(LOG_TAG, String.format("File already exists: %s", file.getAbsolutePath())); @@ -342,13 +326,19 @@ private int SubmitData() throws IOException, UserException { if (file.length() == 0L) { Log.w(LOG_TAG, "Compressing photo failed, the resulting file has no content"); + if (!file.delete()) { + Log.w(LOG_TAG, "Deleting empty output file failed"); + } + return 0; + } else { + FileUtils.deleteFiles(oldInsureeImages); } ContentValues contentValues = new ContentValues(); contentValues.put("PhotoPath", file.getAbsolutePath()); String[] whereArgs = {etCHFID.getText().toString()}; - if(sqlHandler.updateData("tblInsuree", contentValues, "CHFID = ?", whereArgs, false) == 0) { + if (sqlHandler.updateData("tblInsuree", contentValues, "CHFID = ?", whereArgs, false) == 0) { Log.w(LOG_TAG, String.format("Cannot update photo path. No insuree for CHFID: %s", etCHFID.getText().toString())); } diff --git a/app/src/main/java/org/openimis/imispolicies/CheckCommission.java b/app/src/main/java/org/openimis/imispolicies/CheckCommission.java index 5206cd21..76531aeb 100644 --- a/app/src/main/java/org/openimis/imispolicies/CheckCommission.java +++ b/app/src/main/java/org/openimis/imispolicies/CheckCommission.java @@ -6,7 +6,9 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; + import org.openimis.imispolicies.tools.Log; + import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -18,9 +20,10 @@ import android.widget.TextView; import android.widget.Toast; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java b/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java index 8a550525..22753647 100644 --- a/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java +++ b/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java @@ -25,13 +25,11 @@ package org.openimis.imispolicies; -import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.ContentValues; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; @@ -46,16 +44,17 @@ import android.os.Parcelable; import android.provider.MediaStore; import android.support.annotation.RequiresApi; -import android.support.v4.content.FileProvider; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.Base64; +import org.openimis.imispolicies.util.UriUtils; +import org.openimis.imispolicies.util.ZipUtils; +import org.openimis.imispolicies.tools.ImageManager; import org.openimis.imispolicies.tools.Log; -import android.util.Xml; import android.view.LayoutInflater; import android.view.View; import android.webkit.JavascriptInterface; @@ -65,6 +64,7 @@ import com.exact.CallSoap.CallSoap; import com.exact.InsureeImages; import com.exact.uploadfile.UploadFile; +import com.google.zxing.client.android.CaptureActivity; import com.squareup.picasso.Picasso; import com.squareup.picasso.Target; @@ -77,10 +77,9 @@ import java.util.Arrays; import java.util.Date; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; @@ -108,10 +107,11 @@ import java.util.Set; import java.util.regex.Pattern; -import org.openimis.imispolicies.tools.Util; -import org.openimis.imispolicies.tools.Util.AndroidUtil; -import org.openimis.imispolicies.tools.Util.JsonUtil; -import org.xmlpull.v1.XmlSerializer; +import org.openimis.imispolicies.tools.StorageManager; +import org.openimis.imispolicies.util.AndroidUtils; +import org.openimis.imispolicies.util.FileUtils; +import org.openimis.imispolicies.util.JsonUtils; +import org.openimis.imispolicies.util.StringUtils; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; @@ -119,12 +119,9 @@ import static android.database.sqlite.SQLiteDatabase.openOrCreateDatabase; import static android.provider.MediaStore.EXTRA_OUTPUT; -import static org.openimis.imispolicies.tools.Util.JsonUtil.isStringEmpty; -import static org.openimis.imispolicies.tools.Util.StringUtil.isEmpty; public class ClientAndroidInterface { private static final String LOG_TAG_RENEWAL = "RENEWAL"; - private static final String LOG_TAG_SETTINGS = "SETTINGS"; private Context mContext; @@ -134,23 +131,16 @@ public class ClientAndroidInterface { private HashMap controls = new HashMap<>(); private String Path; private File[] files; - private File[] JSONfiles; - private int TotalFiles; - private int UploadCounter; // - private File XMLFile; private int result; private int UserId; - private Date edate; public static boolean Activate = false; private int IsFamilyAvailable; - private String payerId; private int DataDeleted; private int rtPolicyId = 0; private int rtPremiumId = 0; private int rtInsureeId = 0; private int rtEnrolledId = 0; private int enrol_result; - private Bitmap myBitmap; private String resu; private String fname = null; private Bitmap theImage; @@ -161,15 +151,13 @@ public class ClientAndroidInterface { EnrollmentReport enrollmentReport; - StringBuffer buffer = new StringBuffer(); - private ArrayList mylist = new ArrayList<>(); - private String salt; Picasso picassoInstance; Target imageTarget; - private File tempPhotoFile; + StorageManager storageManager; + ClientAndroidInterface(Context c) { mContext = c; @@ -177,8 +165,9 @@ public class ClientAndroidInterface { sqlHandler = new SQLHandler(c); getControls(); SQLiteDatabase database = sqlHandler.getReadableDatabase(); - Path = global.getMainDirectory(); + Path = global.getAppDirectory(); filePath = database.getPath(); + storageManager = StorageManager.of(mContext); database.close(); // activity = (Activity) c.getApplicationContext(); picassoInstance = new Picasso.Builder(mContext) @@ -194,7 +183,6 @@ public void SetUrl(String Url) { } private void getControls() { - String tableName = "tblControls"; String[] columns = {"FieldName", "Adjustibility"}; String where = null; @@ -212,10 +200,7 @@ private void getControls() { } catch (JSONException e) { e.printStackTrace(); } - - } - } public String getSpecificControl(String FieldName) { @@ -281,12 +266,12 @@ public String getControl(String ctl) { @JavascriptInterface public void ShowToast(String msg) { - AndroidUtil.showToast(mContext, msg); + AndroidUtils.showToast(mContext, msg); } @JavascriptInterface public AlertDialog ShowDialog(String msg) { - return AndroidUtil.showDialog(mContext, msg); + return AndroidUtils.showDialog(mContext, msg); } @JavascriptInterface @@ -896,7 +881,11 @@ private JSONObject getFamilySMS(String familyId) { String query = "SELECT * FROM tblFamilySMS where FamilyId = ? LIMIT 1;"; String[] queryArgs = {familyId}; try { - JSONObject result = sqlHandler.getResult(query, queryArgs).getJSONObject(0); + JSONObject result = null; + JSONArray array = sqlHandler.getResult(query, queryArgs); + if (array.length() > 0) { + result = array.getJSONObject(0); + } return result; } catch (JSONException e) { e.printStackTrace(); @@ -959,8 +948,6 @@ public int SaveInsuree(String InsureeData, int FamilyId, int isHead, int ExceedT int isOffline = 1; int insureeIsOffline = 1; int MaxInsureeId = 0; - Boolean res = false; - int newInsureeId = 0; try { global = (Global) mContext.getApplicationContext(); HashMap data = jsonToTable(InsureeData); @@ -1073,7 +1060,6 @@ public int SaveInsuree(String InsureeData, int FamilyId, int isHead, int ExceedT if (global.isNetworkAvailable()) { //if (isOffline == 0){ MaxInsureeId = -MaxInsureeId; - newInsureeId = MaxInsureeId; //} values.put("InsureeId", MaxInsureeId); @@ -1128,41 +1114,11 @@ else if (ExceedThreshold == 0) values.put("isOffline", insureeIsOffline); sqlHandler.updateData("tblInsuree", values, "InsureeId = ? AND (isOffline = ?)", new String[]{String.valueOf(InsureeId), String.valueOf(insureeIsOffline)}); } - if (global.isNetworkAvailable()) { - if (isOffline == 0 || isOffline == 2) { - if (isOffline == 2) isOffline = 0; - if (global.getUserId() > 0) { - if (rtInsureeId > 0) { - newInsureeId = -rtInsureeId; - } else { - newInsureeId = rtInsureeId; - } - if (rtInsureeId == 0 && res) { - inProgress = false; - } else { - } - inProgress = false; - } - inProgress = false; - } else { - inProgress = false; - } - inProgress = false; - } else { - inProgress = false; - } - - - } catch (NumberFormatException e) { - e.printStackTrace(); - throw new Exception(e.getMessage()); - } catch (UserException e) { + } catch (NumberFormatException | UserException e) { e.printStackTrace(); throw new Exception(e.getMessage()); } - while (inProgress) { - } - inProgress = false; + return rtInsureeId; } @@ -1180,15 +1136,18 @@ private String copyImageFromGalleryToApplication(String selectedPath, String Ins Calendar cal = Calendar.getInstance(); String d = format.format(cal.getTime()); - String outputFileName = global.getImageFolder() + InsuranceNumber + "_" + global.getOfficerCode() + "_" + d + "_0_0.jpg"; - File outputFile = new File(outputFileName); + File[] oldFiles = ImageManager.of(mContext).getInsureeImages(InsuranceNumber); + Runnable deleteOldFiles = () -> FileUtils.deleteFiles(oldFiles); + + String outputFileName = InsuranceNumber + "_" + global.getOfficerCode() + "_" + d + "_0_0.jpg"; + File outputFile = new File(global.getImageFolder(), outputFileName); if (!outputFile.createNewFile()) { Log.e("IMAGES", "Creating image copy failed"); } FileOutputStream outputStream = new FileOutputStream(outputFile); - imageTarget = new OutputStreamImageTarget(outputStream, global.getIntKey("image_jpeg_quality", 40)); + imageTarget = new OutputStreamImageTarget(outputStream, global.getIntKey("image_jpeg_quality", 40), deleteOldFiles); try { ((Activity) mContext).runOnUiThread(() -> picassoInstance.load(selectedPath) .resize(global.getIntKey("image_width_limit", 400), @@ -1213,19 +1172,12 @@ public AlertDialog deleteDialog(String msg, final int FamilyId) { .setMessage(msg) .setIcon(R.drawable.ic_about) .setCancelable(false) - .setPositiveButton(R.string.Yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (DeleteFamily(FamilyId) == 1) { - ShowDialog(mContext.getResources().getString(R.string.FamilyDeleted)); - } + .setPositiveButton(R.string.Yes, (dialogInterface, i) -> { + if (DeleteFamily(FamilyId) == 1) { + ShowDialog(mContext.getResources().getString(R.string.FamilyDeleted)); } }) - .setNegativeButton(R.string.No, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - //some code when you click No - } + .setNegativeButton(R.string.No, (dialog, which) -> { }).show(); } @@ -1461,30 +1413,12 @@ else if (dateWithGracePeriod4 != null && (dEnrollDate.compareTo(dateWithGracePer public static String InsuranceNo; public static boolean inProgress = true; - - private void generateTempUri(String tempFileName) { - tempPhotoFile = new File(Path, tempFileName); - try { - if (tempPhotoFile.delete()) { - Log.i("selectPicture", "Leftover temp image deleted"); - } - if (!tempPhotoFile.createNewFile()) { - Log.w("selectPicture", "Temp photo file already exists"); - } - tempPhotoUri = FileProvider.getUriForFile(mContext, - String.format("%s.fileprovider", BuildConfig.APPLICATION_ID), - tempPhotoFile); - } catch (IOException e) { - Log.e("selectPicture", "Temp photo file creation failed", e); - Toast.makeText(mContext, "Temp photo file creation failed", Toast.LENGTH_LONG).show(); - } - } - @JavascriptInterface public void selectPicture() { Path = global.getSubdirectory("Images") + "/"; - generateTempUri("selectPictureTemp.jpg"); + File tempPhotoFile = FileUtils.createTempFile(mContext, "images/selectPictureTemp.jpeg"); + tempPhotoUri = UriUtils.createUriForFile(mContext, tempPhotoFile); if (tempPhotoUri == null) return; Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); @@ -1710,49 +1644,6 @@ public double getPolicyValue(String enrollDate, int ProductId, int FamilyId, Str return PolicyValue; } -/* String imagefile ="/sdcard/DCIM/100ANDRO/DSC_0530.jpg"; - Bitmap bm = ShrinkBitmap(imagefile, 300, 300); - - //this method compresses the image and saves into a location in sdcard - Bitmap ShrinkBitmap(String file, int width, int height){ - - BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); - bmpFactoryOptions.inJustDecodeBounds = true; - Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); - - int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); - int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); - - if (heightRatio > 1 || widthRatio > 1) - { - if (heightRatio > widthRatio) - { - bmpFactoryOptions.inSampleSize = heightRatio; - } else { - bmpFactoryOptions.inSampleSize = widthRatio; - } - } - - bmpFactoryOptions.inJustDecodeBounds = false; - bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); - byte[] imageInByte = stream.toByteArray(); - //this gives the size of the compressed image in kb - long lengthbmp = imageInByte.length / 1024; - - try { - bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream("/sdcard/mediaAppPhotos/compressed_new.jpg")); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - - return bitmap; - }*/ - @JavascriptInterface public String getOfficers(int LocationId, String EnrolmentDate) { @@ -2119,14 +2010,14 @@ public int SavePremiums(String PremiumData, int PolicyId, int PremiumId, int Fam @JavascriptInterface public String getPayers(int RegionId, int DistrictId) { - String Query = "SELECT PayerId, PayerName,P.LocationId FROM tblPayer P \n" + - "LEFT OUTER JOIN tblLocations L ON P.LocationId = L.LocationId\n" + - "WHERE (P.LocationId = " + DistrictId + " OR L.ParentLocationId = P.LocationId OR P.LocationId = 'null' OR P.LocationId = '') " + + String Query = "SELECT PayerId, PayerName,P.LocationId FROM tblPayer P " + + "LEFT OUTER JOIN tblLocations L ON P.LocationId = L.LocationId " + + "WHERE L.LocationId = ? OR L.LocationId = ? OR L.LocationId = 'null' OR L.LocationId = '' OR L.LocationId = 0 " + "ORDER BY L.LocationId"; /* "INNER JOIN uvwLocations L ON P.LocationId = L.LocationId\n" + "WHERE (L.RegionId = " + RegionId + " OR L.RegionId ='null' OR L.RegionId ='') AND (L.DistrictId = " + DistrictId + " OR L.DistrictId ='null' OR L.DistrictId ='') " + " ORDER BY L.LocationId";*/ - JSONArray Payers = sqlHandler.getResult(Query, null); + JSONArray Payers = sqlHandler.getResult(Query, new String[]{String.valueOf(RegionId), String.valueOf(DistrictId)}); return Payers.toString(); } @@ -2923,16 +2814,7 @@ public void uploadEnrolment() throws Exception { new Thread(() -> { try { enrol_result = Enrol(0, 0, 0, 0, 1); - } catch (UserException e) { - finalPd.dismiss(); - e.printStackTrace(); - } catch (JSONException e) { - finalPd.dismiss(); - e.printStackTrace(); - } catch (IOException e) { - finalPd.dismiss(); - e.printStackTrace(); - } catch (NumberFormatException e) { + } catch (UserException | JSONException | IOException | NumberFormatException e) { finalPd.dismiss(); e.printStackTrace(); } @@ -2971,75 +2853,67 @@ public void uploadEnrolment() throws Exception { } @JavascriptInterface - public void CreateEnrolmentXML() throws Exception { - - pd = new ProgressDialog(mContext); - pd = ProgressDialog.show(mContext, "", mContext.getResources().getString(R.string.Uploading)); - - try { - new Thread(() -> { - try { - enrol_result = Enrol(0, 0, 0, 0, 2); - if (enrol_result == 0) { - //zipFile(); - zipFiles(); - deleteUnzippedFie(); - deleteUnzippedPhotos(); - } - } catch (UserException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (NumberFormatException e) { - e.printStackTrace(); + public void CreateEnrolmentXML() { + new Thread(() -> { + try { + enrol_result = Enrol(0, 0, 0, 0, 2); + if (enrol_result == 0) { + storageManager.requestCreateFile(MainActivity.REQUEST_CREATE_ENROL_EXPORT, + "application/octet-stream", getEnrolmentExportFilename()); } - if (mylist.size() == 0) { - ((Activity) mContext).runOnUiThread(() -> { - if (enrol_result != 999) { - //if error is encountered - if (enrolMessages.size() > 0 && enrolMessages != null) { - CharSequence[] charSequence = enrolMessages.toArray(new CharSequence[(enrolMessages.size())]); - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); - builder.setTitle(mContext.getResources().getString(R.string.UploadFailureReport)); - builder.setCancelable(false); - builder.setItems(charSequence, null); - builder.setPositiveButton(mContext.getResources().getString(R.string.Ok), (dialogInterface, i) -> dialogInterface.dismiss()); - AlertDialog dialog = builder.create(); - dialog.show(); - enrolMessages.clear(); - } else { - //deleteImage(); - ShowDialog(mContext.getResources().getString(R.string.XmlCreated)); - } + } catch (Exception e) { + Log.e("ENROL XML", "Error while creating enrolment xml", e); + } + if (mylist.size() == 0) { + ((Activity) mContext).runOnUiThread(() -> { + if (enrol_result != 999) { + //if error is encountered + if (enrolMessages.size() > 0 && enrolMessages != null) { + CharSequence[] charSequences = enrolMessages.toArray(new CharSequence[(enrolMessages.size())]); + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + builder.setTitle(mContext.getResources().getString(R.string.UploadFailureReport)); + builder.setCancelable(false); + builder.setItems(charSequences, null); + builder.setPositiveButton(mContext.getResources().getString(R.string.Ok), (dialogInterface, i) -> dialogInterface.dismiss()); + AlertDialog dialog = builder.create(); + dialog.show(); + enrolMessages.clear(); } else { - ShowDialog(mContext.getResources().getString(R.string.NoDataAvailable)); + //deleteImage(); + ShowDialog(mContext.getResources().getString(R.string.XmlCreated)); } - //ShowDialog(mContext.getResources().getString(R.string.FamilyUploaded)); - }); - } else { - ((Activity) mContext).runOnUiThread( - () -> ShowDialog(mylist.toString())); - } - pd.dismiss(); - }).start(); - } catch (Exception e) { - e.printStackTrace(); - throw new Exception(e.getMessage()); + } else { + AndroidUtils.showToast(mContext, R.string.NoDataAvailable); + } + //ShowDialog(mContext.getResources().getString(R.string.FamilyUploaded)); + }); + } else { + ((Activity) mContext).runOnUiThread( + () -> ShowDialog(mylist.toString())); + } + }).start(); + } + + @JavascriptInterface + public void CreateRenewalExport() { + if (FileUtils.getFileCount(new File(global.getSubdirectory("Renewal"))) > 0) { + new Thread(() -> storageManager.requestCreateFile(MainActivity.REQUEST_CREATE_RENEWAL_EXPORT, + "application/octet-stream", getRenewalExportFilename())).start(); + } else { + AndroidUtils.showToast(mContext, R.string.NoDataAvailable); } + } - /* private void deleteImage() { - File fdelete = new File(PhotoPath.trim()); - if (fdelete.exists()) { - if (fdelete.delete()) { - System.out.println("file Deleted :" + file_dj_path); - } else { - System.out.println("file not Deleted :" + file_dj_path); - } - } - }*/ + @JavascriptInterface + public void CreateFeedbackExport() { + if (FileUtils.getFileCount(new File(global.getSubdirectory("Feedback"))) > 0) { + new Thread(() -> storageManager.requestCreateFile(MainActivity.REQUEST_CREATE_FEEDBACK_EXPORT, + "application/octet-stream", getFeedbackExportFilename())).start(); + } else { + AndroidUtils.showToast(mContext, R.string.NoDataAvailable); + } + } public boolean isPolicyRequired() { return !getRule("AllowFamilyWithoutPolicy", false); @@ -3306,18 +3180,19 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, if (CallerId != 2) { Query += " I.FamilyId = " + FamilyId + " \n"; if (Integer.parseInt(Offline) == 0) { - if (CallerId == 1 || CallerId == 2) { + if (CallerId == 1) { Query += " AND I.InsureeId < 0" + ""; } } } else { - Query += "I.InsureeId < 0 AND ("; + Query += "("; for (int j = 0; j < verifiedId.size(); j++) { + if (getFamilyStatus(Integer.parseInt(verifiedId.get(j))) == 0) { if ((verifiedId.size() - j) == 1) { - Query += " I.FamilyId == " + verifiedId.get(j) + ""; + Query += "I.InsureeId < 0 AND I.FamilyId == " + verifiedId.get(j) + ""; } else { - Query += " I.FamilyId == " + verifiedId.get(j) + " OR "; + Query += "I.InsureeId < 0 AND I.FamilyId == " + verifiedId.get(j) + " OR "; } } else { if ((verifiedId.size() - j) == 1) { @@ -3472,6 +3347,8 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, String InsureePolicy = objEnrol.toString(); if (CallerId != 2) { + InsureeImages[] InsureeImages = FamilyPictures(insureesArray, CallerId); + if (mylist.size() == 0) { JSONObject resultObj = new JSONObject(); JSONArray familyArr = new JSONArray(); @@ -3481,8 +3358,6 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, // Insuree + picture JSONArray tempInsureesArray = new JSONArray(); - InsureeImages[] InsureeImages = FamilyPictures(insureesArray, CallerId); - for (int j = 0; j < insureesArray.length(); j++) { tempInsureesArray = insureesArray; JSONObject imgObj = new JSONObject(); @@ -3517,33 +3392,41 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, ToRestApi rest = new ToRestApi(); HttpResponse response = rest.postToRestApiToken(resultObj, "family"); - - HttpEntity entity = response.getEntity(); - String responseString = EntityUtils.toString(entity); - - boolean parsingErrorOccured = false; - try { - JSONObject responseObject = new JSONObject(responseString); - if (responseObject.has("error_occured") && responseObject.getBoolean("error_occured")) { + String responseString = rest.getContent(response); + if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK + || response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_CREATED) { + boolean parsingErrorOccured = false; + try { + JSONObject responseObject = new JSONObject(responseString); + if (responseObject.has("error_occured") && responseObject.getBoolean("error_occured")) { + EnrolResult = -400; + enrolMessages.add(responseObject.getString("error_message")); + } else if (responseObject.has("response")) { + EnrolResult = responseObject.getInt("response"); + } else { + throw new JSONException("Response does not have required information"); + } + } catch (JSONException e) { EnrolResult = -400; - enrolMessages.add(responseObject.getString("error_message")); - } else if (responseObject.has("response")) { - EnrolResult = responseObject.getInt("response"); - } else { - throw new JSONException("Response does not have required information"); + parsingErrorOccured = true; + } + + if (parsingErrorOccured) { + try { + EnrolResult = Integer.parseInt(responseString); + } catch (NumberFormatException e) { + Log.e("ENROLL", "Sync response is not a valid json or int"); + } } - } catch (JSONException e) { + } else { + enrolMessages.add(mContext.getResources().getString(R.string.HttpResponse, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase())); EnrolResult = -400; - parsingErrorOccured = true; } - if (parsingErrorOccured) { - try { - EnrolResult = Integer.parseInt(responseString); - } catch (NumberFormatException e) { - Log.e("ENROLL", "Sync response is not a valid json or int"); - } + if (EnrolResult != 0) { + Log.d("ENROL", "API RESPONSE: " + mContext.getResources().getString(R.string.HttpResponse, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()) + "\n" + responseString); } + } else { ShowErrorMessages(); break; @@ -3588,16 +3471,17 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, } if (mylist.size() == 0) { - if (CallerId == 1 || CallerId == 2) { + if (CallerId == 1) { DeleteImages(insureesArray, verifiedId, CallerId); - DeleteUploadedData(Integer.parseInt(FamilyId), verifiedId, CallerId); - DeleteFamily(Integer.parseInt(FamilyId)); } + + DeleteUploadedData(Integer.parseInt(FamilyId), verifiedId, CallerId); + DeleteFamily(Integer.parseInt(FamilyId)); } } else { - String ErrMsg = null; + String ErrMsg; switch (EnrolResult) { case -1: ErrMsg = "[" + CHFNumber + "] " + mContext.getString(R.string.MissingHOF); @@ -3629,15 +3513,12 @@ private int Enrol(int oFamilyId, int oInsureeId, int oPolicyId, int oPremiumId, } else { EnrolResult = 0; - if (CallerId == 1 || CallerId == 2) { + if (CallerId == 1) { DeleteImages(insureesArray, verifiedId, CallerId); - DeleteUploadedData(Integer.parseInt(FamilyId), verifiedId, CallerId); } - if (CallerId == 1 || CallerId != 0) { - DeleteImages(insureesArray, verifiedId, CallerId); - if (IsOffline == 0 || IsOffline == 0) { - DeleteFamily(Integer.parseInt(FamilyId)); - } + DeleteUploadedData(Integer.parseInt(FamilyId), verifiedId, CallerId); + if (IsOffline == 0) { + DeleteFamily(Integer.parseInt(FamilyId)); } } @@ -3673,33 +3554,14 @@ public void updatePolicyRecords(String policy) throws JSONException { } } - private void deleteUnzippedFie() { - /* global = (Global) mContext.getApplicationContext(); - @SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy-HH"); - Calendar cal = Calendar.getInstance(); - String d = format.format(cal.getTime());*/ - - String targetPath = global.getSubdirectory("Family"); - File file = new File(targetPath, fname); - file.delete(); - } - - public void deleteUnzippedPhotos() { - String targetPath = global.getSubdirectory("Photos"); - File folder = new File(targetPath); - for (int i = 0; i < folder.listFiles().length; i++) { - if (folder.listFiles()[i].isFile()) { - folder.listFiles()[i].delete(); - } + public void clearDirectory(String directory) { + File[] files = new File(global.getSubdirectory(directory)).listFiles(); + if (files != null) { + FileUtils.deleteFiles(files); } } - public InsureeImages[] FamilyPictures(JSONArray insurees, int CallerId) throws IOException { - - String Path = global.getSubdirectory("Photos"); - //Here we are creating a directory - InsureeImages[] images = new InsureeImages[insurees.length()]; String PhotoPath = null; @@ -3812,86 +3674,49 @@ public static void copy(String name, byte[] data) throws IOException { out.close(); } - public void xmlWriter(String ImgName, byte[] imgcontent) throws IOException { - File Dir = new File(global.getSubdirectory("EnrolmentXML")); - - //Here we are giving name to the XML file - String FileName = "EnrolmentXml.xml"; - - //Here we are creating file in that directory - File EnrollmentXML = new File(Dir, FileName); - //Here we are creating outputstream - FileOutputStream fos = new FileOutputStream(EnrollmentXML, true); - - - XmlSerializer serializer = Xml.newSerializer(); - - serializer.setOutput(fos, "UTF-8"); - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - serializer.startTag(null, "Pictures"); - - serializer.startTag(null, "ImageName"); - serializer.text(ImgName); - serializer.endTag(null, "ImageName"); + public String getEnrolmentExportFilename() { + return getExportFileName("Enrolment"); + } - serializer.startTag(null, "ImageContent"); - serializer.text(String.valueOf(imgcontent)); - serializer.endTag(null, "ImageContent"); + public String getRenewalExportFilename() { + return getExportFileName("Renewal"); + } - serializer.endTag(null, "Pictures"); - serializer.endDocument(); - serializer.flush(); - fos.close(); + public String getFeedbackExportFilename() { + return getExportFileName("Feedback"); } - public void zipFile() { - global = (Global) mContext.getApplicationContext(); - //@SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); - @SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy-HH-mm"); - @SuppressLint("SimpleDateFormat") SimpleDateFormat formatZip = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss"); + public String getExportFileName(String type) { + SimpleDateFormat formatZip = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss", Locale.US); Calendar cal = Calendar.getInstance(); - String d = format.format(cal.getTime()); String dzip = formatZip.format(cal.getTime()); + return type + "_" + global.getOfficerCode() + "_" + dzip + ".rar"; + } - String targetPath = global.getSubdirectory("Enrolment") + File.separator + "Enrolment_" + global.getOfficerCode() + "_" + d + ".xml"; - String zipFilePath = global.getSubdirectory("Enrolment") + File.separator + "Enrolment_" + global.getOfficerCode() + "_" + dzip + ".rar"; - //String unzippedFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/IMIS/Enrolment/Enrolment_"+global.getOfficerCode()+"_"+d+".xml"; + + public File zipEnrolmentFiles() { + File zipFile = FileUtils.createTempFile(mContext, "exports/" + getEnrolmentExportFilename(), true); String password = getRarPwd(); + File imageDir = new File(global.getImageFolder()); + File familyDir = new File(global.getSubdirectory("Family")); - Compressor.zip(targetPath, zipFilePath, password); - //Compressor.unzip(zipFilePath, unzippedFolderPath, password); + return ZipUtils.zipDirectories(zipFile, password, familyDir, imageDir); } - public void zipFiles() { - global = (Global) mContext.getApplicationContext(); - @SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy-HH"); - @SuppressLint("SimpleDateFormat") SimpleDateFormat formatZip = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss"); - Calendar cal = Calendar.getInstance(); - String d = format.format(cal.getTime()); - String dzip = formatZip.format(cal.getTime()); - - String targetPath = global.getSubdirectory("Photos"); - String targetPathFamily = global.getSubdirectory("Family"); - String zipFilePath = global.getSubdirectory("Enrolment") + File.separator + "Enrolment_" + global.getOfficerCode() + "_" + dzip + ".rar"; - //String unzippedFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/IMIS/Photos_"+global.getOfficerCode()+"_"+d+""; + public File zipRenewalFiles() { + File zipFile = FileUtils.createTempFile(mContext, "exports/" + getRenewalExportFilename(), true); String password = getRarPwd(); + File familyDir = new File(global.getSubdirectory("Renewal")); - ArrayList FilesToAdd = new ArrayList(); - File folder = new File(targetPath); - File Family = new File(targetPathFamily); - for (int i = 0; i < folder.listFiles().length; i++) { - if (folder.listFiles()[i].isFile()) { - FilesToAdd.add(new File(folder.listFiles()[i].getPath())); - } - } - for (int i = 0; i < Family.listFiles().length; i++) { - if (Family.listFiles()[i].isFile()) { - FilesToAdd.add(new File(Family.listFiles()[i].getPath())); - } - } + return ZipUtils.zipDirectories(zipFile, password, familyDir); + } - Compressor.zip(FilesToAdd, zipFilePath, password); - //Compressor.unzip(zipFilePath, unzippedFolderPath, password); + public File zipFeedbackFiles() { + File zipFile = FileUtils.createTempFile(mContext, "exports/" + getFeedbackExportFilename(), true); + String password = getRarPwd(); + File familyDir = new File(global.getSubdirectory("Feedback")); + + return ZipUtils.zipDirectories(zipFile, password, familyDir); } public boolean unZipWithPassword(String fileName, String password) { @@ -3900,7 +3725,7 @@ public boolean unZipWithPassword(String fileName, String password) { //String unzippedFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/IMIS/Enrolment/Enrolment_"+global.getOfficerCode()+"_"+d+".xml"; //here we not don't have password set yet so we pass password from Edit Text rar input try { - Compressor.unzip(targetPath, unzippedFolderPath, password); + ZipUtils.unzipPath(targetPath, unzippedFolderPath, password); } catch (Exception e) { return false; } @@ -3914,125 +3739,23 @@ public boolean unZip(String FileName) { String password = getRarPwd(); try { - Compressor.unzip(targetPath, unzippedFolderPath, password); + ZipUtils.unzipPath(targetPath, unzippedFolderPath, password); } catch (Exception e) { return false; } return true; } - public boolean unZipFeedbacksRenewals(String FileName) { - String targetPath = global.getSubdirectory("Database") + File.separator + FileName; - String unzippedFolderPath = global.getSubdirectory("Database"); - + public boolean unZipFeedbacksRenewals(File file) { String password = getRarPwd(); try { - Compressor.unzip(targetPath, unzippedFolderPath, password); + ZipUtils.unzipFile(file, file.getParentFile(), password); } catch (Exception e) { return false; } return true; } - - @JavascriptInterface - public void zipFeedBackRenewal(final String FileType) { - global = (Global) mContext.getApplicationContext(); - //@SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); - @SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss"); - Calendar cal = Calendar.getInstance(); - String d = format.format(cal.getTime()); - - - String targetPath = global.getMainDirectory(); - String zipFilePath = global.getMainDirectory() + File.separator + "Master" + FileType + ".rar"; - //String unzippedFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/IMIS/Photos_"+global.getOfficerCode()+"_"+d+""; - - String password = getRarPwd(); - - ArrayList FilesToAdd = new ArrayList(); - File folder = new File(targetPath); - for (int i = 0; i < folder.listFiles().length; i++) { - final int[] status = {0}; - if (folder.listFiles()[i].isFile()) { - String fname = folder.listFiles()[i].getName(); - if (FileType.equals("Feedback")) { - String str = fname.substring(0, 9); - if (str.equals("feedback_")) { - FilesToAdd.add(new File(folder.listFiles()[i].getPath())); - } - } else { - String str = fname.substring(0, 7); - if (str.equals("RenPol_")) { - FilesToAdd.add(new File(folder.listFiles()[i].getPath())); - } - } - } - - } - - - Compressor.zip(FilesToAdd, zipFilePath, password); - if (FilesToAdd.size() > 0) { - ShowDialog(mContext.getResources().getString(R.string.XmlCreated) + " with " + FilesToAdd.size() + " Files"); - } else { - ShowDialog(mContext.getResources().getString(R.string.NoDataAvailable)); - } - - //Compressor.unzip(zipFilePath, unzippedFolderPath, password); - } - -/* @JavascriptInterface - public void UploadImages(final String Filename) { - - files = GetListOfImages(global.getImageFolder(), Filename); - UploadFile uf = new UploadFile(); - if(files.length > 0){ - if (uf.isValidFTPCredentials()) { - for (int i = 0; i < files.length; i++) { - UploadCounter = i + 1; - if (uf.uploadFileToServer(mContext, files[i], "org.openimis.imispolicies")) { - files[i].delete(); - } - } - } - } -*//* new Thread() { - public void run() { - files = GetListOfImages(global.getImageFolder(), Filename); - UploadFile uf = new UploadFile(); - if(files.length > 0){ - if (uf.isValidFTPCredentials()) { - - for (int i = 0; i < files.length; i++) { - UploadCounter = i + 1; - if (uf.uploadFileToServer(mContext, files[i], "org.openimis.imispolicies")) { - files[i].delete(); - } - } - } - } - - } - }.start();*//* - - }*/ - - public void createZipImage() { -/* OutputStream out; - String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+"/"; - File createDir = new File(root+"Folder Name"+File.separator); - if(!createDir.exists()) { - createDir.mkdir(); - } - File file = new File(root + "Folder Name" + File.separator +"Name of File"); - file.createNewFile(); - out = new FileOutputStream(file); - - out.write(data); - out.close();*/ - } - public String getRarPwd() { global = (Global) mContext.getApplicationContext(); String password = ""; @@ -4245,12 +3968,7 @@ public int isValidLogin(final String Username, final String Password) throws Int cs.setFunctionName("isValidLogin"); UserId = cs.isUserLoggedIn(Username, Password); global.setUserId(UserId); - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - MainActivity.SetLoggedIn(mContext.getResources().getString(R.string.Login), mContext.getResources().getString(R.string.Logout)); - } - }); + ((Activity) mContext).runOnUiThread(() -> MainActivity.SetLoggedIn(mContext.getResources().getString(R.string.Login), mContext.getResources().getString(R.string.Logout))); return UserId; } @@ -4282,7 +4000,7 @@ public String GetSnapshotIndicators() { private void DeleteUploadedData(final int FamilyId, ArrayList FamilyIDs, int CallerId) { if (FamilyIDs.size() == 0) { - FamilyIDs = new ArrayList() {{ + FamilyIDs = new ArrayList<>() {{ add(String.valueOf(FamilyId)); }}; } @@ -4333,63 +4051,49 @@ private void deleteUploadedTableData(String tableName, String where) { } @JavascriptInterface - public Boolean UploadOfflineFeedbackRenewal(final String ActivityName) { - final File[] files, jsonFiles; - final String functionName, jsonPropertyName, path; + public void uploadFeedbacks() { final int totalFiles; final ProgressDialog pd; - result = ToRestApi.UploadStatus.NO_RESPONSE; + if (!global.isNetworkAvailable()) { + ShowDialog(mContext.getResources().getString(R.string.NoInternet)); + return; + } - path = global.getMainDirectory(); + File feedbackDir = new File(global.getSubdirectory("Feedback")); + File[] xmlFiles = feedbackDir.listFiles((file) -> file.getName().endsWith(".xml")); + File[] jsonFiles = feedbackDir.listFiles((file) -> file.getName().endsWith(".json")); - if (ActivityName.equals("renewal")) { - files = GetListOfFiles(path, "Renewal", null); - jsonFiles = GetListOfJSONFiles(path, "Renewal", null); - functionName = "policy/renew"; - jsonPropertyName = "Policy"; - } else { - files = GetListOfFiles(Path, "Feedback", null); - jsonFiles = GetListOfJSONFiles(Path, "Feedback", null); - functionName = "feedback"; - jsonPropertyName = "feedback"; + if (xmlFiles == null || jsonFiles == null) { + ShowDialog(mContext.getResources().getString(R.string.NoFiles)); + DeleteFeedBacks(); + return; } - totalFiles = files.length; + totalFiles = jsonFiles.length; if (totalFiles == 0) { ShowDialog(mContext.getResources().getString(R.string.NoDataAvailable)); - //Clean tables in database as well - if (ActivityName.equals("renewal")) { - DeleteRenewals(); - } else { - DeleteFeedBacks(); - } - - return false; - } - - if (!global.isNetworkAvailable()) { - ShowDialog(mContext.getResources().getString(R.string.NoInternet)); - return false; + DeleteFeedBacks(); + return; } - pd = ProgressDialog.show(mContext, mContext.getResources().getString(R.string.Sync), mContext.getResources().getString(R.string.SyncProcessing)); + pd = AndroidUtils.showProgressDialog(mContext, R.string.Sync, R.string.SyncProcessing); new Thread(() -> { ToRestApi rest = new ToRestApi(); JSONObject obj; int uploadsAccepted = 0, uploadsRejected = 0, uploadFailed = 0; for (int i = 0; i < jsonFiles.length; i++) { - String jsonText = global.getFileText(jsonFiles[i].getPath()); + String jsonText = FileUtils.readFileAsUTF8String(jsonFiles[i]); HttpResponse response = null; int responseCode = -1; int uploadStatus = -1; try { - obj = new JSONObject(jsonText).getJSONObject(jsonPropertyName); - response = rest.postToRestApiToken(obj, functionName); + obj = new JSONObject(jsonText).getJSONObject("feedback"); + response = rest.postToRestApiToken(obj, "feedback"); if (response != null) { responseCode = response.getStatusLine().getStatusCode(); if (responseCode == HttpURLConnection.HTTP_OK) { @@ -4405,11 +4109,11 @@ public Boolean UploadOfflineFeedbackRenewal(final String ActivityName) { } else if (responseCode == HttpURLConnection.HTTP_OK) { if (uploadStatus == ToRestApi.UploadStatus.ACCEPTED) { uploadsAccepted += 1; - MoveFile(files[i], 1); + MoveFile(xmlFiles[i], 1); MoveFile(jsonFiles[i], 1); } else { uploadsRejected += 1; - MoveFile(files[i], 2); + MoveFile(xmlFiles[i], 2); MoveFile(jsonFiles[i], 2); } } @@ -4440,33 +4144,37 @@ public Boolean UploadOfflineFeedbackRenewal(final String ActivityName) { }); pd.dismiss(); }).start(); - return true; } @JavascriptInterface public void uploadRenewals() { - final String path; final int totalFiles; final ProgressDialog pd; - path = global.getMainDirectory(); - File[] files = GetListOfFiles(path, "Renewal", null); - File[] jsonFiles = GetListOfJSONFiles(path, "Renewal", null); + if (!global.isNetworkAvailable()) { + ShowDialog(mContext.getResources().getString(R.string.NoInternet)); + return; + } - totalFiles = jsonFiles.length; + File renewalDir = new File(global.getSubdirectory("Renewal")); + File[] xmlFiles = renewalDir.listFiles((file) -> file.getName().endsWith(".xml")); + File[] jsonFiles = renewalDir.listFiles((file) -> file.getName().endsWith(".json")); - if (totalFiles == 0) { - ShowDialog(mContext.getResources().getString(R.string.NoDataAvailable)); + if (xmlFiles == null || jsonFiles == null) { + ShowDialog(mContext.getResources().getString(R.string.NoFiles)); DeleteRenewals(); return; } - if (!global.isNetworkAvailable()) { - ShowDialog(mContext.getResources().getString(R.string.NoInternet)); + totalFiles = jsonFiles.length; + + if (totalFiles == 0) { + ShowDialog(mContext.getResources().getString(R.string.NoDataAvailable)); + DeleteRenewals(); return; } - pd = AndroidUtil.showProgressDialog(mContext, R.string.Sync, R.string.SyncProcessing); + pd = AndroidUtils.showProgressDialog(mContext, R.string.Sync, R.string.SyncProcessing); new Thread(() -> { StringBuilder messageBuilder = new StringBuilder(); @@ -4485,7 +4193,7 @@ public void uploadRenewals() { int acceptedRenewals = 0; for (int i = 0; i < jsonFiles.length; i++) { - String jsonText = global.getFileText(jsonFiles[i].getPath()); + String jsonText = FileUtils.readFileAsUTF8String(jsonFiles[i]); String renewalInsureeNo = ""; HttpResponse response; @@ -4529,11 +4237,11 @@ public void uploadRenewals() { if (messages.containsKey(uploadStatus)) { if (uploadStatus == ToRestApi.RenewalStatus.ACCEPTED || uploadStatus == ToRestApi.RenewalStatus.ALREADY_ACCEPTED) { - MoveFile(files[i], 1); + MoveFile(xmlFiles[i], 1); MoveFile(jsonFiles[i], 1); acceptedRenewals++; } else { - MoveFile(files[i], 2); + MoveFile(xmlFiles[i], 2); MoveFile(jsonFiles[i], 2); messageBuilder.append(String.format(messageFormat, renewalInsureeNo, messages.get(uploadStatus))); } @@ -4541,15 +4249,17 @@ public void uploadRenewals() { } String successMessage = mContext.getResources().getString(R.string.BulkUpload); - + String failMessage = mContext.getResources().getString(R.string.RenewalRejected); String resultMessage; - if (acceptedRenewals != jsonFiles.length) { + if (acceptedRenewals == 0) { + resultMessage = failMessage; + } else if (acceptedRenewals != jsonFiles.length) { resultMessage = successMessage + "\n" + messageBuilder.toString(); } else { resultMessage = successMessage; } - ((Activity) mContext).runOnUiThread(() -> AndroidUtil.showDialog(mContext, resultMessage)); + ((Activity) mContext).runOnUiThread(() -> AndroidUtils.showDialog(mContext, resultMessage)); pd.dismiss(); }).start(); @@ -4605,7 +4315,7 @@ public String GetListOfImagesContain(final String FileName) { Photos = Directory.listFiles((dir, filename) -> filename.startsWith(FileName + "_")); if (Photos != null && Photos.length > 0) { - Arrays.sort(Photos, (f1, f2) -> f1.getName().compareTo(f2.getName())); + Arrays.sort(Photos, (f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified())); newFileName = Photos[Photos.length - 1].toString(); } return newFileName; @@ -4613,7 +4323,7 @@ public String GetListOfImagesContain(final String FileName) { private void MoveFile(File file, int res) { String Accepted = "", Rejected = ""; - if (file.getName().contains("RenPol_") || file.getName().contains("RenPolJSON_")) { + if (file.getName().contains("Renewal_") || file.getName().contains("RenewalJSON_")) { Accepted = "AcceptedRenewal"; Rejected = "RejectedRenewal"; } else if (file.getName().contains("feedback_") || file.getName().contains("feedbackJSON_")) { @@ -4696,43 +4406,30 @@ public void popUpOfficerDialog() { @JavascriptInterface public void downloadMasterData() throws InterruptedException { - ProgressDialog pd = null; - pd = ProgressDialog.show(mContext, mContext.getResources().getString(R.string.Sync), mContext.getResources().getString(R.string.DownloadingMasterData)); - final ProgressDialog finalPd = pd; - Thread t = new Thread() { - public void run() { - try { - startDownloading(); - finalPd.dismiss(); - - ((Activity) mContext).runOnUiThread(() -> { - ShowDialog(mContext.getResources().getString(R.string.DataDownloadedSuccess)); - Global global = Global.getGlobal(); - global.setOfficerCode(""); -// Intent refresh = new Intent(mContext, MainActivity.class); -// ((MainActivity)mContext).startActivity(refresh); -// ((MainActivity)mContext).finish(); - ((MainActivity) mContext).ShowEnrolmentOfficerDialog(); - }); + ProgressDialog pd = ProgressDialog.show(mContext, mContext.getResources().getString(R.string.Sync), mContext.getResources().getString(R.string.DownloadingMasterData)); + new Thread(() -> { + try { + startDownloading(); - } catch (JSONException e) { - //e.printStackTrace(); - finalPd.dismiss(); - } catch (UserException e) { - //e.printStackTrace(); - finalPd.dismiss(); - } + ((Activity) mContext).runOnUiThread(() -> { + ShowDialog(mContext.getResources().getString(R.string.DataDownloadedSuccess)); + Global global = Global.getGlobal(); + global.setOfficerCode(""); + ((MainActivity) mContext).ShowEnrolmentOfficerDialog(); + }); + } catch (JSONException e) { + Log.e("MASTERDATA", "Error while parsing master data", e); + } catch (UserException e) { + Log.e("MASTERDATA", "Error while downloading master data", e); + ((Activity) mContext).runOnUiThread(() -> { + AndroidUtils.showDialog(mContext, + mContext.getResources().getString(R.string.DataDownloadedFailed), + e.getMessage()); + }); + } finally { + pd.dismiss(); } - }; - t.start(); - - - //return true; - // finally { -// pd.dismiss(); -// } - - + }).start(); } public void importMasterData(String data) throws JSONException, UserException { @@ -4749,17 +4446,19 @@ public void importMasterData(String data) throws JSONException, UserException { } } - @SuppressWarnings("ConstantConditions") + public void startDownloading() throws JSONException, UserException { ToRestApi rest = new ToRestApi(); - String MD = rest.getObjectFromRestApi("master"); - - JSONObject masterData = new JSONObject(MD); - - if (masterData.length() == 0) - throw new UserException(mContext.getResources().getString(R.string.DownloadMasterDataFailed)); + HttpResponse response = rest.getFromRestApi("master"); + String error = rest.getHttpError(mContext, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + if (error == null) { + String MD = rest.getContent(response); + JSONObject masterData = new JSONObject(MD); - processNewFormat(masterData); + processNewFormat(masterData); + } else { + throw new UserException(error); + } } private void processOldFormat(JSONArray masterData) throws UserException { @@ -5164,22 +4863,14 @@ public static void setInsuranceNo(String insuranceNo) { } @JavascriptInterface - public String getScannedNumber() { - //clearInsuranceNo(); - //clearXml(); + public void getScannedNumber() { Intent intent = new Intent("com.google.zxing.client.android.SCAN"); intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); try { - ((Activity) mContext).startActivityForResult(intent, 100); - ((MainActivity) mContext).InsureeNumber = ""; - while (((MainActivity) mContext).InsureeNumber == "") { - - } + ((Activity) mContext).startActivityForResult(intent, RESULT_SCAN); } catch (Exception e) { - e.printStackTrace(); + Log.e("ENROL", "Error while trying to initiate QR scan", e); } - - return ((MainActivity) mContext).InsureeNumber; } @JavascriptInterface @@ -5475,12 +5166,7 @@ public void UpdateInsureePolicy(int PolicyId) {//herman new public File[] getPhotos() { String path = mContext.getApplicationInfo().dataDir + "/Images/"; File Directory = new File(path); - FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) { - return filename.contains("0"); - } - }; + FilenameFilter filter = (dir, filename) -> filename.contains("0"); File[] newFiles = Directory.listFiles(filter); return Directory.listFiles(filter); } @@ -5491,63 +5177,53 @@ public void UploadPhotos() throws JSONException { pd = new ProgressDialog(mContext); pd = ProgressDialog.show(mContext, "", mContext.getResources().getString(R.string.Uploading)); - new Thread() { - public void run() { + new Thread(() -> { // try { // Thread.sleep(10000); // } catch (InterruptedException e) { // e.printStackTrace(); // } - File[] Photo = getPhotos(); - - if (Photo.length > 0) { - UploadFile uf = new UploadFile(); - if (uf.isValidFTPCredentials()) { - for (int i = 0; i < Photo.length; i++) { - UploadCounter = i + 1; - String FileName = Photo[i].toString().substring(Photo[i].toString().lastIndexOf("/") + 1); - String PhotoQuery = "SELECT PhotoPath FROM tblInsuree WHERE isOffline = 1 AND REPLACE(PhotoPath, RTRIM(PhotoPath, REPLACE(PhotoPath, '/', '')), '') = '" + FileName + "'"; - JSONArray jsonArray = sqlHandler.getResult(PhotoQuery, null); - JSONObject jsonObject = null; - String PhotoPath = ""; - if (jsonArray.length() > 0) { - try { - jsonObject = jsonArray.getJSONObject(0); - PhotoPath = jsonObject.getString("PhotoPath"); - } catch (JSONException e) { - e.printStackTrace(); - } + File[] Photo = getPhotos(); + + if (Photo.length > 0) { + UploadFile uf = new UploadFile(); + if (uf.isValidFTPCredentials()) { + for (int i = 0; i < Photo.length; i++) { + String FileName = Photo[i].toString().substring(Photo[i].toString().lastIndexOf("/") + 1); + String PhotoQuery = "SELECT PhotoPath FROM tblInsuree WHERE isOffline = 1 AND REPLACE(PhotoPath, RTRIM(PhotoPath, REPLACE(PhotoPath, '/', '')), '') = '" + FileName + "'"; + JSONArray jsonArray = sqlHandler.getResult(PhotoQuery, null); + JSONObject jsonObject = null; + String PhotoPath = ""; + if (jsonArray.length() > 0) { + try { + jsonObject = jsonArray.getJSONObject(0); + PhotoPath = jsonObject.getString("PhotoPath"); + } catch (JSONException e) { + e.printStackTrace(); } - if (PhotoPath.trim().length() == 0) { - if (uf.uploadFileToServer(mContext, Photo[i], "com.imispolicies.imis.enrollment")) { - RegisterUploadDetails(FileName); - Uploaded = 1; - Photo[i].delete(); - } + } + if (PhotoPath.trim().length() == 0) { + if (uf.uploadFileToServer(mContext, Photo[i], "com.imispolicies.imis.enrollment")) { + RegisterUploadDetails(FileName); + Uploaded = 1; + Photo[i].delete(); } } } - - } else { - Uploaded = 0; } - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - if (Uploaded == 1) { - ShowDialog(mContext.getResources().getString(R.string.PhotosUploaded)); - } else { - ShowDialog(mContext.getResources().getString(R.string.NoPhoto)); - } - } - - }); - - pd.dismiss(); - + } else { + Uploaded = 0; } - }.start(); + ((Activity) mContext).runOnUiThread(() -> { + if (Uploaded == 1) { + ShowDialog(mContext.getResources().getString(R.string.PhotosUploaded)); + } else { + ShowDialog(mContext.getResources().getString(R.string.NoPhoto)); + } + }); + pd.dismiss(); + }).start(); } private SecretKeySpec generateKey(String encPassword) throws Exception { @@ -5627,58 +5303,54 @@ public void BackToDefaultRarPassword() { public int ModifyFamily(final String InsuranceNumber) { IsFamilyAvailable = 0; inProgress = true; - String Query = "SELECT * FROM tblInsuree WHERE Trim(CHFID) = '" + InsuranceNumber + "'"; - JSONArray JsonInsNo = sqlHandler.getResult(Query, null); - if (JsonInsNo.length() > 0) { - IsFamilyAvailable = 2; - inProgress = false; + int insureeCount = sqlHandler.getCount("tblInsuree", "Trim(CHFID) = ?", new String[]{InsuranceNumber}); + if (insureeCount > 0) { + ShowDialog(mContext.getResources().getString(R.string.FamilyExists)); } else { try { ToRestApi rest = new ToRestApi(); - String MD = rest.getObjectFromRestApiToken("family/" + InsuranceNumber.trim()); - if (!isEmpty(MD)) { - JSONObject FamilyData = new JSONObject(MD); - if (FamilyData.length() == 0) { - IsFamilyAvailable = 0; - } else { - DownloadFamilyData(FamilyData); + HttpResponse response = rest.getFromRestApiToken("family/" + InsuranceNumber.trim()); + String error = rest.getHttpError(mContext, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); + String content = rest.getContent(response); + + if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + ShowDialog(mContext.getResources().getString(R.string.InsuranceNumberNotFound)); + } else if (!StringUtils.isEmpty(error)) { + ShowDialog(error); + } else if (StringUtils.isEmpty(content)) { + ShowDialog(mContext.getResources().getString(R.string.SomethingWrongServer)); + } else { + JSONObject FamilyData = new JSONObject(content); + if (FamilyData.length() != 0) { + parseFamilyData(FamilyData); IsFamilyAvailable = 1; + } else { + ShowDialog(mContext.getResources().getString(R.string.InsuranceNumberNotFound)); } } - inProgress = false; - } catch (JSONException e) { - inProgress = false; - e.printStackTrace(); - } catch (UserException e) { - inProgress = false; - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - while (inProgress) { + } catch (JSONException | UserException | IOException e) { + Log.e("MODIFYFAMILY", "Error while downloading a family", e); } } - inProgress = false; return IsFamilyAvailable; } - private void DownloadFamilyData(JSONObject FamilyData) throws JSONException, UserException, IOException { + private void parseFamilyData(JSONObject familyData) throws JSONException, UserException, IOException { JSONArray newFamilyArr = new JSONArray(); JSONArray newInsureeArr = new JSONArray(); - FamilyData.put("familyId", "-" + FamilyData.getString("familyId")); - FamilyData.put("insureeId", "-" + FamilyData.getString("insureeId")); + familyData.put("familyId", "-" + familyData.getString("familyId")); + familyData.put("insureeId", "-" + familyData.getString("insureeId")); // Copy oryginal object - JSONObject cloneFamilyData = new JSONObject(FamilyData.toString()); + JSONObject cloneFamilyData = new JSONObject(familyData.toString()); JSONArray Insuree = (JSONArray) cloneFamilyData.get("insurees"); - String familyUUID = FamilyData.getString("familyUUID"); - String familyId = FamilyData.getString("familyId"); + String familyUUID = familyData.getString("familyUUID"); + String familyId = familyData.getString("familyId"); // Add familyUUID to Insuree for (int i = 0; i < Insuree.length(); i++) { @@ -5723,24 +5395,27 @@ private void DownloadFamilyData(JSONObject FamilyData) throws JSONException, Use for (int i = 0; i < newInsureeArr.length(); i++) { JSONObject insureeObj = newInsureeArr.getJSONObject(i); - if (!isStringEmpty(insureeObj, "photoPath", true)) { - String photoName = insureeObj.getString("photoPath"); - String imagePath = global.getImageFolder() + photoName; - insureeObj.put("photoPath", imagePath); - OutputStream imageOutputStream = new FileOutputStream(imagePath); - if (!isStringEmpty(insureeObj, "photoBase64", true)) { - try { - byte[] imageBytes = Base64.decode(insureeObj.getString("photoBase64").getBytes(), Base64.DEFAULT); - Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); - image.compress(Bitmap.CompressFormat.JPEG, 100, imageOutputStream); - } catch (Exception e) { - Log.e("MODIFYFAMILY", "Error while processing Base64 image", e); - } - } else { - if (photoName.length() > 0) { - String photoUrl = String.format("%sImages/Updated/%s", AppInformation.DomainInfo.getDomain(), photoName); - imageTarget = new OutputStreamImageTarget(imageOutputStream, 100); - ((Activity) mContext).runOnUiThread(() -> picassoInstance.load(photoUrl).into(imageTarget)); + if (!JsonUtils.isStringEmpty(insureeObj, "photoPath", true)) { + String[] photoPathSegments = insureeObj.getString("photoPath").split("[\\\\/]"); + String photoName = photoPathSegments[photoPathSegments.length - 1]; + if (!StringUtils.isEmpty(photoName)) { + String imagePath = global.getImageFolder() + photoName; + insureeObj.put("photoPath", imagePath); + OutputStream imageOutputStream = new FileOutputStream(imagePath); + if (!JsonUtils.isStringEmpty(insureeObj, "photoBase64", true)) { + try { + byte[] imageBytes = Base64.decode(insureeObj.getString("photoBase64").getBytes(), Base64.DEFAULT); + Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); + image.compress(Bitmap.CompressFormat.JPEG, 100, imageOutputStream); + } catch (Exception e) { + Log.e("MODIFYFAMILY", "Error while processing Base64 image", e); + } + } else { + if (photoName.length() > 0) { + String photoUrl = String.format("%sImages/Updated/%s", AppInformation.DomainInfo.getDomain(), photoName); + imageTarget = new OutputStreamImageTarget(imageOutputStream, 100); + ((Activity) mContext).runOnUiThread(() -> picassoInstance.load(photoUrl).into(imageTarget)); + } } } } @@ -5761,7 +5436,7 @@ private boolean InsertFamilyDataFromOnline(JSONArray jsonArray) throws JSONExcep "familyAddress", "ethnicity", "confirmationNo", "confirmationType"}; sqlHandler.insertData("tblFamilies", Columns, jsonArray.toString(), ""); - if (!Util.JsonUtil.isStringEmpty(object, "familySMS", true)) { + if (!JsonUtils.isStringEmpty(object, "familySMS", true)) { JSONObject smsData = object.getJSONObject("familySMS"); try { addOrUpdateFamilySms(object.getInt("familyId"), @@ -6166,71 +5841,66 @@ public boolean CheckInternetAvailable() { public void LoginDialogBox(final String page) { - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - // check internet connection - if (!CheckInternetAvailable()) - return; - // get prompts.xml view - LayoutInflater li = LayoutInflater.from(mContext); - View promptsView = li.inflate(R.layout.login_dialog, null); - - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); - - // set prompts.xml to alertdialog builder - alertDialogBuilder.setView(promptsView); - - final TextView username = (TextView) promptsView.findViewById(R.id.UserName); - final TextView password = (TextView) promptsView.findViewById(R.id.Password); - - // set dialog message - alertDialogBuilder - .setCancelable(false) - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (!username.getText().toString().equals("") || !password.getText().toString().equals("")) { - boolean isUserLogged = false; - isUserLogged = LoginToken(username.getText().toString(), password.getText().toString()); - - if (isUserLogged) { - if (page.equals("Enquire")) { - ((Enquire) mContext).finish(); - Intent intent = new Intent(mContext, Enquire.class); - mContext.startActivity(intent); - } - if (page.equals("Renewals")) { - ((RenewList) mContext).finish(); - Intent intent = new Intent(mContext, RenewList.class); - mContext.startActivity(intent); - } - if (page.equals("Feedbacks")) { - ((FeedbackList) mContext).finish(); - Intent intent = new Intent(mContext, FeedbackList.class); - mContext.startActivity(intent); - } - if (page.equals("Reports")) { - ((FeedbackList) mContext).finish(); - Intent intent = new Intent(mContext, Reports.class); - mContext.startActivity(intent); - } - - } else { - ShowDialog(mContext.getResources().getString(R.string.LoginFail)); - } - } else { - Toast.makeText(mContext, "Please enter user name and password", Toast.LENGTH_LONG).show(); + ((Activity) mContext).runOnUiThread(() -> { + // check internet connection + if (!CheckInternetAvailable()) + return; + // get prompts.xml view + LayoutInflater li = LayoutInflater.from(mContext); + View promptsView = li.inflate(R.layout.login_dialog, null); + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); + + // set prompts.xml to alertdialog builder + alertDialogBuilder.setView(promptsView); + + final TextView username = promptsView.findViewById(R.id.UserName); + final TextView password = promptsView.findViewById(R.id.Password); + + // set dialog message + alertDialogBuilder + .setCancelable(false) + .setPositiveButton("OK", + (dialog, id) -> { + if (!username.getText().toString().equals("") || !password.getText().toString().equals("")) { + boolean isUserLogged = false; + isUserLogged = LoginToken(username.getText().toString(), password.getText().toString()); + + if (isUserLogged) { + if (page.equals("Enquire")) { + ((Enquire) mContext).finish(); + Intent intent = new Intent(mContext, Enquire.class); + mContext.startActivity(intent); } + if (page.equals("Renewals")) { + ((RenewList) mContext).finish(); + Intent intent = new Intent(mContext, RenewList.class); + mContext.startActivity(intent); + } + if (page.equals("Feedbacks")) { + ((FeedbackList) mContext).finish(); + Intent intent = new Intent(mContext, FeedbackList.class); + mContext.startActivity(intent); + } + if (page.equals("Reports")) { + ((FeedbackList) mContext).finish(); + Intent intent = new Intent(mContext, Reports.class); + mContext.startActivity(intent); + } + + } else { + ShowDialog(mContext.getResources().getString(R.string.LoginFail)); } - }); + } else { + Toast.makeText(mContext, "Please enter user name and password", Toast.LENGTH_LONG).show(); + } + }); - // create alert dialog - AlertDialog alertDialog = alertDialogBuilder.create(); + // create alert dialog + AlertDialog alertDialog = alertDialogBuilder.create(); - // show it - alertDialog.show(); - } + // show it + alertDialog.show(); }); } @@ -6347,7 +6017,7 @@ public boolean isLoggingEnabled() { @JavascriptInterface public void clearLogs() { - Util.AndroidUtil.showConfirmDialog( + AndroidUtils.showConfirmDialog( mContext, R.string.ConfirmClearLogs, (d, i) -> new Thread(Log::deleteLogFiles).start() @@ -6356,10 +6026,10 @@ public void clearLogs() { @JavascriptInterface public void exportLogs() { - Util.AndroidUtil.showConfirmDialog( + AndroidUtils.showConfirmDialog( mContext, R.string.ConfirmExportLogs, - (d, i) -> new Thread(Log::zipLogFiles).start() + (d, i) -> new Thread(() -> Log.zipLogFiles(mContext)).start() ); } } diff --git a/app/src/main/java/org/openimis/imispolicies/Compressor.java b/app/src/main/java/org/openimis/imispolicies/Compressor.java deleted file mode 100644 index c4ecf399..00000000 --- a/app/src/main/java/org/openimis/imispolicies/Compressor.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.openimis.imispolicies; - -import net.lingala.zip4j.core.ZipFile; -import net.lingala.zip4j.model.ZipParameters; -import net.lingala.zip4j.util.Zip4jConstants; - -import java.io.File; -import java.util.ArrayList; - -public class Compressor { - public static void zip(ArrayList targetPath, String destinationFilePath, String password) { - try { - ZipParameters parameters = new ZipParameters(); - parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); - parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); - - if (password.length() > 0) { - parameters.setEncryptFiles(true); - parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); - parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); - parameters.setPassword(password); - } - - ZipFile zipFile = new ZipFile(destinationFilePath); - zipFile.addFiles(targetPath, parameters); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void zip(String targetPath, String destinationFilePath, String password) { - try { - ZipParameters parameters = new ZipParameters(); - parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); - parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); - - if (password.length() > 0) { - parameters.setEncryptFiles(true); - parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); - parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); - parameters.setPassword(password); - } - - ZipFile zipFile = new ZipFile(destinationFilePath); - - File targetFile = new File(targetPath); - if (targetFile.exists()) { - zipFile.addFile(targetFile, parameters); - } else if (targetFile.isDirectory()) { - zipFile.addFolder(targetFile, parameters); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void unzip(String targetZipFilePath, String destinationFolderPath, String password) { - try { - ZipFile zipFile = new ZipFile(targetZipFilePath); - if (zipFile.isEncrypted()) { - zipFile.setPassword(password); - } - zipFile.extractAll(destinationFolderPath); - - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/main/java/org/openimis/imispolicies/ControlNumberService.java b/app/src/main/java/org/openimis/imispolicies/ControlNumberService.java index d5c6e296..b80dc323 100644 --- a/app/src/main/java/org/openimis/imispolicies/ControlNumberService.java +++ b/app/src/main/java/org/openimis/imispolicies/ControlNumberService.java @@ -4,16 +4,17 @@ import android.content.ContentValues; import android.content.Intent; import android.content.Context; + import org.openimis.imispolicies.tools.Log; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.openimis.imispolicies.tools.Util; +import org.openimis.imispolicies.util.StringUtils; import java.io.IOException; import java.net.HttpURLConnection; @@ -120,7 +121,7 @@ private void handleActionFetchBulkCN(String productCode) { JSONObject responseContent = new JSONObject(content); errorMessage = getErrorMessage(responseCode, responseContent); - if (Util.StringUtil.isEmpty(errorMessage)) { + if (StringUtils.isEmpty(errorMessage)) { JSONArray controlNumbers = responseContent.getJSONArray("controlNumbers"); insertBulkControlNumbers(controlNumbers); broadcastSuccess(); diff --git a/app/src/main/java/org/openimis/imispolicies/CumulativeIndicators.java b/app/src/main/java/org/openimis/imispolicies/CumulativeIndicators.java index bfdfaca0..888f73af 100644 --- a/app/src/main/java/org/openimis/imispolicies/CumulativeIndicators.java +++ b/app/src/main/java/org/openimis/imispolicies/CumulativeIndicators.java @@ -13,9 +13,10 @@ import android.widget.TextView; import android.widget.Toast; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONException; import org.json.JSONObject; diff --git a/app/src/main/java/org/openimis/imispolicies/CustomOnItemSelectedListener.java b/app/src/main/java/org/openimis/imispolicies/CustomOnItemSelectedListener.java index 034a1f23..2122b938 100644 --- a/app/src/main/java/org/openimis/imispolicies/CustomOnItemSelectedListener.java +++ b/app/src/main/java/org/openimis/imispolicies/CustomOnItemSelectedListener.java @@ -9,13 +9,9 @@ import android.widget.AdapterView.OnItemSelectedListener; public class CustomOnItemSelectedListener implements OnItemSelectedListener { - - OverViewPolicies overViewPolicies = new OverViewPolicies(); - SearchOverViewControlNumber searchOverViewControlNumber = new SearchOverViewControlNumber(); - public void onItemSelected(AdapterView parent, View view, int pos, long id) { - overViewPolicies.PayType = parent.getItemAtPosition(pos).toString(); - searchOverViewControlNumber.PayType = parent.getItemAtPosition(pos).toString(); + OverViewPolicies.PayType = parent.getItemAtPosition(pos).toString(); + SearchOverViewControlNumber.PayType = parent.getItemAtPosition(pos).toString(); /* Toast.makeText(parent.getContext(), "OnItemSelectedListener : " + parent.getItemAtPosition(pos).toString(), Toast.LENGTH_SHORT).show();*/ diff --git a/app/src/main/java/org/openimis/imispolicies/Enquire.java b/app/src/main/java/org/openimis/imispolicies/Enquire.java index 4916ea03..9c22215b 100644 --- a/app/src/main/java/org/openimis/imispolicies/Enquire.java +++ b/app/src/main/java/org/openimis/imispolicies/Enquire.java @@ -53,16 +53,17 @@ import com.squareup.picasso.Picasso; +import cz.msebera.android.httpclient.HttpResponse; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.openimis.imispolicies.util.JsonUtils; import java.io.ByteArrayInputStream; +import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.HashMap; -import static org.openimis.imispolicies.tools.Util.JsonUtil.isStringEmpty; - public class Enquire extends AppCompatActivity { private static final String LOG_TAG = "ENQUIRE"; private static final int REQUEST_SCAN_QR_CODE = 1; @@ -75,6 +76,7 @@ public class Enquire extends AppCompatActivity { private TextView tvName; private TextView tvGender; private TextView tvDOB; + private TextView tvPolicyStatus; private ListView lv; private ImageView iv; private LinearLayout ll; @@ -106,6 +108,7 @@ protected void onCreate(Bundle savedInstanceState) { tvCHFID = findViewById(R.id.tvCHFID); tvName = findViewById(R.id.tvName); tvDOB = findViewById(R.id.tvDOB); + tvPolicyStatus = findViewById(R.id.tvPolicyStatus); tvGender = findViewById(R.id.tvGender); iv = findViewById(R.id.imageView); ImageButton btnGo = findViewById(R.id.btnGo); @@ -186,6 +189,7 @@ private void ClearForm() { tvCHFID.setText(getResources().getString(R.string.InsuranceNumber)); tvName.setText(getResources().getString(R.string.InsureeName)); tvDOB.setText(getResources().getString(R.string.BirthDate)); + tvPolicyStatus.setText(getResources().getString(R.string.EnquirePolicyLabel)); tvGender.setText(getResources().getString(R.string.Gender)); iv.setImageResource(R.drawable.person); ll.setVisibility(View.INVISIBLE); @@ -198,20 +202,28 @@ private void getInsureeInfo() { result = ""; if (global.isNetworkAvailable()) { - ToRestApi rest = new ToRestApi(); - String res = rest.getObjectFromRestApiToken("insuree/" + chfid + "/enquire"); - - JSONObject jobj = new JSONObject(); try { - jobj = new JSONObject(res); - } catch (JSONException e) { - Log.e(LOG_TAG, "Response is not a proper JSON", e); - } - - JSONArray arr = new JSONArray(); - arr.put(jobj); + ToRestApi rest = new ToRestApi(); + HttpResponse response = rest.getFromRestApiToken("insuree/" + chfid + "/enquire"); + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + JSONObject obj = new JSONObject(rest.getContent(response)); + JSONArray arr = new JSONArray(); + arr.put(obj); + result = arr.toString(); + } + else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) { + // No insuree found + result="[{}]"; + } else { + result="NETWORK_ERROR"; + } - result = arr.toString(); + } + catch(Exception e){ + Log.e(LOG_TAG, "Fetching online enquire failed", e); + result="UNKNOWN_ERROR"; + } } else { //TODO: yet to be done result = getDataFromDb(etCHFID.getText().toString()); @@ -221,10 +233,18 @@ private void getInsureeInfo() { try { JSONArray jsonArray = new JSONArray(result); - if (jsonArray.length() == 0) { + if (jsonArray.getJSONObject(0).length()==0) { ca.ShowDialog(getResources().getString(R.string.RecordNotFound)); return; } + else if (jsonArray.getJSONObject(0).equals("NETWORK_ERROR")) { + ca.ShowDialog(getResources().getString(R.string.NoInternet)); + return; + } + else if (jsonArray.getJSONObject(0).equals("UNKNOWN_ERROR")) { + ca.ShowDialog(getResources().getString(R.string.UnknownError)); + return; + } ll.setVisibility(View.VISIBLE); @@ -236,12 +256,13 @@ private void getInsureeInfo() { tvCHFID.setText(jsonObject.getString("chfid")); tvName.setText(jsonObject.getString("insureeName")); tvDOB.setText(jsonObject.getString("dob")); + tvPolicyStatus.setText(getResources().getString(R.string.EnquirePolicyLabel)); tvGender.setText(jsonObject.getString("gender")); if (global.isNetworkAvailable()) { String photo_url_str = ""; try { - if (!isStringEmpty(jsonObject, "photoBase64", true)) { + if (!JsonUtils.isStringEmpty(jsonObject, "photoBase64", true)) { try { byte[] imageBytes = Base64.decode(jsonObject.getString("photoBase64").getBytes(), Base64.DEFAULT); Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); @@ -250,7 +271,7 @@ private void getInsureeInfo() { Log.e(LOG_TAG, "Error while processing Base64 image", e); iv.setImageDrawable(getResources().getDrawable(R.drawable.person)); } - } else if (!isStringEmpty(jsonObject, "photoPath", true)) { + } else if (!JsonUtils.isStringEmpty(jsonObject, "photoPath", true)) { photo_url_str = AppInformation.DomainInfo.getDomain() + jsonObject.getString("photoPath"); iv.setImageResource(R.drawable.person); picasso.load(photo_url_str) @@ -276,31 +297,26 @@ private void getInsureeInfo() { jsonArray = jsonObject.getJSONArray("details"); - for (i = 0; i < jsonArray.length(); i++) { - jsonObject = jsonArray.getJSONObject(i); - + if (jsonArray.length() == 1 && jsonArray.getJSONObject(0).getString("expiryDate").equals("null")) { + tvPolicyStatus.setText(getResources().getString(R.string.EnquirePolicyNotCovered)); + } else { + tvPolicyStatus.setText(getResources().getString(R.string.EnquirePolicyCovered)); + } + for (i = 0; i < jsonArray.length(); i++) { HashMap Policy = new HashMap<>(); jsonObject = jsonArray.getJSONObject(i); - double iDedType = 0; - if (!jsonObject.getString("dedType").equalsIgnoreCase("null")) - iDedType = Double.parseDouble(jsonObject.getString("dedType")); + double iDedType = Double.parseDouble(JsonUtils.getStringOrDefault(jsonObject, "dedType", "0", true)); String Ded = "", Ded1 = "", Ded2 = ""; String Ceiling = "", Ceiling1 = "", Ceiling2 = ""; - String jDed1 = "", jDed2 = "", jCeiling1 = "", jCeiling2 = ""; + String jDed1, jDed2, jCeiling1, jCeiling2; - if (jsonObject.getString("ded1").equalsIgnoreCase("null")) jDed1 = ""; - else jDed1 = jsonObject.getString("ded1"); - if (jsonObject.getString("ded2").equalsIgnoreCase("null")) jDed2 = ""; - else jDed2 = jsonObject.getString("ded2"); - if (jsonObject.getString("ceiling1").equalsIgnoreCase("null")) - jCeiling1 = ""; - else jCeiling1 = jsonObject.getString("ceiling1"); - if (jsonObject.getString("ceiling2").equalsIgnoreCase("null")) - jCeiling2 = ""; - else jCeiling2 = jsonObject.getString("ceiling2"); + jDed1 = JsonUtils.getStringOrDefault(jsonObject, "ded1", "", true); + jDed2 = JsonUtils.getStringOrDefault(jsonObject, "ded2", "", true); + jCeiling1 = JsonUtils.getStringOrDefault(jsonObject, "ceiling1", "", true); + jCeiling2 = JsonUtils.getStringOrDefault(jsonObject, "ceiling2", "", true); //Get the type @@ -326,12 +342,15 @@ private void getInsureeInfo() { } - - Policy.put("Heading", jsonObject.getString("productCode")); - Policy.put("Heading1", jsonObject.getString("expiryDate") + " " + jsonObject.getString("status")); - Policy.put("SubItem1", jsonObject.getString("productName")); - Policy.put("SubItem2", Ded); - Policy.put("SubItem3", Ceiling); + if (JsonUtils.isStringEmpty(jsonObject, "expiryDate", true)) { + Policy.put("Heading", getResources().getString(R.string.EnquireNoPolicies)); + } else { + Policy.put("Heading", jsonObject.getString("productCode")); + Policy.put("Heading1", JsonUtils.getStringOrDefault(jsonObject, "expiryDate", "", true) + " " + jsonObject.getString("status")); + Policy.put("SubItem1", jsonObject.getString("productName")); + Policy.put("SubItem2", Ded); + Policy.put("SubItem3", Ceiling); + } String TotalAdmissionsLeft = buildEnquireValue(jsonObject, "totalAdmissionsLeft", R.string.totalAdmissionsLeft); String TotalVisitsLeft = buildEnquireValue(jsonObject, "totalVisitsLeft", R.string.totalVisitsLeft); @@ -401,7 +420,6 @@ private void getInsureeInfo() { result = ""; } }); - } protected String buildEnquireValue(JSONObject jsonObject, String jsonKey, int labelId) throws JSONException { diff --git a/app/src/main/java/org/openimis/imispolicies/Feedback.java b/app/src/main/java/org/openimis/imispolicies/Feedback.java index f063224d..851cd48c 100644 --- a/app/src/main/java/org/openimis/imispolicies/Feedback.java +++ b/app/src/main/java/org/openimis/imispolicies/Feedback.java @@ -38,7 +38,9 @@ import org.json.JSONException; import org.json.JSONObject; +import org.openimis.imispolicies.tools.Log; import org.xmlpull.v1.XmlSerializer; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -47,6 +49,7 @@ import java.util.Calendar; public class Feedback extends AppCompatActivity { + private static final String LOG_TAG = "FEEDBACK"; private Global global; private EditText etOfficer; @@ -107,53 +110,47 @@ protected void onCreate(Bundle savedInstanceState) { pd = ProgressDialog.show(Feedback.this, "", getResources().getString(R.string.UploadingFeedback)); final String[] feed = {null}; - new Thread() { - public void run() { - String Answers = Answers(); - try { - feed[0] = WriteJSON(String.valueOf(etOfficer.getText()), ClaimUUID, etCHFID.getText().toString(), Answers); - WriteXML(String.valueOf(etOfficer.getText()), ClaimUUID, etCHFID.getText().toString(), Answers); - } catch (IllegalArgumentException | IllegalStateException e) { - e.printStackTrace(); - return; - } catch (IOException e) { - e.printStackTrace(); - return; - } - - msgType = 3; - - runOnUiThread(() -> { - switch (msgType) { - case 1: - DeleteRow(ClaimUUID); - //ca.ShowDialog(getResources().getString(R.string.UploadedSuccessfully)); - Toast.makeText(getApplicationContext(), getResources().getString(R.string.UploadedSuccessfully), Toast.LENGTH_LONG).show(); - break; - case 2: - DeleteRow(ClaimUUID); - //ca. ShowDialog(getResources().getString(R.string.ServerRejected)); - Toast.makeText(getApplicationContext(), getResources().getString(R.string.ServerRejected), Toast.LENGTH_LONG).show(); - break; - case 3: - UpdateRow(ClaimUUID); - //ca. ShowDialog(getResources().getString(R.string.SavedOnSDCard)); - Toast.makeText(getApplicationContext(), getResources().getString(R.string.SavedOnSDCard), Toast.LENGTH_LONG).show(); - break; - case -1: - //ca. ShowDialog(getResources().getString(R.string.FeedBackNotUploaded)); - Toast.makeText(getApplicationContext(), getResources().getString(R.string.FeedBackNotUploaded), Toast.LENGTH_LONG).show(); - break; - } - finish(); - }); - pd.dismiss(); + new Thread(() -> { + String Answers = Answers(); + try { + feed[0] = WriteJSON(String.valueOf(etOfficer.getText()), ClaimUUID, etCHFID.getText().toString(), Answers); + WriteXML(String.valueOf(etOfficer.getText()), ClaimUUID, etCHFID.getText().toString(), Answers); + } catch (IllegalArgumentException | IllegalStateException | IOException e) { + e.printStackTrace(); + return; } - }.start(); + + msgType = 3; + + runOnUiThread(() -> { + switch (msgType) { + case 1: + DeleteRow(ClaimUUID); + //ca.ShowDialog(getResources().getString(R.string.UploadedSuccessfully)); + Toast.makeText(getApplicationContext(), getResources().getString(R.string.UploadedSuccessfully), Toast.LENGTH_LONG).show(); + break; + case 2: + DeleteRow(ClaimUUID); + //ca. ShowDialog(getResources().getString(R.string.ServerRejected)); + Toast.makeText(getApplicationContext(), getResources().getString(R.string.ServerRejected), Toast.LENGTH_LONG).show(); + break; + case 3: + UpdateRow(ClaimUUID); + //ca. ShowDialog(getResources().getString(R.string.SavedOnSDCard)); + Toast.makeText(getApplicationContext(), getResources().getString(R.string.SavedOnSDCard), Toast.LENGTH_LONG).show(); + break; + case -1: + //ca. ShowDialog(getResources().getString(R.string.FeedBackNotUploaded)); + Toast.makeText(getApplicationContext(), getResources().getString(R.string.FeedBackNotUploaded), Toast.LENGTH_LONG).show(); + break; + } + finish(); + }); + pd.dismiss(); + }).start(); }); } - private void DeleteRow(String ClaimUUID) { ca.CleanFeedBackTable(ClaimUUID); } @@ -162,10 +159,9 @@ private void UpdateRow(String ClaimUUID) { ca.UpdateFeedBack(ClaimUUID); } - private void WriteXML(String Officer, String ClaimUUID, String CHFID, String Answers) throws IllegalArgumentException, IllegalStateException, IOException { - File MyDir = new File(global.getMainDirectory()); - FileName = "feedback_" + etClaimCode.getText() + ".xml"; + File MyDir = new File(global.getSubdirectory("Feedback")); + FileName = "Feedback_" + etClaimCode.getText() + ".xml"; FeedbackXML = new File(MyDir, FileName); FileOutputStream fos = new FileOutputStream(FeedbackXML); @@ -203,16 +199,14 @@ private void WriteXML(String Officer, String ClaimUUID, String CHFID, String Ans serializer.endDocument(); serializer.flush(); fos.close(); - - } private String WriteJSON(String Officer, String ClaimUUID, String CHFID, String Answers) { - File MyDir = new File(global.getMainDirectory()); + File MyDir = new File(global.getSubdirectory("Feedback")); SimpleDateFormat format = AppInformation.DateTimeInfo.getDefaultDateFormatter(); Calendar cal = Calendar.getInstance(); String d = format.format(cal.getTime()); - FileName = "feedbackJSON_" + etClaimCode.getText() + ".txt"; + FileName = "FeedbackJSON_" + etClaimCode.getText() + ".json"; FeedbackJSON = new File(MyDir, FileName); JSONObject FullObject = new JSONObject(); @@ -238,27 +232,13 @@ private String WriteJSON(String Officer, String ClaimUUID, String CHFID, String e.printStackTrace(); } - } catch (IllegalStateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); + } catch (IllegalStateException | JSONException e) { + Log.e(LOG_TAG, "Error while writing feedback file", e); } return FullObject.toString(); } - private void MoveFile(File file) { - switch (msgType) { - case 1: - file.renameTo(new File(global.getSubdirectory("AcceptedFeedback"), file.getName())); - break; - case 2: - file.renameTo(new File(global.getSubdirectory("RejectedFeedback"), file.getName())); - break; - } - } - private String Answers() { String Ans = ""; rg1 = findViewById(R.id.radioGroup1); diff --git a/app/src/main/java/org/openimis/imispolicies/FeedbackList.java b/app/src/main/java/org/openimis/imispolicies/FeedbackList.java index ac813bae..1ce1ec8f 100644 --- a/app/src/main/java/org/openimis/imispolicies/FeedbackList.java +++ b/app/src/main/java/org/openimis/imispolicies/FeedbackList.java @@ -131,25 +131,20 @@ protected void onCreate(Bundle savedInstanceState) { etFeedbackSearch.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - ((SimpleAdapter) adapter).getFilter().filter(s); - } @Override public void afterTextChanged(Editable s) { - } }); lv.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { - } @Override @@ -218,7 +213,7 @@ private void fillFeedbacks() { } public String getMasterDataText(String filename) { - ca.unZipFeedbacksRenewals(filename); + //ca.unZipFeedbacksRenewals(filename); String fname = filename.substring(0, filename.indexOf(".")); try { String dir = global.getSubdirectory("Database"); @@ -333,40 +328,33 @@ public void openDialogForFeedbackRenewal() { private void RefreshFeedbacks() throws IOException, XmlPullParserException { if (ca.CheckInternetAvailable()) { // pd = ProgressDialog.show(this, "", getResources().getString(R.string.Loading)); - new Thread() { - public void run() { - String result = null; + new Thread(() -> { + String result = null; - try { - ToRestApi rest = new ToRestApi(); - result = rest.getObjectFromRestApiToken("feedback"); + try { + ToRestApi rest = new ToRestApi(); + result = rest.getObjectFromRestApiToken("feedback"); - if (result.equalsIgnoreCase("[]") || result == null) { - FeedbackList.clear(); - return; - } - } catch (Exception e) { - e.printStackTrace(); + if (result.equalsIgnoreCase("[]") || result == null) { + FeedbackList.clear(); + return; } + } catch (Exception e) { + e.printStackTrace(); + } - Boolean IsInserted = ca.InsertFeedbacks(result); + Boolean IsInserted = ca.InsertFeedbacks(result); - if (!IsInserted) { - ca.ShowDialog(getResources().getString(R.string.ErrorOccurred)); - } - - runOnUiThread(() -> fillFeedbacks()); + if (!IsInserted) { + ca.ShowDialog(getResources().getString(R.string.ErrorOccurred)); + } - // pd.dismiss(); - // swipe.setRefreshing(false); + runOnUiThread(() -> fillFeedbacks()); - } - }.start(); - //fillFeedbacks(); + }).start(); } else { openDialogForFeedbackRenewal(); - //Toast.makeText(this, getResources().getString(R.string.NoInternet), Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/org/openimis/imispolicies/Global.java b/app/src/main/java/org/openimis/imispolicies/Global.java index f5e22362..c2cc9763 100644 --- a/app/src/main/java/org/openimis/imispolicies/Global.java +++ b/app/src/main/java/org/openimis/imispolicies/Global.java @@ -37,35 +37,28 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; -import android.os.Build; import android.os.Environment; -import android.util.DisplayMetrics; +import org.openimis.imispolicies.tools.LanguageManager; import org.openimis.imispolicies.tools.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.openimis.imispolicies.util.StreamUtils; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; -import static org.openimis.imispolicies.BuildConfig.APP_DIR; - public class Global extends Application { private static Global GlobalContext; public static final String PREF_NAME = "CMPref"; + public static final String PREF_LANGUAGE_KEY = "Language"; public static final String PREF_LOG_TAG = "PREFS"; public static final String FILE_IO_LOG_TAG = "FILEIO"; @@ -82,7 +75,6 @@ public class Global extends Application { private String MainDirectory; private String AppDirectory; private Map SubDirectories; - private List ProtectedDirectories; public static Global getGlobal() { return GlobalContext; @@ -97,29 +89,26 @@ public void onCreate() { super.onCreate(); GlobalContext = this; SubDirectories = new HashMap<>(); - ProtectedDirectories = Arrays.asList("Authentications", "Database", "Images"); initSharedPrefsInts(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.VIBRATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.ACCESS_WIFI_STATE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.MANAGE_EXTERNAL_STORAGE}; - } else { - permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.VIBRATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.ACCESS_WIFI_STATE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE}; - } - + permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.VIBRATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.ACCESS_WIFI_STATE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE}; } private void initSharedPrefsInts() { SharedPreferences sp = getSharedPreferences(PREF_NAME, MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); try { - String text = getInputStreamText(getAssets().open("JSON/default_ints.json")); - JSONObject intDefaults = new JSONObject(text); + String text = StreamUtils.readInputStreamAsUTF8String(getAssets().open("JSON/default_ints.json")); - for (Iterator it = intDefaults.keys(); it.hasNext(); ) { - String key = it.next(); + if (text != null) { + JSONObject intDefaults = new JSONObject(text); - if (!sp.contains(key)) { - editor.putInt(key, intDefaults.getInt(key)); + for (Iterator it = intDefaults.keys(); it.hasNext(); ) { + String key = it.next(); + + if (!sp.contains(key)) { + editor.putInt(key, intDefaults.getInt(key)); + } } } } catch (IOException e) { @@ -215,12 +204,13 @@ public int isSDCardAvailable() { } } - public void changeLanguage(Context ctx, String Language) { - Resources res = ctx.getResources(); - DisplayMetrics dm = res.getDisplayMetrics(); - Configuration config = res.getConfiguration(); - config.locale = new Locale(Language.toLowerCase()); - res.updateConfiguration(config, dm); + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); +// Locale locale = LocaleUtil.getLocaleFromTag(getStoredLanguage()); +// newConfig.locale = locale; +// Locale.setDefault(locale); +// getResources().updateConfiguration(newConfig, getResources().getDisplayMetrics()); } private String createOrCheckDirectory(String path) { @@ -233,21 +223,9 @@ private String createOrCheckDirectory(String path) { } } - public String getMainDirectory() { - if (MainDirectory == null || "".equals(MainDirectory)) { - String documentsDir = createOrCheckDirectory(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString()); - MainDirectory = createOrCheckDirectory(documentsDir + File.separator + APP_DIR); - - if ("".equals(documentsDir) || "".equals(MainDirectory)) { - Log.w(FILE_IO_LOG_TAG, "Main directory could not be created"); - } - } - return MainDirectory; - } - public String getAppDirectory() { if (AppDirectory == null || "".equals(AppDirectory)) { - AppDirectory = createOrCheckDirectory(getApplicationInfo().dataDir); + AppDirectory = createOrCheckDirectory(getApplicationInfo().dataDir + File.separator); if ("".equals(AppDirectory)) { Log.w(FILE_IO_LOG_TAG, "App directory could not be created"); @@ -258,15 +236,8 @@ public String getAppDirectory() { public String getSubdirectory(String subdirectory) { if (!SubDirectories.containsKey(subdirectory) || "".equals(SubDirectories.get(subdirectory))) { - String directory; - - if (ProtectedDirectories.contains(subdirectory)) { - directory = getAppDirectory(); - } else { - directory = getMainDirectory(); - } - - String subDirPath = createOrCheckDirectory(directory + File.separator + subdirectory); + String directory = getAppDirectory(); + String subDirPath = createOrCheckDirectory(directory + subdirectory + File.separator); if ("".equals(subDirPath)) { Log.w(FILE_IO_LOG_TAG, String.format("%s directory could not be created", subdirectory)); @@ -278,32 +249,6 @@ public String getSubdirectory(String subdirectory) { return SubDirectories.get(subdirectory); } - public String getFileText(String path) { - String result = ""; - try { - InputStream inputStream = new FileInputStream(path); - result = getInputStreamText(inputStream); - } catch (IOException e) { - Log.e(FILE_IO_LOG_TAG, String.format("Creating input stream for path: %s failed", path), e); - } - return result; - } - - public String getInputStreamText(InputStream inputStream) { - String line; - StringBuilder stringBuilder = new StringBuilder(); - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append("\n"); - } - } catch (IOException e) { - Log.e(FILE_IO_LOG_TAG, "Reading text from input stream failed", e); - } - return stringBuilder.toString(); - } - public int getIntKey(String key, int defaultValue) { try { return getSharedPreferences(PREF_NAME, MODE_PRIVATE).getInt(key, defaultValue); @@ -346,7 +291,7 @@ public void setStringKey(String key, String value) { public LinkedHashMap getHFLevels() { LinkedHashMap levels = new LinkedHashMap<>(); try { - String text = getInputStreamText(getAssets().open("JSON/hflevels.json")); + String text = StreamUtils.readInputStreamAsUTF8String(getAssets().open("JSON/hflevels.json")); JSONArray root = new JSONArray(text); for (int i = 0; i < root.length(); i++) { @@ -385,13 +330,13 @@ public void grantUriPermissions(Context context, Uri uri, Intent intent, int per } } - public void sendFile(Uri uri, String mimeType) { + public void sendFile(Context context, Uri uri, String mimeType) { Intent shareExportIntent = new Intent(Intent.ACTION_SEND); shareExportIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareExportIntent.putExtra(Intent.EXTRA_STREAM, uri); shareExportIntent.setType(mimeType); Intent chooserIntent = Intent.createChooser(shareExportIntent, null); grantUriPermissions(this, uri, chooserIntent, Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(chooserIntent); + context.startActivity(chooserIntent); } } diff --git a/app/src/main/java/org/openimis/imispolicies/MainActivity.java b/app/src/main/java/org/openimis/imispolicies/MainActivity.java index 71ecd94b..cf19aa96 100644 --- a/app/src/main/java/org/openimis/imispolicies/MainActivity.java +++ b/app/src/main/java/org/openimis/imispolicies/MainActivity.java @@ -33,20 +33,20 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; -import android.os.Environment; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.text.TextUtils; + +import org.openimis.imispolicies.tools.LanguageManager; import org.openimis.imispolicies.tools.Log; + import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -65,11 +65,15 @@ import android.widget.TextView; import android.widget.Toast; +import com.google.zxing.client.android.Intents; + import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.openimis.imispolicies.tools.Util; +import org.openimis.imispolicies.util.AndroidUtils; +import org.openimis.imispolicies.util.StringUtils; +import org.openimis.imispolicies.util.UriUtils; import java.io.BufferedReader; import java.io.File; @@ -80,16 +84,15 @@ import java.io.InputStreamReader; import java.io.OutputStream; -import static android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION; - public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { public static final String LOG_TAG = "MAIN_ACTIVITY"; - private static final int REQUEST_ALL_FILES_ACCESS_CODE = 7; private static final int REQUEST_PERMISSIONS_CODE = 1; - private static final int REQUEST_PICK_MD_FILE = 4; - private static final String PREFS_NAME = "CMPref"; + private static final int REQUEST_PICK_MD_FILE = 2; + public static final int REQUEST_CREATE_ENROL_EXPORT = 3; + public static final int REQUEST_CREATE_FEEDBACK_EXPORT = 4; + public static final int REQUEST_CREATE_RENEWAL_EXPORT = 5; private NavigationView navigationView; private SQLHandler sqlHandler; @@ -98,6 +101,7 @@ public class MainActivity extends AppCompatActivity static Global global; private static final int MENU_LANGUAGE_1 = Menu.FIRST; private static final int MENU_LANGUAGE_2 = Menu.FIRST + 1; + private static final int MENU_LANGUAGE_3 = Menu.FIRST + 2; private String Language1 = ""; private String Language2 = ""; private String LanguageCode1 = ""; @@ -112,6 +116,9 @@ public class MainActivity extends AppCompatActivity String calledFrom = "java"; public File f; public String etRarPassword = ""; + private AlertDialog enrolmentOfficerDialog; + private AlertDialog masterDataDialog; + private AlertDialog permissionDialog; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -131,7 +138,10 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } wv.evaluateJavascript(String.format("selectImageCallback(\"%s\");", selectedImage), null); } else if (requestCode == ClientAndroidInterface.RESULT_SCAN && resultCode == RESULT_OK && data != null) { - this.InsureeNumber = data.getStringExtra("SCAN_RESULT"); + String insureeNumber = data.getStringExtra(Intents.Scan.RESULT); + if(!StringUtils.isEmpty(insureeNumber)) { + wv.evaluateJavascript(String.format("scanQrCallback(\"%s\");", insureeNumber), null); + } } else if (requestCode == REQUEST_PICK_MD_FILE) { if (resultCode == RESULT_OK && data != null) { Uri uri = data.getData(); @@ -150,10 +160,47 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } else { finish(); } - } else if (requestCode == REQUEST_ALL_FILES_ACCESS_CODE) { - if (checkRequirements()) { - onAllRequirementsMet(); + } else if (requestCode == REQUEST_CREATE_ENROL_EXPORT && resultCode == RESULT_OK && data != null) { + Uri fileUri = data.getData(); + + File exportFile = ca.zipEnrolmentFiles(); + if (exportFile != null) { + ca.clearDirectory("Family"); + ca.clearDirectory("Images"); + + UriUtils.copyFileToUri(this, exportFile, fileUri); + if (!exportFile.delete()) { + Log.w("EXPORT", "Deleting enrol export cache failed"); + } + AndroidUtils.showToast(this, R.string.XmlCreated); + } + } else if (requestCode == REQUEST_CREATE_RENEWAL_EXPORT && resultCode == RESULT_OK && data != null) { + Uri fileUri = data.getData(); + + File exportFile = ca.zipRenewalFiles(); + if (exportFile != null) { + ca.clearDirectory("Renewal"); + + UriUtils.copyFileToUri(this, exportFile, fileUri); + if (!exportFile.delete()) { + Log.w("EXPORT", "Deleting renewal export cache failed"); + } + AndroidUtils.showToast(this, R.string.XmlCreated); } + } else if (requestCode == REQUEST_CREATE_FEEDBACK_EXPORT && resultCode == RESULT_OK && data != null) { + Uri fileUri = data.getData(); + + File exportFile = ca.zipFeedbackFiles(); + if (exportFile != null) { + ca.clearDirectory("Feedback"); + + UriUtils.copyFileToUri(this, exportFile, fileUri); + if (!exportFile.delete()) { + Log.w("EXPORT", "Deleting feedback export cache failed"); + } + AndroidUtils.showToast(this, R.string.XmlCreated); + } + } else { //if user cancels ClientAndroidInterface.inProgress = false; @@ -173,17 +220,12 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis @Override protected void onCreate(Bundle savedInstanceState) { global = (Global) getApplicationContext(); - //Check if user has language set - SharedPreferences spHF = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); - selectedLanguage = spHF.getString("Language", "en"); - changeLanguage(selectedLanguage, false); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sqlHandler = new SQLHandler(this); sqlHandler.isPrivate = true; //Set the Image folder path - global.setImageFolder(global.getApplicationInfo().dataDir + "/Images/"); - CreateFolders(); + global.setImageFolder(global.getSubdirectory("Images")); //Check if database exists File database = global.getDatabasePath(SQLHandler.DBNAME); if (!database.exists()) { @@ -224,7 +266,6 @@ protected void onCreate(Bundle savedInstanceState) { //noinspection deprecation settings.setRenderPriority(WebSettings.RenderPriority.HIGH); settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); - settings.setAppCacheEnabled(true); settings.setDomStorageEnabled(true); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); settings.setUseWideViewPort(true); @@ -257,8 +298,7 @@ public void onReceivedTitle(WebView view, String title) { Login.setOnClickListener(v -> { wv.loadUrl("file:///android_asset/pages/Login.html?s=3"); - DrawerLayout drawer1 = findViewById(R.id.drawer_layout); - drawer1.closeDrawer(GravityCompat.START); + drawer.closeDrawer(GravityCompat.START); SetLoggedIn(getApplication().getResources().getString(R.string.Login), getApplication().getResources().getString(R.string.Logout)); }); ca = new ClientAndroidInterface(context); @@ -289,23 +329,11 @@ protected void onResume() { OfficerName.setText(global.getOfficerName()); } - public static void SetLoggedIn(String Lg, String Lo) { + public static void SetLoggedIn(String LogInText, String LogOutText) { if (global.isLoggedIn()) { - Login.setText(Lo); + Login.setText(LogOutText); } else { - Login.setText(Lg); - } - } - - public void CreateFolders() { - boolean dirsCreated = !"".equals(global.getMainDirectory()); - String[] subdirectories = {"Enrolment", "Photos", "Database", "Authentications", "AcceptedFeedback", "RejectedFeedback", "AcceptedRenewal", "RejectedRenewal", "Family", "EnrolmentXML"}; - for (String dir : subdirectories) { - dirsCreated &= !"".equals(global.getSubdirectory(dir)); - } - - if (!dirsCreated) { - Toast.makeText(getApplicationContext(), getResources().getString(R.string.ImisDirNotCreated), Toast.LENGTH_SHORT).show(); + Login.setText(LogInText); } } @@ -370,9 +398,7 @@ public void PickMasterDataFileDialogFromPage() { } // Write your code here to execute after dialog }).setNegativeButton(getResources().getString(R.string.No), - (dialog, id) -> dialog.cancel()); - - alertDialog2.show(); + (dialog, id) -> dialog.cancel()).show(); } public void ConfirmMasterDataDialog(String filename) { @@ -391,9 +417,7 @@ public void ConfirmMasterDataDialog(String filename) { (dialog, id) -> { dialog.cancel(); finish(); - }); - - alertDialog2.show(); + }).show(); } public void ConfirmDialogPage(String filename) { @@ -409,28 +433,23 @@ public void ConfirmDialogPage(String filename) { MasterDataLocalAsync masterDataLocalAsync = new MasterDataLocalAsync(); masterDataLocalAsync.execute(); }).setNegativeButton(getResources().getString(R.string.Quit), - (dialog, id) -> dialog.cancel()); - - alertDialog2.show(); + (dialog, id) -> dialog.cancel()).show(); } public void ShowEnrolmentOfficerDialog() { final ClientAndroidInterface ca = new ClientAndroidInterface(context); final int MasterData = ca.isMasterDataAvailable(); -// OfficerCode= ca.ShowDialogText() ; LayoutInflater li = LayoutInflater.from(context); @SuppressLint("InflateParams") View promptsView = li.inflate(R.layout.dialog, null); - android.support.v7.app.AlertDialog alertDialog = null; - - final android.support.v7.app.AlertDialog.Builder alertDialogBuilder = new android.support.v7.app.AlertDialog.Builder( + final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( context); alertDialogBuilder.setView(promptsView); - final EditText userInput = (EditText) promptsView.findViewById(R.id.txtOfficerCode); - final TextView tVDialogTile = (TextView) promptsView.findViewById(R.id.tvDialogTitle); + final EditText userInput = promptsView.findViewById(R.id.txtOfficerCode); + final TextView tVDialogTile = promptsView.findViewById(R.id.tvDialogTitle); if (MasterData == 0) { tVDialogTile.setText(getResources().getString(R.string.MasterDataNotFound)); @@ -447,7 +466,7 @@ public void ShowEnrolmentOfficerDialog() { negativeButton = R.string.No; } - alertDialogBuilder + enrolmentOfficerDialog = alertDialogBuilder .setCancelable(false) .setPositiveButton(getResources().getString(positiveButton), (dialog, id) -> { @@ -484,13 +503,11 @@ public void ShowEnrolmentOfficerDialog() { (dialog, id) -> { dialog.cancel(); finish(); - }); - - alertDialog = alertDialogBuilder.show(); + }).show(); } public void ShowMasterDataDialog() { - new AlertDialog.Builder(context) + masterDataDialog = new AlertDialog.Builder(context) .setTitle(R.string.MasterData) .setMessage(R.string.MasterDataNotFound) .setCancelable(false) @@ -526,7 +543,7 @@ public void ShowDialogTex2() { alertDialogBuilder.setView(promptsView); - final EditText userInput = (EditText) promptsView.findViewById(R.id.etRarPass); + final EditText userInput = promptsView.findViewById(R.id.etRarPass); alertDialogBuilder .setCancelable(false) @@ -617,7 +634,7 @@ private void createImageFolder() { @Override public void onBackPressed() { - DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + DrawerLayout drawer = findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { @@ -640,43 +657,26 @@ public boolean onCreateOptionsMenu(Menu menu) { if (!Language2.equals("")) { menu.add(0, MENU_LANGUAGE_2, 0, Language2); } + menu.add(0, MENU_LANGUAGE_3, 0, getResources().getString(R.string.LanguageSettings)); return true; } - private void changeLanguage(String LanguageCode, boolean withRefresh) { - - //General gen = new General(); - global.changeLanguage(this, LanguageCode); - - if (withRefresh) { - //Restart the activity for change to be affected - Intent refresh = new Intent(MainActivity.this, MainActivity.class); - startActivity(refresh); - finish(); - } - setPreferences(); - //OfficerName.setText(global.getOfficerName()); - } - @Override public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - switch (item.getItemId()) { case MENU_LANGUAGE_1: selectedLanguage = LanguageCode1; - changeLanguage(selectedLanguage, true); - + new LanguageManager(this).setLanguage(selectedLanguage); return true; case MENU_LANGUAGE_2: selectedLanguage = LanguageCode2; - changeLanguage(selectedLanguage, true); + new LanguageManager(this).setLanguage(selectedLanguage); + return true; + case MENU_LANGUAGE_3: + new LanguageManager(this).openLanguageSettings(); return true; } - return super.onOptionsItemSelected(item); } @@ -799,7 +799,6 @@ protected void onPostExecute(Void aVoid) { Intent refresh = new Intent(MainActivity.this, MainActivity.class); startActivity(refresh); finish(); - setPreferences(); } } @@ -830,22 +829,12 @@ protected void onPostExecute(Void aVoid) { Intent refresh = new Intent(MainActivity.this, MainActivity.class); startActivity(refresh); finish(); - setPreferences(); } } - - private void setPreferences() { - SharedPreferences Lang = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); - SharedPreferences.Editor editor = Lang.edit(); - editor.putString("Language", selectedLanguage); - editor.apply(); - } - @Override protected void onStop() { super.onStop(); - setPreferences(); } // private void CheckForUpdates() { @@ -892,27 +881,6 @@ public static boolean hasPermissions(Context context, String... permissions) { return true; } - public void externalStorageAccessDialog() { - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context) - .setTitle(R.string.ExternalStorageAccess) - .setMessage(getResources().getString(R.string.ExternalStorageAccessInfo, getResources().getString(R.string.app_name_policies))) - .setCancelable(false) - .setPositiveButton(R.string.Ok, - (dialog, id) -> { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { - Intent intent = new Intent(ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); - startActivityForResult(intent, REQUEST_ALL_FILES_ACCESS_CODE); - } - }) - .setNegativeButton(R.string.ForceClose, - (dialog, id) -> { - dialog.cancel(); - finish(); - }); - - alertDialogBuilder.show(); - } - public void PermissionsDialog() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context) .setTitle(R.string.Permissions) @@ -926,17 +894,10 @@ public void PermissionsDialog() { finish(); }); - alertDialogBuilder.show(); + permissionDialog = alertDialogBuilder.show(); } public boolean checkRequirements() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - if (!Environment.isExternalStorageManager()) { - externalStorageAccessDialog(); - return false; - } - } - if (!hasPermissions(this, global.getPermissions())) { PermissionsDialog(); return false; @@ -955,9 +916,21 @@ public void onAllRequirementsMet() { ShowEnrolmentOfficerDialog(); } global.isSDCardAvailable(); + new LanguageManager(this).checkSystemLanguage(); } public String getSelectedLanguage() { return selectedLanguage; } + + @Override + public void recreate() { + for (AlertDialog dialog : new AlertDialog[]{masterDataDialog, enrolmentOfficerDialog, permissionDialog}) { + if(dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + } + + super.recreate(); + } } diff --git a/app/src/main/java/org/openimis/imispolicies/NotEnrolledPoliciesOverview.java b/app/src/main/java/org/openimis/imispolicies/NotEnrolledPoliciesOverview.java index 5afdd17e..2630213a 100644 --- a/app/src/main/java/org/openimis/imispolicies/NotEnrolledPoliciesOverview.java +++ b/app/src/main/java/org/openimis/imispolicies/NotEnrolledPoliciesOverview.java @@ -24,9 +24,10 @@ import android.widget.Spinner; import android.widget.TextView; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -513,8 +514,7 @@ private void getControlNumber(final JSONObject order) { private void handleRequestResult(Intent intent) { if (intent.getAction().equals(ControlNumberService.ACTION_REQUEST_SUCCESS)) { policyDeleteDialogReport(getResources().getString(R.string.requestSent)); - } - else if (intent.getAction().equals(ControlNumberService.ACTION_REQUEST_ERROR)) { + } else if (intent.getAction().equals(ControlNumberService.ACTION_REQUEST_ERROR)) { String errorMessage = intent.getStringExtra(ControlNumberService.FIELD_ERROR_MESSAGE); showSnackbar(errorMessage); } @@ -527,8 +527,7 @@ public void showSnackbar(String message) { .setAction("Action", null).show(); } - public void refresh() - { + public void refresh() { finish(); startActivity(getIntent()); } diff --git a/app/src/main/java/org/openimis/imispolicies/OutputStreamImageTarget.java b/app/src/main/java/org/openimis/imispolicies/OutputStreamImageTarget.java index d3d74c9b..932a311a 100644 --- a/app/src/main/java/org/openimis/imispolicies/OutputStreamImageTarget.java +++ b/app/src/main/java/org/openimis/imispolicies/OutputStreamImageTarget.java @@ -2,6 +2,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.Drawable; + import org.openimis.imispolicies.tools.Log; import com.squareup.picasso.Picasso; @@ -13,15 +14,28 @@ public class OutputStreamImageTarget implements Target { private static final String LOG_TAG = "OSIMAGETARGET"; private final OutputStream outputStream; private final int imageQuality; + private final Runnable onSuccess; public OutputStreamImageTarget(OutputStream outputStream, int imageQuality) { this.outputStream = outputStream; this.imageQuality = imageQuality; + this.onSuccess = () -> { + }; + } + + public OutputStreamImageTarget(OutputStream outputStream, int imageQuality, Runnable onSuccess) { + this.outputStream = outputStream; + this.imageQuality = imageQuality; + this.onSuccess = onSuccess; } @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { - bitmap.compress(Bitmap.CompressFormat.JPEG, imageQuality, outputStream); + if (bitmap.compress(Bitmap.CompressFormat.JPEG, imageQuality, outputStream)) { + onSuccess.run(); + } else { + Log.e(LOG_TAG, "Compressing image failed"); + } } @Override diff --git a/app/src/main/java/org/openimis/imispolicies/OverViewControlNumbers.java b/app/src/main/java/org/openimis/imispolicies/OverViewControlNumbers.java index a0a5fb16..c75b7a69 100644 --- a/app/src/main/java/org/openimis/imispolicies/OverViewControlNumbers.java +++ b/app/src/main/java/org/openimis/imispolicies/OverViewControlNumbers.java @@ -19,9 +19,10 @@ import android.widget.TextView; import android.widget.Toast; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/app/src/main/java/org/openimis/imispolicies/OverViewPolicies.java b/app/src/main/java/org/openimis/imispolicies/OverViewPolicies.java index b3ee2d8f..5788939e 100644 --- a/app/src/main/java/org/openimis/imispolicies/OverViewPolicies.java +++ b/app/src/main/java/org/openimis/imispolicies/OverViewPolicies.java @@ -23,9 +23,10 @@ import android.widget.Spinner; import android.widget.TextView; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -41,8 +42,8 @@ import android.widget.Toast; public class OverViewPolicies extends AppCompatActivity { - private Global global; - private JSONArray policy; + private Global global; + private JSONArray policy; private ClientAndroidInterface clientAndroidInterface; private RecyclerView PolicyRecyclerView; private OverViewPoliciesAdapter overViewPoliciesAdapter; diff --git a/app/src/main/java/org/openimis/imispolicies/RenewList.java b/app/src/main/java/org/openimis/imispolicies/RenewList.java index 97b2936d..12b983d5 100644 --- a/app/src/main/java/org/openimis/imispolicies/RenewList.java +++ b/app/src/main/java/org/openimis/imispolicies/RenewList.java @@ -36,7 +36,10 @@ import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextWatcher; + +import org.openimis.imispolicies.tools.LanguageManager; import org.openimis.imispolicies.tools.Log; + import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -50,18 +53,15 @@ import android.widget.TextView; import android.widget.Toast; -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; +import cz.msebera.android.httpclient.HttpResponse; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.openimis.imispolicies.tools.Util; +import org.openimis.imispolicies.util.FileUtils; +import org.openimis.imispolicies.util.UriUtils; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; import java.net.HttpURLConnection; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -70,9 +70,8 @@ public class RenewList extends AppCompatActivity { private static final String LOG_TAG = "RENEWAL"; - private static final int REQUEST_OPEN_DOCUMENT_CODE = 1; + private static final int REQUEST_IMPORT_RENEWAL_FILE = 1; private Global global; - private String aBuffer = ""; private ListView lv; private SwipeRefreshLayout swipe; private ArrayList> renewalList = new ArrayList<>(); @@ -80,7 +79,6 @@ public class RenewList extends AppCompatActivity { private ClientAndroidInterface ca; private ListAdapter adapter; public String UnlistedRenPolicy; - boolean isUserLogged = false; @Override @@ -178,12 +176,28 @@ public void confirmImportRenewal(String filename, Uri uri) { .setMessage(filename) .setPositiveButton(R.string.Yes, (dialog, which) -> new Thread(() -> { - if (copyRenewalFile(filename, uri)) { - ca.unZipFeedbacksRenewals(filename); - String txtFilename = Util.FileUtil.replaceFilenameExtension(filename, ".txt"); - loadRenewalFile(txtFilename); - ca.InsertRenewalsFromExtract(aBuffer); - runOnUiThread(this::fillRenewals); + File renewalFile = copyRenewalFile(uri); + if (renewalFile != null) { + ca.unZipFeedbacksRenewals(renewalFile); + File[] unzippedFiles = null; + File renewalDir = renewalFile.getParentFile(); + if (renewalDir != null) { + unzippedFiles = renewalDir.listFiles((file) -> file.isFile() && !file.equals(renewalFile)); + } + if (unzippedFiles != null) { + if (unzippedFiles.length == 0) { + Log.w(LOG_TAG, "No renewal files after unpacking"); + } + for (File f : unzippedFiles) { + String renewals = loadRenewalFile(f); + if (renewals != null) { + ca.InsertRenewalsFromExtract(renewals); + } + } + runOnUiThread(this::fillRenewals); + FileUtils.deleteFiles(unzippedFiles); + } + FileUtils.deleteFile(renewalFile); } }).start()) .setNegativeButton(R.string.No, @@ -191,44 +205,34 @@ public void confirmImportRenewal(String filename, Uri uri) { .show(); } - private void loadRenewalFile(String filename) { - File file = new File(global.getSubdirectory("Database"), filename); - try { - if (file.exists()) { - InputStream inputStream = new FileInputStream(file); - aBuffer = Util.StreamUtil.readInputStreamAsUTF8String(inputStream); - } else { - Log.e(LOG_TAG, "Unpacked renewal file does not exists"); - } - } catch (IOException e) { - Log.e(LOG_TAG, "Error while creating input stream for renewal file", e); + private String loadRenewalFile(File file) { + if (file.exists()) { + return FileUtils.readFileAsUTF8String(file); + } else { + Log.e(LOG_TAG, "Unpacked renewal file does not exists"); + return null; } } - private boolean copyRenewalFile(String filename, Uri uri) { - try { - boolean success; - InputStream is = getContentResolver().openInputStream(uri); - File outputFile = new File(global.getSubdirectory("Database"), filename); - - if (outputFile.exists()) { - success = outputFile.delete(); - if (!success) { - throw new IOException("Deleting existing renewal file failed"); - } - } + public void NoRenewalsFoundDialog() { + AlertDialog.Builder alertDialog2 = new AlertDialog.Builder( + RenewList.this); - success = outputFile.createNewFile(); - if (!success) { - throw new IOException("Creating new renewal file failed"); - } + alertDialog2.setTitle("Alert") + .setMessage(getResources().getString(R.string.NoRenewalFound)) + .setPositiveButton("OK", null) + .create() + .show(); + } - IOUtils.copy(is, new FileOutputStream(outputFile)); - return true; - } catch (Exception e) { - Log.e(LOG_TAG, "Copying renewal file failed", e); + private File copyRenewalFile(Uri uri) { + File copiedFile = UriUtils.copyUriContentToCache(this, uri, "imports/renewal/renewal.rar"); + if (copiedFile != null) { + return copiedFile; + } else { + Log.e(LOG_TAG, "Copying renewal file failed, uri: " + uri); + return null; } - return false; } public void requestImportRenewal() { @@ -241,7 +245,7 @@ public void requestImportRenewal() { intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("*/*"); try { - startActivityForResult(intent, REQUEST_OPEN_DOCUMENT_CODE); + startActivityForResult(intent, REQUEST_IMPORT_RENEWAL_FILE); } catch (ActivityNotFoundException e) { Toast.makeText(getApplicationContext(), getResources().getString(R.string.NoFileExporerInstalled), Toast.LENGTH_SHORT).show(); } @@ -254,9 +258,9 @@ public void requestImportRenewal() { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_OPEN_DOCUMENT_CODE && resultCode == RESULT_OK && data != null) { + if (requestCode == REQUEST_IMPORT_RENEWAL_FILE && resultCode == RESULT_OK && data != null) { Uri uri = data.getData(); - String filename = Util.UriUtil.getDisplayName(this, uri); + String filename = UriUtils.getDisplayName(this, uri); String expectedFilename = String.format("renewal_%s.rar", global.getOfficerCode().toLowerCase()); if (filename != null && filename.toLowerCase().equals(expectedFilename)) { @@ -279,7 +283,7 @@ private void fillRenewals() { JSONObject object; try { - HashMap renewal; + HashMap renewal; JSONArray jsonArray = new JSONArray(result); renewalList.clear(); @@ -297,6 +301,9 @@ private void fillRenewals() { renewal.put("RenewalUUID", ""); renewalList.add(renewal); + if (jsonArray.length()==0) { + this.NoRenewalsFoundDialog(); + } for (int i = 0; i < jsonArray.length(); i++) { object = jsonArray.getJSONObject(i); diff --git a/app/src/main/java/org/openimis/imispolicies/Renewal.java b/app/src/main/java/org/openimis/imispolicies/Renewal.java index fd8578ab..53a7d72a 100644 --- a/app/src/main/java/org/openimis/imispolicies/Renewal.java +++ b/app/src/main/java/org/openimis/imispolicies/Renewal.java @@ -49,12 +49,15 @@ import com.google.zxing.client.android.Intents; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.openimis.imispolicies.tools.Util.StringUtil; +import org.openimis.imispolicies.tools.LanguageManager; +import org.openimis.imispolicies.tools.Log; +import org.openimis.imispolicies.util.StringUtils; import org.xmlpull.v1.XmlSerializer; import java.io.File; @@ -70,6 +73,7 @@ import static android.widget.AdapterView.INVALID_POSITION; public class Renewal extends AppCompatActivity { + private static final String LOG_TAG = "RENEWAL"; private Global global; private SQLHandler sqlHandler; @@ -91,7 +95,6 @@ public class Renewal extends AppCompatActivity { private int LocationId; private int RenewalId; private String RenewalUUID; - private int result; private EditText PolicyValue; private ListAdapter adapter; @@ -165,7 +168,11 @@ protected void onCreate(Bundle savedInstanceState) { BindSpinnerProduct(); } else { spProduct.setVisibility(View.GONE); - assignNextFreeCn(etProductCode.getText().toString()); + + if (ca.IsBulkCNUsed()) { + assignNextFreeCn(etProductCode.getText().toString()); + } + BindSpinnerPayers(); } @@ -216,7 +223,7 @@ protected void onCreate(Bundle savedInstanceState) { try { startActivityForResult(intent, INTENT_ACTIVITY_SCAN_CODE); } catch (Exception e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Error while trying to initiate QR scan", e); } } ); @@ -265,17 +272,15 @@ private String GetSelectedProduct() { private void WriteXML() { try { - //Create All directories - File MyDir = new File(global.getMainDirectory()); //Create File name Date date = Calendar.getInstance().getTime(); String d = AppInformation.DateTimeInfo.getDefaultFileDatetimeFormatter().format(date); - FileName = "RenPol_" + d + "_" + etCHFID.getText().toString() + "_" + etReceiptNo.getText().toString() + ".xml"; + FileName = "Renewal_" + d + "_" + etCHFID.getText().toString() + "_" + etReceiptNo.getText().toString() + ".xml"; d = AppInformation.DateTimeInfo.getDefaultDateFormatter().format(date); String PayerId = GetSelectedPayer(); //Create XML file - File policyXML = new File(MyDir, FileName); + File policyXML = new File(global.getSubdirectory("Renewal"), FileName); FileOutputStream fos = new FileOutputStream(policyXML); @@ -335,23 +340,21 @@ private void WriteXML() { fos.close(); } catch (Exception e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Error while saving renewal file", e); } - } public String WriteJSON() { - File MyDir = new File(global.getMainDirectory()); Date date = Calendar.getInstance().getTime(); String d = AppInformation.DateTimeInfo.getDefaultFileDatetimeFormatter().format(date); - FileName = "RenPolJSON_" + d + "_" + etCHFID.getText().toString() + "_" + etReceiptNo.getText().toString() + ".txt"; + FileName = "RenewalJSON_" + d + "_" + etCHFID.getText().toString() + "_" + etReceiptNo.getText().toString() + ".json"; String PayerId = GetSelectedPayer(); String ProductCode = GetSelectedProduct(); d = AppInformation.DateTimeInfo.getDefaultDateFormatter().format(date); //Create XML file - File policyJSON = new File(MyDir, FileName); + File policyJSON = new File(global.getSubdirectory("Renewal"), FileName); JSONObject FullObject = new JSONObject(); @@ -381,13 +384,13 @@ public String WriteJSON() { myOutWriter.close(); fOut.close(); } catch (IOException e) { - e.printStackTrace(); + Log.e(LOG_TAG, "IO error while saving renewal file", e); } } catch (IllegalStateException e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Illegal state error while saving renewal file", e); } catch (JSONException e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Json error while saving renewal file", e); } return FullObject.toString(); @@ -493,7 +496,7 @@ private void BindSpinnerPayers(int LocationId) { spPayer.setAdapter((SpinnerAdapter) adapter); } } catch (JSONException e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Error while binding payers", e); } } @@ -539,7 +542,7 @@ private void BindSpinnerProduct() { spProduct.setAdapter(adapter); } } catch (JSONException e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Error while binding products", e); } } @@ -621,7 +624,7 @@ private boolean isValidate() { ToRestApi rest = new ToRestApi(); response = rest.postToRestApiToken(receiptObj, "premium/receipt"); } catch (Exception e) { - e.printStackTrace(); + Log.e(LOG_TAG, "Error while checking receipt no", e); } if (response != null) { @@ -663,7 +666,7 @@ private void showInfoDialog(int resId) { } private void assignNextFreeCn(String productCode) { - if (!StringUtil.equals(productCode, "0")) { + if (!StringUtils.equals(productCode, "0")) { String controlNumber = sqlHandler.getNextFreeCn(etOfficer.getText().toString(), productCode); if (controlNumber != null) { etControlNumber.setText(controlNumber); diff --git a/app/src/main/java/org/openimis/imispolicies/SQLHandler.java b/app/src/main/java/org/openimis/imispolicies/SQLHandler.java index b960182e..7927849f 100644 --- a/app/src/main/java/org/openimis/imispolicies/SQLHandler.java +++ b/app/src/main/java/org/openimis/imispolicies/SQLHandler.java @@ -32,6 +32,7 @@ import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.support.annotation.NonNull; import android.text.TextUtils; import org.openimis.imispolicies.tools.Log; import android.util.Xml; @@ -474,7 +475,7 @@ public void onOpen(SQLiteDatabase db) { private void openDatabase() { String dbPath = mContext.getDatabasePath(DBNAME).getPath(); - String dbOfflinePath = global.getMainDirectory() + File.separator + OFFLINEDBNAME; + String dbOfflinePath = global.getAppDirectory() + File.separator + OFFLINEDBNAME; if (mDatabase != null && mDatabase.isOpen()) { return; } @@ -569,8 +570,6 @@ public String getExportAsXML(String QueryF, String QueryI, String QueryPL, Strin String d = format.format(cal.getTime()); File Dir = new File(global.getSubdirectory("Family")); - Dir.mkdir(); - //Here we are giving name to the XML file String FileName = "Enrolment_" + OfficerCode + "_" + d + ".xml"; @@ -675,7 +674,6 @@ public String getExportAsXML(String QueryF, String QueryI, String QueryPL, Strin } } if (sublabel.equals("Family")) { - serializer = addFamilySmsTag(serializer, cursor.getString(0)); } serializer.endTag(null, sublabel); @@ -689,7 +687,7 @@ public String getExportAsXML(String QueryF, String QueryI, String QueryPL, Strin e.printStackTrace(); } - + serializer.endTag(null, "Enrolment"); serializer.endDocument(); serializer.flush(); fos.close(); @@ -1049,4 +1047,36 @@ public int getRegionId(int districtId) { } return result; } + + /** + * @return Default Language as specified by SortOrder in tblLanguages, return DEFAULT_LANGUAGE_CODE before initialization + */ + @NonNull + public String getDefaultLanguage() { + openDatabase(); + String result = BuildConfig.DEFAULT_LANGUAGE_CODE; + try (Cursor c = mDatabase.query(tblLanguages, + new String[]{"LanguageCode"}, + null, + null, + null, + null, + "SortOrder ASC", + "1")) { + c.moveToFirst(); + if (!c.isAfterLast()) { + result = c.getString(0); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + closeDatabase(); + } + return result; + } + + @NonNull + public JSONArray getSupportedLanguages() { + return getResult(tblLanguages, new String[]{"LanguageCode"}, null, null); + } } diff --git a/app/src/main/java/org/openimis/imispolicies/SnapshotIndicators.java b/app/src/main/java/org/openimis/imispolicies/SnapshotIndicators.java index 19a63013..3507aad0 100644 --- a/app/src/main/java/org/openimis/imispolicies/SnapshotIndicators.java +++ b/app/src/main/java/org/openimis/imispolicies/SnapshotIndicators.java @@ -42,9 +42,10 @@ import android.widget.TextView; import android.widget.Toast; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONException; import org.json.JSONObject; diff --git a/app/src/main/java/org/openimis/imispolicies/Statistics.java b/app/src/main/java/org/openimis/imispolicies/Statistics.java index 6570bffa..ab5ab6a3 100644 --- a/app/src/main/java/org/openimis/imispolicies/Statistics.java +++ b/app/src/main/java/org/openimis/imispolicies/Statistics.java @@ -44,13 +44,15 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; + import java.text.DateFormat; import com.exact.CallSoap.CallSoap; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -76,7 +78,7 @@ public class Statistics extends AppCompatActivity { private static final int ToDate_Dialog_ID = 1; private final Calendar cal = Calendar.getInstance(); private ArrayList> FeedbackStats = new ArrayList<>(); - ArrayList> EnrolmentStats = new ArrayList>(); + ArrayList> EnrolmentStats = new ArrayList>(); private String OfficerCode; private String Caller; private Global global; @@ -215,8 +217,8 @@ public boolean onOptionsItemSelected(MenuItem item) { new Thread() { public void run() { - if(!IsEnrolment) - GetStatistics(); + if (!IsEnrolment) + GetStatistics(); else GetEnrolmentStats(); pd.dismiss(); @@ -260,16 +262,18 @@ private void GetStatistics() { ToRestApi rest = new ToRestApi(); if (Caller.equals("F")) { - HttpResponse response = rest.postToRestApiToken(objStats,"report/feedback"); + HttpResponse response = rest.postToRestApiToken(objStats, "report/feedback"); try { stats = EntityUtils.toString(response.getEntity()); - } catch (Exception e) {} + } catch (Exception e) { + } } else if (Caller.equals("R")) { - HttpResponse response = rest.postToRestApiToken(objStats,"report/renewal"); + HttpResponse response = rest.postToRestApiToken(objStats, "report/renewal"); try { stats = EntityUtils.toString(response.getEntity()); - } catch (Exception e) {} + } catch (Exception e) { + } } final String finalStats = stats; @@ -320,7 +324,8 @@ else if (Caller.equals("R")) } - private void GetEnrolmentStats(){ + + private void GetEnrolmentStats() { EnrolmentStats = new ArrayList<>(); Date FromDate, ToDate; @@ -346,7 +351,7 @@ private void GetEnrolmentStats(){ } ToRestApi rest = new ToRestApi(); - HttpResponse response = rest.postToRestApiToken(objEnrolment,"report/enrolment"); + HttpResponse response = rest.postToRestApiToken(objEnrolment, "report/enrolment"); HttpEntity entity = response.getEntity(); String entityString = ""; @@ -355,7 +360,8 @@ private void GetEnrolmentStats(){ try { entityString = EntityUtils.toString(entity); enrolmentStatsObj = new JSONObject(entityString); - } catch (Exception e) {} + } catch (Exception e) { + } final JSONObject finalEnrolmentStatsObj = enrolmentStatsObj; @@ -363,10 +369,10 @@ private void GetEnrolmentStats(){ @Override public void run() { try { - if(finalEnrolmentStatsObj.length() == 0){ + if (finalEnrolmentStatsObj.length() == 0) { ShowDialog(getResources().getString(R.string.NoStatFound)); - }else{ - HashMap data = new HashMap(); + } else { + HashMap data = new HashMap(); data.put("Label", "Total Submitted"); data.put("Value", String.valueOf(finalEnrolmentStatsObj.get("totalSubmitted"))); EnrolmentStats.add(data); @@ -379,19 +385,19 @@ public void run() { ListAdapter adapter = new SimpleAdapter(Statistics.this, EnrolmentStats, R.layout.lvstats, - new String[]{"Label","Value"}, - new int[]{R.id.tvStatsLabel,R.id.tvStats} + new String[]{"Label", "Value"}, + new int[]{R.id.tvStatsLabel, R.id.tvStats} ); lvStats.setAdapter(adapter); } - } - catch (JSONException e) { + } catch (JSONException e) { e.printStackTrace(); } } }); } + private AlertDialog ShowDialog(String msg) { return new AlertDialog.Builder(this) .setMessage(msg) diff --git a/app/src/main/java/org/openimis/imispolicies/ToRestApi.java b/app/src/main/java/org/openimis/imispolicies/ToRestApi.java index 7d8781cc..fb57d89f 100644 --- a/app/src/main/java/org/openimis/imispolicies/ToRestApi.java +++ b/app/src/main/java/org/openimis/imispolicies/ToRestApi.java @@ -1,14 +1,17 @@ package org.openimis.imispolicies; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.util.EntityUtils; +import android.content.Context; + +import cz.msebera.android.httpclient.HttpEntity; +import cz.msebera.android.httpclient.HttpResponse; +import cz.msebera.android.httpclient.client.HttpClient; +import cz.msebera.android.httpclient.client.methods.HttpDelete; +import cz.msebera.android.httpclient.client.methods.HttpGet; +import cz.msebera.android.httpclient.client.methods.HttpPost; +import cz.msebera.android.httpclient.entity.StringEntity; +import cz.msebera.android.httpclient.impl.client.DefaultHttpClient; +import cz.msebera.android.httpclient.util.EntityUtils; + import org.json.JSONObject; import org.openimis.imispolicies.tools.Log; @@ -107,7 +110,7 @@ public HttpResponse postToRestApi(JSONObject object, String functionName, boolea if (object != null && responseCode >= 400 && !functionName.equals("login")) { String body = object.toString(); if (body.length() > 1000) { - body = body.substring(0,1000); + body = body.substring(0, 1000); } Log.e("HTTP_POST", "Body: " + body); } @@ -142,6 +145,10 @@ public HttpResponse getFromRestApiToken(final String functionName) { return getFromRestApi(functionName, true); } + public HttpResponse getFromRestApi(final String functionName) { + return getFromRestApi(functionName, false); + } + public HttpResponse deleteFromRestApiToken(final String functionName) { HttpClient httpClient = new DefaultHttpClient(); HttpDelete httpDelete = new HttpDelete(uri + functionName); @@ -175,7 +182,7 @@ public String getContent(HttpResponse response) { content = EntityUtils.toString(respEntity); if (content != null && content.length() > 0 && response.getStatusLine().getStatusCode() >= 400) { - Log.e("HTTP", "Error response: " + content); + Log.e("HTTP", "Error " + response.getStatusLine().getStatusCode() + ", response: " + content); } } catch (IOException e) { e.printStackTrace(); @@ -198,4 +205,18 @@ private String buildTokenHeader() { } return ""; } + + public String getHttpError(Context context, int httpResponseCode, String httpReason) { + if (httpResponseCode == HttpURLConnection.HTTP_OK || httpResponseCode == HttpURLConnection.HTTP_CREATED) { + return null; + } else if (httpResponseCode == HttpURLConnection.HTTP_NOT_FOUND) { + return context.getResources().getString(R.string.NotFound); + } else if (httpResponseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { + return context.getResources().getString(R.string.Unauthorized); + } else if (httpResponseCode == HttpURLConnection.HTTP_FORBIDDEN) { + return context.getResources().getString(R.string.Forbidden); + } else { + return context.getResources().getString(R.string.HttpResponse, httpResponseCode, httpReason); + } + } } diff --git a/app/src/main/java/org/openimis/imispolicies/tools/ImageManager.java b/app/src/main/java/org/openimis/imispolicies/tools/ImageManager.java index 679639b2..4c7820c8 100644 --- a/app/src/main/java/org/openimis/imispolicies/tools/ImageManager.java +++ b/app/src/main/java/org/openimis/imispolicies/tools/ImageManager.java @@ -4,6 +4,7 @@ import android.content.Context; import org.openimis.imispolicies.Global; +import org.openimis.imispolicies.util.FileUtils; import java.io.File; @@ -23,14 +24,14 @@ protected ImageManager(Context context) { } public File getNewestInsureeImage(String insureeNumber) { - return Util.FileUtil.getNewestFileStartingWith( + return FileUtils.getNewestFileStartingWith( new File(Global.getGlobal().getImageFolder()), insureeNumber + "_" ); } public File[] getInsureeImages(String insureeNumber) { - return Util.FileUtil.getFilesStartingWith( + return FileUtils.getFilesStartingWith( new File(Global.getGlobal().getImageFolder()), insureeNumber + "_" ); diff --git a/app/src/main/java/org/openimis/imispolicies/tools/LanguageManager.java b/app/src/main/java/org/openimis/imispolicies/tools/LanguageManager.java new file mode 100644 index 00000000..53a08db6 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/tools/LanguageManager.java @@ -0,0 +1,244 @@ +package org.openimis.imispolicies.tools; + +import android.app.Activity; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.icu.text.LocaleDisplayNames; +import android.os.Build; +import android.os.LocaleList; +import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; +import android.util.DisplayMetrics; + +import org.json.JSONArray; +import org.json.JSONException; +import org.openimis.imispolicies.BuildConfig; +import org.openimis.imispolicies.Global; +import org.openimis.imispolicies.R; +import org.openimis.imispolicies.SQLHandler; +import org.openimis.imispolicies.util.AndroidUtils; +import org.openimis.imispolicies.util.LocaleUtils; +import org.openimis.imispolicies.util.StringUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; + +public class LanguageManager { + + private static class LanguageContextWrapper extends ContextWrapper { + public LanguageContextWrapper(Context base) { + super(base); + } + } + + private static final String LOG_TAG = "LANGUAGEMANAGER"; + private final Global global; + private final Context context; + + public LanguageManager(@NonNull Context context) { + this.context = context; + global = (Global) context.getApplicationContext(); + } + + /** + * Check if current system language is supported as denoted in Master Data (tblLanguages) + * If the current system language does not match to any of the supported languages then this method + * will show a dialog telling the user what languages are supported + */ + public void checkSystemLanguage() { + List supportedLocales = getSupportedLocales(); + if (!isSystemLanguageSupported(supportedLocales)) { + showNotSupportedLanguagePrompt(supportedLocales); + } + } + + /** + * Check if stored language is the current language. If not, then set stored language as current. + */ + public void restoreLanguage() { + restoreLanguage(true); + } + + /** + * Check if stored language is the current language. If not, then set stored language as current. + * + * @param withRestart should the current context be restarted (if it's Activity). + */ + public void restoreLanguage(boolean withRestart) { + String language = getStoredLanguage(); + setLanguage(language, withRestart); + } + + /** + * Set specified language as stored and current language. + * + * @param language The language tag to be used. + * @param withRestart should the current context be restarted (if it's Activity). + */ + public void setLanguage(@NonNull String language, boolean withRestart) { + if (!isCurrentLanguage(language)) { + setStoredLanguage(language); + setCurrentLanguage(language); + if (withRestart && context instanceof Activity) { + ((Activity) context).recreate(); + } + } + } + + /** + * Set specified language as stored and current language. + * The current context will be restarted (if it's Activity). + * + * @param language The language tag to be used. + */ + public void setLanguage(@NonNull String language) { + setLanguage(language, true); + } + + public ContextWrapper getWrappedContext() { + restoreLanguage(false); + return new LanguageContextWrapper(context); + } + + /** + * Opens system language settings. This is a preferred method to change language + */ + public void openLanguageSettings() { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClassName("com.android.settings", "com.android.settings.LanguageSettings"); + context.startActivity(intent); + } + + /** + * Check if given language is current default language (as in Locale.getDefault()). + * + * @param language language tag to check + * @return is the specified language tag current default + */ + private boolean isCurrentLanguage(@NonNull String language) { + String currentLanguage = LocaleUtils.getLanguageTag(getCurrentLocale()); + return language.toLowerCase(Locale.ROOT).equals(currentLanguage.toLowerCase()); + } + + /** + * @return current system Locale object + */ + private Locale getCurrentLocale() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + return getSystemLocales().get(0); + } else { + //noinspection deprecation + return context.getResources().getConfiguration().locale; + } + } + + /** + * @return LocaleList of all current system languages (sorted) + */ + @RequiresApi(api = Build.VERSION_CODES.N) + private LocaleList getSystemLocales() { + return context.getResources().getConfiguration().getLocales(); + } + + /** + * Returns current resource language Locale object. The Locale is created from language tag stored + * in "LanguageCode" resource key. + * + * @return current resource Locale object + */ + private Locale getCurrentResourceLocale() { + return LocaleUtils.getLocaleFromTag(context.getResources().getString(R.string.LanguageCode)); + } + + /** + * Update locale of resources in current context to the selected language + * + * @param newLanguage language tag to use + */ + private void setCurrentLanguage(@NonNull String newLanguage) { + Resources resources = context.getResources(); + DisplayMetrics displayMetrics = resources.getDisplayMetrics(); + Configuration config = resources.getConfiguration(); + config.locale = LocaleUtils.getLocaleFromTag(newLanguage); + resources.updateConfiguration(config, displayMetrics); + Locale.setDefault(config.locale); + } + + private void setStoredLanguage(String locale) { + global.setStringKey(Global.PREF_LANGUAGE_KEY, locale); + } + + private String getStoredLanguage() { + String defaultLanguage = null; + File database = global.getDatabasePath(SQLHandler.DBNAME); + if (database.exists()) { + defaultLanguage = new SQLHandler(context).getDefaultLanguage(); + } else { + defaultLanguage = BuildConfig.DEFAULT_LANGUAGE_CODE; + } + return global.getStringKey(Global.PREF_LANGUAGE_KEY, defaultLanguage); + } + + /** + * @return List of supported languages from tblLanguages + */ + private List getSupportedLocales() { + JSONArray languagesArray = new SQLHandler(context).getSupportedLanguages(); + List supportedLocales = new ArrayList<>(languagesArray.length()); + + try { + for (int i = 0; i < languagesArray.length(); i++) { + supportedLocales.add(LocaleUtils.getLocaleFromTag(languagesArray.getJSONObject(i).getString("LanguageCode"))); + } + } catch (JSONException e) { + Log.e(LOG_TAG, "Error while parsing supported languages", e); + } + + return supportedLocales; + } + + /** + * This method check if system language (or any of the system languages on Android 7+) matches any of the supported languages + * @param supportedLocales List of supported languages + * @return does system language match any supported language + */ + private boolean isSystemLanguageSupported(List supportedLocales) { + boolean isLocaleSupported = false; + + //System locale matches one of the supported locales if it is equal (language and country, or the supported locale is language only and system locale matches the language) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // Android 7 new language matching system + List systemLocales = LocaleUtils.toList(getSystemLocales()); + isLocaleSupported = systemLocales.stream().anyMatch(systemLocale -> supportedLocales.stream().anyMatch(locale -> locale.getCountry().equals("") && locale.getLanguage().equals(systemLocale.getLanguage()) || systemLocale.equals(locale))); + } else { // Legacy language matching + Locale systemLocale = getCurrentLocale(); + for (Locale locale : supportedLocales) { + if (locale.getCountry().equals("") && locale.getLanguage().equals(systemLocale.getLanguage()) || systemLocale.equals(locale)) { + isLocaleSupported = true; + break; + } + } + } + + return isLocaleSupported; + } + + private void showNotSupportedLanguagePrompt(List supportedLocales) { + String message = context.getResources().getString(R.string.SystemLanguageNotSupported); + message += "\n\n" + context.getResources().getString(R.string.SupportedLanguages, StringUtils.join("\n", supportedLocales, this::getLanguageDisplayName)); + AndroidUtils.showDialog(context, message, context.getResources().getString(R.string.menu_settings), (d, i) -> openLanguageSettings()); + } + + private String getLanguageDisplayName(Locale locale) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + return LocaleDisplayNames.getInstance(Locale.getDefault()).localeDisplayName(locale); + } else { + return locale.getDisplayName(); + } + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/tools/StorageManager.java b/app/src/main/java/org/openimis/imispolicies/tools/StorageManager.java index 0503f708..475b70f3 100644 --- a/app/src/main/java/org/openimis/imispolicies/tools/StorageManager.java +++ b/app/src/main/java/org/openimis/imispolicies/tools/StorageManager.java @@ -1,29 +1,18 @@ package org.openimis.imispolicies.tools; import android.app.Activity; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.DocumentsContract; import android.support.annotation.NonNull; -import android.support.v4.content.FileProvider; import android.util.Log; -import org.openimis.imispolicies.BuildConfig; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - public class StorageManager { protected static final String LOG_TAG = "STORAGEMANAGER"; - protected static final String FILE_PROVIDER_NAME = String.format("%s.fileprovider", BuildConfig.APPLICATION_ID); protected final Context context; - protected final ContentResolver contentResolver; public static StorageManager of(Context context) { return new StorageManager(context); @@ -31,7 +20,6 @@ public static StorageManager of(Context context) { protected StorageManager(Context context) { this.context = context; - this.contentResolver = this.context.getContentResolver(); } public void requestOpenDirectory(int requestCode, Uri initialUri) { @@ -93,109 +81,4 @@ public void requestCreateFile(int requestCode, @NonNull String mimeType, String public void requestCreateFile(int requestCode, @NonNull String mimeType, String initialFileName) { requestCreateFile(requestCode, mimeType, initialFileName, null); } - - /** - * Copy the content of the provided uri to provided file. The file location must allow creating - * a file and writing to a file. - * - * @param uri Uri of the file to copy. The Uri should allow read and should be openable - * @param targetFile File to be used as output stream - * @return File object pointing to created file - */ - public File copyUriContentToFile(@NonNull Uri uri, @NonNull File targetFile) { - if (!targetFile.exists()) { - Util.FileUtil.createFileWithSubdirectories(targetFile); - } - try (InputStream is = contentResolver.openInputStream(uri)) { - Util.FileUtil.writeToFile(targetFile, is); - } catch (IOException e) { - Log.e(LOG_TAG, "Error while opening streams", e); - } - - return targetFile; - } - - - /** - * Create a content URI for a file owned by the app. The directory path have to be specified in - * res/xml/paths.xml to be eligible to provide content. Uri returned by this method can be shared - * with other apps with intents. - * - * @param file File to be specified by generated content URI - * @return Content URI for a given file - */ - public Uri createUriForFile(@NonNull File file) { - Uri uri = FileProvider.getUriForFile(context, FILE_PROVIDER_NAME, file); - if (uri == null) { - org.openimis.imispolicies.tools.Log.w(LOG_TAG, "Failed to create temp photo URI"); - } - return uri; - } - - /** - * Copy the content of the provided uri to cache directory under provided path. The caller is - * responsible to delete the file after use. The file can be deleted by Android or the user - * without notifying the app. - * - * @param uri Uri of the file to copy. The Uri should allow read and should be openable - * @param targetPath Path inside cache directory to save the file (cache location will be appended) - * @return File object pointing to created file - */ - public File copyUriContentToCache(@NonNull Uri uri, @NonNull String targetPath) { - return copyUriContentToFile(uri, new File(context.getCacheDir(), targetPath)); - } - - /** - * Create a temporary file inside app's cache directory under specified path. This file should be - * manually deleted, but the cache directory can be emptied by the user or by the Android to save - * storage space. If the file exists, it will be deleted and recreated. - * - * @param targetPath Path to the temporary file inside cache, the cache root will be appended - * @return Created temp file - */ - public File createTempFile(@NonNull String targetPath) { - return createTempFile(targetPath, false); - } - - /** - * Create a temporary file inside app's cache directory under specified path. This file should be - * manually deleted, but the cache directory can be emptied by the user or by the Android to save - * storage space. If the file exists, it will be deleted and recreated. - * - * @param targetPath Path to the temporary file inside cache, the cache root will be appended - * @param preparePathOly Set to true if the abstract path should point to non-existing file - * (i.e. to forward the file object to a library to create the file) - * @return Created temp file - */ - public File createTempFile(@NonNull String targetPath, boolean preparePathOly) { - File tempFile = new File(context.getCacheDir(), targetPath); - - if (tempFile.exists() && tempFile.delete()) { - org.openimis.imispolicies.tools.Log.i(LOG_TAG, "Leftover temp file deleted: " + tempFile.getAbsolutePath()); - } - - if (preparePathOly) { - File parentFile = tempFile.getParentFile(); - if (parentFile != null) { - return Util.FileUtil.createDirectoryWithSubdirectories(parentFile) ? tempFile : null; - } else { - return null; - } - } else { - return Util.FileUtil.createFileWithSubdirectories(tempFile) ? tempFile : null; - } - } - - /** - * Convenience method for removing a temp file form specified path inside cache directory created - * by createTempFile(String). The file can also be safely deleted with returned File object. - * - * @param targetPath Path to the temporary file inside cache, the cache root will be appended - * @return true if file under targetPath does not exist or was successfully deleted, false if file - * exists and delete failed - */ - public boolean removeTempFile(@NonNull String targetPath) { - File tempFile = new File(context.getCacheDir(), targetPath); - return !tempFile.exists() || tempFile.delete(); - } } diff --git a/app/src/main/java/org/openimis/imispolicies/tools/Util.java b/app/src/main/java/org/openimis/imispolicies/tools/Util.java deleted file mode 100644 index b700137a..00000000 --- a/app/src/main/java/org/openimis/imispolicies/tools/Util.java +++ /dev/null @@ -1,371 +0,0 @@ -package org.openimis.imispolicies.tools; - -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.database.Cursor; -import android.net.Uri; -import android.provider.OpenableColumns; -import android.support.annotation.NonNull; -import android.text.TextUtils; -import android.widget.Toast; - -import org.json.JSONException; -import org.json.JSONObject; -import org.openimis.imispolicies.R; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; - -public class Util { - public static class StringUtil { - /** - * @param string String to be checked - * @return is string null or empty - */ - public static boolean isEmpty(CharSequence string) { - return isEmpty(string, false); - } - - /** - * @param string String to be checked - * @param checkNullString Should "null" string be considered empty - * @return is string null or empty - */ - public static boolean isEmpty(CharSequence string, boolean checkNullString) { - return string == null - || string.equals("") - || (string.equals("null") && checkNullString); - } - - public static boolean equals(CharSequence s1, CharSequence s2) { - return TextUtils.equals(s1, s2); - } - } - - public static class JsonUtil { - /** - * @param object Json object - * @param field field to be checked - * @return if the field does not exists, is null or empty - */ - public static boolean isStringEmpty(JSONObject object, @NonNull String field) { - return isStringEmpty(object, field, false); - } - - /** - * @param object Json object - * @param field field to be checked - * @param checkNullString Should "null" string be considered empty - * @return if the field does not exists, is null or empty - */ - public static boolean isStringEmpty(JSONObject object, @NonNull String field, boolean checkNullString) { - try { - return object == null - || !object.has(field) - || StringUtil.isEmpty(object.getString(field), checkNullString); - } catch (JSONException e) { - return true; - } - } - } - - public static class AndroidUtil { - public static ProgressDialog showProgressDialog(Context context, int titleResId, int messageResId) { - return ProgressDialog.show( - context, - context.getResources().getString(titleResId), - context.getResources().getString(messageResId) - ); - } - - public static void showToast(Context context, int messageResId) { - Toast.makeText(context, messageResId, Toast.LENGTH_SHORT).show(); - } - - public static void showToast(Context context, CharSequence message) { - Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); - } - - public static AlertDialog showDialog(Context context, int messageResId) { - return new AlertDialog.Builder(context) - .setMessage(messageResId) - .setCancelable(false) - .setPositiveButton(R.string.Ok, (dialogInterface, i) -> { - }).show(); - } - - public static AlertDialog showDialog(Context context, CharSequence message) { - return new AlertDialog.Builder(context) - .setMessage(message) - .setCancelable(false) - .setPositiveButton(R.string.Ok, (dialogInterface, i) -> { - }).show(); - } - - public static AlertDialog showConfirmDialog(Context context, int messageResId, DialogInterface.OnClickListener onPositive) { - return new AlertDialog.Builder(context) - .setMessage(messageResId) - .setCancelable(false) - .setPositiveButton(R.string.Ok, onPositive) - .setNegativeButton(R.string.Cancel, (dialogInterface, i) -> { - }).show(); - } - } - - public static class UriUtil { - private static final String LOG_TAG = "UriUtil"; - - public static String getDisplayName(@NonNull Context context, @NonNull Uri uri) { - try (Cursor c = context.getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null)) { - c.moveToFirst(); - c.moveToFirst(); - return c.getString(c.getColumnIndex(OpenableColumns.DISPLAY_NAME)); - } catch (Exception e) { - Log.e(LOG_TAG, "Reading file name from URI failed", e); - } - return null; - } - - public static void writeToUri(@NonNull Context context, @NonNull Uri uri, @NonNull InputStream is) { - try (OutputStream os = context.getContentResolver().openOutputStream(uri, "w")) { - StreamUtil.bufferedStreamCopy(is, os); - } catch (IOException e) { - Log.e(LOG_TAG, "Writing to uri failed: " + uri, e); - } - } - - /** - * Copy byte content of the file to location described by the uri. The uri must be openable and - * allow writing. The file must be openable and readable. - * - * @param file File to be read - * @param uri Uri pointing to writable location - */ - public static void copyFileToUri(@NonNull Context context, @NonNull File file, @NonNull Uri uri) { - try (InputStream is = new FileInputStream(file)) { - Util.UriUtil.writeToUri(context, uri, is); - } catch (IOException e) { - android.util.Log.e(LOG_TAG, "Error while opening streams", e); - } - } - - /** - * Copy byte content of the file to location described by the uri. The uri must be openable and - * allow writing. The file must be openable and readable. - * - * @param filePath Path to file to be read - * @param uri Uri pointing to writable location - */ - public static void copyFileToUri(@NonNull Context context, @NonNull String filePath, @NonNull Uri uri) { - copyFileToUri(context, new File(filePath), uri); - } - } - - public static class StreamUtil { - private static final int buffSize = 8192; - private static final String LOG_TAG = "StreamUtil"; - - /** - * Only use this method if you can be sure the content of the input stream - * can be read, is a UTF-8 text and will fit in memory (as String). - * - * @param is input stream to be read - * @return content of the input stream or null if IO exception occurs - */ - public static String readInputStreamAsUTF8String(@NonNull InputStream is) { - try (BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - StringBuilder stringBuilder = null; - String inputStr; - while ((inputStr = streamReader.readLine()) != null) { - if(stringBuilder != null) { - stringBuilder.append("\n"); - stringBuilder.append(inputStr); - } else { - stringBuilder = new StringBuilder(inputStr); - } - } - return stringBuilder != null? stringBuilder.toString(): null; - } catch (IOException e) { - Log.e(LOG_TAG, "Error while reading input stream", e); - } - - return null; - } - - /** - * Copy input stream to output stream using a byte buffer (8kb by default) - * - * @param is source stream - * @param os target stream - * @throws IOException thrown on read/write error - */ - public static void bufferedStreamCopy(@NonNull InputStream is, @NonNull OutputStream os) throws IOException { - byte[] buffer = new byte[buffSize]; - - int read; - while ((read = is.read(buffer)) >= 0) { - os.write(buffer, 0, read); - } - } - } - - public static class FileUtil { - private static final String LOG_TAG = "FileUtil"; - - /** - * Replaces the extension of the file - * - * @param filename filename ending with extension - * @param targetExtension target extension, including a dot (to protect from replacing - * a substring inside filename that match current extension) - * @return filename with replaced extension, or null if the filename does not end with - * extension - */ - public static String replaceFilenameExtension(@NonNull String filename, @NonNull String targetExtension) { - try { - String currentExtension = filename.substring(filename.lastIndexOf('.')); - return filename.replace(currentExtension, targetExtension); - } catch (IndexOutOfBoundsException e) { - Log.e(LOG_TAG, "Filename does not have an extension at the end", e); - } - return null; - } - - public static boolean createFileWithSubdirectories(@NonNull File file) { - try { - File parent = file.getParentFile(); - - if (parent != null && !parent.exists() && !parent.mkdirs()) { - Log.e(LOG_TAG, "Creating parent directories failed for path: " + file.getAbsolutePath()); - } - - if (!file.createNewFile()) { - Log.e(LOG_TAG, "File already exists: " + file.getAbsolutePath()); - } - - return true; - } catch (Exception e) { - Log.e(LOG_TAG, "Error while creating file: " + file.getAbsolutePath(), e); - } - - return false; - } - - public static boolean createDirectoryWithSubdirectories(@NonNull File directory) { - try { - if (!directory.exists() && !directory.mkdirs()) { - Log.e(LOG_TAG, "Creating directory failed for path: " + directory.getAbsolutePath()); - } - return true; - } catch (Exception e) { - Log.e(LOG_TAG, "Error while creating directory: " + directory.getAbsolutePath(), e); - } - - return false; - } - - public static void deleteFiles(File[] files) { - for (File file : files) { - if (!file.delete()) { - Log.w(LOG_TAG, "Delete file failed: " + file.getAbsolutePath()); - } - } - } - - public static void writeToFile(@NonNull File file, @NonNull InputStream is) { - try (OutputStream os = new FileOutputStream(file)) { - StreamUtil.bufferedStreamCopy(is, os); - } catch (IOException e) { - Log.e(LOG_TAG, "Error while writing to file: " + file.getAbsolutePath(), e); - } - } - - public static File[] getFilesStartingWith(@NonNull File directory, @NonNull String filenamePrefix) { - if (!directory.exists()) { - android.util.Log.e(LOG_TAG, "Directory does not exists: " + directory); - return null; - } - - if (!directory.isDirectory()) { - android.util.Log.e(LOG_TAG, "Provided path is not a directory: " + directory); - return null; - } - - return directory.listFiles((dir, filename) -> filename.startsWith(filenamePrefix)); - } - - public static File getNewestFileStartingWith(@NonNull File directory, @NonNull String filenamePrefix) { - File[] files = getFilesStartingWith(directory, filenamePrefix); - if (files == null || files.length == 0) { - return null; - } - Arrays.sort(files, (f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified())); - return files[files.length - 1]; - } - - public static String readFileAsUTF8String(@NonNull File file) { - try { - InputStream is = new FileInputStream(file); - return StreamUtil.readInputStreamAsUTF8String(is); - } catch (IOException e) { - Log.e(LOG_TAG, "Opening input stream failed for file: " + file.getAbsolutePath(), e); - } - return null; - } - - public static File createOrCheckDirectory(File directory) { - if (directory.exists() || directory.mkdirs()) { - return directory; - } else { - return null; - } - } - - public static File zipDirectories(File outputFile, String zipPassword, File... directories) { - ArrayList filesToAdd = new ArrayList<>(); - for (File directory : directories) { - if (!directory.exists() || !directory.isDirectory()) { - Log.w(LOG_TAG, "Provided file is not a directory: " + directory); - continue; - } - - File[] files = directory.listFiles(); - if (files == null) { - Log.w(LOG_TAG, "Reading a directory filed: " + directory); - continue; - } - - Collections.addAll(filesToAdd, files); - } - - return Compressor.zip(filesToAdd, outputFile, zipPassword); - } - - public static int getFileCount(File directory) { - if (!directory.exists() || !directory.isDirectory()) { - Log.e(LOG_TAG, "Not a directory: " + directory.getAbsolutePath()); - return -1; - } - - File[] files = directory.listFiles(File::isFile); - if (files != null) { - return files.length; - } else { - Log.e(LOG_TAG, "Counting files failed: " + directory.getAbsolutePath()); - return -1; - } - } - } -} diff --git a/app/src/main/java/org/openimis/imispolicies/util/AndroidUtils.java b/app/src/main/java/org/openimis/imispolicies/util/AndroidUtils.java new file mode 100644 index 00000000..1ebd2ff0 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/AndroidUtils.java @@ -0,0 +1,58 @@ +package org.openimis.imispolicies.util; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.widget.Toast; + +import org.openimis.imispolicies.R; + +public class AndroidUtils { + public static ProgressDialog showProgressDialog(Context context, int titleResId, int messageResId) { + return ProgressDialog.show( + context, + context.getResources().getString(titleResId), + context.getResources().getString(messageResId) + ); + } + + public static void showToast(Context context, int messageResId) { + Toast.makeText(context, messageResId, Toast.LENGTH_SHORT).show(); + } + + public static void showToast(Context context, CharSequence message) { + Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); + } + + public static AlertDialog showDialog(Context context, CharSequence title, CharSequence message, boolean isCancelable, CharSequence positiveLabel, DialogInterface.OnClickListener onPositive, CharSequence neutralLabel, DialogInterface.OnClickListener onNeutral, CharSequence negativeLabel, DialogInterface.OnClickListener onNegative) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + if (title != null) builder.setTitle(title); + if (message != null) builder.setMessage(message); + builder.setCancelable(isCancelable); + if (positiveLabel != null) builder.setPositiveButton(positiveLabel, onPositive); + if (neutralLabel != null) builder.setPositiveButton(neutralLabel, onNeutral); + if (negativeLabel != null) builder.setNegativeButton(negativeLabel, onNegative); + return builder.show(); + } + + public static AlertDialog showDialog(Context context, int messageResId) { + return showDialog(context, null, context.getResources().getString(messageResId), false, context.getResources().getString(R.string.Ok), null, null, null, null, null); + } + + public static AlertDialog showDialog(Context context, CharSequence message) { + return showDialog(context, null, message, false, context.getResources().getString(R.string.Ok), null, null, null, null, null); + } + + public static AlertDialog showDialog(Context context, CharSequence title, CharSequence message) { + return showDialog(context, title, message, false, context.getResources().getString(R.string.Ok), null, null, null, null, null); + } + + public static AlertDialog showConfirmDialog(Context context, int messageResId, DialogInterface.OnClickListener onPositive) { + return showDialog(context, null, context.getResources().getString(messageResId), false, context.getResources().getString(R.string.Ok), onPositive, null, null, context.getResources().getString(R.string.Cancel), null); + } + + public static AlertDialog showDialog(Context context, String message, String positiveLabel, DialogInterface.OnClickListener onPositive) { + return showDialog(context, null, message, false, positiveLabel, onPositive, null, null, context.getResources().getString(R.string.Cancel), null); + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/FileUtils.java b/app/src/main/java/org/openimis/imispolicies/util/FileUtils.java new file mode 100644 index 00000000..b9d5f832 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/FileUtils.java @@ -0,0 +1,196 @@ +package org.openimis.imispolicies.util; + +import android.content.Context; +import android.support.annotation.NonNull; + +import org.openimis.imispolicies.tools.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +public class FileUtils { + private static final String LOG_TAG = "FileUtil"; + + /** + * Replaces the extension of the file + * + * @param filename filename ending with extension + * @param targetExtension target extension, including a dot (to protect from replacing + * a substring inside filename that match current extension) + * @return filename with replaced extension, or null if the filename does not end with + * extension + */ + public static String replaceFilenameExtension(@NonNull String filename, @NonNull String targetExtension) { + try { + String currentExtension = filename.substring(filename.lastIndexOf('.')); + return filename.replace(currentExtension, targetExtension); + } catch (IndexOutOfBoundsException e) { + Log.e(LOG_TAG, "Filename does not have an extension at the end", e); + } + return null; + } + + public static boolean createFileWithSubdirectories(@NonNull File file) { + try { + File parent = file.getParentFile(); + + if (parent != null && !parent.exists() && !parent.mkdirs()) { + Log.e(LOG_TAG, "Creating parent directories failed for path: " + file.getAbsolutePath()); + } + + if (!file.createNewFile()) { + Log.e(LOG_TAG, "File already exists: " + file.getAbsolutePath()); + } + + return true; + } catch (Exception e) { + Log.e(LOG_TAG, "Error while creating file: " + file.getAbsolutePath(), e); + } + + return false; + } + + public static boolean createDirectoryWithSubdirectories(@NonNull File directory) { + try { + if (!directory.exists() && !directory.mkdirs()) { + Log.e(LOG_TAG, "Creating directory failed for path: " + directory.getAbsolutePath()); + } + return true; + } catch (Exception e) { + Log.e(LOG_TAG, "Error while creating directory: " + directory.getAbsolutePath(), e); + } + + return false; + } + + public static void deleteFiles(File[] files) { + for (File file : files) { + deleteFile(file); + } + } + + public static void deleteFile(File file) { + if (file.exists()) { + if (!file.delete()) { + Log.w(LOG_TAG, "Delete file failed: " + file.getAbsolutePath()); + } + } else { + Log.w(LOG_TAG, "File does not exists: " + file.getAbsolutePath()); + } + } + + public static void writeToFile(@NonNull File file, @NonNull InputStream is) { + try (OutputStream os = new FileOutputStream(file)) { + StreamUtils.bufferedStreamCopy(is, os); + } catch (IOException e) { + Log.e(LOG_TAG, "Error while writing to file: " + file.getAbsolutePath(), e); + } + } + + public static File[] getFilesStartingWith(@NonNull File directory, @NonNull String filenamePrefix) { + if (!directory.exists()) { + android.util.Log.e(LOG_TAG, "Directory does not exists: " + directory); + return null; + } + + if (!directory.isDirectory()) { + android.util.Log.e(LOG_TAG, "Provided path is not a directory: " + directory); + return null; + } + + return directory.listFiles((dir, filename) -> filename.startsWith(filenamePrefix)); + } + + public static File getNewestFileStartingWith(@NonNull File directory, @NonNull String filenamePrefix) { + File[] files = getFilesStartingWith(directory, filenamePrefix); + if (files == null || files.length == 0) { + return null; + } + Arrays.sort(files, (f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified())); + return files[files.length - 1]; + } + + public static String readFileAsUTF8String(@NonNull File file) { + try { + InputStream is = new FileInputStream(file); + return StreamUtils.readInputStreamAsUTF8String(is); + } catch (IOException e) { + Log.e(LOG_TAG, "Opening input stream failed for file: " + file.getAbsolutePath(), e); + } + return null; + } + + public static int getFileCount(File directory) { + if (!directory.exists() || !directory.isDirectory()) { + Log.e(LOG_TAG, "Not a directory: " + directory.getAbsolutePath()); + return -1; + } + + File[] files = directory.listFiles(File::isFile); + if (files != null) { + return files.length; + } else { + Log.e(LOG_TAG, "Counting files failed: " + directory.getAbsolutePath()); + return -1; + } + } + + /** + * Create a temporary file inside app's cache directory under specified path. This file should be + * manually deleted, but the cache directory can be emptied by the user or by the Android to save + * storage space. If the file exists, it will be deleted and recreated. + * + * @param targetPath Path to the temporary file inside cache, the cache root will be appended + * @return Created temp file + */ + public static File createTempFile(@NonNull Context context, @NonNull String targetPath) { + return createTempFile(context, targetPath, false); + } + + /** + * Create a temporary file inside app's cache directory under specified path. This file should be + * manually deleted, but the cache directory can be emptied by the user or by the Android to save + * storage space. If the file exists, it will be deleted and recreated. + * + * @param targetPath Path to the temporary file inside cache, the cache root will be appended + * @param preparePathOly Set to true if the abstract path should point to non-existing file + * (i.e. to forward the file object to a library to create the file) + * @return Created temp file + */ + public static File createTempFile(@NonNull Context context, @NonNull String targetPath, boolean preparePathOly) { + File tempFile = new File(context.getCacheDir(), targetPath); + + if (tempFile.exists() && tempFile.delete()) { + org.openimis.imispolicies.tools.Log.i(LOG_TAG, "Leftover temp file deleted: " + tempFile.getAbsolutePath()); + } + + if (preparePathOly) { + File parentFile = tempFile.getParentFile(); + if (parentFile != null) { + return FileUtils.createDirectoryWithSubdirectories(parentFile) ? tempFile : null; + } else { + return null; + } + } else { + return FileUtils.createFileWithSubdirectories(tempFile) ? tempFile : null; + } + } + + /** + * Convenience method for removing a temp file form specified path inside cache directory created + * by createTempFile(String). The file can also be safely deleted with returned File object. + * + * @param targetPath Path to the temporary file inside cache, the cache root will be appended + * @return true if file under targetPath does not exist or was successfully deleted, false if file + * exists and delete failed + */ + public static boolean removeTempFile(@NonNull Context context, @NonNull String targetPath) { + File tempFile = new File(context.getCacheDir(), targetPath); + return !tempFile.exists() || tempFile.delete(); + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/JsonUtils.java b/app/src/main/java/org/openimis/imispolicies/util/JsonUtils.java new file mode 100644 index 00000000..38ef09ab --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/JsonUtils.java @@ -0,0 +1,52 @@ +package org.openimis.imispolicies.util; + +import android.support.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +public class JsonUtils { + /** + * @param object Json object + * @param field field to be checked + * @return if the field does not exists, is null or empty + */ + public static boolean isStringEmpty(JSONObject object, @NonNull String field) { + return isStringEmpty(object, field, false); + } + + /** + * @param object Json object + * @param field field to be checked + * @param checkNullString Should "null" string be considered empty + * @return if the field does not exists, is null or empty + */ + public static boolean isStringEmpty(JSONObject object, @NonNull String field, boolean checkNullString) { + try { + return object == null + || !object.has(field) + || StringUtils.isEmpty(object.getString(field), checkNullString); + } catch (JSONException e) { + return true; + } + } + + /** + * @param object Json object + * @param field field to be checked + * @param defaultValue default value to be used if requested value does not exists + * @param checkNullString Should "null" string be considered empty + * @return value of the specified field if exists, default value otherwise + */ + public static String getStringOrDefault(@NonNull JSONObject object, @NonNull String field, String defaultValue, boolean checkNullString) { + try { + if (!isStringEmpty(object, field, checkNullString)) { + return object.getString(field); + } else { + return defaultValue; + } + } catch (JSONException e) { + return defaultValue; + } + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/LocaleUtils.java b/app/src/main/java/org/openimis/imispolicies/util/LocaleUtils.java new file mode 100644 index 00000000..417aa469 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/LocaleUtils.java @@ -0,0 +1,63 @@ +package org.openimis.imispolicies.util; + +import android.os.Build; +import android.os.LocaleList; +import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class LocaleUtils { + /** + * @param locale Locale to parse + * @return language tag for provided Locale object + */ + @NonNull + public static String getLanguageTag(@NonNull Locale locale) { + String languageTag; + String language = locale.getLanguage(); + String country = locale.getCountry(); + if (language.contains("-") || StringUtils.isEmpty(country)) { + languageTag = language; + } else { + languageTag = String.format("%s-%s", language, country); + } + return languageTag; + } + + /** + * Parse given language tag to Locale object. This method will parse "en" to Locale("en") and "en-US" + * into Locale("en", "US"). Locale("en-US") in an incorrect declaration. + * + * @param languageTag language tag to parse + * @return Locale object for given language tag + */ + @NonNull + public static Locale getLocaleFromTag(@NonNull String languageTag) { + String[] segments = languageTag.split("-"); + if (segments.length == 1) { + return new Locale(segments[0]); + } else { + return new Locale(segments[0], segments[1]); + } + } + + /** + * This method helps convert LocaleList object into java collection of Locale objects. This allows to use + * generic collection tools to be used with the LocaleList object. + * + * @param localeList System LocaleList object + * @return List of Locale objects accessible in LocaleList object + */ + @RequiresApi(api = Build.VERSION_CODES.N) + @NonNull + public static List toList(@NonNull LocaleList localeList) { + List result = new ArrayList<>(localeList.size()); + for (int i = 0; i < localeList.size(); i++) { + result.add(localeList.get(i)); + } + return result; + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/StreamUtils.java b/app/src/main/java/org/openimis/imispolicies/util/StreamUtils.java new file mode 100644 index 00000000..623b3b48 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/StreamUtils.java @@ -0,0 +1,60 @@ +package org.openimis.imispolicies.util; + +import android.support.annotation.NonNull; + +import org.openimis.imispolicies.tools.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +public class StreamUtils { + private static final int buffSize = 8192; + private static final String LOG_TAG = "STREAMUTIL"; + + /** + * Only use this method if you can be sure the content of the input stream + * can be read, is a UTF-8 text and will fit in memory (as String). + * + * @param is input stream to be read + * @return content of the input stream or null if IO exception occurs + */ + public static String readInputStreamAsUTF8String(@NonNull InputStream is) { + try (BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + StringBuilder stringBuilder = null; + String inputStr; + while ((inputStr = streamReader.readLine()) != null) { + if (stringBuilder != null) { + stringBuilder.append("\n"); + stringBuilder.append(inputStr); + } else { + stringBuilder = new StringBuilder(inputStr); + } + } + return stringBuilder != null ? stringBuilder.toString() : null; + } catch (IOException e) { + Log.e(LOG_TAG, "Error while reading input stream", e); + } + + return null; + } + + /** + * Copy input stream to output stream using a byte buffer (8kb by default) + * + * @param is source stream + * @param os target stream + * @throws IOException thrown on read/write error + */ + public static void bufferedStreamCopy(@NonNull InputStream is, @NonNull OutputStream os) throws IOException { + byte[] buffer = new byte[buffSize]; + + int read; + while ((read = is.read(buffer)) >= 0) { + os.write(buffer, 0, read); + } + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/StringUtils.java b/app/src/main/java/org/openimis/imispolicies/util/StringUtils.java new file mode 100644 index 00000000..6114e2b5 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/StringUtils.java @@ -0,0 +1,56 @@ +package org.openimis.imispolicies.util; + +import android.text.TextUtils; + +import java.util.List; +import java.util.function.Function; + +public class StringUtils { + public interface StringAccessor { + /** + * Return any string accessed from object. That can any String field, any String representation of + * a field or toString() of a whole object + * + * @return string accessed from object of type T + */ + String apply(T object); + } + + /** + * @param string String to be checked + * @return is string null or empty + */ + public static boolean isEmpty(CharSequence string) { + return isEmpty(string, false); + } + + /** + * @param string String to be checked + * @param checkNullString Should "null" string be considered empty (case insensitive) + * @return is string null or empty + */ + public static boolean isEmpty(CharSequence string, boolean checkNullString) { + return string == null + || string.equals("") + || (string.toString().equalsIgnoreCase("null") && checkNullString); + } + + /** + * Null-safe equality check (true if both are null) + */ + public static boolean equals(CharSequence s1, CharSequence s2) { + return TextUtils.equals(s1, s2); + } + + public static String join(String delimiter, Iterable collection, StringAccessor accessor) { + StringBuilder builder = new StringBuilder(); + for (T item : collection) { + if (builder.length() == 0) { + builder.append(accessor.apply(item)); + } else { + builder.append(delimiter).append(accessor.apply(item)); + } + } + return builder.toString(); + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/util/UriUtils.java b/app/src/main/java/org/openimis/imispolicies/util/UriUtils.java new file mode 100644 index 00000000..6f138fb7 --- /dev/null +++ b/app/src/main/java/org/openimis/imispolicies/util/UriUtils.java @@ -0,0 +1,127 @@ +package org.openimis.imispolicies.util; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.OpenableColumns; +import android.support.annotation.NonNull; +import android.support.v4.content.FileProvider; + +import org.openimis.imispolicies.BuildConfig; +import org.openimis.imispolicies.tools.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class UriUtils { + private static final String LOG_TAG = "URIUTIL"; + public static final String FILE_PROVIDER_NAME = String.format("%s.fileprovider", BuildConfig.APPLICATION_ID); + + public static String getDisplayName(@NonNull Context context, @NonNull Uri uri) { + try (Cursor c = context.getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null)) { + c.moveToFirst(); + c.moveToFirst(); + return c.getString(c.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + } catch (Exception e) { + Log.e(LOG_TAG, "Reading file name from URI failed", e); + } + return null; + } + + + public static void writeToUri(@NonNull Context context, @NonNull Uri uri, @NonNull InputStream is) { + try (OutputStream os = context.getContentResolver().openOutputStream(uri, "w")) { + StreamUtils.bufferedStreamCopy(is, os); + } catch (IOException e) { + Log.e(LOG_TAG, "Writing to uri failed: " + uri, e); + } + } + + /** + * Copy byte content of the file to location described by the uri. The uri must be openable and + * allow writing. The file must be openable and readable. + * + * @param file File to be read + * @param uri Uri pointing to writable location + */ + public static void copyFileToUri(@NonNull Context context, @NonNull File file, @NonNull Uri uri) { + try (InputStream is = new FileInputStream(file)) { + writeToUri(context, uri, is); + } catch (IOException e) { + android.util.Log.e(LOG_TAG, "Error while opening streams", e); + } + } + + /** + * Copy byte content of the file to location described by the uri. The uri must be openable and + * allow writing. The file must be openable and readable. + * + * @param filePath Path to file to be read + * @param uri Uri pointing to writable location + */ + public static void copyFileToUri(@NonNull Context context, @NonNull String filePath, @NonNull Uri uri) { + copyFileToUri(context, new File(filePath), uri); + } + + /** + * Copy the content of the provided uri to provided file. The file location must allow creating + * a file and writing to a file. + * + * @param uri Uri of the file to copy. The Uri should allow read and should be openable + * @param targetFile File to be used as output stream + * @return File object pointing to created file + */ + public static File copyUriContentToFile(@NonNull Context context, @NonNull Uri uri, @NonNull File targetFile) { + if (!targetFile.exists()) { + FileUtils.createFileWithSubdirectories(targetFile); + } + try (InputStream is = context.getContentResolver().openInputStream(uri)) { + FileUtils.writeToFile(targetFile, is); + } catch (IOException e) { + android.util.Log.e(LOG_TAG, "Error while opening streams", e); + } + + return targetFile; + } + + + /** + * Create a content URI for a file owned by the app. The directory path have to be specified in + * res/xml/paths.xml to be eligible to provide content. Uri returned by this method can be shared + * with other apps with intents. + * + * @param file File to be specified by generated content URI + * @return Content URI for a given file + */ + public static Uri createUriForFile(@NonNull Context context, @NonNull File file) { + Uri uri = FileProvider.getUriForFile(context, FILE_PROVIDER_NAME, file); + if (uri == null) { + org.openimis.imispolicies.tools.Log.w(LOG_TAG, "Failed to create temp photo URI"); + } + return uri; + } + + /** + * Copy the content of the provided uri to cache directory under provided path. The caller is + * responsible to delete the file after use. The file can be deleted by Android or the user + * without notifying the app. + * + * @param uri Uri of the file to copy. The Uri should allow read and should be openable + * @param targetPath Path inside cache directory to save the file (cache location will be appended) + * @return File object pointing to created file + */ + public static File copyUriContentToCache(@NonNull Context context, @NonNull Uri uri, @NonNull String targetPath) { + File outputFile = FileUtils.createTempFile(context, targetPath, false); + if (outputFile != null) { + return copyUriContentToFile(context, uri, outputFile); + } else { + Log.e(LOG_TAG, "Creating temp file failed for: " + targetPath); + return null; + } + + + } +} diff --git a/app/src/main/java/org/openimis/imispolicies/tools/Compressor.java b/app/src/main/java/org/openimis/imispolicies/util/ZipUtils.java similarity index 56% rename from app/src/main/java/org/openimis/imispolicies/tools/Compressor.java rename to app/src/main/java/org/openimis/imispolicies/util/ZipUtils.java index 06008a18..2619b343 100644 --- a/app/src/main/java/org/openimis/imispolicies/tools/Compressor.java +++ b/app/src/main/java/org/openimis/imispolicies/util/ZipUtils.java @@ -1,15 +1,39 @@ -package org.openimis.imispolicies.tools; +package org.openimis.imispolicies.util; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.util.Zip4jConstants; +import org.openimis.imispolicies.tools.Log; + import java.io.File; import java.util.ArrayList; +import java.util.Collections; + +public class ZipUtils { + private static final String LOG_TAG = "ZIPUTILS"; + + public static File zipDirectories(File outputFile, String zipPassword, File... directories) { + ArrayList filesToAdd = new ArrayList<>(); + for (File directory : directories) { + if (!directory.exists() || !directory.isDirectory()) { + Log.w(LOG_TAG, "Provided file is not a directory: " + directory); + continue; + } + + File[] files = directory.listFiles(); + if (files == null) { + Log.w(LOG_TAG, "Reading a directory filed: " + directory); + continue; + } + + Collections.addAll(filesToAdd, files); + } + + return zipFiles(filesToAdd, outputFile, zipPassword); + } -public class Compressor { - private static final String LOG_TAG = "COMPRESSOR"; - public static File zip(ArrayList filesToAdd, File destinationFile, String password) { + public static File zipFiles(ArrayList filesToAdd, File destinationFile, String password) { try { ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); @@ -31,7 +55,7 @@ public static File zip(ArrayList filesToAdd, File destinationFile, String return null; } - public static void zip(String targetPath, String destinationFilePath, String password) { + public static void zipPath(String targetPath, String destinationFilePath, String password) { try { ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); @@ -57,7 +81,20 @@ public static void zip(String targetPath, String destinationFilePath, String pas } } - public static void unzip(String targetZipFilePath, String destinationFolderPath, String password) { + public static void unzipFile(File targetZipFile, File destinationFolder, String password) { + try { + ZipFile zipFile = new ZipFile(targetZipFile); + if (zipFile.isEncrypted()) { + zipFile.setPassword(password); + } + zipFile.extractAll(destinationFolder.getPath()); + + } catch (Exception e) { + Log.e(LOG_TAG, "Error while decompressing", e); + } + } + + public static void unzipPath(String targetZipFilePath, String destinationFolderPath, String password) { try { ZipFile zipFile = new ZipFile(targetZipFilePath); if (zipFile.isEncrypted()) { @@ -66,7 +103,7 @@ public static void unzip(String targetZipFilePath, String destinationFolderPath, zipFile.extractAll(destinationFolderPath); } catch (Exception e) { - Log.e(LOG_TAG, "Error while compressing", e); + Log.e(LOG_TAG, "Error while decompressing", e); } } } diff --git a/app/src/main/res/layout/activity_enquire.xml b/app/src/main/res/layout/activity_enquire.xml index 5637752c..c3a98d25 100644 --- a/app/src/main/res/layout/activity_enquire.xml +++ b/app/src/main/res/layout/activity_enquire.xml @@ -62,9 +62,9 @@ tools:ignore="RtlHardcoded" /> + android:orientation="vertical"> + + diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index ec3925f4..8f33f82c 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -56,5 +56,5 @@ + android:title="@string/menu_settings" /> diff --git a/app/src/main/res/values-fr-rCM/strings.xml b/app/src/main/res/values-fr-rCM/strings.xml deleted file mode 100644 index 8f5187c9..00000000 --- a/app/src/main/res/values-fr-rCM/strings.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - openIMIS - admin@imis.com - Accueil - Adhésion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Région - District - Section - Village/GO - Situation de pauvreté - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir une Région - Choisir un district - Choisir une section - Choisir un village/GO - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Autres noms - Nom de famille - Date de naissance - Genre - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Éducation - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Sél. genre - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Sél. agent - Sél. un Paquet de bénéfice - Sél. Mois - Date d\'adhésion - Paquet de bénéfice - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom de l\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - openIMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Numéro d\'assuré invalide - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Le process a échoué: mauvais fichier ou mauvais code agent. - Soumettre - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de Paquet de bénéfice - Chargement… - Données envoyées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été envoyées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Envoi ... - Aucun retour d\'information trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Envoi des retours... - Envoyer tous les retours - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la prestation - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du Paquet de bénéfice - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Entrez le mot de passe Rar - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Il y a eu un problème sur le serveur. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille envoyée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Envoyer les adhésions - Créer un XML d\'adhésions - Envoyer les renouvellements - Envoyer les retours - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter openIMIS ? - envoyer le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les retours d\'information n\'ont pas pu être téléchargés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être envoyé, veuillez réessayer plus tard. - Région de PPS - Région actuelle - Envoyé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être envoyées au serveur. Enregistré sur les carte mémoire externe. - Photo envoyées avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Envoyer toutes les images - Photos envoyées avec succès - Aucune photo trouvée - Envoyer les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirm - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été envoyée - Pas de donné disponible - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec de l\'envoi - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les contrats ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer le XML des retours - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Polices renouvelées non listées - Renouveler votre police - Nom de l\'utilisateur - Code de la prestation - Encoder ici - Entrer le nom d\'utilisateur et du mot de passe - Login a été entré avec succès - Entrée non valide - Montant total - Numéros de contrôle - aperçu des polices d\'assurance - Aperçu des numéros de contrôle - Numéros de contrôle - Aperçu des polices - Aperçu des numéros de contrôle - Nom du Paquet de bénéfice: - Date d\'envoi - Date demandée: - Code du Paquet de bénéfice: - Noms: - Renouvellement: - N° d\'assuré - Demandé au - Demandé du - Envoi au - au - Envoi du - Paquet de bénéfice - Effacer - Demandé - Nombre de polices trouvé - Montant de la contribution - Processus Complet - Veuillez sélectionner un police - Succès - Vous n\'avez pas les droits pour cette fonctionnalité - OK - Pas de donné sélectionnée pour la suppression - Obtenir le numéro de contrôle - Les polices n\'ont pas été supprimées car elles ne sont pas encore envoyées au serveur. - sur - Requête envoyée avec succès - Cette police ne peut pas être supprimées car elle n\'est pas encore envoyée au serveur. - Type de paiement - Requête - PAS DE CONNECTION INTERNET - Voulez-vous importer le ficher .txt dans la base de donnée ? - Il n\'y a pas d\'application de gestion des fichiers d\'installé. - Chargement fichier: - Incomplet! - Contrôler la commission - Année - Payée - Vérifiée - obtenir les commissions - Rapport de Commissions - Montant - commissions - Rechercher les politiques inscrites - Recherche des n° de contrôle - Vue d\'ensemble - Polices - Pas de donnée - Entrer l\'année - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Dernier versement - Polices enregistrées - Polices non enregistrées - Demande pour polices non enregistrées - Numéro de téléphone non fourni - Les produits d\'assurance des polices sélectionnées ne sont pas uniques - Montant de la contribution - Choisir la date - Obtenir - Date du - Date à - Envoyer un SMS - SMS demandé - TotalAdmissionsLeft - TotalVisitsLeft - TotalConsultationsLeft - TotalSurgeriesLeft - TotalDeliveriesLeft - TotalAntenatalLeft - ConsultationAmountLeft - SurgeryAmountLeft - HospitalizationAmountLeft - AntenatalAmountLeft - DeliveryAmountLeft - Please login first, to check receipt number. - IMIS Directory could not be created. - Cumulative Indicators - Language Of SMS - Approval Of SMS - Payment Overview - Get payment CN for enrolled policies - Get payment CN for not enrolled policies - Overview payment CN - Please login first, to download renewals. - Select All - Deselect All - Synchronization processing - Vulnerability - Select Vulnerability - Bulk Control Numbers - Assigned Control Numbers: - Free Control Numbers: - Fetch Bulk Control Numbers - Fetch - Please log in first, to fetch control numbers. - No control numbers left for this product. Please fetch control numbers or provide control number from other source. - Control Number : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Renewal accepted - Renewal already accepted - Renewal rejected - Grace period expired - Control number error - Unexpected exception - Invalid renewal file - Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. - Do you want to select renewal file to import? - RAR Password - Save RAR Password - Set the default RAR password - Default RAR Password - Wait %1$s seconds - Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. - CN limit reached - diff --git a/app/src/main/res/values-fr-rMR/strings.xml b/app/src/main/res/values-fr-rMR/strings.xml deleted file mode 100644 index 3d9ea319..00000000 --- a/app/src/main/res/values-fr-rMR/strings.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - Polices openIMIS - admin@imis.com - Accueil - Adhésion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Région - District - Section - Village/GO - Situation de pauvreté - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir une Région - Choisir un district - Choisir une section - Choisir un village/GO - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Autres noms - Nom de famille - Date de naissance - Genre - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Éducation - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Sél. genre - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Sél. agent - Sél. un Paquet de bénéfice - Sél. Mois - Date d\'adhésion - Paquet de bénéfice - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom de l\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - openIMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Numéro d\'assuré invalide - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Le process a échoué: mauvais fichier ou mauvais code agent. - Soumettre - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de Paquet de bénéfice - Chargement… - Données téléversées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été téléversées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Téléversement ... - Aucun retour d\'information trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Téléversement des retours... - Téléverser tous les retours - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la prestation - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du Paquet de bénéfice - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Entrez le mot de passe Rar - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Il y a eu un problème sur le serveur. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille téléversée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Téléverser les adhésions - Créer un XML d\'adhésions - Téléverser les renouvellements - Téléverser les retours - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter openIMIS ? - Téléverser le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les retours d\'information n\'ont pas pu être téléchargés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être téléversé, veuillez réessayer plus tard. - Région de PPS - Région actuelle - Téléversé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être téléversées sur le serveur. Enregistré sur les carte mémoire externe. - Photo téléversée avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Téléverser toutes les images - Photos téléversées avec succès - Aucune photo trouvée - Téléverser les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirmer - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été téléversée - Pas de donné disponible - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec du téléversement - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les contrats ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer le XML des retours - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Polices renouvelées non listées - Renouveler votre police - Nom de l\'utilisateur - Code de la prestation - Encoder ici - Entrer le nom d\'utilisateur et du mot de passe - Login a été entré avec succès - Entrée non valide - Montant total - Numéros de contrôle - aperçu des polices d\'assurance - Aperçu des numéros de contrôle - Numéros de contrôle - Aperçu des polices - Aperçu des numéros de contrôle - Nom du Paquet de bénéfice: - Date téléversement: - Date demandée: - Code du Paquet de bénéfice: - Noms: - Renouvellement: - N° d\'assuré - Demandé au - Demandé du - Téléversé au - au - Téléversé du - Paquet de bénéfice - Effacer - Demandé - Nombre de polices trouvé - Montant de la contribution - Processus Complet - Veuillez sélectionner un police - Succès - Vous n\'avez pas les droits pour cette fonctionnalité - OK - Pas de donné sélectionnée pour la suppression - Obtenir le numéro de contrôle - Les polices n\'ont pas été supprimées car elles ne sont pas encore téléversées - sur - Requête envoyée avec succès - Cette police ne peut pas être supprimées car elle n\'est pas encore téléversées. - Type de paiement - Requête - PAS DE CONNECTION INTERNET - Voulez-vous importer le ficher .txt dans la base de donnée ? - Il n\'y a pas d\'application de gestion des fichiers d\'installé. - Chargement fichier: - Incomplet! - Contrôler la commission - Année - Payée - Vérifiée - obtenir les commissions - Rapport de Commissions - Montant - commissions - Rechercher les politiques inscrites - Recherche des n° de contrôle - Vue d\'ensemble - Polices - Pas de donnée - Entrer l\'année - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Dernier versement - Polices enregistrées - Polices non enregistrées - Demande pour polices non enregistrées - Numéro de téléphone non fourni - Les produits d\'assurance des polices sélectionnées ne sont pas uniques - Montant de la contribution - Choisir la date - Obtenir - Date du - Date à - Envoyer un SMS - SMS demandé - TotalAdmissionsLeft - TotalVisitsLeft - TotalConsultationsLeft - TotalSurgeriesLeft - TotalDeliveriesLeft - TotalAntenatalLeft - ConsultationAmountLeft - SurgeryAmountLeft - HospitalizationAmountLeft - AntenatalAmountLeft - DeliveryAmountLeft - Veuillez d\'abord vous connecter pour vérifier le numéro de reçu. - Le répertoire IMIS n\'a pas pu être créé. - Indicateurs cumulatifs - Langue des SMS - Approbation de SMS - Aperçu des paiements - Obtenir le CN de paiement pour les polices inscrites - Obtenir le CN de paiement pour les polices non inscrites - Aperçu paiement CN - Veuillez d\'abord vous connecter pour télécharger les renouvellements. - Tout sélectionner - Tout déselectionner - Traitement de synchronisation - Vulnérabilité - Sélectionnez la vulnérabilité - Numéros de contrôle en masse - Numéros de contrôle attribués : - Numéros de contrôle disponibles : - Récupérer les numéros de contrôle en masse - Chercher - Veuillez d\'abord vous connecter pour récupérer les numéros de contrôle. - Il ne reste aucun numéro de contrôle pour ce produit. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Numéro de contrôle : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Renewal accepted - Renewal already accepted - Renewal rejected - Grace period expired - Control number error - Unexpected exception - Invalid renewal file - Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. - Voulez-vous sélectionner le fichier de renouvellement à importer? - RAR Password - Save RAR Password - Set the default RAR password - Default RAR Password - Wait %1$s seconds - Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. - Limite CN atteinte - diff --git a/app/src/main/res/values-fr-rNE/strings.xml b/app/src/main/res/values-fr-rNE/strings.xml deleted file mode 100644 index 81338a96..00000000 --- a/app/src/main/res/values-fr-rNE/strings.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - Polices openIMIS - admin@imis.com - Accueil - Adhésion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Région - District - Antenne locale - Village/GO/quartier - Situation de pauvreté/indigent - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir une Région - Choisir un district - Choisir un antenne locale - Choisir un village/GO/quartier - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Prénom(s) - Nom de famille - Date de naissance - Genre - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Éducation - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Sél. genre - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Sél. agent - Sél. un Paquet de bénéfice - Sél. Mois - Date d\'adhésion - Paquet de bénéfice - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom de l\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - openIMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Numéro d\'assuré invalide - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Le process a échoué: mauvais fichier ou mauvais code agent. - Soumettre - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de Paquet de bénéfice - Chargement… - Données téléversées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été téléversées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Téléversement ... - Aucun retour d\'information trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Téléversement des retours... - Téléverser tous les retours - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la prestation - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du Paquet de bénéfice - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Entrez le mot de passe Rar - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Il y a eu un problème sur le serveur. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille téléversée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Téléverser les adhésions - Créer un XML d\'adhésions - Téléverser les renouvellements - Téléverser les retours - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter openIMIS ? - Téléverser le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les retours d\'information n\'ont pas pu être téléchargés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être téléversé, veuillez réessayer plus tard. - Région de PPS - Région actuelle - Téléversé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être téléversées sur le serveur. Enregistré sur les carte mémoire externe. - Photo téléversée avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Téléverser toutes les images - Photos téléversées avec succès - Aucune photo trouvée - Téléverser les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirmer - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été téléversée - Pas de donné disponible - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec du téléversement - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les contrats ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer le XML des retours - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Polices renouvelées non listées - Renouveler votre police - Nom de l\'utilisateur - Code de la prestation - Encoder ici - Entrer le nom d\'utilisateur et du mot de passe - Login a été entré avec succès - Entrée non valide - Montant total - Numéros de contrôle - aperçu des polices d\'assurance - Aperçu des numéros de contrôle - Numéros de contrôle - Aperçu des polices - Aperçu des numéros de contrôle - Nom du Paquet de bénéfice: - Date téléversement: - Date demandée: - Code du Paquet de bénéfice: - Noms: - Renouvellement: - N° d\'assuré - Demandé au - Demandé du - Téléversé au - au - Téléversé du - Paquet de bénéfice - Effacer - Demandé - Nombre de polices trouvé - Montant de la contribution - Processus Complet - Veuillez sélectionner un police - Succès - Vous n\'avez pas les droits pour cette fonctionnalité - OK - Pas de donné sélectionnée pour la suppression - Obtenir le numéro de contrôle - Les polices n\'ont pas été supprimées car elles ne sont pas encore téléversées - sur - Requête envoyée avec succès - Cette police ne peut pas être supprimées car elle n\'est pas encore téléversées. - Type de paiement - Requête - PAS DE CONNECTION INTERNET - Voulez-vous importer le ficher .txt dans la base de donnée ? - Il n\'y a pas d\'application de gestion des fichiers d\'installé. - Chargement fichier: - Incomplet! - Contrôler la commission - Année - Payée - Vérifiée - obtenir les commissions - Rapport de Commissions - Montant - commissions - Rechercher les politiques inscrites - Recherche des n° de contrôle - Vue d\'ensemble - Polices - Pas de donnée - Entrer l\'année - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Dernier versement - Polices enregistrées - Polices non enregistrées - Demande pour polices non enregistrées - Numéro de téléphone non fourni - Les produits d\'assurance des polices sélectionnées ne sont pas uniques - Montant de la contribution - Choisir la date - Obtenir - Date du - Date à - Envoyer un SMS - SMS demandé - Total admissions restantes - Total visites restantes - Total consultations restantes - Total chirurgies restantes - Total accouchements restant - Total soins anténataux restant - Montant restant chirurgie - Montant restant chirurgie - Montant restant hospitalisation - Montant restant soin anténatal - Montant restant accouchement - Veuillez d\'abord vous connecter pour vérifier le numéro de reçu. - Le répertoire IMIS n\'a pas pu être créé. - Indicateurs cumulatifs - Langue des SMS - Approbation de SMS - Aperçu des paiements - Obtenir le numéro de contrôle de paiement pour les polices inscrites - Obtenir le numéro de contrôle de paiement pour les polices non inscrites - Aperçu du numéro de contrôle de paiement - Veuillez d\'abord vous connecter pour télécharger les renouvellements. - Tout sélectionner - Tout déselectionner - Traitement de synchronisation - Vulnérabilité - Sélectionnez la vulnérabilité - Numéros de contrôle en masse - Numéros de contrôle attribués : - Numéros de contrôle disponibles : - Récupérer les numéros de contrôle en masse - Chercher - Veuillez d\'abord vous connecter pour récupérer les numéros de contrôle. - Il ne reste aucun numéro de contrôle pour ce produit. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Numéro de contrôle : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Demande de renouvellement acceptée - Demande de renouvellement déjà acceptée - Demande de renouvellement rejetée - Période d\'approbation expirée - Erreur de numéro de contrôle - Exception inattendue - Fichier de renouvellements invalide - Le numéro de contrôle \"%1$s\" n\'est pas présent dans la mémoire du téléphone. Veuillez confirmer que ce numéro est correct. - Do you want to select renewal file to import? - RAR Password - Save RAR Password - Set the default RAR password - Default RAR Password - Wait %1$s seconds - Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. - CN limit reached - diff --git a/app/src/main/res/values-fr-rTD/strings.xml b/app/src/main/res/values-fr-rTD/strings.xml deleted file mode 100644 index d7e7366d..00000000 --- a/app/src/main/res/values-fr-rTD/strings.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - IMIS - admin@imis.com - Accueil - Adhesion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Promoteur - Mutuelle - Section - Village/GO - Situation de pauvreté - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir un promoteur - Choisir une mutuelle - Choisir une section - Choisir un village/GO - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Autres noms - Nom de famille - Date de naissance - Sexe - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Education - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Choisir le sexe - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Choisir un agent - Sélectionner un produit - Sél. Mois - Date d\'adhésion - Produit - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom d\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - IMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Numéro d\'assuré invalide - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Process Failed, Wrong File or Officer code. - Submit - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de produit - Chargement… - Données téléversées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été téléversées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Téléversement ... - Aucun commentaire trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Chargement des commentaires... - Téléverser tous les commentaires - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la demande de remboursement - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du produit - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Entrez le mot de passe Rar - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Il y a eu un problème sur le serveur. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille téléversée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Téléverser les adhésions - Créer un XML d\'adhésions - Téléverser les renouvellements - Téléverser les commentaires - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter IMIS ? - Téléverser le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les commentaires n\'ont pas pu être téléversés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être téléversé, veuillez réessayer plus tard. - Région de PPS - Promoteur actuel - Téléversé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être téléversées sur le serveur. Enregistré sur les carte mémoire externe. - Photo téléversée avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Téléverser toutes les images - Photos téléversées avec succès - Aucune photo trouvée - Téléverser les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirmer - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été téléchargée - Pas de donné disponible - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec du téléversement - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les services du contrat ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer des commentaires XML - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Unlisted Renewal Policies - Renew Your Policy - Nom de l\'utilisateur - Code de la prestation - Encoder ici - Entrer le nom d\'utilisateur et du mot de passe - Login a été entré avec succès - Entrée non valide - Montant total - Numéros de contrôle - aperçu des polices d\'assurance - Aperçu des numéros de contrôle - Numéros de contrôle - Aperçu des polices - Aperçu des numéros de contrôle - Nom du Paquet de bénéfice: - Date téléversement: - Date demandée: - Code du Paquet de bénéfice: - Noms: - Renouvellement: - N° d\'assuré - Demandé au - Demandé du - Téléversé au - au - Téléversé du - Paquet de bénéfice - Effacer - Demandé - Nombre de polices trouvé - Montant de la contribution - Processus Complet - Veuillez sélectionner un police - Succès - Vous n\'avez pas les droits pour cette fonctionnalité - OK - Pas de donné sélectionnée pour la suppression - Obtenir le numéro de contrôle - Les polices n\'ont pas été supprimées car elles ne sont pas encore téléversées - sur - Requête envoyée avec succès - Cette police ne peut pas être supprimées car elle n\'est pas encore téléversées. - Type de paiement - Requête - PAS DE CONNECTION INTERNET - Voulez-vous importer le ficher .txt dans la base de donnée ? - Il n\'y a pas d\'application de gestion des fichiers d\'installé. - Chargement fichier: - Incomplet! - Contrôler la commission - Année - Payée - Vérifiée - obtenir les commissions - Rapport de Commissions - Montant - commissions - Rechercher les politiques inscrites - Recherche des n° de contrôle - Vue d\'ensemble - Polices - Pas de donnée - Entrer l\'année - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Dernier versement - Polices enregistrées - Polices non enregistrées - Demande pour polices non enregistrées - Numéro de téléphone non fourni - Les produits d\'assurance des polices sélectionnées ne sont pas uniques - Montant de la contribution - Choisir la date - Obtenir - Date du - Date à - Envoyer un SMS - SMS demandé - TotalAdmissionsLeft - TotalVisitsLeft - TotalConsultationsLeft - TotalSurgeriesLeft - TotalDeliveriesLeft - TotalAntenatalLeft - ConsultationAmountLeft - SurgeryAmountLeft - HospitalizationAmountLeft - AntenatalAmountLeft - DeliveryAmountLeft - Veuillez d\'abord vous connecter pour vérifier le numéro de reçu. - Le répertoire IMIS n\'a pas pu être créé. - Indicateurs cumulatifs - Langue des SMS - Approbation de SMS - Aperçu des paiements - Obtenir le CN de paiement pour les polices inscrites - Obtenir le CN de paiement pour les polices non inscrites - Aperçu paiement CN - Veuillez d\'abord vous connecter pour télécharger les renouvellements. - Tout sélectionner - Tout déselectionner - Traitement de synchronisation - Vulnérabilité - Sélectionnez la vulnérabilité - Numéros de contrôle en masse - Numéros de contrôle attribués : - Numéros de contrôle disponibles : - Récupérer les numéros de contrôle en masse - Chercher - Veuillez d\'abord vous connecter pour récupérer les numéros de contrôle. - Il ne reste aucun numéro de contrôle pour ce produit. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Numéro de contrôle : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Renewal accepted - Renewal already accepted - Renewal rejected - Grace period expired - Control number error - Unexpected exception - Invalid renewal file - Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. - Voulez-vous sélectionner le fichier de renouvellement à importer? - RAR Password - Save RAR Password - Set the default RAR password - Default RAR Password - Wait %1$s seconds - Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. - Limite CN atteinte - diff --git a/app/src/main/res/values-fr-rcd/strings.xml b/app/src/main/res/values-fr-rcd/strings.xml deleted file mode 100644 index a653f668..00000000 --- a/app/src/main/res/values-fr-rcd/strings.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - IMIS - admin@imis.com - Accueil - Adhesion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Promoteur - Mutuelle - Section - Village/GO - Situation de pauvreté - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir un promoteur - Choisir une mutuelle - Choisir une section - Choisir un village/GO - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Autres noms - Nom de famille - Date de naissance - Sexe - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Education - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Choisir le sexe - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Choisir un agent - Sélectionner un produit - Select Month - Date d\'adhésion - Produit - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom d\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - IMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Numéro d\'assuré invalide - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Process Failed, Wrong File or Officer code. - Submit - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de produit - Chargement… - Données téléversées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été téléversées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Téléversement ... - Aucun commentaire trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Chargement des commentaires... - Téléverser tous les commentaires - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la demande de remboursement - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du produit - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Enter Rar Password - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Something went wrong on the server. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille téléversée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Téléverser les adhésions - Créer un XML d\'adhésions - Téléverser les renouvellements - Téléverser les commentaires - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter IMIS ? - Téléverser le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les commentaires n\'ont pas pu être téléversés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être téléversé, veuillez réessayer plus tard. - Région de PPS - Promoteur actuel - Téléversé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être téléversées sur le serveur. Enregistré sur les carte mémoire externe. - Photo téléversée avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Téléverser toutes les images - Photos téléversées avec succès - Aucune photo trouvée - Téléverser les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirm - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été téléchargée - No data available - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec du téléversement - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les services du contrat ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer des commentaires XML - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Unlisted Renewal Policies - Renew Your Policy - Username - Claim Code - Type here - Please enter username and password - Login Successful - Entrée non valide - Montant total - Control Numbers - Overview Policies - Overview Control Numbers - Control Numbers - Overview policies - Overview control numbers - Product Name: - Date téléversement: - Requested Date: - Product Code: - Names: - Renewal: - Insurance No. - Requested To - Requested From - Téléversé au - TO - Téléversé du - Insurance product - Clear - Requested - Number of found policies - Amount of contribution - Process Complete - Please select a policy/policies to request - Successfully - Not authorized - OK - No data was selected to delete - Get Control Number - Les polices n\'ont pas été supprimées car elles ne sont pas encore téléversées - of - Request has been sent successfully - Cette police ne peut pas être supprimées car elle n\'est pas encore téléversées. - Type of payment - Request - NO INTERNET CONNECTION - Do you want to import .txt file from your DATABASE folder? - There are no file explorer clients installed. - Load file: - Incomplete! - Check Commission - Year - Paid - Check - Get Commissions - Commissions Report - Amount - commissions - Rechercher les politiques inscrites - Search Control Numbers - Overviews - Policies - No data - Please fill the year - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Last Installment - Enrolled Policies - Polices non enregistrées - Request for Not Enrolled Policies - Phone number not provided - Insurance products of the selected policies are not unique - Amount of contribution - Pick Date - Get - Date From - Date To - Send SMS - Requested SMS - TotalAdmissionsLeft - TotalVisitsLeft - TotalConsultationsLeft - TotalSurgeriesLeft - TotalDeliveriesLeft - TotalAntenatalLeft - ConsultationAmountLeft - SurgeryAmountLeft - HospitalizationAmountLeft - AntenatalAmountLeft - DeliveryAmountLeft - Please login first, to check receipt number. - IMIS Directory could not be created. - Cumulative Indicators - Language Of SMS - Approval Of SMS - Payment Overview - Get payment CN for enrolled policies - Get payment CN for not enrolled policies - Overview payment CN - Please login first, to download renewals. - Select All - Deselect All - Synchronization processing - Vulnerability - Select Vulnerability - Bulk Control Numbers - Assigned Control Numbers: - Free Control Numbers: - Fetch Bulk Control Numbers - Fetch - Please log in first, to fetch control numbers. - No control numbers left for this product. Please fetch control numbers or provide control number from other source. - Control Number : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Renewal accepted - Renewal already accepted - Renewal rejected - Grace period expired - Control number error - Unexpected exception - Invalid renewal file - Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. - Do you want to select renewal file to import? - RAR Password - Save RAR Password - Set the default RAR password - Default RAR Password - Wait %1$s seconds - Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. - CN limit reached - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0067d6ea..1d08e87e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -444,9 +444,6 @@ Wait %1$s seconds Control number request finished. If the available CN amount does not increase, please try again in %1$s seconds. CN limit reached - Wait - Suspend - Enforce No control numbers received from the server You cannot receive more control numbers for this product Export all logs: @@ -456,6 +453,29 @@ Clear all logs: Clear logs Do you want to clear logs? + Wait + Suspend + Enforce without a policy without a premium + HTTP response: %1$d — %2$s + No policies registered. + This cheque number already used + This cheque number was aborted + Could not download cheque numbers data + Policy Status: Covered + Policy Status: Not Covered + Policy Status + This cheque number not exist + Please add a picture + Entry does not exist. + Authorization failed. + Unknown Error. + You are not allowed to take this action. + en + Language settings + Current resource language: %1$s + Current system language is not supported. The app will use the default language. + Supported languages:\n%1$s + Data download failed diff --git a/app/src/main/res/xml/paths.xml b/app/src/main/res/xml/paths.xml index 3acd7ab6..f6e484ca 100644 --- a/app/src/main/res/xml/paths.xml +++ b/app/src/main/res/xml/paths.xml @@ -1,4 +1,5 @@ + diff --git a/app/src/release/java/org/openimis/imispolicies/tools/Log.java b/app/src/release/java/org/openimis/imispolicies/tools/Log.java index ad642c49..485413fe 100644 --- a/app/src/release/java/org/openimis/imispolicies/tools/Log.java +++ b/app/src/release/java/org/openimis/imispolicies/tools/Log.java @@ -1,5 +1,7 @@ package org.openimis.imispolicies.tools; +import android.content.Context; + import org.openimis.imispolicies.BuildConfig; /** @@ -40,7 +42,7 @@ public static void e(String tag, String msg) { public static void e(String tag, String msg, Throwable thr) { } - public static void zipLogFiles() { + public static void zipLogFiles(Context context) { } public static void deleteLogFiles() { diff --git a/app/src/tchad/res/values-fr/strings.xml b/app/src/tchad/res/values-fr/strings.xml deleted file mode 100644 index 35b70ae8..00000000 --- a/app/src/tchad/res/values-fr/strings.xml +++ /dev/null @@ -1,439 +0,0 @@ - - - Ouvrir le menu de navigation - Fermer le menu de navigation - Réglages - Veuillez patienter... - La page se charge... - IMIS - admin@imis.com - Accueil - Adhesion - Renouvellement - Retour d\'information - Synchroniser - A propos - Quitter - Promoteur - Mutuelle - Section - Village/GO - Situation de pauvreté - Type de confirmation - No. de confirmation - Type de groupe - Ethnicité - Adresse permanente - Suivant - Choisir un promoteur - Choisir une mutuelle - Choisir une section - Choisir un village/GO - Oui - Non - Sélectionner le statut de pauvreté - Sélectionner le type de confirmation - Sélectionner le type de groupe - OK - Veuillez vérifier tous les champs obligatoires marqués en rouge. - Numéro d\'assurance - Autres noms - Nom de famille - Date de naissance - Sexe - État matrimonial - Carte de bénéficiaire - District actuel - Municipalité actuelle - Village actuel - Adresse actuelle - Profession - Education - Numéro de téléphone - Email - Type d\'identification - Numéro d\'identification - District de PPS - Niveau de PPS - Premier point de service - Choisir le sexe - Masculin - Féminin - Autre - Sélectionner l\'état civil - Marié - Célibataire - Divorcé - Veuf - Non spécifié - Sélectionner la carte de bénéficiaire - Choisir un métier - Choisir une éducation - Sélectionner le type d\'identification - Sélectionner le niveau FOSA - Dispensaire - Centre de santé - Hôpital - Choisir une FOSA - Sauvegarder - Relation - Sélectionner une relation - Famille enregistrée avec succès - Une erreur s\'est produite lors du traitement des données. - Erreur lors de l\'insertion de données - Erreur lors de la mise à jour des données - Le membre avec ce numéro d\'assurance existe déjà. - Ajouter - Nouveau - Choisir un agent - Sélectionner un produit - Sél. Mois - Date d\'adhésion - Produit - Date d\'entrée en vigueur - Date de début - Date d\'expiration - Agent - Statut du contrat : - Valeur du contrat : - Solde : - Contribution : - Recherche - Payeur - Date de paiement - Catégorie de contribution - Numéro du reçu - Contribution payée - Type de paiement - Sélectionnez Payeur - Sélectionner le niveau - Contribution et autres - Frais de photo - Sélectionnez le type de paiement - Argent liquide - Téléphone mobile - Virement bancaire - Numéro de reçu : - Expiré - Actif - En attente - Suspendu - Le numéro de reçu doit être unique. - Le contrat a une contribution. Veuillez d\'abord supprimer les contributions - Contrat avec succès - Contribution supprimée avec succès - Assuré supprimé avec succès - Vous ne pouvez pas supprimer le chef de famille. - La famille a un contrat, veuillez d\'abord supprimer le contrat. - Assuré non supprimé - Famille supprimée - Scanner - Nom d\'assuré - La carte SD est en mode lecture seule. Veuillez régler le mode de lecture/écriture et redémarrer l\'application. - IMIS a besoin d\'une carte mémoire externe pour fonctionner. Veuillez insérer la carte mémoire et redémarrer l\'application. - Fermeture forcée - Veuillez entrer le numéro d\'assurance - Invalid Insurance number - Obtenir des informations sur l\'assurance... - Obtention d\'un aperçu général... - Obtention d\'un rapport cumulatif... - Le membre avec ce numéro d\'assurance n\'existe pas. - Aucun renouvellement trouvé - Veuillez vérifier votre connexion Internet. - !Process Failed, Wrong File or Officer code. - Submit - Annuler le contrat - Voulez-vous mettre fin à ce contrat ? - Code de produit - Chargement… - Données téléversées sur le serveur avec succès. - Données sont rejetées par le serveur. Les données sont déplacées dans le dossier rejeté du téléphone. - Les données ont été téléversées avec succès. Veuillez vérifier vos dossiers rejetés/acceptés pour vérifier la réponse du serveur. - Veuillez entrer le code de l\'agent - Le fichier est enregistré sur un support de stockage externe. - Téléversement ... - Aucun commentaire trouvé - Une connexion Internet est nécessaire pour visualiser les statistiques. - Aperçu - Aucune donnée trouvée - Statistiques - Code de réclamation - Avez-vous été traité à l\'établissement à cette date ? - Vous a-t-on demandé un paiement à l\'établissement par le personnel ? - Vous a-t-on prescrit des médicaments ? - Avez-vous obtenu des médicaments de l\'établissement ? - Dans quelle mesure êtes-vous satisfait des soins que vous avez reçus à l\'établissement de santé ? Taux sur une échelle de 1 à 5 (1 = non satisfait ; 5 = très satisfait) - Chargement des commentaires... - Téléverser tous les commentaires - Veuillez entrer le code de l\'agent - Veuillez entrer le numéro de la demande de remboursement - Veuillez entrer le numéro d\'assurance - Il faut répondre à toutes les questions. - Date de fin - Veuillez entrer la date de fin - En cours... - Veuillez entrer la date de début - Veuillez entrer le numéro de reçu. - Veuillez entrer le code du produit - Veuillez entrer le montant - Ce numéro de reçu est déjà utilisé. - Aucun fichier trouvé. - De - Nom d\'utilisateur - Échec de connexion - Mot de passe - Entrez le mot de passe Rar - Code de l\'agent: - Code de l\'agent incorrect - Se connecter - Impossible de connecter le serveur. Opération annulée. - Il y a eu un problème sur le serveur. - Famille ne peut pas être insérée, s\'il vous plaît contacter l\'administrateur du système. - Famille téléversée avec succès - Chef de famille manquant - Une famille avec ce numéro d\'assurance existe déjà. - Numéro d\'assurance en double trouvé - Numéro de reçu en double trouvé - Impossible de télécharger les données de base. - Téléchargement des données de base - Données téléchargées avec succès - Supprimer - Modifier - Paiement - Données de base non trouvées, souhaitez-vous télécharger.... ? - Application d\'adhésions - Version : - Nom : - Date de sortie - Total de familles : - Total des assurés : - Total des contrats : - Total des contributions : - Téléverser les adhésions - Créer un XML d\'adhésions - Téléverser les renouvellements - Téléverser les commentaires - Télécharger les données de base - Un instant s\'il vous plait - Langue - Familles - Ajouter une nouvelle famille - Famille et assurés - Famille et contrats - Ajouter/Modifier assuré - Ajouter/Modifier le contrat - Contributions - Ajouter/Modifier la contribution - Voulez-vous quitter IMIS ? - Téléverser le rapport - OK - Assuré - Date jusqu\'au - Nom - Nom FOSA - Date du et jusqu\'au - Temps mis à jour - Annuler - Les commentaires n\'ont pas pu être téléversés, veuillez réessayer plus tard. - Le renouvellement n\'a pas pu être téléversé, veuillez réessayer plus tard. - Région de PPS - Promoteur actuel - Téléversé avec succès. S\'il vous plaît vérifier les dossiers acceptés / rejetés. - Suppression échouée - Cette famille a été supprimée seulement hors ligne parce qu\'elle a un contrat en ligne. - Contrat avec date d\'adhésion : - \" Modifié \" - Voulez-vous activer cet assuré ?]]> - Les contrats avec les dates d\'adhésion suivantes ont atteint leur nombre maximum de membres et, par conséquent, cette assurance ne sera pas couverte par ces polices, mais l\'assuré est ajouté à la famille : - Acquérir - Les données ont été sauvegardées sur la carte mémoire externe. - Les données n\'ont pas pu être téléversées sur le serveur. Enregistré sur les carte mémoire externe. - Photo téléversée avec succès. - La photo a été enregistrée avec succès. - Aucune image trouvée. - Veuillez capturer une image - Téléverser toutes les images - Photos téléversées avec succès - Aucune photo trouvée - Téléverser les photos - \"Recherche \" - Modifier la famille - Télécharger la famille - Familles éditées - Assurés édités - Contrats révisés - Contributions éditées - Numéro d\'assurance introuvable - Numéro d\'assurance requis - Suppression... - Une connexion Internet est nécessaire pour supprimer des données en ligne. - Veuillez d\'abord vous connecter pour supprimer les données en ligne. - La suppression d\'un contrat supprimera également les contributions qui s\'y trouvent. - La suppression de la famille supprimera également tous les assurés, les polices et les cotisations de cette famille. - Confirmer - Déconnexion - La famille existe déjà dans le téléphone - La nouvelle version du IMIS est maintenant disponible. - Cliquez ici pour télécharger. - Enregistrement... - Le processus a été interrompu. Veuillez vérifier votre connexion Internet. - Aucune famille n\'a été téléchargée - Pas de donné disponible - XML a été créé - Échec de la création de XML - Aucune donnée n\'a été créée - S\'il vous plaît entrer le numéro d\'assuré - sans contrat/contribution - sans photo - Échec du téléversement - Supprimé avec succès - Email invalide ! - Échec sur le serveur, la mise à jour des données a échouée ! - Le prix du contrat est couvert. Voulez-vous toujours ajouter une contribution ? - La contribution dépasse le prix du contrat. - Le prix du contrat n\'est pas encore couvert, veuillez sélectionner l\'action à effectuer. - - Rapports - Indicateurs d\'aperçu général - Indicateurs cumulatifs - Nombre de familles ayant des contrats actifs - Nombre de familles dont le contrat est expiré - Nombre de familles ayant des contrats en attente - Nombre de familles dont les services du contrat ont été suspendus - Nombre de nouveaux contrats - Nombre de contrats renouvelés - Nombre de contrats expirés - Nombre de familles avec contrats suspendus - Montant de la contribution collectée - Statistiques actuelles - Créer des commentaires XML - Créer des renouvellements XML - Double chef de famille trouvé sur le serveur, veuillez contacter votre responsable informatique. - Unlisted Renewal Policies - Renew Your Policy - Nom de l\'utilisateur - Code de la prestation - Encoder ici - Entrer le nom d\'utilisateur et du mot de passe - Login a été entré avec succès - Entrée non valide - Montant total - Numéros de contrôle - aperçu des polices d\'assurance - Aperçu des numéros de contrôle - Numéros de contrôle - Aperçu des polices - Aperçu des numéros de contrôle - Nom du Paquet de bénéfice: - Date téléversement: - Date demandée: - Code du Paquet de bénéfice: - Noms: - Renouvellement: - N° d\'assuré - Demandé au - Demandé du - Téléversé au - au - Téléversé du - Paquet de bénéfice - Effacer - Demandé - Nombre de polices trouvé - Montant de la contribution - Processus Complet - Veuillez sélectionner un police - Succès - Vous n\'avez pas les droits pour cette fonctionnalité - OK - Pas de donné sélectionnée pour la suppression - Obtenir le numéro de contrôle - Les polices n\'ont pas été supprimées car elles ne sont pas encore téléversées - sur - Requête envoyée avec succès - Cette police ne peut pas être supprimées car elle n\'est pas encore téléversées. - Type de paiement - Requête - PAS DE CONNECTION INTERNET - Voulez-vous importer le ficher .txt dans la base de donnée ? - Il n\'y a pas d\'application de gestion des fichiers d\'installé. - Chargement fichier: - Incomplet! - Contrôler la commission - Année - Payée - Vérifiée - obtenir les commissions - Rapport de Commissions - Montant - commissions - Rechercher les politiques inscrites - Recherche des n° de contrôle - Vue d\'ensemble - Polices - Pas de donnée - Entrer l\'année - Suppression de la famille supprimera également tous les assurés, les polices et les cotisations de la famille. - Dernier versement - Polices enregistrées - Polices non enregistrées - Demande pour polices non enregistrées - Numéro de téléphone non fourni - Les produits d\'assurance des polices sélectionnées ne sont pas uniques - Montant de la contribution - Choisir la date - Obtenir - Date du - Date à - Envoyer un SMS - SMS demandé - TotalAdmissionsLeft - TotalVisitsLeft - TotalConsultationsLeft - TotalSurgeriesLeft - TotalDeliveriesLeft - TotalAntenatalLeft - ConsultationAmountLeft - SurgeryAmountLeft - HospitalizationAmountLeft - AntenatalAmountLeft - DeliveryAmountLeft - Veuillez d\'abord vous connecter pour vérifier le numéro de reçu. - Le répertoire IMIS n\'a pas pu être créé. - Indicateurs cumulatifs - Langue des SMS - Approbation de SMS - Aperçu des paiements - Obtenir le CN de paiement pour les polices inscrites - Obtenir le CN de paiement pour les polices non inscrites - Aperçu paiement CN - Veuillez d\'abord vous connecter pour télécharger les renouvellements. - Tout sélectionner - Tout déselectionner - Traitement de synchronisation - Vulnérabilité - Sélectionnez la vulnérabilité - Numéros de contrôle en masse - Numéros de contrôle attribués : - Numéros de contrôle disponibles : - Récupérer les numéros de contrôle en masse - Chercher - Veuillez d\'abord vous connecter pour récupérer les numéros de contrôle. - Il ne reste aucun numéro de contrôle pour ce produit. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Numéro de contrôle : - Aucun numéro de contrôle attribué à cette politique. Veuillez récupérer les numéros de contrôle ou fournir le numéro de contrôle d\'une autre source. - Données de base - Accès au stockage externe - Pour fonctionner correctement, %1$s nécessite un accès au stockage externe. Veuillez l\'autoriser pour %1$s dans l\'écran suivant afin d\'utiliser l\'application. - Autorisations - Pour fonctionner correctement, %1$s nécessite plusieurs autorisations. Veuillez les autoriser dans l\'écran suivant afin d\'utiliser l\'application. - Veuillez remplir le mois - Renewal accepted - Renewal already accepted - Renewal rejected - Grace period expired - Control number error - Unexpected exception - Invalid renewal file - Control number \"%1$s\" is not present in phone memory. Please confirm that this control number is correct. - diff --git a/build.gradle b/build.gradle index adff27eb..3f272a79 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:7.0.3' - classpath "org.ajoberstar.grgit:grgit-gradle:4.1.0" + classpath 'com.android.tools.build:gradle:7.2.2' + classpath "org.ajoberstar.grgit:grgit-gradle:4.1.1" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a734ceb6..3e92091e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip