diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index da2044165cb59ffaa8c8854ee599dbe7c7fad00b..2632a8fce4f0bba6cc3a2b252c77ef116f3b0788 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -4,6 +4,18 @@ <value> <entry key="app"> <State> + <runningDeviceTargetSelectedWithDropDown> + <Target> + <type value="RUNNING_DEVICE_TARGET" /> + <deviceKey> + <Key> + <type value="SERIAL_NUMBER" /> + <value value="RR8R202MELK" /> + </Key> + </deviceKey> + </Target> + </runningDeviceTargetSelectedWithDropDown> + <timeTargetWasSelectedWithDropDown value="2024-04-05T01:18:14.127059300Z" /> <runningDeviceTargetsSelectedWithDialog> <Target> <type value="RUNNING_DEVICE_TARGET" /> diff --git a/app/src/main/java/com/example/bondoman/MainActivity.kt b/app/src/main/java/com/example/bondoman/MainActivity.kt index 2b3190730f73d5ad0ef97cac00dcd9324aaa61d3..d1cc0b087862d14eee6b1eeddc0413ead83ff0b2 100644 --- a/app/src/main/java/com/example/bondoman/MainActivity.kt +++ b/app/src/main/java/com/example/bondoman/MainActivity.kt @@ -26,6 +26,7 @@ import androidx.activity.viewModels import com.example.bondoman.models.TransactionViewModel import com.example.bondoman.room.BondomanDatabase import com.example.bondoman.services.LocationDefault +import com.example.bondoman.ui.chart.ChartViewModel import com.example.bondoman.ui.nointernet.NoInternetFragment import com.google.android.gms.location.LocationServices import retrofit2.HttpException @@ -44,11 +45,16 @@ class MainActivity : AppCompatActivity() { TransactionViewModel.provideFactory(db.dao,LocationDefault(this,LocationServices.getFusedLocationProviderClient(this)),applicationContext,this) } + private val chartViewModel: ChartViewModel by viewModels { + ChartViewModel.provideFactory(db.dao,applicationContext,this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) locationPermission() d("OKE",viewModel.state.value.toString()) + d("DONT DELETE",chartViewModel.toString()) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) replaceFragment(CartFragment(), NoInternetFragment(), "Cart") 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 6a2900e9d923eb4f605ce879fe09c76a44d867f5..e8b1dee87e091dd391de4fcd89728ed9e2d10ccb 100644 --- a/app/src/main/java/com/example/bondoman/models/Transaction.kt +++ b/app/src/main/java/com/example/bondoman/models/Transaction.kt @@ -32,4 +32,5 @@ data class Transaction( data class TransactionStats( val kategori: Transaction.Category, val total: Float, + val count: Float, ) 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 d288436e13aa3d427a8345aea181c7f7c4506d26..8e946a4ce721960ae9690f3718f62be7923bcab0 100644 --- a/app/src/main/java/com/example/bondoman/room/TransactionDao.kt +++ b/app/src/main/java/com/example/bondoman/room/TransactionDao.kt @@ -33,7 +33,7 @@ interface TransactionDao { @Query("DELETE FROM `transaction`") suspend fun deleteAll() - @Query("SELECT kategori, SUM(nominal) AS total FROM `transaction` GROUP BY kategori") + @Query("SELECT kategori, SUM(nominal) AS total, COUNT() as count FROM `transaction` GROUP BY kategori") fun getTransactionStats(): Flow<List<TransactionStats>> } \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/ui/chart/ChartEvent.kt b/app/src/main/java/com/example/bondoman/ui/chart/ChartEvent.kt new file mode 100644 index 0000000000000000000000000000000000000000..a0bc82958f90667787c9f2358d0da2974015c267 --- /dev/null +++ b/app/src/main/java/com/example/bondoman/ui/chart/ChartEvent.kt @@ -0,0 +1,5 @@ +package com.example.bondoman.ui.chart + +sealed interface ChartEvent { + +} \ No newline at end of file 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 3aca81fdb757159d1048fd5c931d55b5a5d10a22..2e491f9107852a62e4c0c9b0903d0d9294977ade 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 @@ -2,22 +2,31 @@ package com.example.bondoman.ui.chart import android.graphics.Color import android.os.Bundle +import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button +import androidx.fragment.app.activityViewModels 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 import com.github.mikephil.charting.data.PieEntry import com.github.mikephil.charting.utils.ColorTemplate +import android.util.Log.d +import androidx.lifecycle.lifecycleScope +import com.example.bondoman.models.TransactionViewModel +import com.example.bondoman.services.TransactionEvent +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect class ChartFragment : Fragment() { @@ -29,6 +38,8 @@ class ChartFragment : Fragment() { private var transactionsStats : ArrayList<TransactionStats> = ArrayList() + private val chartViewModel by activityViewModels<ChartViewModel>() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } @@ -50,31 +61,38 @@ class ChartFragment : Fragment() { sortValueButton = binding.sortByValueButton sortCountButton = binding.sortByCountButton - // TODO : FETCH DATA FROM ROOM - initDummy() + d("GEDEBUGEMING", "breakpoint 1") + d("GEDEBUGEMING",chartViewModel.transactionStats.value.toString()) + d("GEDEBUGEMING", "breakpoint 10") - generateChart(true,"Sorted by Value") + runningBackgroundUpdateUI(true) sortValueButton.setOnClickListener{ - - + runningBackgroundUpdateUI(true) } sortCountButton.setOnClickListener { - generateChart(false, "Sorted by Count") + runningBackgroundUpdateUI(false) + } + } + private fun runningBackgroundUpdateUI(isSortedByValue: Boolean){ + CoroutineScope(Dispatchers.Main).launch { + chartViewModel.transactionStats.value.collect { stats -> + transactionsStats.clear() + transactionsStats.addAll(stats) + generateChart(transactionsStats,isSortedByValue) + } } - - } - fun generateChart(sortByValue: Boolean, chartTitle: String){ + private fun generateChart(transactionStats: List<TransactionStats>, isSortedByValue: Boolean){ val list:ArrayList<PieEntry> = ArrayList() - for(transaction in transactionsStats){ - if(sortByValue){ - list.add(PieEntry(transaction.total, transaction.kategori)) + for(stats in transactionStats){ + if(isSortedByValue){ + list.add(PieEntry(stats.total, stats.kategori.toString())) } else { - list.add(PieEntry(transaction.total, transaction.kategori)) + list.add(PieEntry(stats.count, stats.kategori.toString())) } } @@ -90,18 +108,12 @@ class ChartFragment : Fragment() { pieChart.description.text= "Pie Chart" - pieChart.centerText=chartTitle + if(isSortedByValue){ + pieChart.centerText = "Sorted by Value" + } else { + pieChart.centerText = "Sorted by Count" + } pieChart.animateY(1000) } - - fun initDummy(){ - transactionsStats.add( - TransactionStats(kategori = Transaction.Category.PEMBELIAN, total = 6868f) - ) - - transactionsStats.add( - TransactionStats(kategori = Transaction.Category.PENJUALAN, total = 7878f) - ) - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/ui/chart/ChartState.kt b/app/src/main/java/com/example/bondoman/ui/chart/ChartState.kt new file mode 100644 index 0000000000000000000000000000000000000000..aa630cd937b51f738a5216473d26eaa9450642c3 --- /dev/null +++ b/app/src/main/java/com/example/bondoman/ui/chart/ChartState.kt @@ -0,0 +1,7 @@ +package com.example.bondoman.ui.chart + +import com.example.bondoman.models.TransactionStats + +data class ChartState( + val transactionStats : List<TransactionStats> = emptyList(), +) diff --git a/app/src/main/java/com/example/bondoman/ui/chart/ChartViewModel.kt b/app/src/main/java/com/example/bondoman/ui/chart/ChartViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..9f5a8e19d6287e72109e540ae4e1fd8e23d01848 --- /dev/null +++ b/app/src/main/java/com/example/bondoman/ui/chart/ChartViewModel.kt @@ -0,0 +1,50 @@ +package com.example.bondoman.ui.chart + +import android.content.Context +import android.os.Bundle +import androidx.lifecycle.AbstractSavedStateViewModelFactory +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.savedstate.SavedStateRegistryOwner +import com.example.bondoman.models.Transaction +import com.example.bondoman.models.TransactionStats +import com.example.bondoman.room.TransactionDao +import com.example.bondoman.services.LocationClient +import com.example.bondoman.services.TransactionState +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.stateIn + +@OptIn(ExperimentalCoroutinesApi::class) +class ChartViewModel(private val dao: TransactionDao, private val context: Context): ViewModel() { + private val _state = MutableStateFlow(ChartState()) + private val _transactionStats = MutableStateFlow(dao.getTransactionStats() ) + val transactionStats = _transactionStats.asStateFlow() + + // Define ViewModel factory in a companion object + companion object { + fun provideFactory( + dao: TransactionDao, + context: Context, + owner: SavedStateRegistryOwner, + defaultArgs: Bundle? = null, + ): AbstractSavedStateViewModelFactory = + object : AbstractSavedStateViewModelFactory(owner, defaultArgs) { + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create( + key: String, + modelClass: Class<T>, + handle: SavedStateHandle + ): T { + return ChartViewModel(dao, context) as T + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/ui/settings/SettingsFragment.kt b/app/src/main/java/com/example/bondoman/ui/settings/SettingsFragment.kt index 86d783020f0a2b1d5938e5247cb54c81545717f7..f72fad650c5a7476a54c9b7220fed658ce7e9486 100644 --- a/app/src/main/java/com/example/bondoman/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/example/bondoman/ui/settings/SettingsFragment.kt @@ -13,22 +13,14 @@ import com.example.bondoman.R import com.example.bondoman.databinding.FragmentChartBinding import com.example.bondoman.databinding.FragmentSettingsBinding -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" - -/** - * A simple [Fragment] subclass. - * Use the [SettingsFragment.newInstance] factory method to - * create an instance of this fragment. - */ class SettingsFragment : Fragment() { private lateinit var binding: FragmentSettingsBinding private lateinit var saveButton: Button private lateinit var sendButton: Button private lateinit var logoutButton: Button + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) }