From 60e95fbc17342e8e7cb27331cdd35c55eb7d9058 Mon Sep 17 00:00:00 2001 From: Iliyan Germanov Date: Thu, 21 Apr 2022 21:13:04 +0300 Subject: [PATCH] Implement declarative wallet balance calculation --- .../wallet/domain/action/CompositionFilter.kt | 17 ++++++++++ .../wallet/domain/action/CompositionMap.kt | 21 ++++++++++++ .../wallet/domain/action/CompositionSum.kt | 29 ++++++++++++++++ .../wallet/domain/action/CompositionUtils.kt | 9 ----- .../action/wallet/CalcWalletBalanceAct.kt | 34 ++++++++----------- .../com/ivy/wallet/ui/home/HomeViewModel.kt | 16 +++++---- 6 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/com/ivy/wallet/domain/action/CompositionFilter.kt create mode 100644 app/src/main/java/com/ivy/wallet/domain/action/CompositionMap.kt create mode 100644 app/src/main/java/com/ivy/wallet/domain/action/CompositionSum.kt delete mode 100644 app/src/main/java/com/ivy/wallet/domain/action/CompositionUtils.kt diff --git a/app/src/main/java/com/ivy/wallet/domain/action/CompositionFilter.kt b/app/src/main/java/com/ivy/wallet/domain/action/CompositionFilter.kt new file mode 100644 index 0000000000..f158a90cba --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/domain/action/CompositionFilter.kt @@ -0,0 +1,17 @@ +package com.ivy.wallet.domain.action + +suspend infix fun (suspend (A) -> List).thenFilter( + predicate: (B) -> Boolean +): suspend (A) -> List = + { a -> + val list = this(a) + list.filter(predicate) + } + +suspend infix fun (Action>).thenFilter( + predicate: (B) -> Boolean +): suspend (A) -> List = + { a -> + val list = this(a) + list.filter(predicate) + } diff --git a/app/src/main/java/com/ivy/wallet/domain/action/CompositionMap.kt b/app/src/main/java/com/ivy/wallet/domain/action/CompositionMap.kt new file mode 100644 index 0000000000..030693a946 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/domain/action/CompositionMap.kt @@ -0,0 +1,21 @@ +package com.ivy.wallet.domain.action + +suspend infix fun (suspend (A) -> List).thenMap( + transform: suspend (B) -> C +): suspend (A) -> List = + { a -> + val list = this(a) + list.map { + transform(it) + } + } + +suspend infix fun (Action>).thenMap( + transform: suspend (B) -> C +): suspend (A) -> List = + { a -> + val list = this(a) + list.map { + transform(it) + } + } diff --git a/app/src/main/java/com/ivy/wallet/domain/action/CompositionSum.kt b/app/src/main/java/com/ivy/wallet/domain/action/CompositionSum.kt new file mode 100644 index 0000000000..27ebc0d769 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/domain/action/CompositionSum.kt @@ -0,0 +1,29 @@ +package com.ivy.wallet.domain.action + +import java.math.BigDecimal + +suspend infix fun (suspend (A) -> List).thenSum( + value: (B) -> BigDecimal +): suspend (A) -> BigDecimal = + { a -> + val list = this(a) + list.fold( + initial = BigDecimal.ZERO, + operation = { acc, b -> + acc + value(b) + } + ) + } + +suspend infix fun (Action>).thenSum( + value: (B) -> BigDecimal +): suspend (A) -> BigDecimal = + { a -> + val list = this(a) + list.fold( + initial = BigDecimal.ZERO, + operation = { acc, b -> + acc + value(b) + } + ) + } \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/domain/action/CompositionUtils.kt b/app/src/main/java/com/ivy/wallet/domain/action/CompositionUtils.kt deleted file mode 100644 index 8f66a37365..0000000000 --- a/app/src/main/java/com/ivy/wallet/domain/action/CompositionUtils.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.ivy.wallet.domain.action - -suspend infix fun (suspend (Any) -> List).thenFilter( - predicate: (A) -> Boolean -): suspend (Any) -> List = - { a -> - val list = this(a) - list.filter(predicate) - } diff --git a/app/src/main/java/com/ivy/wallet/domain/action/wallet/CalcWalletBalanceAct.kt b/app/src/main/java/com/ivy/wallet/domain/action/wallet/CalcWalletBalanceAct.kt index 599a4b6079..00337cddeb 100644 --- a/app/src/main/java/com/ivy/wallet/domain/action/wallet/CalcWalletBalanceAct.kt +++ b/app/src/main/java/com/ivy/wallet/domain/action/wallet/CalcWalletBalanceAct.kt @@ -1,10 +1,8 @@ package com.ivy.wallet.domain.action.wallet import arrow.core.toOption -import com.ivy.wallet.domain.action.FPAction +import com.ivy.wallet.domain.action.* import com.ivy.wallet.domain.action.account.AccountsAct -import com.ivy.wallet.domain.action.fixUnit -import com.ivy.wallet.domain.action.then import java.math.BigDecimal import javax.inject.Inject @@ -17,23 +15,21 @@ class CalcWalletBalanceAct @Inject constructor( override suspend fun Input.compose(): suspend () -> BigDecimal = recipe().fixUnit() private suspend fun Input.recipe(): suspend (Unit) -> BigDecimal = - accountsAct then { - it.filter { acc -> acc.includeInBalance } - } then { - it.map { acc -> calcAccBalanceAct(CalcAccBalanceAct.Input(acc)) } - } then { - it.map { balanceOutput -> - exchangeAct( - ExchangeAct.Input( - baseCurrency = baseCurrency, - fromCurrency = balanceOutput.account.currency.toOption(), - toCurrency = balanceCurrency, - amount = balanceOutput.balance - ) + accountsAct thenFilter { + it.includeInBalance + } thenMap { + calcAccBalanceAct(CalcAccBalanceAct.Input(it)) + } thenMap { + exchangeAct( + ExchangeAct.Input( + baseCurrency = baseCurrency, + fromCurrency = it.account.currency.toOption(), + toCurrency = balanceCurrency, + amount = it.balance ) - } - } then { balances -> - balances.sumOf { it.orNull() ?: BigDecimal.ZERO } + ) + } thenSum { + it.orNull() ?: BigDecimal.ZERO } data class Input( diff --git a/app/src/main/java/com/ivy/wallet/ui/home/HomeViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/home/HomeViewModel.kt index 1aef9faa04..eb5ed938c8 100644 --- a/app/src/main/java/com/ivy/wallet/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/home/HomeViewModel.kt @@ -100,12 +100,16 @@ class HomeViewModel @Inject constructor( val timeRange = period.toRange(ivyContext.startDayOfMonth) - //TODO: Fix that! -// updateState { -// it.copy( -// balance = calcAccountBalanceAct(settings.currency) -// ) -// } + updateState { + it.copy( + balance = calcAccountBalanceAct( + CalcWalletBalanceAct.Input( + baseCurrency = settings.currency, + balanceCurrency = settings.currency + ) + ) + ) + } updateState { it.copy(