diff --git a/app/src/main/kotlin/de/dbauer/expensetracker/widget/UpcomingPaymentsWidgetModel.kt b/app/src/main/kotlin/de/dbauer/expensetracker/widget/UpcomingPaymentsWidgetModel.kt index bd9d61b9..08594678 100644 --- a/app/src/main/kotlin/de/dbauer/expensetracker/widget/UpcomingPaymentsWidgetModel.kt +++ b/app/src/main/kotlin/de/dbauer/expensetracker/widget/UpcomingPaymentsWidgetModel.kt @@ -1,69 +1,46 @@ package de.dbauer.expensetracker.widget import androidx.compose.runtime.mutableStateListOf -import de.dbauer.expensetracker.shared.data.Recurrence -import de.dbauer.expensetracker.shared.data.RecurringExpenseData import de.dbauer.expensetracker.shared.data.UpcomingPaymentData -import de.dbauer.expensetracker.shared.model.DateTimeCalculator +import de.dbauer.expensetracker.shared.model.UpcomingPaymentsExpander import de.dbauer.expensetracker.shared.model.database.IExpenseRepository -import de.dbauer.expensetracker.shared.toLocaleString -import kotlinx.datetime.DateTimeUnit -import kotlinx.datetime.LocalDate +import de.dbauer.expensetracker.shared.model.datastore.IUserPreferencesRepository +import kotlinx.coroutines.flow.combine +import kotlinx.datetime.DatePeriod import kotlinx.datetime.TimeZone -import kotlinx.datetime.atStartOfDayIn -import kotlin.time.Instant +import kotlinx.datetime.plus +import kotlinx.datetime.toLocalDateTime +import kotlin.time.Clock class UpcomingPaymentsWidgetModel( private val expenseRepository: IExpenseRepository, + private val userPreferencesRepository: IUserPreferencesRepository, ) { private val _upcomingPaymentsData = mutableStateListOf() val upcomingPaymentsData: List get() = _upcomingPaymentsData suspend fun init() { - expenseRepository.allRecurringExpensesByPrice.collect { recurringExpenses -> - onDatabaseUpdated(recurringExpenses) - } - } - - private fun onDatabaseUpdated(recurringExpenses: List) { - _upcomingPaymentsData.clear() - recurringExpenses.forEach { expense -> - expense.firstPayment?.let { firstPayment -> - val nextPaymentDay = - getNextPaymentDay(firstPayment, expense.everyXRecurrence, expense.recurrence) - val nextPaymentRemainingDays = DateTimeCalculator.getDaysFromNowUntil(nextPaymentDay) - val nextPaymentDate = nextPaymentDay.atStartOfDayIn(TimeZone.UTC).toLocaleString() - _upcomingPaymentsData.add( - UpcomingPaymentData( - id = expense.id, - name = expense.name, - price = expense.price, - nextPaymentRemainingDays = nextPaymentRemainingDays, - nextPaymentDate = nextPaymentDate, - tags = expense.tags, - ), - ) + combine( + expenseRepository.allRecurringExpensesByPrice, + userPreferencesRepository.upcomingPaymentHorizonMonths.get(), + ) { expenses, horizonMonths -> expenses to horizonMonths } + .collect { (recurringExpenses, horizonMonths) -> + val from = + Clock.System + .now() + .toLocalDateTime(TimeZone.currentSystemDefault()) + .date + val until = from.plus(DatePeriod(months = horizonMonths)) + val payments = + UpcomingPaymentsExpander.collectFuturePayments( + expenseRepository = expenseRepository, + recurringExpenses = recurringExpenses, + from = from, + until = until, + ) + _upcomingPaymentsData.clear() + _upcomingPaymentsData.addAll(payments) } - } - _upcomingPaymentsData.sortBy { it.nextPaymentRemainingDays } - } - - private fun getNextPaymentDay( - firstPayment: Instant, - everyXRecurrence: Int, - recurrence: Recurrence, - ): LocalDate { - return DateTimeCalculator.getDayOfNextOccurrenceFromNow( - from = firstPayment, - everyXRecurrence = everyXRecurrence, - recurrence = - when (recurrence) { - Recurrence.Daily -> DateTimeUnit.DAY - Recurrence.Weekly -> DateTimeUnit.WEEK - Recurrence.Monthly -> DateTimeUnit.MONTH - Recurrence.Yearly -> DateTimeUnit.YEAR - }, - ) } }