From 23850d4bfe642abbc910d1dea70bf358a280cb2f Mon Sep 17 00:00:00 2001 From: Mariya Date: Fri, 15 Dec 2023 16:52:20 +0530 Subject: [PATCH] csv --- .../shelved.patch | 0 ...ckout_at_04-12-2023_02_50_pm__Changes_.xml | 4 - app/build.gradle | 8 +- app/src/main/AndroidManifest.xml | 4 +- .../hposregistration/dao/MyDataBase.kt | 2 +- .../example/hposregistration/dao/UserDao.kt | 3 + .../hposregistration/data/MainRepository.kt | 4 + .../data/datasource/LocalFileDataSource.kt | 124 ++++++++++++++++++ .../hposregistration/data/user/UserData.kt | 4 +- .../example/hposregistration/di/AppModule.kt | 7 + .../hposregistration/network/UserDao.kt | 3 + .../ui/fragments/UserListFragment.kt | 61 ++++++++- .../ui/viewmodels/RegistrationViewModel.kt | 27 ++++ app/src/main/res/drawable/downloads.xml | 5 + .../main/res/layout/fragment_user_list.xml | 9 ++ app/src/main/res/values/strings.xml | 5 +- 16 files changed, 258 insertions(+), 12 deletions(-) delete mode 100644 .idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm_[Changes]/shelved.patch delete mode 100644 .idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm__Changes_.xml create mode 100644 app/src/main/java/com/example/hposregistration/data/datasource/LocalFileDataSource.kt create mode 100644 app/src/main/res/drawable/downloads.xml diff --git a/.idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm_[Changes]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm_[Changes]/shelved.patch deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm__Changes_.xml b/.idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm__Changes_.xml deleted file mode 100644 index 536290a..0000000 --- a/.idea/shelf/Uncommitted_changes_before_Checkout_at_04-12-2023_02_50_pm__Changes_.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 07b1ee5..afed6c1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,10 +91,12 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.13.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2' + implementation 'com.opencsv:opencsv:5.5' + //Room - implementation "androidx.room:room-ktx:2.6.0" - implementation "androidx.room:room-runtime:2.6.0" - kapt ("androidx.room:room-compiler:2.6.0") + implementation "androidx.room:room-ktx:2.6.1" + implementation "androidx.room:room-runtime:2.6.1" + kapt ("androidx.room:room-compiler:2.6.1") // Barcode scanner implementation 'com.journeyapps:zxing-android-embedded:4.3.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 14f9ab4..9cda14d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,7 +7,9 @@ android:required="false" /> + + @@ -43,7 +45,7 @@ diff --git a/app/src/main/java/com/example/hposregistration/dao/MyDataBase.kt b/app/src/main/java/com/example/hposregistration/dao/MyDataBase.kt index cdcf480..607b9f5 100644 --- a/app/src/main/java/com/example/hposregistration/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hposregistration/dao/MyDataBase.kt @@ -5,7 +5,7 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import com.example.hposregistration.data.user.UserData -@Database(entities = [UserData::class], version = 1, exportSchema = false) +@Database(entities = [UserData::class], version = 3, exportSchema = false) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao } \ No newline at end of file diff --git a/app/src/main/java/com/example/hposregistration/dao/UserDao.kt b/app/src/main/java/com/example/hposregistration/dao/UserDao.kt index bdff697..3028322 100644 --- a/app/src/main/java/com/example/hposregistration/dao/UserDao.kt +++ b/app/src/main/java/com/example/hposregistration/dao/UserDao.kt @@ -20,4 +20,7 @@ interface UserDao { @Query("DELETE FROM user_table WHERE _id = :id") suspend fun deleteById(id: String) + + @Query("UPDATE user_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/hposregistration/data/MainRepository.kt b/app/src/main/java/com/example/hposregistration/data/MainRepository.kt index 715827d..7151662 100644 --- a/app/src/main/java/com/example/hposregistration/data/MainRepository.kt +++ b/app/src/main/java/com/example/hposregistration/data/MainRepository.kt @@ -30,4 +30,8 @@ class MainRepository @Inject constructor( return userFireBaseDao.addUserToDatabase(userData) } + suspend fun updateCSVFieldById(id: String, isCSVCreated: Boolean) { + userDao.updateCSVFieldById(id, isCSVCreated) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/hposregistration/data/datasource/LocalFileDataSource.kt b/app/src/main/java/com/example/hposregistration/data/datasource/LocalFileDataSource.kt new file mode 100644 index 0000000..829bf9e --- /dev/null +++ b/app/src/main/java/com/example/hposregistration/data/datasource/LocalFileDataSource.kt @@ -0,0 +1,124 @@ +package com.example.hpostesting.data.datasource + +import android.os.Environment +import com.example.hposregistration.data.user.UserData + +import com.opencsv.CSVWriter +import java.io.File +import java.io.FileWriter +import java.io.IOException + +class LocalFileDataSource { + + 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){ + val writer = FileWriter(File(filepath)) + + writer.append(contents) + writer.flush() + 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", + "bloodGroup", + "birthYear", // Include other fields from the data class + "state", + "abhaId", + "userImageURL", + "testStatus", // Assuming testStatus is a boolean field + "gender", + "appVersion", + "phoneNumber", + "careOf", + "maritalStatus", + "category", + "caste", + "subCaste", + "house", + "city", + "district", + "state", + "pinCode", + "isUnderMedication", + "isUnderTransfusion", + "sickleCellHistory", + "userImageURL", + "registeredBy", + "createdAt", + "registrationCenterName" + + ) + csvWriter.writeNext(header) + + // Write data rows + for (data in dataList) { + val row = arrayOf( + data._id, + data.name, + data.bloodGroup, + data.birthYear ?: "", // Replace with the actual birthYear field + data.state, + data.abhaId, + data.userImageURL, + data.testStatus?.toString() ?: "", + data.gender, + data.appVersion ?: "", + data.phoneNumber, + data.careOf, + data.maritalStatus, + data.category, + data.caste, + data.subCaste ?: "", + data.house, + data.city, + data.district, + data.state, + data.pinCode, + data.isUnderMedication?.toString() ?: "", + data.isUnderTransfusion?.toString() ?: "", + data.sickleCellHistory ?: "", + data.userImageURL, + data.registeredBy ?: "", + data.createdAt ?: "", + data.registrationCenterName ?: "" + + ) + csvWriter.writeNext(row) + } + writer.close() + return true + } catch (e: IOException) { + e.printStackTrace() + return false + } + } + + private fun getExternalStorageDirectory(): File { + val folder = File(Environment.getExternalStorageDirectory(), "HPOSRegistration") + + if (!folder.exists()) { + folder.mkdirs() + } + + return folder + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hposregistration/data/user/UserData.kt b/app/src/main/java/com/example/hposregistration/data/user/UserData.kt index 5ecc79d..7afb5f5 100644 --- a/app/src/main/java/com/example/hposregistration/data/user/UserData.kt +++ b/app/src/main/java/com/example/hposregistration/data/user/UserData.kt @@ -32,7 +32,9 @@ data class UserData( var registeredBy: String? = "", var createdAt: String? = "", var registrationCenterName: String? = "", - var testStatus: Boolean = false + var testStatus: Boolean = false, + var isCSVCreated: Boolean = false, + var localFlag: Boolean = false, ){ enum class Gender { MALE, diff --git a/app/src/main/java/com/example/hposregistration/di/AppModule.kt b/app/src/main/java/com/example/hposregistration/di/AppModule.kt index 9f0bdf2..bda8c90 100644 --- a/app/src/main/java/com/example/hposregistration/di/AppModule.kt +++ b/app/src/main/java/com/example/hposregistration/di/AppModule.kt @@ -5,6 +5,7 @@ import android.content.Context import androidx.room.Room import com.example.hposregistration.dao.MyDatabase import com.example.hposregistration.dao.UserDao +import com.example.hpostesting.data.datasource.LocalFileDataSource import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -41,4 +42,10 @@ object AppModule { fun provideContext(application: Application): Context { return application.applicationContext } + + @Provides + @Singleton + fun provideLocalFileDataSource(): LocalFileDataSource { + return LocalFileDataSource() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hposregistration/network/UserDao.kt b/app/src/main/java/com/example/hposregistration/network/UserDao.kt index a05f0bf..c7a548d 100644 --- a/app/src/main/java/com/example/hposregistration/network/UserDao.kt +++ b/app/src/main/java/com/example/hposregistration/network/UserDao.kt @@ -1,5 +1,6 @@ package com.example.hposregistration.network +import androidx.room.Query import com.example.hposregistration.data.Response import com.example.hposregistration.data.user.UserData import com.google.firebase.firestore.FirebaseFirestore @@ -24,6 +25,8 @@ class UserDao { } } + + // suspend fun getPatientList(): List { // return patientCollection.get().await().toObjects(UserData::class.java) // } diff --git a/app/src/main/java/com/example/hposregistration/ui/fragments/UserListFragment.kt b/app/src/main/java/com/example/hposregistration/ui/fragments/UserListFragment.kt index b125f3d..ad574fe 100644 --- a/app/src/main/java/com/example/hposregistration/ui/fragments/UserListFragment.kt +++ b/app/src/main/java/com/example/hposregistration/ui/fragments/UserListFragment.kt @@ -5,11 +5,13 @@ import android.content.Context import android.content.DialogInterface import android.content.SharedPreferences import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.Toast +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.example.hposregistration.adapters.UserListOfflineAdapter @@ -30,7 +32,7 @@ class UserListFragment : BaseFragment() { private var _binding: FragmentUserListBinding? = null private val binding get() = _binding!! - private val viewModel by viewModels() + private val viewModel:RegistrationViewModel by activityViewModels() private var isOnline = false @@ -81,6 +83,10 @@ class UserListFragment : BaseFragment() { showUploadDialog(requireContext()) } + binding.btnSaveLocal.setOnClickListener { + showDownloadDialog(requireContext()) + } + binding.btnsettings.setOnClickListener{ findNavController().navigate(R.id.action_userListFragment_to_languageSettingsFragment) @@ -174,6 +180,25 @@ class UserListFragment : BaseFragment() { adapter.startListening() } + + 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 fetchFromLocalDB() { binding.uploadData.visibility = View.GONE viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> @@ -196,6 +221,40 @@ class UserListFragment : BaseFragment() { } } + + private fun downloadLocalDBData(dialog: DialogInterface) { + viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> + try { + val downloadList = mutableListOf() + + userDataList.forEach { userData -> + // Log details for debugging + Log.d("DownloadDebug", "userData: $userData, isCSVCreated: ${userData.isCSVCreated}") + + if (userData.isCSVCreated) { + downloadList.add(userData) + } + } + // Log the size of downloadList for debugging + Log.d("DownloadDebug", "downloadList size: ${downloadList.size}") + + if (downloadList.isNotEmpty()) { + // Call ViewModel function to create CSV with filtered data + viewModel.createCSV(downloadList, requireContext()) + Toast.makeText(requireContext(), "CSV file downloaded successfully", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(requireContext(), "No data to download", Toast.LENGTH_SHORT).show() + } + } catch (e: Exception) { + e.printStackTrace() + Toast.makeText(requireContext(), "Error downloading CSV file", Toast.LENGTH_SHORT).show() + } finally { + dialog.dismiss() + } + } + } + + private fun deteleIncompleteRegistration(userDataList: List) { userDataList.forEach { if (it.userImageURL.isEmpty()) { diff --git a/app/src/main/java/com/example/hposregistration/ui/viewmodels/RegistrationViewModel.kt b/app/src/main/java/com/example/hposregistration/ui/viewmodels/RegistrationViewModel.kt index 930e4ca..f9ead41 100644 --- a/app/src/main/java/com/example/hposregistration/ui/viewmodels/RegistrationViewModel.kt +++ b/app/src/main/java/com/example/hposregistration/ui/viewmodels/RegistrationViewModel.kt @@ -10,14 +10,21 @@ import com.example.hposregistration.data.MainRepository import com.example.hposregistration.data.NetworkStatusLiveData import com.example.hposregistration.data.Response import com.example.hposregistration.data.user.UserData +import com.example.hposregistration.dao.UserDao +import com.example.hpostesting.data.datasource.LocalFileDataSource import com.google.firebase.storage.FirebaseStorage import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale import javax.inject.Inject @HiltViewModel class RegistrationViewModel @Inject constructor( private val mainRepository: MainRepository, + private val userdao: UserDao, + private val localFileDataSource: LocalFileDataSource, context: Context ) : ViewModel() { @@ -73,4 +80,24 @@ class RegistrationViewModel @Inject constructor( fun deleteById(userId: String) = viewModelScope.launch { mainRepository.deleteById(id = userId) } + + fun createCSV(userData: List, appContext: Context) = + viewModelScope.launch { + val fileName = "${getCurrentDate()}.csv" + if (localFileDataSource.exportDataToCSV(fileName, userData)) { + userData.forEach { data -> + data.localFlag = true + mainRepository.updateCSVFieldById( + data._id, + true + ) + } + } + } + + private fun getCurrentDate(): String { + val dateFormat = SimpleDateFormat("dd-MM-yy", Locale.getDefault()) + val currentDate = Date() + return dateFormat.format(currentDate) + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/downloads.xml b/app/src/main/res/drawable/downloads.xml new file mode 100644 index 0000000..17e7f58 --- /dev/null +++ b/app/src/main/res/drawable/downloads.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_user_list.xml b/app/src/main/res/layout/fragment_user_list.xml index dd10574..5c5c18f 100644 --- a/app/src/main/res/layout/fragment_user_list.xml +++ b/app/src/main/res/layout/fragment_user_list.xml @@ -80,6 +80,15 @@ app:layout_constraintTop_toBottomOf="@+id/tv_title" tools:listitem="@layout/user_item_view" /> + + You have scanned the Aadhar ID, need to enter Aadhar ID number you have scanned and Abha ID manually You have scanned the Abha ID You have scanned the Aadhar ID - + Download CSV + Download DB Tests + Do you want to download the local DB tests in CSV format? + Upload done successfully NT-A NT-B