init
This commit is contained in:
@@ -16,6 +16,7 @@ import cc.n0th1ng.tripmoney.data.entity.ExchangeRate
|
||||
import cc.n0th1ng.tripmoney.data.entity.Expense
|
||||
import cc.n0th1ng.tripmoney.data.entity.Trip
|
||||
import cc.n0th1ng.tripmoney.utils.Icons
|
||||
import cc.n0th1ng.tripmoney.utils.colors
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -96,19 +97,12 @@ private class DatabasePrepopulator(
|
||||
tripDao.insert(Trip(name = "Włochy", startDate = "2025-01-01", currency = "PLN"))
|
||||
tripDao.insert(Trip(name = "Szwajcaria", startDate = "2025-03-01", currency = "EUR"))
|
||||
tripDao.insert(Trip(name = "Portugalia", startDate = "2026-03-01", currency = "USD"))
|
||||
categoryDao.insert(Category(name = "Hotel", icon = Icons.HOTEL, color = "#B3E5FC"))
|
||||
categoryDao.insert(Category(name = "Jedzenie", icon = Icons.RESTAURANT, color = "#C8E6C9"))
|
||||
categoryDao.insert(Category(name = "Transport", icon = Icons.FLIGHT, color = "#FFCDD2"))
|
||||
categoryDao.insert(Category(name = "Rozrywka", icon = Icons.ATTRACTION, color = "#FFF9C4"))
|
||||
categoryDao.insert(Category(name = "Zakupy", icon = Icons.GROCERIES, color = "#E1BEE7"))
|
||||
categoryDao.insert(Category(name = "Zakupy1", icon = Icons.GROCERIES, color = "#D7CCC8"))
|
||||
categoryDao.insert(Category(name = "Zakupy2", icon = Icons.GROCERIES, color = "#BBDEFB"))
|
||||
categoryDao.insert(Category(name = "Zakupy3", icon = Icons.GROCERIES, color = "#D1C4E9"))
|
||||
categoryDao.insert(Category(name = "Zakupy4", icon = Icons.GROCERIES, color = "#DCEDC8"))
|
||||
categoryDao.insert(Category(name = "Zakupy5", icon = Icons.GROCERIES, color = "#F0F4C3"))
|
||||
categoryDao.insert(Category(name = "Zakupy6", icon = Icons.GROCERIES, color = "#FFE0B2"))
|
||||
categoryDao.insert(Category(name = "Zakupy7", icon = Icons.GROCERIES, color = "#D7CCC8"))
|
||||
categoryDao.insert(Category(name = "Zakupy8", icon = Icons.GROCERIES, color = "#CFD8DC"))
|
||||
categoryDao.insert(Category(name = "Hotel", icon = Icons.HOTEL, color = colors.random()))
|
||||
categoryDao.insert(Category(name = "Jedzenie", icon = Icons.RESTAURANT, color = colors.random()))
|
||||
categoryDao.insert(Category(name = "Transport", icon = Icons.FLIGHT, color = colors.random()))
|
||||
categoryDao.insert(Category(name = "Rozrywka", icon = Icons.ATTRACTION, color = colors.random()))
|
||||
categoryDao.insert(Category(name = "Zakupy", icon = Icons.GROCERIES,color = colors.random()))
|
||||
|
||||
|
||||
val now = LocalDateTime.now()
|
||||
expenseDao.insert(
|
||||
|
||||
@@ -3,27 +3,58 @@ package cc.n0th1ng.tripmoney.data.dao
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Upsert
|
||||
import cc.n0th1ng.tripmoney.data.dto.SummaryPerCategoryRaw
|
||||
import cc.n0th1ng.tripmoney.data.entity.Expense
|
||||
import cc.n0th1ng.tripmoney.data.entity.ExpenseDto
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ExpenseDao {
|
||||
@Upsert
|
||||
suspend fun insert(expense: Expense)
|
||||
|
||||
@Transaction
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM expense WHERE trip_id = :tripId
|
||||
ORDER BY DATETIME(expense.datetime) DESC
|
||||
"""
|
||||
)
|
||||
fun expenseDto(tripId: Int): PagingSource<Int, ExpenseDto>
|
||||
fun expenseDtoPaged(tripId: Int): PagingSource<Int, ExpenseDto>
|
||||
|
||||
@Transaction
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM expense WHERE trip_id = :tripId
|
||||
ORDER BY DATETIME(expense.datetime) DESC
|
||||
"""
|
||||
)
|
||||
fun expenseDto(tripId: Int): Flow<List<ExpenseDto>>
|
||||
|
||||
@Delete
|
||||
suspend fun delete(expense: Expense)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
c.id as categoryId,
|
||||
c.name as categoryName,
|
||||
c.icon as icon,
|
||||
c.color as color,
|
||||
SUM(e.amount) as amount,
|
||||
e.currency as currency
|
||||
FROM
|
||||
expense e
|
||||
JOIN
|
||||
category c ON e.category_id = c.id
|
||||
WHERE
|
||||
e.trip_id = :tripId
|
||||
GROUP BY
|
||||
c.id, c.name, c.icon, c.color, e.currency
|
||||
"""
|
||||
)
|
||||
fun summaryPerCategoryRaw(tripId: Int): Flow<List<SummaryPerCategoryRaw>>
|
||||
|
||||
}
|
||||
|
||||
@@ -23,4 +23,9 @@ interface TripDao {
|
||||
|
||||
@Delete
|
||||
suspend fun delete(trip: Trip)
|
||||
|
||||
@Query(
|
||||
"SELECT * FROM trip where trip.id = :tripId"
|
||||
)
|
||||
fun trip(tripId: Int): Trip?
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cc.n0th1ng.tripmoney.data.dto
|
||||
|
||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
||||
import cc.n0th1ng.tripmoney.utils.Currencies
|
||||
import cc.n0th1ng.tripmoney.utils.Icons
|
||||
|
||||
data class SummaryPerCategory(
|
||||
val category: Category,
|
||||
val amount: Double,
|
||||
val percent: Float,
|
||||
val currency: Currencies
|
||||
)
|
||||
|
||||
data class SummaryPerCategoryRaw(
|
||||
val categoryId: Int,
|
||||
val categoryName: String,
|
||||
val icon: Icons,
|
||||
val color: String,
|
||||
val amount: Double,
|
||||
val currency: String
|
||||
)
|
||||
|
||||
@@ -40,14 +40,13 @@ class ExchangeRateRepository @Inject constructor(
|
||||
date = date.toString()
|
||||
)
|
||||
)
|
||||
clearOldRates()
|
||||
rate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private suspend fun clearOldRates(daysToKeep: Int = 180) {
|
||||
suspend fun clearOldRates(daysToKeep: Int = 180) {
|
||||
val cutoffDate = LocalDate.now().minusDays(daysToKeep.toLong()).toString()
|
||||
exchangeRateDao.deleteOldRates(cutoffDate)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import cc.n0th1ng.tripmoney.data.dao.ExpenseDao
|
||||
import cc.n0th1ng.tripmoney.data.dto.SummaryPerCategoryRaw
|
||||
import cc.n0th1ng.tripmoney.data.entity.Expense
|
||||
import cc.n0th1ng.tripmoney.data.entity.ExpenseDto
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -22,10 +23,18 @@ class ExpenseRepository @Inject constructor(private val expenseDao: ExpenseDao)
|
||||
expenseDao.delete(expense)
|
||||
}
|
||||
|
||||
fun getExpenses(tripId: Int): Flow<PagingData<ExpenseDto>> {
|
||||
fun getExpensesPaged(tripId: Int): Flow<PagingData<ExpenseDto>> {
|
||||
return Pager(
|
||||
config = PagingConfig(pageSize = 50, enablePlaceholders = false),
|
||||
pagingSourceFactory = { expenseDao.expenseDto(tripId) }
|
||||
pagingSourceFactory = { expenseDao.expenseDtoPaged(tripId) }
|
||||
).flow
|
||||
}
|
||||
|
||||
fun getExpenses(tripId: Int): Flow<List<ExpenseDto>> {
|
||||
return expenseDao.expenseDto(tripId)
|
||||
}
|
||||
|
||||
fun getSummaryPerCategory(tripId: Int): Flow<List<SummaryPerCategoryRaw>> {
|
||||
return expenseDao.summaryPerCategoryRaw(tripId)
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,13 @@ import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import cc.n0th1ng.tripmoney.data.repository.PreferenceKeys.APP_THEME
|
||||
import cc.n0th1ng.tripmoney.data.repository.PreferenceKeys.CURRENT_TRIP
|
||||
import cc.n0th1ng.tripmoney.data.repository.PreferenceKeys.DEFAULT_CURRENCY
|
||||
import cc.n0th1ng.tripmoney.utils.Currencies
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.DEFAULT_CONCURRENCY
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.util.Currency
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@@ -18,6 +22,7 @@ val Context.preferencesDataStore by preferencesDataStore(name = "app_preferences
|
||||
object PreferenceKeys {
|
||||
val APP_THEME = intPreferencesKey("app_theme")
|
||||
val CURRENT_TRIP = intPreferencesKey("current_trip")
|
||||
val DEFAULT_CURRENCY = stringPreferencesKey("default_currency")
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +39,16 @@ class PreferencesRepository @Inject constructor(@ApplicationContext private val
|
||||
prefs[CURRENT_TRIP] ?: -1
|
||||
}
|
||||
|
||||
val defaultCurrencyFlow: Flow<Currencies> =
|
||||
context.preferencesDataStore.data.map { prefs ->
|
||||
Currencies.valueOf(prefs[DEFAULT_CURRENCY] ?: Currencies.default().name)
|
||||
}
|
||||
|
||||
suspend fun saveDefaultCurrency(currency: Currencies) {
|
||||
context.preferencesDataStore.edit { prefs ->
|
||||
prefs[DEFAULT_CURRENCY] = currency.name
|
||||
}
|
||||
}
|
||||
suspend fun saveCurrentTrip(tripId: Int) {
|
||||
context.preferencesDataStore.edit { prefs ->
|
||||
prefs[CURRENT_TRIP] = tripId
|
||||
|
||||
@@ -23,6 +23,10 @@ class TripRepository @Inject constructor(private val tripDao: TripDao) {
|
||||
).flow
|
||||
}
|
||||
|
||||
fun getTrip(tripId: Int): Trip? {
|
||||
return tripDao.trip(tripId)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
suspend fun delete(trip: Trip) {
|
||||
tripDao.delete(trip)
|
||||
|
||||
Reference in New Issue
Block a user