Skip to content
This repository has been archived by the owner on Nov 5, 2024. It is now read-only.

Commit

Permalink
Fix error crash and improvement UX for account transfer type in Trans…
Browse files Browse the repository at this point in the history
…action screen (#3163)
  • Loading branch information
isaacnguyen0809 authored Apr 26, 2024
1 parent 5b30c09 commit dfe841c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class PieChartAct @Inject constructor(
private val trnsWithRangeAndAccFiltersAct: TrnsWithRangeAndAccFiltersAct,
private val calcTrnsIncomeExpenseAct: LegacyCalcTrnsIncomeExpenseAct,
private val categoryRepository: CategoryRepository,
private val categoryIncomeWithAccountFiltersAct: LegacyCategoryIncomeWithAccountFiltersAct
private val categoryIncomeWithAccountFiltersAct: LegacyCategoryIncomeWithAccountFiltersAct,
) : FPAction<PieChartAct.Input, PieChartAct.Output>() {

private val accountTransfersCategory =
Expand Down Expand Up @@ -127,7 +127,7 @@ class PieChartAct @Inject constructor(
accountIdFilterList: List<UUID>,

@SideEffect
allAccounts: suspend () -> List<Account>
allAccounts: suspend () -> List<Account>,
): Pair<List<Account>, Set<UUID>> {
val accountsUsed = if (accountIdFilterList.isEmpty()) {
allAccounts then ::filterExcluded
Expand Down Expand Up @@ -205,26 +205,26 @@ class PieChartAct @Inject constructor(
treatTransferAsIncExp: Boolean,

@SideEffect
incomeExpenseTransfer: suspend () -> IncomeExpenseTransferPair
incomeExpenseTransfer: suspend () -> IncomeExpenseTransferPair,
): BigDecimal {
val incExpQuad = incomeExpenseTransfer()
return when (type) {
TransactionType.INCOME -> {
incExpQuad.income +
if (treatTransferAsIncExp) {
incExpQuad.transferIncome
} else {
BigDecimal.ZERO
}
if (treatTransferAsIncExp) {
incExpQuad.transferIncome
} else {
BigDecimal.ZERO
}
}

TransactionType.EXPENSE -> {
incExpQuad.expense +
if (treatTransferAsIncExp) {
incExpQuad.transferExpense
} else {
BigDecimal.ZERO
}
if (treatTransferAsIncExp) {
incExpQuad.transferExpense
} else {
BigDecimal.ZERO
}
}

else -> BigDecimal.ZERO
Expand All @@ -245,7 +245,7 @@ class PieChartAct @Inject constructor(
incomeExpenseTransfer: suspend () -> IncomeExpenseTransferPair,

@SideEffect
categoryAmounts: suspend () -> List<CategoryAmount>
categoryAmounts: suspend () -> List<CategoryAmount>,
): List<CategoryAmount> {
val incExpQuad = incomeExpenseTransfer()

Expand All @@ -260,7 +260,7 @@ class PieChartAct @Inject constructor(
}

val categoryTrans = transactions().filter {
it.type == TransactionType.TRANSFER && it.categoryId == null
it.type == TransactionType.TRANSFER
}.filter {
if (type == TransactionType.EXPENSE) {
accountIdFilterSet.contains(it.accountId)
Expand Down Expand Up @@ -293,7 +293,7 @@ class PieChartAct @Inject constructor(
val accountIdFilterList: List<UUID>,
val treatTransferAsIncExp: Boolean = false,
val showAccountTransfersCategory: Boolean = treatTransferAsIncExp,
val existingTransactions: List<Transaction> = emptyList()
val existingTransactions: List<Transaction> = emptyList(),
)

data class Output(val totalAmount: Double, val categoryAmounts: ImmutableList<CategoryAmount>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ fun BoxWithConstraintsScope.TransactionsScreen(screen: TransactionsScreen) {
}

UI(
screen = screen,
period = uiState.period,
baseCurrency = uiState.baseCurrency,
currency = uiState.currency,
Expand Down Expand Up @@ -201,6 +202,7 @@ fun BoxWithConstraintsScope.TransactionsScreen(screen: TransactionsScreen) {
@Suppress("LongMethod", "LongParameterList")
@Composable
private fun BoxWithConstraintsScope.UI(
screen: TransactionsScreen,
period: TimePeriod,
baseCurrency: String,
currency: String,
Expand Down Expand Up @@ -293,6 +295,7 @@ private fun BoxWithConstraintsScope.UI(
) {
item {
Header(
screen = screen,
history = history,
income = income,
expenses = expenses,
Expand Down Expand Up @@ -562,8 +565,10 @@ private fun BoxWithConstraintsScope.DeleteModals(
}
}

@Suppress("LongParameterList")
@Composable
private fun Header(
screen: TransactionsScreen,
history: ImmutableList<TransactionHistoryItem>,
currency: String,
baseCurrency: String,
Expand Down Expand Up @@ -592,10 +597,15 @@ private fun Header(
) {
Spacer(Modifier.height(20.dp))

val hideEditAndDeleteButtonForAccountTransfer =
screen.transactions.none { it.type == TransactionType.TRANSFER }

ItemStatisticToolbar(
contrastColor = contrastColor,
onEdit = onEdit,
onDelete = onDelete
onDelete = onDelete,
showEditButton = hideEditAndDeleteButtonForAccountTransfer,
showDeleteButton = hideEditAndDeleteButtonForAccountTransfer,
)

Spacer(Modifier.height(24.dp))
Expand Down Expand Up @@ -830,7 +840,8 @@ private fun BoxWithConstraintsScope.Preview_empty() {
skipAllModalVisible = false,
onSkipAllModalVisible = {},
onChoosePeriodModal = {},
choosePeriodModal = null
choosePeriodModal = null,
screen = TransactionsScreen(),
)
}
}
Expand Down Expand Up @@ -875,7 +886,8 @@ private fun BoxWithConstraintsScope.Preview_crypto() {
skipAllModalVisible = false,
onSkipAllModalVisible = {},
onChoosePeriodModal = {},
choosePeriodModal = null
choosePeriodModal = null,
screen = TransactionsScreen(),
)
}
}
Expand Down Expand Up @@ -922,7 +934,8 @@ private fun BoxWithConstraintsScope.Preview_empty_upcoming() {
skipAllModalVisible = false,
onSkipAllModalVisible = {},
onChoosePeriodModal = {},
choosePeriodModal = null
choosePeriodModal = null,
screen = TransactionsScreen(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.toArgb
import androidx.lifecycle.viewModelScope
import arrow.core.toOption
import com.ivy.base.legacy.SharedPrefs
import com.ivy.base.legacy.Transaction
import com.ivy.base.legacy.TransactionHistoryItem
import com.ivy.base.legacy.stringRes
import com.ivy.base.model.TransactionType
import com.ivy.data.db.dao.read.AccountDao
import com.ivy.data.db.dao.write.WriteCategoryDao
Expand All @@ -17,10 +19,14 @@ import com.ivy.data.db.dao.write.WriteTransactionDao
import com.ivy.data.model.AccountId
import com.ivy.data.model.Category
import com.ivy.data.model.CategoryId
import com.ivy.data.model.primitive.ColorInt
import com.ivy.data.model.primitive.IconAsset
import com.ivy.data.model.primitive.NotBlankTrimmedString
import com.ivy.data.repository.AccountRepository
import com.ivy.data.repository.CategoryRepository
import com.ivy.data.repository.TagRepository
import com.ivy.data.repository.mapper.TransactionMapper
import com.ivy.design.l0_system.RedLight
import com.ivy.frp.then
import com.ivy.legacy.IvyWalletCtx
import com.ivy.legacy.data.model.TimePeriod
Expand All @@ -36,6 +42,7 @@ import com.ivy.legacy.utils.selectEndTextFieldValue
import com.ivy.navigation.Navigation
import com.ivy.navigation.TransactionsScreen
import com.ivy.ui.ComposeViewModel
import com.ivy.ui.R
import com.ivy.wallet.domain.action.account.AccTrnsAct
import com.ivy.wallet.domain.action.account.AccountsAct
import com.ivy.wallet.domain.action.account.CalcAccBalanceAct
Expand All @@ -55,6 +62,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.launch
import java.time.Instant
import java.util.UUID
import javax.inject.Inject
import com.ivy.legacy.datamodel.Account as LegacyAccount
Expand Down Expand Up @@ -85,7 +93,7 @@ class TransactionsViewModel @Inject constructor(
private val categoryWriter: WriteCategoryDao,
private val plannedPaymentRuleWriter: WritePlannedPaymentRuleDao,
private val transactionMapper: TransactionMapper,
private val tagRepository: TagRepository
private val tagRepository: TagRepository,
) : ComposeViewModel<TransactionsState, TransactionsEvent>() {

private val period = mutableStateOf(ivyContext.selectedPeriod)
Expand Down Expand Up @@ -610,13 +618,20 @@ class TransactionsViewModel @Inject constructor(
}

private suspend fun initForAccountTransfersCategory(
categoryId: UUID?,
accountFilterList: List<UUID>,
transactions: List<Transaction>,
) {
initWithTransactions.value = true

category.value = categories.value.firstOrNull { it.id.value == categoryId }
val accountTransferCategory = Category(
name = NotBlankTrimmedString.unsafe(stringRes(R.string.account_transfers)),
color = ColorInt(RedLight.toArgb()),
icon = IconAsset.unsafe("transfer"),
id = CategoryId(UUID.randomUUID()),
lastUpdated = Instant.EPOCH,
orderNum = 0.0,
removed = false,
)
category.value = accountTransferCategory
val accountFilterIdSet = accountFilterList.toHashSet()
val trans = transactions.filter {
it.categoryId == null && (
Expand Down Expand Up @@ -850,7 +865,6 @@ class TransactionsViewModel @Inject constructor(

screen.unspecifiedCategory == true && screen.transactions.isNotEmpty() -> {
initForAccountTransfersCategory(
screen.categoryId,
screen.accountIdFilterList,
screen.transactions
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ivy.legacy.ui.component

import android.annotation.SuppressLint
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
Expand All @@ -17,12 +18,14 @@ import com.ivy.wallet.ui.theme.components.CircleButton
import com.ivy.wallet.ui.theme.components.DeleteButton
import com.ivy.wallet.ui.theme.components.IvyOutlinedButton

@SuppressLint("ComposeModifierMissing")
@Deprecated("Old design system. Use `:ivy-design` and Material3")
@Composable
fun ItemStatisticToolbar(
contrastColor: Color,

onEdit: () -> Unit,
showEditButton: Boolean = true,
showDeleteButton: Boolean = true,
onDelete: () -> Unit,
) {
Row(
Expand All @@ -43,21 +46,25 @@ fun ItemStatisticToolbar(

Spacer(Modifier.weight(1f))

IvyOutlinedButton(
iconStart = R.drawable.ic_edit,
text = stringRes(R.string.edit),
borderColor = contrastColor,
iconTint = contrastColor,
textColor = contrastColor,
solidBackground = false
) {
onEdit()
if (showEditButton) {
IvyOutlinedButton(
iconStart = R.drawable.ic_edit,
text = stringRes(R.string.edit),
borderColor = contrastColor,
iconTint = contrastColor,
textColor = contrastColor,
solidBackground = false
) {
onEdit()
}
}

Spacer(Modifier.width(16.dp))

DeleteButton {
onDelete()
if (showDeleteButton) {
DeleteButton {
onDelete()
}
}

Spacer(Modifier.width(24.dp))
Expand Down

0 comments on commit dfe841c

Please sign in to comment.