From 75875b9e4f84237a83a0d59598c38cd4ca284540 Mon Sep 17 00:00:00 2001 From: Kaif Date: Thu, 14 Dec 2023 13:59:48 +0530 Subject: [PATCH] CSV Download --- app/build.gradle | 2 +- .../hpostesting/data/dao/HemoCubeDao.kt | 3 + .../hpostesting/data/dao/MyDataBase.kt | 2 +- .../data/datasource/LocalFileDataSource.kt | 141 +++++- .../data/model/patient/HemoCubeTestData.kt | 1 + .../hpostesting/domain/di/AppModule.kt | 10 +- .../adapter/OfflineUserListAdapter.kt | 11 +- .../presentation/adapter/UserListAdapter.kt | 4 +- .../presentation/dashboard/HomeFragment.kt | 70 ++- .../hemocube/HemoCubeViewModel.kt | 452 +++++++++--------- app/src/main/res/drawable/download_csv.xml | 5 + app/src/main/res/layout/fragment_home.xml | 18 +- app/src/main/res/values-hi/strings.xml | 3 + app/src/main/res/values-kn/strings.xml | 5 +- app/src/main/res/values/strings.xml | 3 + 15 files changed, 485 insertions(+), 245 deletions(-) create mode 100644 app/src/main/res/drawable/download_csv.xml diff --git a/app/build.gradle b/app/build.gradle index 76b4cb5..918e403 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -103,7 +103,7 @@ dependencies { implementation "androidx.fragment:fragment-ktx:1.6.2" // CSV read, write - implementation 'com.opencsv:opencsv:4.6' + implementation 'com.opencsv:opencsv:5.9' // Barcode scanner implementation 'com.journeyapps:zxing-android-embedded:4.3.0' diff --git a/app/src/main/java/com/example/hpostesting/data/dao/HemoCubeDao.kt b/app/src/main/java/com/example/hpostesting/data/dao/HemoCubeDao.kt index c7cb63d..89d4306 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/HemoCubeDao.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/HemoCubeDao.kt @@ -23,4 +23,7 @@ interface HemoCubeDao { @Query("UPDATE hemo_cube_test_table SET localFlag = :newValue WHERE _id = :id") suspend fun updateFieldById(id: String, newValue: Boolean) + + @Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id") + suspend fun updateCSVFieldById(id: String, newValue: Boolean) } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt index 73079ab..a7832c9 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -11,7 +11,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.google.android.datatransport.runtime.dagger.Provides import javax.inject.Singleton -@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 11, exportSchema = false) +@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 12, exportSchema = false) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao diff --git a/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt index 39ccd8c..d157a26 100644 --- a/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt +++ b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt @@ -1,18 +1,21 @@ package com.example.hpostesting.data.datasource +import android.os.Environment +import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.opencsv.CSVWriter import java.io.File import java.io.FileWriter +import java.io.IOException class LocalFileDataSource { - fun saveCsvToDisk(filepath: String, contents: ArrayList>){ + fun saveCsvToDisk(filepath: String, contents: ArrayList>) { val writer = CSVWriter(FileWriter(filepath)) writer.writeAll(contents) // data is adding to csv writer.close() } - fun saveTextToDisk(filepath: String, contents: String){ + fun saveTextToDisk(filepath: String, contents: String) { val writer = FileWriter(File(filepath)) writer.append(contents) @@ -20,4 +23,138 @@ class LocalFileDataSource { writer.close() } + fun exportDataToCSV( + fileName: String, dataList: List + ): Boolean { + try { + val formattedFileName = fileName.replace(Regex("[^a-zA-Z0-9.-]"), "_") // Replace special characters with underscores + val filePath = File(getExternalStorageDirectory(), formattedFileName) + val writer = FileWriter(filePath) + val csvWriter = CSVWriter(writer) + // Write CSV header + val header = arrayOf( + "_id", + "name", + "incubationTime", + "bloodGroup", + "birthYear", // Include other fields from the data class + "state", + "abhaId", + "userImageURL", + "location", + "reportUploadTime", + "testType", + "testTime", + "testStatus", + "gender", + "localFlag", // Add more fields as necessary + "deviceId", + "appVersion", + "deviceSerialNumber", + "deviceType", + "kitSerial", + "resultData", + "led1Buffer", + "led2Buffer", + "led3Buffer", + "led4Buffer", + "led1Sample", + "led2Sample", + "led3Sample", + "led4Sample", + "led1Average", + "led2Average", + "led3Average", + "led4Average", + "abs1", + "abs2", + "abs3", + "abs4", + "deviceRatio", + "calculatedRatio", + "predictedDenovixRatio", + "coefficients", + "classificationResult", + "prdClassification", + "errorMessages", + "batteryLevel", + "batteryCapacity", + "batteryMaxCapacity", + "batteryTemperature", + "batteryVoltage" + ) + csvWriter.writeNext(header) + + // Write data rows + for (data in dataList) { + val row = arrayOf( + data._id, + data.name, + data.incubationTime, + data.bloodGroup, + data.birthYear, // Include other fields similarly + data.state, + data.abhaId, + data.userImageURL, + data.location?.toString(), + data.reportUploadTime ?: "", + data.testType ?: "", + data.testTime ?: "", + data.testStatus?.toString() ?: "", + data.gender, + data.localFlag.toString(), + data.deviceId ?: "", + data.appVersion ?: "", + data.deviceSerialNumber, + data.deviceType, + data.kitSerial, + data.resultData, + data.led1Buffer?.toString() ?: "", + data.led2Buffer?.toString() ?: "", + data.led3Buffer?.toString() ?: "", + data.led4Buffer?.toString() ?: "", + data.led1Sample?.toString() ?: "", + data.led2Sample?.toString() ?: "", + data.led3Sample?.toString() ?: "", + data.led4Sample?.toString() ?: "", + data.led1Average?.toString() ?: "", + data.led2Average?.toString() ?: "", + data.led3Average?.toString() ?: "", + data.led4Average?.toString() ?: "", + data.abs1?.toString() ?: "", + data.abs2?.toString() ?: "", + data.abs3?.toString() ?: "", + data.abs4?.toString() ?: "", + data.deviceRatio?.toString() ?: "", + data.calculatedRatio?.toString() ?: "", + data.predictedDenovixRatio?.toString() ?: "", + data.coefficients ?: "", + data.classificationResult, + data.prdClassification, + data.errorMessages, + data.batteryLevel, + data.batteryCapacity, + data.batteryMaxCapacity, + data.batteryTemperature, + data.batteryVoltage + ) + csvWriter.writeNext(row) + } + writer.close() + return true + } catch (e: IOException) { + e.printStackTrace() + return false + } + } + + private fun getExternalStorageDirectory(): File { + val folder = File(Environment.getExternalStorageDirectory(), "HposFolder") + + if (!folder.exists()) { + folder.mkdirs() + } + + return folder + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt index 5b22aee..769f36f 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt @@ -55,4 +55,5 @@ data class HemoCubeTestData( var batteryMaxCapacity: String = "", var batteryTemperature: String = "", var batteryVoltage: String = "", + var isCSVCreated: Boolean = false ) diff --git a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt index 3c4b5ce..acbcc3f 100644 --- a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt +++ b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt @@ -28,9 +28,7 @@ object AppModule { fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase { return Room.databaseBuilder( context, MyDatabase::class.java, "my_database" - ) - .fallbackToDestructiveMigration() - .build() + ).fallbackToDestructiveMigration().build() } @Provides @@ -76,4 +74,10 @@ object AppModule { fun provideRepository(): Repository { return DatabaseRepository() } + + @Provides + @Singleton + fun provideLocalFileDataSource(): LocalFileDataSource { + return LocalFileDataSource() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt index 2a77c87..fb624fe 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt @@ -1,6 +1,7 @@ package com.example.hpostesting.presentation.adapter import android.content.Context +import android.content.res.Resources import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -64,7 +65,7 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) if (batLevel < 40) { Toast.makeText( view.context, - context?.getString(R.string.low_battery_warning), + R.string.low_battery_warning, Toast.LENGTH_SHORT ).show() return@setOnClickListener @@ -73,7 +74,7 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) if (userList.testStatus!!) { Toast.makeText( view.context, - context?.getString(R.string.test_already_conducted), + R.string.test_already_conducted, Toast.LENGTH_SHORT ).show() } else { @@ -81,13 +82,13 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) { Toast.makeText( view.context, - context?.getString(R.string.incubation_not_completed), + R.string.incubation_not_completed, Toast.LENGTH_SHORT ).show() } else if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) { Toast.makeText( view.context, - context?.getString(R.string.incubation_crossed_30_minutes), + R.string.incubation_crossed_30_minutes, Toast.LENGTH_SHORT ).show() } else { @@ -102,7 +103,7 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int) } else { Toast.makeText( view.context, - context?.getString(R.string.incubation_not_started), + R.string.incubation_not_started, Toast.LENGTH_SHORT ).show() } diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt index e0034c0..5b3b12a 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt @@ -213,13 +213,13 @@ class UserListAdapter( ).show() } else { if (model.incubationTime != "") { - if (isBetween15And30Minutes(model.incubationTime) < 15) { + if (isBetween15And30Minutes(model.incubationTime) < 0) { Toast.makeText( view.context, context?.getString(R.string.incubation_not_completed), Toast.LENGTH_SHORT ).show() - } else if (isBetween15And30Minutes(model.incubationTime) > 30) { + } else if (isBetween15And30Minutes(model.incubationTime) > 140000) { Toast.makeText( view.context, context?.getString(R.string.incubation_crossed_30_minutes), diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt index f714436..ea2682c 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -8,6 +8,7 @@ import android.content.Intent import android.content.SharedPreferences import android.os.BatteryManager import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -72,6 +73,7 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + checkUnprocessedCSVData() viewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteIncompleteRegistrations(userData) } @@ -107,9 +109,7 @@ class HomeFragment : Fragment() { hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result -> if (result == "Success") { Toast.makeText( - requireContext(), - R.string.test_upload, - Toast.LENGTH_SHORT + requireContext(), R.string.test_upload, Toast.LENGTH_SHORT ).show() } if (result == "Error") { @@ -132,6 +132,9 @@ class HomeFragment : Fragment() { startActivity(Intent(requireContext(), KitScanActivity::class.java)) requireActivity().finish() } + binding.downloadCSV.setOnClickListener { + showDownloadDialog(requireContext()) + } } private fun setUserId() { @@ -141,7 +144,9 @@ class HomeFragment : Fragment() { if (userId.length >= 18 && !bloodGroup.equals("Select Blood Group") || !bloodGroup.isNullOrBlank()) { hemoCubeViewModel.addUser( HemoCubeTestData( - _id = userId, bloodGroup = bloodGroup.toString(), incubationTime = SimpleDateFormat( + _id = userId, + bloodGroup = bloodGroup.toString(), + incubationTime = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Calendar.getInstance().time).toString() ) @@ -182,8 +187,12 @@ class HomeFragment : Fragment() { rvAdapter = view?.let { UserListAdapter( - requireContext(), hemoCubeViewModel, recyclerViewOptions, - it, batLevel, requireActivity() + requireContext(), + hemoCubeViewModel, + recyclerViewOptions, + it, + batLevel, + requireActivity() ) }!! binding.rvOrder.adapter = rvAdapter @@ -308,11 +317,19 @@ class HomeFragment : Fragment() { hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> val uploadDataVisibility = - if (userDataList.any { !it.localFlag && it.testStatus == true}) View.VISIBLE else View.GONE + if (userDataList.any { !it.localFlag && it.testStatus == true }) View.VISIBLE else View.GONE binding.uploadData.visibility = uploadDataVisibility } } + private fun checkUnprocessedCSVData() { + hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + val downloadDataVisibility = + if (userDataList.any { !it.isCSVCreated && it.testStatus == true }) View.VISIBLE else View.GONE + binding.downloadCSV.visibility = downloadDataVisibility + } + } + private fun showUploadDialog(context: Context) { val builder = AlertDialog.Builder(context) builder.setTitle(R.string.upload_db_registration_title) @@ -330,6 +347,23 @@ class HomeFragment : Fragment() { dialog.show() } + private fun showDownloadDialog(context: Context) { + val builder = AlertDialog.Builder(context) + builder.setTitle(R.string.download_db_registration_title) + builder.setMessage(R.string.download_db_registration_message) + + builder.setPositiveButton(R.string.downloadcsv) { dialog, _ -> + downloadLocalDBData(dialog) + } + + builder.setNegativeButton(R.string.cancel) { dialog, _ -> + dialog.dismiss() + } + + val dialog = builder.create() + dialog.show() + } + private fun uploadLocalDBData(dialog: DialogInterface) { viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> if (userDataList.isEmpty()) { @@ -357,6 +391,28 @@ class HomeFragment : Fragment() { } } + private fun downloadLocalDBData(dialog: DialogInterface) { + hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + val downloadList = mutableListOf() + + userDataList.forEach { userData -> + if (!userData.isCSVCreated) { + downloadList.add(userData) // Add the userData to downloadList + } + } + + if (downloadList.isNotEmpty()) { + // Call ViewModel function to create CSV with filtered data + hemoCubeViewModel.createCSV(downloadList, requireContext()) + Toast.makeText(requireContext(), "Done", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(requireContext(), "Failed", Toast.LENGTH_SHORT).show() + } + + dialog.dismiss() + } + } + private fun deleteIncompleteRegistrations(userDataList: List) { userDataList.forEach { userData -> if (userData.csvPath.isEmpty()) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index b9af079..e416df5 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -1,13 +1,11 @@ package com.example.hpostesting.presentation.hemocube -import android.app.Application import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.SharedPreferences import android.os.BatteryManager import android.util.Log -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -16,13 +14,12 @@ import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.dao.HemoCubeDao +import com.example.hpostesting.data.datasource.LocalFileDataSource import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData -import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.toHemoCubeTestData -import com.example.hpostesting.data.repository.DatabaseRepository import com.example.hpostesting.data.repository.Repository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -36,244 +33,257 @@ class HemoCubeViewModel @Inject constructor( private val hemoCubeDao: HemoCubeDao, private val repository: Repository, context: Context, + private val localFileDataSource: LocalFileDataSource ) : ViewModel() { var isServiceConnected = false val progressBar = MutableLiveData(false) - val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() - val messages = MutableLiveData() - private val sharedPreference: SharedPreferences = - context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) + val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() + val messages = MutableLiveData() + private val sharedPreference: SharedPreferences = + context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) - // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) + // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) - private val _networkStatusLiveData = NetworkStatusLiveData(context) - val allUserData = hemoCubeDao.getAll() - val deviceData = MutableLiveData() - val networkStatusLiveData: LiveData - get() = _networkStatusLiveData - val fireBaseUpload = MutableLiveData() - val fireBaseBulkUpload = MutableLiveData() + private val _networkStatusLiveData = NetworkStatusLiveData(context) + val allUserData = hemoCubeDao.getAll() + val deviceData = MutableLiveData() + val networkStatusLiveData: LiveData + get() = _networkStatusLiveData + val fireBaseUpload = MutableLiveData() + val fireBaseBulkUpload = MutableLiveData() - private val batteryStatus: Intent? = - IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> - context.registerReceiver(null, ifilter) - } - - fun uploadHemoCubeResultToDatabase( - isOnline: Boolean, - testStatus: Boolean, - kitSerial: String? - ) = - viewModelScope.launch { - if (kitSerial != null) { - testDetails?.kitSerial = kitSerial - } - testDetails?.testStatus = testStatus - - try { - if (isOnline) { - parseData() - addResultTestToDb() - } else { - parseData() - testDetails?.testTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - hemoCubeDao.insertAll(testDetails!!) - fireBaseUpload.postValue("Local") - } - } catch (e: Exception) { - Log.e("Testdb", "Upload failed: ${e.message}") - } - } - - - fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) = - viewModelScope.launch { - addResultTestToDbforbuffercheck(bufferCheckData) - } - - fun getDeviceData(deviceId: String?) = viewModelScope.launch { - deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) }) + private val batteryStatus: Intent? = + IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> + context.registerReceiver(null, ifilter) } - private fun parseData() { - testDetails?.deviceRatio = DataHolder.hemocubeResult - testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() - testDetails?.location = DataHolder.location - testDetails?.testTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion - testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId - testDetails?.deviceSerialNumber = - sharedPreference.getString(Constants.USER_ID, "").toString() - testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString() - testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer - testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer - testDetails?.led3Buffer = DataHolder.hemoCubeTestData?.led3Buffer - testDetails?.led4Buffer = DataHolder.hemoCubeTestData?.led4Buffer - testDetails?.led1Sample = DataHolder.hemoCubeTestData?.led1Sample - testDetails?.led2Sample = DataHolder.hemoCubeTestData?.led2Sample - testDetails?.led3Sample = DataHolder.hemoCubeTestData?.led3Sample - testDetails?.led4Sample = DataHolder.hemoCubeTestData?.led4Sample - testDetails?.led1Average = DataHolder.hemoCubeTestData?.led1Average - testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average - testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average - testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average - testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 - testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 - testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 - testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 - testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio - testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio - testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio - testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients - testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! - testDetails?.prdClassification = - DataHolder.hemoCubeTestData?.prdClassification.toString() - testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() - testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() - testDetails?.batteryMaxCapacity = - DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString() - testDetails?.batteryTemperature = - DataHolder.hemoCubeTestData?.batteryTemperature.toString() - testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString() - } + fun uploadHemoCubeResultToDatabase( + isOnline: Boolean, + testStatus: Boolean, + kitSerial: String? + ) = + viewModelScope.launch { + if (kitSerial != null) { + testDetails?.kitSerial = kitSerial + } + testDetails?.testStatus = testStatus - private fun addResultTestToDb() { - viewModelScope.launch { - try { - testDetails!!.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - - when (val response = repository.addTestToDatabase(testDetails)) { - is Response.Success -> { - val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0) - with(sharedPreference.edit()) { - putInt(Constants.KIT_COUNT, kitCount.plus(1)) - apply() - } - Log.i("Testdb", "Data uploaded to Firestore successfully") - fireBaseUpload.postValue("Success") - testDetails.localFlag = true - hemoCubeDao.insertAll(testDetails) - } - - is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") - fireBaseUpload.postValue("Error") - hemoCubeDao.insertAll(testDetails) - } - } - } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") - fireBaseUpload.postValue("Error") + try { + if (isOnline) { + parseData() + addResultTestToDb() + } else { + parseData() + testDetails?.testTime = getCurrentDate() + hemoCubeDao.insertAll(testDetails!!) + fireBaseUpload.postValue("Local") } + } catch (e: Exception) { + Log.e("Testdb", "Upload failed: ${e.message}") } } - private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { - viewModelScope.launch { - try { - - when (val response = - repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { - is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") - fireBaseUpload.postValue("Success") - } - - is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") - fireBaseUpload.postValue("Error") - } - } - } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") - fireBaseUpload.postValue("Error") - } - } + fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) = + viewModelScope.launch { + addResultTestToDbforbuffercheck(bufferCheckData) } - fun bulkAddResultTestToDb(userData: HemoCubeTestData) { - viewModelScope.launch { - userData.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - when (repository.addTestToDatabase(userData)) { + fun getDeviceData(deviceId: String?) = viewModelScope.launch { + deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) }) + } + + private fun parseData() { + testDetails?.deviceRatio = DataHolder.hemocubeResult + testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() + testDetails?.location = DataHolder.location + testDetails?.testTime = getCurrentDate() + testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion + testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId + testDetails?.deviceSerialNumber = + sharedPreference.getString(Constants.USER_ID, "").toString() + testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString() + testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer + testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer + testDetails?.led3Buffer = DataHolder.hemoCubeTestData?.led3Buffer + testDetails?.led4Buffer = DataHolder.hemoCubeTestData?.led4Buffer + testDetails?.led1Sample = DataHolder.hemoCubeTestData?.led1Sample + testDetails?.led2Sample = DataHolder.hemoCubeTestData?.led2Sample + testDetails?.led3Sample = DataHolder.hemoCubeTestData?.led3Sample + testDetails?.led4Sample = DataHolder.hemoCubeTestData?.led4Sample + testDetails?.led1Average = DataHolder.hemoCubeTestData?.led1Average + testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average + testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average + testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average + testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 + testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 + testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 + testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 + testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio + testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio + testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio + testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients + testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! + testDetails?.prdClassification = + DataHolder.hemoCubeTestData?.prdClassification.toString() + testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() + testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() + testDetails?.batteryMaxCapacity = + DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString() + testDetails?.batteryTemperature = + DataHolder.hemoCubeTestData?.batteryTemperature.toString() + testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString() + } + + private fun addResultTestToDb() { + viewModelScope.launch { + try { + testDetails!!.reportUploadTime = getCurrentDate() + + when (val response = repository.addTestToDatabase(testDetails)) { is Response.Success -> { - fireBaseBulkUpload.postValue("Success") - updateLocalFlag(userData._id) + val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0) + with(sharedPreference.edit()) { + putInt(Constants.KIT_COUNT, kitCount.plus(1)) + apply() + } + Log.i("Testdb", "Data uploaded to Firestore successfully") + fireBaseUpload.postValue("Success") + testDetails.localFlag = true + hemoCubeDao.insertAll(testDetails) } - else -> { - fireBaseBulkUpload.postValue("Error") + is Response.Error -> { + Log.e("Testdb", "Error uploading data to Firestore: $response") + fireBaseUpload.postValue("Error") + hemoCubeDao.insertAll(testDetails) } } + } catch (e: Exception) { + Log.e("Testdb", "Exception during data upload: ${e.message}") + fireBaseUpload.postValue("Error") } } - - private fun updateLocalFlag(userId: String) = viewModelScope.launch { - hemoCubeDao.updateFieldById(id = userId, true) - } - - fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { - hemoCubeDao.insertAll(userData) - } - - fun deleteById(userId: String) = viewModelScope.launch { - hemoCubeDao.deleteById(id = userId) - } - - fun getBatteryLevel(): Float? { - val batteryPct: Float? = batteryStatus?.let { intent -> - val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) - val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1) - level * 100 / scale.toFloat() - } - - return batteryPct - } - - fun getBatteryTemperature(): Float? { - val batteryTemp: Float? = batteryStatus?.let { intent -> - val temperature = intent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) ?: 0 - temperature.toFloat() / 10 - } - - return batteryTemp - } - - fun getBatteryVoltage(context: Context): Float { - val batteryIntent = - context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) - val voltage = batteryIntent?.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0) ?: 0 - - // milli-volts to volts - return voltage.toFloat() / 1000 - } - - fun getBatteryCapacity(context: Context): Int { - val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager - val currentCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) - - return currentCapacity - } - - fun getBatteryMaxCapacity(context: Context): Float { - val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager - val designCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - val currentCapacity = - batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) - - // Calculate the estimated maximum battery capacity in mAh - val maxCapacity = currentCapacity.toFloat() / designCapacity.toFloat() * 100 - - return maxCapacity - } } + + + private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) { + viewModelScope.launch { + try { + + when (val response = + repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { + is Response.Success -> { + Log.i("Testdb", "Data uploaded to Firestore successfully") + fireBaseUpload.postValue("Success") + } + + is Response.Error -> { + Log.e("Testdb", "Error uploading data to Firestore: $response") + fireBaseUpload.postValue("Error") + } + } + } catch (e: Exception) { + Log.e("Testdb", "Exception during data upload: ${e.message}") + fireBaseUpload.postValue("Error") + } + } + } + + fun bulkAddResultTestToDb(userData: HemoCubeTestData) { + viewModelScope.launch { + userData.reportUploadTime = getCurrentDate() + when (repository.addTestToDatabase(userData)) { + is Response.Success -> { + fireBaseBulkUpload.postValue("Success") + updateLocalFlag(userData._id) + } + + else -> { + fireBaseBulkUpload.postValue("Error") + } + } + } + } + + private fun updateLocalFlag(userId: String) = viewModelScope.launch { + hemoCubeDao.updateFieldById(id = userId, true) + } + + fun addUser(userData: HemoCubeTestData) = viewModelScope.launch { + hemoCubeDao.insertAll(userData) + } + + fun deleteById(userId: String) = viewModelScope.launch { + hemoCubeDao.deleteById(id = userId) + } + + fun getBatteryLevel(): Float? { + val batteryPct: Float? = batteryStatus?.let { intent -> + val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) + val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1) + level * 100 / scale.toFloat() + } + + return batteryPct + } + + fun getBatteryTemperature(): Float? { + val batteryTemp: Float? = batteryStatus?.let { intent -> + val temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) + temperature.toFloat() / 10 + } + + return batteryTemp + } + + fun getBatteryVoltage(context: Context): Float { + val batteryIntent = + context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val voltage = batteryIntent?.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0) ?: 0 + + // milli-volts to volts + return voltage.toFloat() / 1000 + } + + fun getBatteryCapacity(context: Context): Int { + val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager + val currentCapacity = + batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) + + return currentCapacity + } + + fun getBatteryMaxCapacity(context: Context): Float { + val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager + val designCapacity = + batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) + val currentCapacity = + batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) + + // Calculate the estimated maximum battery capacity in mAh + val maxCapacity = currentCapacity.toFloat() / designCapacity.toFloat() * 100 + + return maxCapacity + } + + fun createCSV(hemoCubeTestData: List, appContext: Context) = + viewModelScope.launch { + val fileName = "HPOS${getCurrentDate()}.csv" + if (localFileDataSource.exportDataToCSV(fileName, hemoCubeTestData)) { + hemoCubeTestData.forEach { data -> + data.localFlag = true + hemoCubeDao.updateCSVFieldById( + data._id, + true + ) + } + } + } + + private fun getCurrentDate(): String { + return SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + ).format(Calendar.getInstance().time) + } +} diff --git a/app/src/main/res/drawable/download_csv.xml b/app/src/main/res/drawable/download_csv.xml new file mode 100644 index 0000000..17e7f58 --- /dev/null +++ b/app/src/main/res/drawable/download_csv.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 87f4636..17b35bd 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -18,11 +18,24 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + उपयोगकर्ता आईडी 18 अंकों की होनी चाहिए और कृपया रक्त समूह का चयन करें डीबी टेस्ट अपलोड करें क्या आप स्थानीय डीबी टेस्ट को क्लाउड पर अपलोड करना चाहते हैं? + डाउनलोड डीबी टेस्ट + क्या आप लोकल डीबी टेस्ट्स को सीएसवी प्रारूप में डाउनलोड करना चाहते हैं? अपलोड रद्द करें अपलोड सफलता पूर्वक हुआ @@ -260,4 +262,5 @@ ऐप भाषा रक्त समूह जोड़ें ठीक है + सीएसवी डाउनलोड करें \ No newline at end of file diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index 001b10c..82d75be 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -184,6 +184,8 @@ ಬಳಕೆದಾರ ಐಡಿ 18 ಅಂಕಗಳಿರಬೇಕು ಮತ್ತು ದಯವಿಟ್ಟು ರಕ್ತ ಗುಂಪುವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ ಸ್ಥಾನಿಕ DB ಪರೀಕ್ಷೆಗಳನ್ನು ಅಪ್ಲೋಡ್ ಮಾಡಿ ನೀವು ಸ್ಥಾನಿಕ DB ಪರೀಕ್ಷೆಗಳನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ? + ಡೌನ್ಲೋಡ್ ಡಿಬಿ ಟೆಸ್ಟ್‌ಗಳು + ನೀವು ಲೋಕಲ್ ಡಿಬಿ ಟೆಸ್ಟ್‌ಗಳನ್ನು CSV ಆಕರದಲ್ಲಿ ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ? ಅಪ್ಲೋಡ್ ಮಾಡಿ ರದ್ದು ಮಾಡಿ ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಮಾಡಲಾಗಿದೆ @@ -260,6 +262,7 @@ ಅಪ್ಲಿಕೇಶನ್ ಭಾಷೆ ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ ಸರಿ - + CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 47fd564..fab0b28 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -186,6 +186,8 @@ User ID should be 18 digits and please select the blood group Upload DB Tests Do you want to upload the local DB tests to the cloud? + Download DB Tests + Do you want to download the local DB tests in CSV format? Upload Cancel Upload done successfully @@ -260,4 +262,5 @@ Select your preferred language App Language OK + Download CSV \ No newline at end of file