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