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

Commit

Permalink
Merge pull request #787 from Vishwa-Raghavendra/AccountScreen
Browse files Browse the repository at this point in the history
Account screen
  • Loading branch information
ILIYANGERMANOV authored Apr 25, 2022
2 parents fcc55db + 518d66d commit 38b1247
Show file tree
Hide file tree
Showing 15 changed files with 273 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.ivy.wallet.domain.pure.data.ClosedTimeRange
import com.ivy.wallet.domain.pure.data.IncomeExpensePair
import com.ivy.wallet.domain.pure.transaction.AccountValueFunctions
import com.ivy.wallet.domain.pure.transaction.foldTransactions
import java.math.BigDecimal
import javax.inject.Inject

class CalcAccIncomeExpenseAct @Inject constructor(
Expand All @@ -25,22 +26,25 @@ class CalcAccIncomeExpenseAct @Inject constructor(
arg = account.id,
valueFunctions = nonEmptyListOf(
AccountValueFunctions::income,
AccountValueFunctions::expense
AccountValueFunctions::expense,
AccountValueFunctions::transferIncome,
AccountValueFunctions::transferExpense
)
)
} then { values ->
Output(
account = account,
incomeExpensePair = IncomeExpensePair(
income = values[0],
expense = values[1]
income = values[0] + if (includeTransfersInCalc) values[2] else BigDecimal.ZERO,
expense = values[1] + if (includeTransfersInCalc) values[3] else BigDecimal.ZERO
)
)
}

data class Input(
val account: Account,
val range: ClosedTimeRange = ClosedTimeRange.allTimeIvy()
val range: ClosedTimeRange = ClosedTimeRange.allTimeIvy(),
val includeTransfersInCalc: Boolean = false
)

