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

Commit

Permalink
WIP: Re-work domain logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ILIYANGERMANOV committed Apr 24, 2022
1 parent 6c600b7 commit 490eef0
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ class AccTrnsAct @Inject constructor(
val accountId: UUID,
val range: ClosedTimeRange
)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import arrow.core.nonEmptyListOf
import com.ivy.fp.action.FPAction
import com.ivy.fp.action.then
import com.ivy.wallet.domain.data.core.Account
import com.ivy.wallet.domain.pure.AccountValueFunctions
import com.ivy.wallet.domain.pure.core.calcValues
import com.ivy.wallet.domain.pure.data.ClosedTimeRange
import com.ivy.wallet.domain.pure.transaction.AccountValueFunctions
import com.ivy.wallet.domain.pure.transaction.foldTransactions
import java.math.BigDecimal
import javax.inject.Inject

Expand All @@ -20,7 +20,7 @@ class CalcAccBalanceAct @Inject constructor(
range = range
)
} then accTrnsAct then { accTrns ->
calcValues(
foldTransactions(
transactions = accTrns,
arg = account.id,
valueFunctions = nonEmptyListOf(AccountValueFunctions::balance)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.ivy.wallet.domain.action.settings

import com.ivy.fp.action.FPAction
import java.math.BigDecimal
import javax.inject.Inject

class CalcBufferDiffAct @Inject constructor() : FPAction<CalcBufferDiffAct.Input, BigDecimal>() {

override suspend fun Input.compose(): suspend () -> BigDecimal = {
balance - buffer
}

data class Input(
val balance: BigDecimal,
val buffer: BigDecimal
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.ivy.wallet.domain.action.settings

import com.ivy.fp.action.FPAction
import com.ivy.fp.action.then
import com.ivy.wallet.domain.data.core.Settings
import com.ivy.wallet.io.persistence.dao.SettingsDao
import javax.inject.Inject

class SettingsAct @Inject constructor(
private val settingsDao: SettingsDao
) : FPAction<Unit, Settings>() {
override suspend fun Unit.compose(): suspend () -> Settings = suspend {
io { settingsDao.findFirst() }
} then { it.toDomain() }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ivy.wallet.domain.action.transaction

import com.ivy.fp.action.FPAction
import com.ivy.fp.action.then
import com.ivy.wallet.domain.data.TransactionHistoryItem
import com.ivy.wallet.domain.pure.data.ClosedTimeRange
import javax.inject.Inject

class HistoryWithDateDivsAct @Inject constructor(
private val historyTrnsAct: HistoryTrnsAct,
private val trnsWithDateDivsAct: TrnsWithDateDivsAct
) : FPAction<HistoryWithDateDivsAct.Input, List<TransactionHistoryItem>>() {

override suspend fun Input.compose(): suspend () -> List<TransactionHistoryItem> = suspend {
HistoryTrnsAct.Input(range)
} then historyTrnsAct then { trns ->
TrnsWithDateDivsAct.Input(
baseCurrency = baseCurrency,
transactions = trns
)
} then trnsWithDateDivsAct

data class Input(
val range: ClosedTimeRange,
val baseCurrency: String
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import com.ivy.wallet.domain.pure.transaction.transactionsWithDateDividers
import com.ivy.wallet.io.persistence.dao.AccountDao
import javax.inject.Inject

class TrnsWithDateDividersAct @Inject constructor(
class TrnsWithDateDivsAct @Inject constructor(
private val accountDao: AccountDao,
private val exchangeAct: ExchangeAct
) : FPAction<TrnsWithDateDividersAct.Input, List<TransactionHistoryItem>>() {
) : FPAction<TrnsWithDateDivsAct.Input, List<TransactionHistoryItem>>() {

override suspend fun Input.compose(): suspend () -> List<TransactionHistoryItem> = suspend {
transactionsWithDateDividers(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.ivy.wallet.domain.action.viewmodel.home

import arrow.core.nonEmptyListOf
import arrow.core.toOption
import com.ivy.fp.action.FPAction
import com.ivy.fp.action.then
import com.ivy.fp.action.thenMap
import com.ivy.wallet.domain.action.ExchangeAct
import com.ivy.wallet.domain.action.account.AccTrnsAct
import com.ivy.wallet.domain.data.core.Account
import com.ivy.wallet.domain.pure.ExchangeData
import com.ivy.wallet.domain.pure.account.filterExcluded
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 com.ivy.wallet.domain.pure.util.orZero
import java.math.BigDecimal
import javax.inject.Inject

class CalcBalanceIncsExpsAct @Inject constructor(
private val accTrnsAct: AccTrnsAct,
private val exchangeAct: ExchangeAct
) : FPAction<CalcBalanceIncsExpsAct.Input, CalcBalanceIncsExpsAct.Output>() {

override suspend fun Input.compose(): suspend () -> Output = suspend {
filterExcluded(accounts)
} thenMap { acc ->
Pair(
acc,
accTrnsAct(
AccTrnsAct.Input(
accountId = acc.id,
range = range
)
)
)
} thenMap { (acc, trns) ->
Pair(
acc,
foldTransactions(
transactions = trns,
valueFunctions = nonEmptyListOf(
AccountValueFunctions::balance,
AccountValueFunctions::income,
AccountValueFunctions::expense
),
arg = acc.id
)
)
} thenMap { (acc, stats) ->
stats.map {
exchangeAct(
ExchangeAct.Input(
data = ExchangeData(
baseCurrency = baseCurrency,
fromCurrency = acc.currency.toOption()
),
amount = it
),
).orZero()
}
} then { statsList ->
Output(
balance = statsList[0].sumOf { it },
incomeExpense = IncomeExpensePair(
income = statsList[1].sumOf { it },
expense = statsList[2].sumOf { it }
)
)
}

data class Input(
val baseCurrency: String,
val accounts: List<Account>,
val range: ClosedTimeRange,
)

data class Output(
val balance: BigDecimal,
val incomeExpense: IncomeExpensePair,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.ivy.wallet.domain.action.viewmodel.home

class CalcHomeDueStatsAct {
}
5 changes: 3 additions & 2 deletions app/src/main/java/com/ivy/wallet/domain/data/core/Settings.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.ivy.wallet.domain.data.core

import com.ivy.design.l0_system.Theme
import java.math.BigDecimal
import java.util.*

data class Settings(
val theme: Theme,
val currency: String,
val bufferAmount: Double,
val baseCurrency: String,
val bufferAmount: BigDecimal,
val name: String,

val id: UUID = UUID.randomUUID()
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/ivy/wallet/domain/pure/Exchange.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import java.math.BigDecimal
data class ExchangeData(
val baseCurrency: String,
val fromCurrency: Option<String>,
val toCurrency: String,
val toCurrency: String = baseCurrency,
)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.ivy.wallet.domain.pure.account

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

fun filterExcluded(accounts: List<Account>): List<Account> =
accounts.filter { it.includeInBalance }
29 changes: 0 additions & 29 deletions app/src/main/java/com/ivy/wallet/domain/pure/data/FPAccount.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.ivy.wallet.domain.pure
package com.ivy.wallet.domain.pure.transaction

import com.ivy.wallet.domain.data.TransactionType
import com.ivy.wallet.domain.data.core.Transaction
import com.ivy.wallet.domain.pure.core.ValueFunction
import java.math.BigDecimal
import java.util.*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.ivy.wallet.domain.pure
package com.ivy.wallet.domain.pure.transaction

import arrow.core.Option
import arrow.core.toOption
import com.ivy.fp.SideEffect
import com.ivy.wallet.domain.data.TransactionType
import com.ivy.wallet.domain.data.core.Account
import com.ivy.wallet.domain.data.core.Transaction
import com.ivy.wallet.domain.pure.core.SuspendValueFunction
import java.math.BigDecimal
import java.util.*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
package com.ivy.wallet.domain.pure.core
package com.ivy.wallet.domain.pure.transaction

import arrow.core.NonEmptyList
import arrow.core.nonEmptyListOf
import com.ivy.fp.Pure
import com.ivy.wallet.domain.data.core.Transaction
import com.ivy.wallet.domain.pure.util.mapIndexedNel
import com.ivy.wallet.domain.pure.util.mapIndexedNelSuspend
import com.ivy.wallet.domain.pure.util.nonEmptyListOfZeros
import java.math.BigDecimal

typealias ValueFunction<A> = (Transaction, A) -> BigDecimal
typealias SuspendValueFunction<A> = suspend (Transaction, A) -> BigDecimal

@Pure
fun <Arg> calcValues(
fun <Arg> foldTransactions(
transactions: List<Transaction>,
valueFunctions: NonEmptyList<ValueFunction<Arg>>,
arg: Arg
): NonEmptyList<BigDecimal> = calculateValueFunctionsSum(
): NonEmptyList<BigDecimal> = sumTransactionsInternal(
valueFunctionArgument = arg,
transactions = transactions,
valueFunctions = valueFunctions
)


typealias ValueFunction<A> = (Transaction, A) -> BigDecimal
typealias SuspendValueFunction<A> = suspend (Transaction, A) -> BigDecimal

@Pure
internal tailrec fun <A> calculateValueFunctionsSum(
valueFunctionArgument: A,
internal tailrec fun <A> sumTransactionsInternal(
transactions: List<Transaction>,
valueFunctionArgument: A,
valueFunctions: NonEmptyList<ValueFunction<A>>,
sum: NonEmptyList<BigDecimal> = nonEmptyListOfZeros(n = valueFunctions.size)
): NonEmptyList<BigDecimal> {
return if (transactions.isEmpty())
sum
else
calculateValueFunctionsSum(
sumTransactionsInternal(
valueFunctionArgument = valueFunctionArgument,
transactions = transactions.drop(1),
valueFunctions = valueFunctions,
Expand All @@ -45,16 +45,27 @@ internal tailrec fun <A> calculateValueFunctionsSum(
}

@Pure
internal tailrec suspend fun <A> calculateValueFunctionsSumSuspend(
valueFunctionArgument: A,
suspend fun <Arg> foldTransactionsSuspend(
transactions: List<Transaction>,
valueFunctions: NonEmptyList<SuspendValueFunction<Arg>>,
arg: Arg
): NonEmptyList<BigDecimal> = sumTransactionsSuspendInternal(
transactions = transactions,
valueFunctions = valueFunctions,
valueFunctionArgument = arg
)

@Pure
internal tailrec suspend fun <A> sumTransactionsSuspendInternal(
transactions: List<Transaction>,
valueFunctionArgument: A,
valueFunctions: NonEmptyList<SuspendValueFunction<A>>,
sum: NonEmptyList<BigDecimal> = nonEmptyListOfZeros(n = valueFunctions.size)
): NonEmptyList<BigDecimal> {
return if (transactions.isEmpty())
sum
else
calculateValueFunctionsSumSuspend(
sumTransactionsSuspendInternal(
valueFunctionArgument = valueFunctionArgument,
transactions = transactions.drop(1),
valueFunctions = valueFunctions,
Expand All @@ -63,4 +74,16 @@ internal tailrec suspend fun <A> calculateValueFunctionsSumSuspend(
sumValue + valueFunction(transactions.first(), valueFunctionArgument)
}
)
}

suspend fun <A> sumTransactions(
transactions: List<Transaction>,
valueFunction: SuspendValueFunction<A>,
argument: A
): BigDecimal {
return sumTransactionsSuspendInternal(
transactions = transactions,
valueFunctionArgument = argument,
valueFunctions = nonEmptyListOf(valueFunction)
).head
}
Loading

0 comments on commit 490eef0

Please sign in to comment.