diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 9cc81e63d1cf3099f2e26ffdd831d0cb30c4bcca..da2044165cb59ffaa8c8854ee599dbe7c7fad00b 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -4,18 +4,17 @@ <value> <entry key="app"> <State> - <targetSelectedWithDropDown> + <runningDeviceTargetsSelectedWithDialog> <Target> - <type value="QUICK_BOOT_TARGET" /> + <type value="RUNNING_DEVICE_TARGET" /> <deviceKey> <Key> - <type value="VIRTUAL_DEVICE_PATH" /> - <value value="C:\Users\dzafa\.android\avd\Pixel_7_Pro_API_34.avd" /> + <type value="SERIAL_NUMBER" /> + <value value="RR8R202MELK" /> </Key> </deviceKey> </Target> - </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2024-04-01T08:55:20.631393400Z" /> + </runningDeviceTargetsSelectedWithDialog> </State> </entry> </value> diff --git a/app/src/main/java/com/example/bondoman/models/Transaction.kt b/app/src/main/java/com/example/bondoman/models/Transaction.kt index f6f51a725a1356c2cf3d2f461d81fa4c157c2d1c..8533e4e12e5a11fa826cb94e80819a3771c5ccf0 100644 --- a/app/src/main/java/com/example/bondoman/models/Transaction.kt +++ b/app/src/main/java/com/example/bondoman/models/Transaction.kt @@ -24,6 +24,5 @@ data class Transaction( data class TransactionStats( val kategori: Transaction.Category, - val count: Int, - val totalNominal: Float + val total: Float, ) diff --git a/app/src/main/java/com/example/bondoman/models/TransactionViewModel.kt b/app/src/main/java/com/example/bondoman/models/TransactionViewModel.kt index e0164ebabfabc1ee3eeec28be2caea9a0f2ea32c..8b80f96835aee69899a4051dfe926e5035aea9ab 100644 --- a/app/src/main/java/com/example/bondoman/models/TransactionViewModel.kt +++ b/app/src/main/java/com/example/bondoman/models/TransactionViewModel.kt @@ -5,17 +5,11 @@ import android.os.Bundle import androidx.lifecycle.AbstractSavedStateViewModelFactory import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY -import androidx.lifecycle.createSavedStateHandle import androidx.lifecycle.viewModelScope -import androidx.lifecycle.viewmodel.CreationExtras import com.example.bondoman.models.Transaction.Category import com.example.bondoman.room.TransactionDao import com.example.bondoman.services.TransactionEvent import com.example.bondoman.services.TransactionState -import com.google.android.material.search.SearchView.TransitionState -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.stateIn @@ -23,17 +17,32 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.math.BigDecimal import java.time.LocalDate -import androidx.lifecycle.createSavedStateHandle import androidx.savedstate.SavedStateRegistryOwner -import com.example.bondoman.MainActivity +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flatMapLatest +@OptIn(ExperimentalCoroutinesApi::class) class TransactionViewModel(private val dao : TransactionDao) : ViewModel() { private val _state = MutableStateFlow(TransactionState()) private val _transactions = MutableStateFlow(dao.observeAll() ) + private val _sortTransactionStatsByValue = MutableStateFlow(true) + private val _transactionStats = _sortTransactionStatsByValue + .flatMapLatest { sortTransactionStatsByValue -> + when(sortTransactionStatsByValue){ + true -> dao.getTransactionStatsByValue() + false -> dao.getTransactionStatsByCount() + } + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) - val state = _transactions.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), TransactionState()) + // val state = _transactions.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), TransactionState()) + val state = combine(_state,_transactions, _sortTransactionStatsByValue, _transactionStats) {state, transactions, sortTransactionStatsByValue, transactionStats -> + state.copy( + sortTransactionStatsByValue = sortTransactionStatsByValue, + transactionStats = transactionStats + )}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), TransactionState()) @@ -98,6 +107,10 @@ class TransactionViewModel(private val dao : TransactionDao) : ViewModel() { ) } } + + is TransactionEvent.ChangeTransactionStats -> { + _sortTransactionStatsByValue.value = event.sortTransactionStatsByValue + } } } diff --git a/app/src/main/java/com/example/bondoman/room/TransactionDao.kt b/app/src/main/java/com/example/bondoman/room/TransactionDao.kt index 187f1b68133c119c2f4e72b8dadfb1f1bfb23ad3..5c0390fe4a455bf6c090bf766f5c6cb7abd590f9 100644 --- a/app/src/main/java/com/example/bondoman/room/TransactionDao.kt +++ b/app/src/main/java/com/example/bondoman/room/TransactionDao.kt @@ -29,7 +29,10 @@ interface TransactionDao { @Query("DELETE FROM `transaction`") suspend fun deleteAll() - @Query("SELECT kategori, COUNT(id) AS count, SUM(nominal) AS totalNominal FROM `transaction` GROUP BY kategori") - fun getTransactionStats(): Flow<List<TransactionStats>> + @Query("SELECT kategori, SUM(nominal) AS total FROM `transaction` GROUP BY kategori") + suspend fun getTransactionStatsByValue(): Flow<List<TransactionStats>> + + @Query("SELECT kategori, COUNT(id) AS total FROM `transaction` GROUP BY kategori") + suspend fun getTransactionStatsByCount(): Flow<List<TransactionStats>> } \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/services/TransactionEvent.kt b/app/src/main/java/com/example/bondoman/services/TransactionEvent.kt index 36667f5f5d156a8462eac46568e683cc16c4ca99..0eb2684d6267c0612e7f2e56b49b6e8b25978b45 100644 --- a/app/src/main/java/com/example/bondoman/services/TransactionEvent.kt +++ b/app/src/main/java/com/example/bondoman/services/TransactionEvent.kt @@ -10,4 +10,5 @@ sealed interface TransactionEvent { data class SetNominal(val Nominal: BigDecimal) : TransactionEvent data class SetKategori(val Kategori: Category) : TransactionEvent data class SetLokasi(val Lokasi: Location) : TransactionEvent + data class ChangeTransactionStats(val sortTransactionStatsByValue: Boolean): TransactionEvent } \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/services/TransactionState.kt b/app/src/main/java/com/example/bondoman/services/TransactionState.kt index df4080c776c23b968d3c333508331314167395cb..626d2b83617d3212bbba4e350d41e58fa444f625 100644 --- a/app/src/main/java/com/example/bondoman/services/TransactionState.kt +++ b/app/src/main/java/com/example/bondoman/services/TransactionState.kt @@ -2,11 +2,14 @@ package com.example.bondoman.services import android.location.Location import com.example.bondoman.models.Transaction import com.example.bondoman.models.Transaction.Category +import com.example.bondoman.models.TransactionStats import java.math.BigDecimal import java.time.LocalDate data class TransactionState ( val transactions : List<Transaction> = emptyList(), + val transactionStats : List<TransactionStats> = emptyList(), + val sortTransactionStatsByValue: Boolean = true, val judul: String = "", val nominal: BigDecimal = BigDecimal(0), val kategori: Category = Category.PEMBELIAN, diff --git a/app/src/main/java/com/example/bondoman/ui/chart/ChartFragment.kt b/app/src/main/java/com/example/bondoman/ui/chart/ChartFragment.kt index 714627195eb4916f53ab8ad5e382110d790f7f36..d62f634ae64628f06e29237641daa11c843134f1 100644 --- a/app/src/main/java/com/example/bondoman/ui/chart/ChartFragment.kt +++ b/app/src/main/java/com/example/bondoman/ui/chart/ChartFragment.kt @@ -6,9 +6,13 @@ import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Button import com.example.bondoman.R import com.example.bondoman.databinding.FragmentChartBinding import com.example.bondoman.databinding.FragmentLoginBinding +import com.example.bondoman.models.Transaction +import com.example.bondoman.models.TransactionStats +import com.example.bondoman.services.TransactionEvent import com.github.mikephil.charting.charts.PieChart import com.github.mikephil.charting.data.PieData import com.github.mikephil.charting.data.PieDataSet @@ -18,7 +22,12 @@ import com.github.mikephil.charting.utils.ColorTemplate class ChartFragment : Fragment() { private lateinit var binding: FragmentChartBinding - lateinit var pieChart: PieChart + private lateinit var pieChart: PieChart + + private lateinit var sortValueButton: Button + private lateinit var sortCountButton: Button + + private var transactionsStats : ArrayList<TransactionStats> = ArrayList() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -37,12 +46,37 @@ class ChartFragment : Fragment() { binding = FragmentChartBinding.bind(view) - var pieChart = binding.chart + pieChart = binding.chart + sortValueButton = binding.sortByValueButton + sortCountButton = binding.sortByCountButton + + // TODO : FETCH DATA FROM ROOM + initDummy() + + generateChart(true,"Sorted by Value") + + sortValueButton.setOnClickListener{ + + + } + sortCountButton.setOnClickListener { + generateChart(false, "Sorted by Count") + } + + + } + + fun generateChart(sortByValue: Boolean, chartTitle: String){ val list:ArrayList<PieEntry> = ArrayList() - list.add(PieEntry(30f,"Pembelian")) - list.add(PieEntry(50f,"Penjualan")) + for(transaction in transactionsStats){ + if(sortByValue){ + list.add(PieEntry(transaction.totalNominal, transaction.kategori)) + } else { + list.add(PieEntry(transaction.count.toFloat(), transaction.kategori)) + } + } val pieDataSet= PieDataSet(list,"Chart") @@ -56,8 +90,18 @@ class ChartFragment : Fragment() { pieChart.description.text= "Pie Chart" - pieChart.centerText="List" + pieChart.centerText=chartTitle + + pieChart.animateY(1000) + } + + fun initDummy(){ + transactionsStats.add( + TransactionStats(kategori = Transaction.Category.PEMBELIAN, count = 10, totalNominal = 10000f) + ) - pieChart.animateY(2000) + transactionsStats.add( + TransactionStats(kategori = Transaction.Category.PENJUALAN, count = 89, totalNominal = 800123f) + ) } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_chart.xml b/app/src/main/res/layout/fragment_chart.xml index c4f4655b1165d7a8f6072cdc39202b15658fbeb9..7e58b94e11bcaac6e0c17c6cb28fc65210f7f488 100644 --- a/app/src/main/res/layout/fragment_chart.xml +++ b/app/src/main/res/layout/fragment_chart.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/ConstraintLayout" android:layout_width="match_parent" @@ -13,4 +14,22 @@ android:id="@+id/chart"> </com.github.mikephil.charting.charts.PieChart> + + <Button + android:id="@+id/sortByValueButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="100dp" + android:text="@string/chart_sort_value_title" + app:layout_constraintBottom_toBottomOf="@+id/chart" + app:layout_constraintStart_toStartOf="parent" /> + + <Button + android:id="@+id/sortByCountButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/chart_sort_count_title" + app:layout_constraintBottom_toTopOf="@+id/sortByValueButton" + app:layout_constraintStart_toStartOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae9dec8a6782bbfb750d001d606f41b7c8580347..520a5299792d9405d8de086d5d321de03d1924c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,4 +8,6 @@ <string name="settings_save_button_title">Save Transaction</string> <string name="settings_send_button_title">Send Transaction to Email</string> <string name="settings_logout_button_title">Logout</string> + <string name="chart_sort_value_title">Sort by Value</string> + <string name="chart_sort_count_title">Sort by Count</string> </resources> \ No newline at end of file