data class Output(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class AccountDataAct @Inject constructor(
val incomeExpensePair = calcAccIncomeExpenseAct(
CalcAccIncomeExpenseAct.Input(
account = acc,
range = range
range = range,
includeTransfersInCalc = includeTransfersInCalc
)
).incomeExpensePair

Expand All @@ -60,6 +61,7 @@ class AccountDataAct @Inject constructor(
data class Input(
val accounts: List<Account>,
val baseCurrency: String,
val range: ClosedTimeRange
val range: ClosedTimeRange,
val includeTransfersInCalc: Boolean = false
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class ExportZipLogic(
hashmap[SharedPrefs.HIDE_CURRENT_BALANCE] =
sharedPrefs.getBoolean(SharedPrefs.HIDE_CURRENT_BALANCE, false).toString()

hashmap[SharedPrefs.TRANSFERS_AS_INCOME_EXPENSE] =
sharedPrefs.getBoolean(SharedPrefs.TRANSFERS_AS_INCOME_EXPENSE, false).toString()

return hashmap
}

Expand Down Expand Up @@ -261,6 +264,11 @@ class ExportZipLogic(
(completeData.sharedPrefs[SharedPrefs.HIDE_CURRENT_BALANCE] ?: "false").toBoolean()
)

sharedPrefs.putBoolean(
SharedPrefs.TRANSFERS_AS_INCOME_EXPENSE,
(completeData.sharedPrefs[SharedPrefs.TRANSFERS_AS_INCOME_EXPENSE] ?: "false").toBoolean()
)

plannedPayments.await()
settings.await()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ object AccountValueFunctions {
amount else BigDecimal.ZERO
}

fun transferIncome(
transaction: Transaction,
accountId: UUID
): BigDecimal = with(transaction) {
if (this.toAccountId == accountId && type == TransactionType.TRANSFER)
toAmount else BigDecimal.ZERO
}

fun expense(
transaction: Transaction,
accountId: UUID
Expand All @@ -50,6 +58,15 @@ object AccountValueFunctions {
amount else BigDecimal.ZERO
}

fun transferExpense(
transaction: Transaction,
accountId: UUID
): BigDecimal = with(transaction) {
if (this.accountId == accountId && type == TransactionType.TRANSFER)
amount else BigDecimal.ZERO
}


fun incomeCount(
transaction: Transaction,
accountId: UUID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SharedPrefs(appContext: Context) {
const val START_DATE_OF_MONTH = "start_date_of_month"
const val SHOW_NOTIFICATIONS = "show_notifications"
const val HIDE_CURRENT_BALANCE = "hide_current_balance"
const val TRANSFERS_AS_INCOME_EXPENSE = "transfers_as_inc_exp"
//----------------------------- App Settings -----------------------------------------------

//-------------------------------- Customer Journey ----------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/com/ivy/wallet/ui/accounts/AccountState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ivy.wallet.ui.accounts

import com.ivy.wallet.utils.UiText

data class AccountState(
val baseCurrency: String = "",
val accountsData: List<AccountData> = emptyList(),
val totalBalanceWithExcluded: Double = 0.0,
val totalBalanceWithExcludedText: UiText = UiText.DynamicString(""),
val reorderVisible: Boolean = false
)
9 changes: 9 additions & 0 deletions app/src/main/java/com/ivy/wallet/ui/accounts/AccountsEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.ivy.wallet.ui.accounts

import com.ivy.wallet.domain.data.core.Account

sealed class AccountsEvent {
data class OnReorder(val reorderedList: List<AccountData>) : AccountsEvent()
data class OnEditAccount(val editedAccount: Account, val newBalance: Double) : AccountsEvent()
data class OnReorderModalVisible(val reorderVisible: Boolean) : AccountsEvent()
}
137 changes: 59 additions & 78 deletions app/src/main/java/com/ivy/wallet/ui/accounts/AccountsTab.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.ivy.wallet.ui.accounts

import androidx.compose.foundation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -30,55 +36,39 @@ import com.ivy.wallet.ui.ivyWalletCtx
import com.ivy.wallet.ui.main.MainTab
import com.ivy.wallet.ui.theme.*
import com.ivy.wallet.ui.theme.components.*
import com.ivy.wallet.ui.theme.modal.edit.AccountModal
import com.ivy.wallet.ui.theme.modal.edit.AccountModalData
import com.ivy.wallet.utils.UiText
import com.ivy.wallet.utils.clickableNoIndication
import com.ivy.wallet.utils.format
import com.ivy.wallet.utils.horizontalSwipeListener
import com.ivy.wallet.utils.onScreenStart

@Composable
fun BoxWithConstraintsScope.AccountsTab(screen: Main) {
val viewModel: AccountsViewModel = viewModel()

val baseCurrency by viewModel.baseCurrencyCode.collectAsState()
val accounts by viewModel.accounts.collectAsState()
val totalBalanceWithExcluded by viewModel.totalBalanceWithExcluded.collectAsState()
val state by viewModel.state().collectAsState()

onScreenStart {
viewModel.start()
}

UI(
baseCurrency = baseCurrency,
accounts = accounts,
totalBalanceWithExcluded = totalBalanceWithExcluded,

onReorder = viewModel::reorder,
onEditAccount = viewModel::editAccount,
state = state,
onEventHandler = viewModel::onEvent
)
}

@Composable
private fun BoxWithConstraintsScope.UI(
baseCurrency: String,
accounts: List<AccountData>,
totalBalanceWithExcluded: Double?,

onReorder: (List<AccountData>) -> Unit,
onEditAccount: (Account, Double) -> Unit,
state: AccountState = AccountState(),
onEventHandler: (AccountsEvent) -> Unit = {}
) {
var reorderVisible by remember { mutableStateOf(false) }
var accountModalData: AccountModalData? by remember { mutableStateOf(null) }

val nav = navigation()
val ivyContext = ivyWalletCtx()

Column(
LazyColumn(
modifier = Modifier
.fillMaxSize()
.statusBarsPadding()
.navigationBarsPadding()
.verticalScroll(rememberScrollState())
.horizontalSwipeListener(
sensitivity = 200,
onSwipeLeft = {
Expand All @@ -89,88 +79,86 @@ private fun BoxWithConstraintsScope.UI(
}
),
) {
Spacer(Modifier.height(32.dp))

Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Spacer(Modifier.width(24.dp))
item {
Spacer(Modifier.height(32.dp))

Column {
Text(
text = stringResource(R.string.accounts),
style = UI.typo.b1.style(
color = UI.colors.pureInverse,
fontWeight = FontWeight.ExtraBold
Row(
verticalAlignment = Alignment.CenterVertically
) {
Spacer(Modifier.width(24.dp))

Column {
Text(
text = stringResource(R.string.accounts),
style = UI.typo.b1.style(
color = UI.colors.pureInverse,
fontWeight = FontWeight.ExtraBold
)
)
)

if (totalBalanceWithExcluded != null) {
Spacer(Modifier.height(4.dp))

Text(
text = stringResource(R.string.total, baseCurrency,
totalBalanceWithExcluded.format(
baseCurrency
)),
text = state.totalBalanceWithExcludedText.asString(),
style = UI.typo.nB2.style(
color = Gray,
fontWeight = FontWeight.Bold
)
)
}
}

Spacer(Modifier.weight(1f))

Spacer(Modifier.weight(1f))
ReorderButton {
onEventHandler.invoke(AccountsEvent.OnReorderModalVisible(reorderVisible = true))
}

ReorderButton {
reorderVisible = true
Spacer(Modifier.width(24.dp))
}

Spacer(Modifier.width(24.dp))
Spacer(Modifier.height(16.dp))
}


Spacer(Modifier.height(16.dp))

val nav = navigation()
for (accountData in accounts) {
items(state.accountsData) {
AccountCard(
baseCurrency = baseCurrency,
accountData = accountData,
baseCurrency = state.baseCurrency,
accountData = it,
onBalanceClick = {
nav.navigateTo(
ItemStatistic(
accountId = accountData.account.id,
accountId = it.account.id,
categoryId = null
)
)
},
onLongClick = {
reorderVisible = true
onEventHandler.invoke(AccountsEvent.OnReorderModalVisible(reorderVisible = true))
}
) {
nav.navigateTo(
ItemStatistic(
accountId = accountData.account.id,
accountId = it.account.id,
categoryId = null
)
)
}
}

Spacer(Modifier.height(150.dp)) //scroll hack
item {
Spacer(Modifier.height(150.dp)) //scroll hack
}
}

ReorderModalSingleType(
visible = reorderVisible,
initialItems = accounts,
visible = state.reorderVisible,
initialItems = state.accountsData,
dismiss = {
reorderVisible = false
onEventHandler.invoke(AccountsEvent.OnReorderModalVisible(reorderVisible = false))
},
onReordered = onReorder
onReordered = {
onEventHandler.invoke(AccountsEvent.OnReorder(reorderedList = it))
}
) { _, item ->
Text(
modifier = Modifier
Expand All @@ -184,15 +172,6 @@ private fun BoxWithConstraintsScope.UI(
)
)
}

AccountModal(
modal = accountModalData,
onCreateAccount = { },
onEditAccount = onEditAccount,
dismiss = {
accountModalData = null
}
)
}

@Composable
Expand Down Expand Up @@ -341,9 +320,9 @@ private fun AccountHeader(
@Composable
private fun PreviewAccountsTab() {
IvyWalletPreview {
UI(
val state = AccountState(
baseCurrency = "BGN",
accounts = listOf(
accountsData = listOf(
AccountData(
account = Account("Phyre", color = Green.toArgb()),
balance = 2125.0,
Expand Down Expand Up @@ -384,9 +363,11 @@ private fun PreviewAccountsTab() {
),
),
totalBalanceWithExcluded = 25.54,

onReorder = {},
onEditAccount = { _, _ -> }
totalBalanceWithExcludedText = UiText.StringResource(
R.string.total, "BGN", "25.54"
)
)

UI(state = state)
}
}
Loading

0 comments on commit 38b1247

Please sign in to comment.