Compare commits
3 Commits
2ab7ef3f65
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfbb1056d7 | ||
|
|
43aec61c75 | ||
|
|
e6c8cf5cd3 |
@@ -10,7 +10,9 @@ plugins {
|
|||||||
android {
|
android {
|
||||||
namespace = "cc.n0th1ng.tripmoney"
|
namespace = "cc.n0th1ng.tripmoney"
|
||||||
compileSdk = 36
|
compileSdk = 36
|
||||||
|
buildFeatures {
|
||||||
|
buildConfig = true
|
||||||
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "cc.n0th1ng.tripmoney"
|
applicationId = "cc.n0th1ng.tripmoney"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import androidx.room.Database
|
|||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
|
import cc.n0th1ng.tripmoney.BuildConfig
|
||||||
import cc.n0th1ng.tripmoney.data.dao.CategoryDao
|
import cc.n0th1ng.tripmoney.data.dao.CategoryDao
|
||||||
import cc.n0th1ng.tripmoney.data.dao.ExchangeRateDao
|
import cc.n0th1ng.tripmoney.data.dao.ExchangeRateDao
|
||||||
import cc.n0th1ng.tripmoney.data.dao.ExpenseDao
|
import cc.n0th1ng.tripmoney.data.dao.ExpenseDao
|
||||||
@@ -34,8 +35,7 @@ import javax.inject.Singleton
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
entities = [Trip::class, Expense::class, Category::class, ExchangeRate::class],
|
entities = [Trip::class, Expense::class, Category::class, ExchangeRate::class], version = 1
|
||||||
version = 1
|
|
||||||
)
|
)
|
||||||
@TypeConverters(Converters::class)
|
@TypeConverters(Converters::class)
|
||||||
abstract class TripDatabase : RoomDatabase() {
|
abstract class TripDatabase : RoomDatabase() {
|
||||||
@@ -57,23 +57,28 @@ object DatabaseModule {
|
|||||||
fun provideTripDatabase(
|
fun provideTripDatabase(
|
||||||
@ApplicationContext context: Context
|
@ApplicationContext context: Context
|
||||||
): TripDatabase {
|
): TripDatabase {
|
||||||
val db: TripDatabase = Room.inMemoryDatabaseBuilder(
|
val builder = if (BuildConfig.DEBUG) Room.inMemoryDatabaseBuilder(
|
||||||
// val db: TripDatabase = Room.databaseBuilder(
|
context = context, klass = TripDatabase::class.java
|
||||||
// name = "tripmoney_db",
|
) else Room.databaseBuilder(
|
||||||
|
name = "tripmoney_db",
|
||||||
context = context,
|
context = context,
|
||||||
klass = TripDatabase::class.java,
|
klass = TripDatabase::class.java,
|
||||||
)
|
)
|
||||||
.allowMainThreadQueries() // TODO Remove in production!
|
|
||||||
.fallbackToDestructiveMigration() // TODO Handle schema changes during dev
|
|
||||||
.build()
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
val db: TripDatabase =
|
||||||
DatabasePrepopulator(
|
builder.fallbackToDestructiveMigration() // TODO Handle schema changes during dev
|
||||||
tripDao = db.tripDao(),
|
.build()
|
||||||
categoryDao = db.categoryDao(),
|
|
||||||
expenseDao = db.expenseDao()
|
if (BuildConfig.DEBUG) {
|
||||||
).prepopulate()
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
DatabasePrepopulator(
|
||||||
|
tripDao = db.tripDao(),
|
||||||
|
categoryDao = db.categoryDao(),
|
||||||
|
expenseDao = db.expenseDao()
|
||||||
|
).prepopulate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,74 +152,46 @@ private class DatabasePrepopulator(
|
|||||||
|
|
||||||
val sampleCategories = listOf(
|
val sampleCategories = listOf(
|
||||||
Category(
|
Category(
|
||||||
name = "Hotel",
|
name = "Hotel", icon = Icons.HOTEL, color = colors.random()
|
||||||
icon = Icons.HOTEL,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Jedzenie",
|
name = "Jedzenie", icon = Icons.RESTAURANT, color = colors.random()
|
||||||
icon = Icons.RESTAURANT,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Transport",
|
name = "Transport", icon = Icons.FLIGHT, color = colors.random()
|
||||||
icon = Icons.FLIGHT,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Rozrywka",
|
name = "Rozrywka", icon = Icons.ATTRACTION, color = colors.random()
|
||||||
icon = Icons.ATTRACTION,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy",
|
name = "Zakupy", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy1",
|
name = "Zakupy1", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy2",
|
name = "Zakupy2", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy3",
|
name = "Zakupy3", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy4",
|
name = "Zakupy4", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy5",
|
name = "Zakupy5", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy6",
|
name = "Zakupy6", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy7",
|
name = "Zakupy7", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy8",
|
name = "Zakupy8", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
Category(
|
Category(
|
||||||
name = "Zakupy9",
|
name = "Zakupy9", icon = Icons.GROCERIES, color = colors.random()
|
||||||
icon = Icons.GROCERIES,
|
|
||||||
color = colors.random()
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -240,8 +217,7 @@ private class DatabasePrepopulator(
|
|||||||
note = if (i % 3 == 0) "Some note" else "",
|
note = if (i % 3 == 0) "Some note" else "",
|
||||||
datetime = datetime,
|
datetime = datetime,
|
||||||
rate = if (Random.nextBoolean()) Random.nextDouble(
|
rate = if (Random.nextBoolean()) Random.nextDouble(
|
||||||
0.1,
|
0.1, 5.0
|
||||||
5.0
|
|
||||||
) else 1.0
|
) else 1.0
|
||||||
)
|
)
|
||||||
expense
|
expense
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import androidx.room.Query
|
|||||||
import androidx.room.RewriteQueriesToDropUnusedColumns
|
import androidx.room.RewriteQueriesToDropUnusedColumns
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import androidx.room.Upsert
|
import androidx.room.Upsert
|
||||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
|
||||||
import cc.n0th1ng.tripmoney.data.entity.Expense
|
import cc.n0th1ng.tripmoney.data.entity.Expense
|
||||||
import cc.n0th1ng.tripmoney.data.entity.ExpenseDto
|
import cc.n0th1ng.tripmoney.data.entity.ExpenseDto
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -100,7 +99,7 @@ interface ExpenseDao {
|
|||||||
WHERE trip.id = :tripId
|
WHERE trip.id = :tripId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun budgetLeft(tripId: Int): Double?
|
fun budgetLeft(tripId: Int): Flow<Double?>
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun delete(expense: Expense)
|
suspend fun delete(expense: Expense)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import cc.n0th1ng.tripmoney.data.entity.ExpenseDto
|
|||||||
import cc.n0th1ng.tripmoney.utils.Currencies
|
import cc.n0th1ng.tripmoney.utils.Currencies
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import java.util.OptionalDouble
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExpenseRepository @Inject constructor(
|
class ExpenseRepository @Inject constructor(
|
||||||
@@ -21,7 +20,7 @@ class ExpenseRepository @Inject constructor(
|
|||||||
private val exchangeRateRepository: ExchangeRateRepository
|
private val exchangeRateRepository: ExchangeRateRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getBudgetLeft(tripId: Int): Double? {
|
fun getBudgetLeft(tripId: Int): Flow<Double?> {
|
||||||
return expenseDao.budgetLeft(tripId)
|
return expenseDao.budgetLeft(tripId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package cc.n0th1ng.tripmoney.screens.settings
|
package cc.n0th1ng.tripmoney.screens.settings
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
@@ -36,34 +35,23 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.core.content.FileProvider
|
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import cc.n0th1ng.tripmoney.R.string
|
||||||
import cc.n0th1ng.tripmoney.R.*
|
|
||||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
|
||||||
import cc.n0th1ng.tripmoney.data.entity.Trip
|
import cc.n0th1ng.tripmoney.data.entity.Trip
|
||||||
import cc.n0th1ng.tripmoney.data.repository.AppTheme
|
import cc.n0th1ng.tripmoney.data.repository.AppTheme
|
||||||
import cc.n0th1ng.tripmoney.navigation.Screens
|
import cc.n0th1ng.tripmoney.navigation.Screens
|
||||||
import cc.n0th1ng.tripmoney.screens.listexpense.CategorySelectionDialog
|
|
||||||
import cc.n0th1ng.tripmoney.screens.listexpense.CurrencySelectionDialog
|
import cc.n0th1ng.tripmoney.screens.listexpense.CurrencySelectionDialog
|
||||||
import cc.n0th1ng.tripmoney.screens.statistics.categories
|
|
||||||
import cc.n0th1ng.tripmoney.theme.TripMoneyTheme
|
import cc.n0th1ng.tripmoney.theme.TripMoneyTheme
|
||||||
import cc.n0th1ng.tripmoney.utils.AllPreviews
|
import cc.n0th1ng.tripmoney.utils.AllPreviews
|
||||||
import cc.n0th1ng.tripmoney.utils.Currencies
|
import cc.n0th1ng.tripmoney.utils.Currencies
|
||||||
import cc.n0th1ng.tripmoney.utils.Icons
|
|
||||||
import cc.n0th1ng.tripmoney.utils.saveCsv
|
|
||||||
import cc.n0th1ng.tripmoney.utils.shareCsv
|
import cc.n0th1ng.tripmoney.utils.shareCsv
|
||||||
import cc.n0th1ng.tripmoney.viewmodel.ExpenseAndCategoryViewModel
|
import cc.n0th1ng.tripmoney.viewmodel.ExpenseAndCategoryViewModel
|
||||||
import cc.n0th1ng.tripmoney.viewmodel.SettingsViewModel
|
import cc.n0th1ng.tripmoney.viewmodel.SettingsViewModel
|
||||||
import cc.n0th1ng.tripmoney.viewmodel.TripViewModel
|
import cc.n0th1ng.tripmoney.viewmodel.TripViewModel
|
||||||
import com.composables.icons.materialsymbols.outlined.R
|
import com.composables.icons.materialsymbols.outlined.R
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -168,7 +156,7 @@ fun SettingsScreen(
|
|||||||
iconResource = R.drawable.materialsymbols_ic_label_outlined
|
iconResource = R.drawable.materialsymbols_ic_label_outlined
|
||||||
)
|
)
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
onClick = onCategoriesClick,
|
onClick = {},
|
||||||
stringResource(string.add_expense),
|
stringResource(string.add_expense),
|
||||||
supportingText = stringResource(string.add_expense_settings),
|
supportingText = stringResource(string.add_expense_settings),
|
||||||
iconResource = R.drawable.materialsymbols_ic_payments_outlined,
|
iconResource = R.drawable.materialsymbols_ic_payments_outlined,
|
||||||
|
|||||||
@@ -60,11 +60,12 @@ fun StatisticsScreen() {
|
|||||||
.collectAsState(emptyList())
|
.collectAsState(emptyList())
|
||||||
val summaryAmount by expenseAndCategoryViewModel.getSummaryAmount(currentTripId)
|
val summaryAmount by expenseAndCategoryViewModel.getSummaryAmount(currentTripId)
|
||||||
.collectAsState(0.0)
|
.collectAsState(0.0)
|
||||||
|
val moneyLeft by expenseAndCategoryViewModel.getBudgetLeft(currentTripId).collectAsState(null)
|
||||||
StatisticsScreen(
|
StatisticsScreen(
|
||||||
summaryPerCategoryList,
|
summaryPerCategoryList,
|
||||||
summaryAmount,
|
summaryAmount,
|
||||||
Currencies.valueOf(currentTrip?.currency ?: Currencies.default().name),
|
Currencies.valueOf(currentTrip?.currency ?: Currencies.default().name),
|
||||||
expenseAndCategoryViewModel.getBudgetLeft(currentTripId)
|
moneyLeft
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ import org.apache.commons.csv.CSVFormat
|
|||||||
import org.apache.commons.csv.CSVPrinter
|
import org.apache.commons.csv.CSVPrinter
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.OptionalDouble
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.collections.mapValues
|
|
||||||
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -42,7 +40,7 @@ open class ExpenseAndCategoryViewModel @Inject constructor(
|
|||||||
private val tripRepo: TripRepository
|
private val tripRepo: TripRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
fun getBudgetLeft(tripId: Int): Double? {
|
fun getBudgetLeft(tripId: Int): Flow<Double?> {
|
||||||
return expenseRepo.getBudgetLeft(tripId)
|
return expenseRepo.getBudgetLeft(tripId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user