From 5f88ed5f695b528e3202b417867bca52eeefad10 Mon Sep 17 00:00:00 2001
From: rayhanp1402 <rayhan.hanif14maulana@gmail.com>
Date: Tue, 2 Apr 2024 19:30:50 +0700
Subject: [PATCH] feat: Save transactions to .xls and .xlsx

---
 .../bondoyap/ui/settings/SettingsFragment.kt  | 12 ++-
 .../ui/settings/TransactionsExporter.kt       | 85 +++++++++++--------
 .../ui/transactions/TransactionsViewModel.kt  |  4 +
 .../ui/transactions/data/TransactionsDao.kt   |  3 +
 .../data/TransactionsRepository.kt            |  4 +
 5 files changed, 68 insertions(+), 40 deletions(-)

diff --git a/app/src/main/java/com/example/bondoyap/ui/settings/SettingsFragment.kt b/app/src/main/java/com/example/bondoyap/ui/settings/SettingsFragment.kt
index 27637f9..0166c33 100644
--- a/app/src/main/java/com/example/bondoyap/ui/settings/SettingsFragment.kt
+++ b/app/src/main/java/com/example/bondoyap/ui/settings/SettingsFragment.kt
@@ -8,11 +8,15 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.Toast
 import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
 import androidx.lifecycle.ViewModelProvider
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.example.bondoyap.databinding.FragmentSettingsBinding
 import com.example.bondoyap.service.api.Constants.ACTION_RANDOMIZE_TRANSACTIONS
 import com.example.bondoyap.ui.login.LoginActivity
