Skip to content

Commit fe1eaf7

Browse files
committed
Integration of reconciliations on home overview
1 parent c8caff9 commit fe1eaf7

File tree

9 files changed

+2045
-241
lines changed

9 files changed

+2045
-241
lines changed

android/src/main/kotlin/br/com/dillmann/fireflycompanion/android/home/main/HomeOverview.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,27 @@ fun HomeOverview() {
9898
valueProvider = { it.spent?.abs() },
9999
)
100100
DetailBlock(
101-
title = i18n(R.string.left_to_spend),
101+
title = i18n(R.string.reconciliation),
102102
summary = summary,
103103
tintColor = AppColors.Blue,
104+
valueProvider = { it.reconciliations },
105+
)
106+
DetailBlock(
107+
title = i18n(R.string.left_to_spend),
108+
summary = summary,
109+
tintColor = AppColors.Yellow,
104110
valueProvider = { it.leftToSpend },
105111
)
106112
DetailBlock(
107-
title = i18n(R.string.balance),
113+
title = i18n(R.string.gross_balance),
108114
summary = summary,
109115
valueProvider = { it.balance },
110116
)
117+
DetailBlock(
118+
title = i18n(R.string.net_balance),
119+
summary = summary,
120+
valueProvider = { it.balance?.plus(it.reconciliations ?: BigDecimal.ZERO) },
121+
)
111122
}
112123
}
113124
}

android/src/main/res/values-pt/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<string name="earned">Ganhos</string>
2525
<string name="spent">Gastos</string>
2626
<string name="left_to_spend">Orçamento restante</string>
27-
<string name="balance">Balanço geral</string>
27+
<string name="gross_balance">Balanço bruto</string>
2828
<string name="onboarding_main_title">Olá 👋</string>
2929
<string name="onboarding_main_message">Bem-vindo ao Firefly Companion. Antes de usar o aplicativo, precisamos nos
3030
conectar ao seu servidor Firefly III.
@@ -143,4 +143,5 @@
143143
<string name="to">até</string>
144144
<string name="to_pay_at">a pagar em</string>
145145
<string name="paid_at">pago em</string>
146+
<string name="net_balance">Balanço final</string>
146147
</resources>

android/src/main/res/values/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<string name="earned">Earned</string>
2525
<string name="spent">Spent</string>
2626
<string name="left_to_spend">Left to spend</string>
27-
<string name="balance">Balance</string>
27+
<string name="gross_balance">Gross balance</string>
2828
<string name="onboarding_main_title">Hello there 👋</string>
2929
<string name="onboarding_main_message">Welcome to Firefly Companion. Before using the app, we need to connect to
3030
your Firefly III server.
@@ -142,4 +142,5 @@
142142
<string name="to">to</string>
143143
<string name="to_pay_at">to pay at</string>
144144
<string name="paid_at">paid at</string>
145+
<string name="net_balance">Net balance</string>
145146
</resources>

business/src/main/kotlin/br/com/dillmann/fireflycompanion/business/overview/model/SummaryOverview.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ data class SummaryOverview(
1313
val unpaidBills: BigDecimal? = null,
1414
val leftToSpend: BigDecimal? = null,
1515
val balance: BigDecimal? = null,
16+
val reconciliations: BigDecimal? = null,
1617
) : Serializable

http-client/firefly.http

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Authorization: Bearer {{token}}
1010
GET {{base-url}}/v1/accounts?type=asset&active=true
1111
Authorization: Bearer {{token}}
1212

13+
### Transactions
14+
GET {{base-url}}/v1/transactions?start=2025-10-01&end=2025-10-31&type=reconciliation
15+
Authorization: Bearer {{token}}
16+
1317
### Expenses by category
1418
GET {{base-url}}/v1/insight/expense/category?start=2025-08-01&end=2025-08-30
1519
Authorization: Bearer {{token}}

third-party/src/main/kotlin/br/com/dillmann/fireflycompanion/thirdparty/summary/Module.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ internal val SummaryModule =
1010
module {
1111
single { SummaryApi(get(Qualifiers.API_BASE_URL), get()) }
1212
single<SummaryConverter> { getConverter() }
13-
single<OverviewRepository> { OverviewHttpRepository(get(), get(),get()) }
13+
single<OverviewRepository> { OverviewHttpRepository(get(), get(), get(),get()) }
1414
}

third-party/src/main/kotlin/br/com/dillmann/fireflycompanion/thirdparty/summary/OverviewHttpRepository.kt

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,86 @@ import br.com.dillmann.fireflycompanion.business.overview.OverviewRepository
55
import br.com.dillmann.fireflycompanion.business.overview.model.SummaryOverview
66
import br.com.dillmann.fireflycompanion.thirdparty.firefly.apis.InsightApi
77
import br.com.dillmann.fireflycompanion.thirdparty.firefly.apis.SummaryApi
8+
import br.com.dillmann.fireflycompanion.thirdparty.firefly.apis.TransactionsApi
9+
import br.com.dillmann.fireflycompanion.thirdparty.firefly.models.AccountTypeProperty
10+
import br.com.dillmann.fireflycompanion.thirdparty.firefly.models.BasicSummaryEntry
11+
import br.com.dillmann.fireflycompanion.thirdparty.firefly.models.TransactionTypeFilter
12+
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.Deferred
14+
import kotlinx.coroutines.async
15+
import kotlinx.coroutines.coroutineScope
16+
import java.math.BigDecimal
817
import java.time.LocalDate
918

