Update Category model and interactions according to backend

- added expense and archiving
This commit is contained in:
William Brawner 2020-07-27 17:33:07 -07:00
parent 8817f06c3d
commit 8dd96d04ac
7 changed files with 49 additions and 82 deletions

View file

@ -67,6 +67,9 @@ class AddEditCategoryActivity : AppCompatActivity(), CoroutineScope {
menu?.findItem(R.id.action_delete)?.isVisible = true
edit_category_name.setText(category.title)
edit_category_amount.setText(String.format("%.02f", category.amount / 100.0f))
expense.isChecked = category.expense
income.isChecked = !category.expense
archived.isChecked = category.archived
}
}
@ -103,7 +106,9 @@ class AddEditCategoryActivity : AppCompatActivity(), CoroutineScope {
id = id,
title = edit_category_name.text.toString(),
amount = edit_category_amount.text.toLong(),
budgetId = (budgetSpinner.selectedItem as Budget).id!!
budgetId = (budgetSpinner.selectedItem as Budget).id!!,
expense = expense.isChecked,
archived = archived.isChecked
))
finish()
}

View file

@ -1,75 +0,0 @@
package com.wbrawner.budget.ui.categories
import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.RecyclerView
import com.wbrawner.budget.R
import com.wbrawner.budget.common.category.Category
import com.wbrawner.budget.ui.EXTRA_CATEGORY_ID
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext
class CategoryAdapter(
private val activity: Activity,
private val data: List<Category>,
private val viewModel: CategoryViewModel
) : RecyclerView.Adapter<CategoryAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_category, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = data.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val category = data[position]
holder.title?.text = category.title
// TODO: Format according to budget's currency
holder.amount?.text = String.format("${'$'}%.02f", category.amount / 100.0f)
holder.progress?.max = category.amount.toInt()
holder.launch {
val balance = viewModel.getBalance(category.id!!)
holder.progress?.isIndeterminate = false
holder.progress?.setProgress(
(-1 * balance).toInt(),
true
)
holder.amount?.text = holder.itemView.context.getString(
R.string.balance_remaning,
(category.amount + balance) / 100.0f
)
}
holder.itemView.setOnClickListener {
startActivity(
activity,
Intent(it.context.applicationContext, AddEditCategoryActivity::class.java)
.apply {
putExtra(EXTRA_CATEGORY_ID, category.id!!)
},
null
)
}
}
override fun onViewRecycled(holder: ViewHolder) {
holder.coroutineContext.cancel()
super.onViewRecycled(holder)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), CoroutineScope {
override val coroutineContext: CoroutineContext = Dispatchers.Main
val title: TextView? = itemView.findViewById(R.id.category_title)
val amount: TextView? = itemView.findViewById(R.id.category_amount)
val progress: ProgressBar? = itemView.findViewById(R.id.category_progress)
}
}

View file

@ -73,17 +73,23 @@ class CategoryViewHolder(
name.text = category.title
// TODO: Format according to budget's currency
amount.text = String.format("${'$'}%.02f", category.amount / 100.0f)
val tintColor = if (category.expense) R.color.colorTextRed else R.color.colorTextGreen
val colorStateList = with(itemView.context) {
android.content.res.ColorStateList.valueOf(getColor(tintColor))
}
progressBar.progressTintList = colorStateList
progressBar.indeterminateTintList = colorStateList
progressBar.max = category.amount.toInt()
launch {
val balance = viewModel.getBalance(category.id!!)
val balance = viewModel.getBalance(category)
progressBar.isIndeterminate = false
progressBar.setProgress(
(-1 * balance).toInt(),
balance,
true
)
amount.text = itemView.context.getString(
R.string.balance_remaning,
(category.amount + balance) / 100.0f
(category.amount - balance) / 100.0f
)
}
itemView.setOnClickListener {

View file

@ -49,8 +49,10 @@ class CategoryViewModel @Inject constructor(
categoryRepo.delete(id)
}
suspend fun getBalance(id: Long) = showLoader {
categoryRepo.getBalance(id)
suspend fun getBalance(category: Category) = showLoader {
val balance = categoryRepo.getBalance(category.id!!)
val multiplier = if (category.expense) -1 else 1
return@showLoader (balance * multiplier).toInt()
}
}

View file

@ -50,6 +50,32 @@
android:inputType="numberDecimal" />
</com.google.android.material.textfield.TextInputLayout>
<RadioGroup
android:id="@+id/categoryExpenseContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/expense"
android:text="@string/type_expense"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:id="@+id/income"
android:text="@string/type_income"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RadioGroup>
<CheckBox
android:id="@+id/archived"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/archived" />
<TextView
android:id="@+id/budgetHint"
style="@style/TextAppearance.MaterialComponents.Caption"

View file

@ -53,4 +53,5 @@
<string name="action_cancel">Cancel</string>
<string name="prompt_month">Month</string>
<string name="prompt_year">Year</string>
<string name="archived">Archived</string>
</resources>

View file

@ -5,7 +5,9 @@ data class Category(
val id: Long? = null,
val title: String,
val description: String? = null,
val amount: Long
val amount: Long,
val expense: Boolean = true,
val archived: Boolean = false
) {
override fun toString(): String {
return title