+import com.example.bondoyap.ui.transactions.TransactionsApplication
+import com.example.bondoyap.ui.transactions.TransactionsViewModel
+import com.example.bondoyap.ui.transactions.TransactionsViewModelFactory
 
 class SettingsFragment : Fragment() {
 
@@ -20,6 +24,10 @@ class SettingsFragment : Fragment() {
     private val binding get() = _binding!!
     private lateinit var settingsViewModel: SettingsViewModel
 
+    private val transactionsViewModel: TransactionsViewModel by viewModels {
+        TransactionsViewModelFactory((requireContext().applicationContext as TransactionsApplication).repository)
+    }
+
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
@@ -72,9 +80,7 @@ class SettingsFragment : Fragment() {
             Log.d("BroadcastDebug", "Sending broadcast from SettingsFragment")
         }
 
-        val database = MockDatabase()
-        val exporter = TransactionsExporter(database)
-
+        val exporter = TransactionsExporter(transactionsViewModel, requireContext())
 
         saveButton.setOnClickListener {
             Toast.makeText(appContext, "Menyimpan transaksi...", Toast.LENGTH_SHORT).show()
diff --git a/app/src/main/java/com/example/bondoyap/ui/settings/TransactionsExporter.kt b/app/src/main/java/com/example/bondoyap/ui/settings/TransactionsExporter.kt
index f145acb..05c7615 100644
--- a/app/src/main/java/com/example/bondoyap/ui/settings/TransactionsExporter.kt
+++ b/app/src/main/java/com/example/bondoyap/ui/settings/TransactionsExporter.kt
@@ -1,51 +1,41 @@
 package com.example.bondoyap.ui.settings
 
+import android.content.Context
+import android.location.Address
+import android.location.Geocoder
 import android.os.Environment
+import android.os.Handler
+import android.os.Looper
 import android.util.Log
+import androidx.lifecycle.viewModelScope
+import com.example.bondoyap.ui.transactions.TransactionsViewModel
+import com.example.bondoyap.ui.transactions.data.Transactions
 import io.github.evanrupert.excelkt.Sheet
 import io.github.evanrupert.excelkt.workbook
+import kotlinx.coroutines.launch
 import org.apache.poi.ss.usermodel.FillPatternType
 import org.apache.poi.ss.usermodel.IndexedColors
 import java.io.File
+import java.util.Locale
 
-interface Database {
-    fun getTransactions(): List<Transaction>
-}
-
-class MockDatabase : Database {
-    override fun getTransactions(): List<Transaction> {
-        return findTransactions()
-    }
-}
-
-data class Transaction(
-    val date: String,
-    val category: String,
-    val amount: Double,
-    val name: String,
-    val location: String
-)
-
-fun findTransactions(): List<Transaction> = listOf(
-    Transaction("2024-04-01", "Pemasukan", 100.0, "Gaji", "AAAAA"),
-    Transaction("2024-04-02", "Pengeluaran", 50.0, "Belanja", "BBBBB"),
-    Transaction("2024-04-03", "Pemasukan", 200.0, "Bonus", "CCCC")
-)
-
-class TransactionsExporter(private val database: Database) {
+class TransactionsExporter(private val transactionsViewModel: TransactionsViewModel, val context: Context) {
     fun exportToXLS() {
-        val transactions = database.getTransactions()
-        Log.d("SaveDebug", "xls function")
-        writeToExcel("transactions.xls", transactions)
+        transactionsViewModel.viewModelScope.launch {
+            val transactions = transactionsViewModel.getAllTransactionsList()
+            Log.d("SaveDebug", "xls function")
+            writeToExcel("transactions.xls", transactions)
+        }
     }
 
     fun exportToXLSX() {
-        val transactions = database.getTransactions()
-        Log.d("SaveDebug", "xls function")
-        writeToExcel("transactions.xlsx", transactions)
+        transactionsViewModel.viewModelScope.launch {
+            val transactions = transactionsViewModel.getAllTransactionsList()
+            Log.d("SaveDebug", "xlsx function")
+            writeToExcel("transactions.xlsx", transactions)
+        }
     }
 
-    private fun writeToExcel(fileName: String, transactions: List<Transaction>) {
+    private fun writeToExcel(fileName: String, transactions: List<Transactions>) {
         val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
         val file = File(downloadsDir, fileName)
 
@@ -55,11 +45,32 @@ class TransactionsExporter(private val database: Database) {
 
                 for (transaction in transactions) {
                     row {
-                        cell(transaction.date)
-                        cell(transaction.category)
-                        cell(transaction.amount)
-                        cell(transaction.name)
-                        cell(transaction.location)
+                        cell(transaction.tanggal)
+                        cell(
+                            if (transaction.isPemasukan) {
+                                "Pemasukan"
+                            } else {
+                                "Pengeluaran"
+                            }
+                        )
+                        cell(transaction.nominal)
+                        cell(transaction.judul)
+                        cell(if (transaction.longitude.isEmpty() || transaction.latitude.isEmpty()) {
+                            "Unavailable"
+                        } else {
+                            val addresses: List<Address> =
+                                Geocoder(context, Locale.getDefault()).getFromLocation(
+                                    transaction.latitude.toDouble(),
+                                    transaction.longitude.toDouble(),
+                                    1
+                                ) ?: emptyList()
+                            if (addresses.isNotEmpty()) {
+                                val locationName = addresses[0].getAddressLine(0)
+                                locationName
+                            } else {
+                                "Unavailable"
+                            }
+                        })
                     }
                 }
             }
diff --git a/app/src/main/java/com/example/bondoyap/ui/transactions/TransactionsViewModel.kt b/app/src/main/java/com/example/bondoyap/ui/transactions/TransactionsViewModel.kt
index 012172e..3f5582d 100644
--- a/app/src/main/java/com/example/bondoyap/ui/transactions/TransactionsViewModel.kt
+++ b/app/src/main/java/com/example/bondoyap/ui/transactions/TransactionsViewModel.kt
@@ -28,6 +28,10 @@ class TransactionsViewModel(
         }
         return deferred.await()
     }
+
+    suspend fun getAllTransactionsList(): List<Transactions> {
+        return repository.getAllTransactionsList()
+    }
 }
 
 class TransactionsViewModelFactory(private val repository: TransactionsRepository): ViewModelProvider.Factory {
diff --git a/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsDao.kt b/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsDao.kt
index d09b361..00dd1fc 100644
--- a/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsDao.kt
+++ b/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsDao.kt
@@ -18,6 +18,9 @@ interface TransactionsDao {
     @Query("SELECT * FROM transactions")
     fun getTransactions(): Flow<List<Transactions>>
 
+    @Query("SELECT * FROM transactions")
+    suspend fun getTransactionsList(): List<Transactions>
+
     @Query("SELECT * FROM transactions WHERE transactions.id == :transactionsId")
     suspend fun getTransactionById(transactionsId: Int?): Transactions
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsRepository.kt b/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsRepository.kt
index 2a5dcda..c376411 100644
--- a/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsRepository.kt
+++ b/app/src/main/java/com/example/bondoyap/ui/transactions/data/TransactionsRepository.kt
@@ -19,4 +19,8 @@ class TransactionsRepository(private val transactionsDao: TransactionsDao) {
     suspend fun get(transactionId: Int?): Transactions {
         return transactionsDao.getTransactionById(transactionId)
     }
+
+    suspend fun getAllTransactionsList(): List<Transactions> {
+        return transactionsDao.getTransactionsList()
+    }
 }
\ No newline at end of file
-- 
GitLab