1019
internal class OverviewHttpRepository(
1120
private val summaryApi: SummaryApi,
21+
private val transactions: TransactionsApi,
1222
private val insightApi: InsightApi,
1323
private val converter: SummaryConverter,
1424
) : OverviewRepository {
1525
override suspend fun getSummaryByCurrency(
1626
startDate: LocalDate,
1727
endDate: LocalDate,
1828
currency: Currency,
19-
): SummaryOverview? {
20-
val response =
29+
): SummaryOverview =
30+
coroutineScope {
31+
val basicSummary = getBasicSummary(startDate, endDate, currency)
32+
val reconciliationAmount = getReconciliationAmount(startDate, endDate, currency)
33+
34+
converter.toDomain(
35+
currency = currency,
36+
summary = basicSummary.await(),
37+
reconciliationAmount = reconciliationAmount.await(),
38+
)
39+
}
40+
41+
override suspend fun getExpensesByCategory(startDate: LocalDate, endDate: LocalDate) =
42+
insightApi.insightExpenseCategory(start = startDate, end = endDate).map(converter::toDomain)
43+
44+
private fun CoroutineScope.getReconciliationAmount(
45+
startDate: LocalDate,
46+
endDate: LocalDate,
47+
currency: Currency,
48+
): Deferred<BigDecimal> =
49+
async {
50+
var pageNumber = 1
51+
val data = mutableListOf<BigDecimal>()
52+
53+
do {
54+
val page =
55+
transactions.listTransaction(
56+
start = startDate,
57+
end = endDate,
58+
type = TransactionTypeFilter.RECONCILIATION,
59+
page = pageNumber++,
60+
)
61+
62+
data += page
63+
.data
64+
.flatMap { it.attributes.transactions }
65+
.filter { it.currencyId == currency.id }
66+
.map {
67+
if (it.sourceType == AccountTypeProperty.RECONCILIATION_ACCOUNT)
68+
it.amount.abs()
69+
else
70+
it.amount.abs().negate()
71+
}
72+
73+
} while (page.data.isNotEmpty())
74+
75+
data.sumOf { it }
76+
}
77+
78+
private fun CoroutineScope.getBasicSummary(
79+
startDate: LocalDate,
80+
endDate: LocalDate,
81+
currency: Currency,
82+
): Deferred<Map<String, BasicSummaryEntry>> =
83+
async {
2184
summaryApi.getBasicSummary(
2285
start = startDate,
2386
end = endDate,
2487
currencyCode = currency.code,
2588
)
26-
27-
return response
28-
.takeIf { it.isNotEmpty() }
29-
?.let { converter.toDomain(currency, it) }
30-
}
31-
32-
override suspend fun getExpensesByCategory(startDate: LocalDate, endDate: LocalDate) =
33-
insightApi.insightExpenseCategory(start = startDate, end = endDate).map(converter::toDomain)
89+
}
3490
}

third-party/src/main/kotlin/br/com/dillmann/fireflycompanion/thirdparty/summary/SummaryConverter.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ internal interface SummaryConverter {
1818
fun toDomain(input: InsightGroupEntry): ExpensesByCategoryOverview
1919

2020
@Mapping(target = "currency", source = "currency")
21-
@Mapping(target = "balance", expression = "java(getValue(\"balance\", currency, data))")
22-
@Mapping(target = "spent", expression = "java(getValue(\"spent\", currency, data))")
23-
@Mapping(target = "earned", expression = "java(getValue(\"earned\", currency, data))")
24-
@Mapping(target = "billsPaid", expression = "java(getValue(\"bills-paid\", currency, data))")
25-
@Mapping(target = "unpaidBills", expression = "java(getValue(\"bills-unpaid\", currency, data))")
26-
@Mapping(target = "leftToSpend", expression = "java(getValue(\"left-to-spend\", currency, data))")
27-
@Mapping(target = "netWorth", expression = "java(getValue(\"net-worth\", currency, data))")
28-
fun toDomain(currency: Currency, data: Map<String, BasicSummaryEntry>): SummaryOverview
21+
@Mapping(target = "balance", expression = "java(getValue(\"balance\", currency, summary))")
22+
@Mapping(target = "spent", expression = "java(getValue(\"spent\", currency, summary))")
23+
@Mapping(target = "earned", expression = "java(getValue(\"earned\", currency, summary))")
24+
@Mapping(target = "billsPaid", expression = "java(getValue(\"bills-paid\", currency, summary))")
25+
@Mapping(target = "unpaidBills", expression = "java(getValue(\"bills-unpaid\", currency, summary))")
26+
@Mapping(target = "leftToSpend", expression = "java(getValue(\"left-to-spend\", currency, summary))")
27+
@Mapping(target = "netWorth", expression = "java(getValue(\"net-worth\", currency, summary))")
28+
@Mapping(target = "reconciliations", source = "reconciliationAmount")
29+
fun toDomain(
30+
currency: Currency,
31+
summary: Map<String, BasicSummaryEntry>,
32+
reconciliationAmount: BigDecimal,
33+
): SummaryOverview
2934

3035
fun getValue(type: String, currency: Currency, data: Map<String, BasicSummaryEntry>): BigDecimal? =
3136
data["$type-in-${currency.code}"]?.monetaryValue

0 commit comments

Comments
 (0)