import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/api/api_client.dart'; import '../../core/cache/cached.dart'; import '../portfolio/providers.dart' show scopeProvider; import 'data/income_api.dart'; final incomeApiProvider = Provider( (ref) => IncomeApi(ref.watch(apiProvider).dio), ); /// How far the calendar looks ahead, in months. 12 is the contract default. final calendarMonthsProvider = StateProvider((ref) => 12); final calendarIncludePaidProvider = StateProvider((ref) => false); /// Доходы shares the portfolio-wide [scopeProvider]: switching the scope on Портфель must /// not leave the income calendar showing a different portfolio. See `docs/ai/offline-cache.md`. final incomeCalendarProvider = FutureProvider.autoDispose>((ref) async { final scope = ref.watch(scopeProvider); final months = ref.watch(calendarMonthsProvider); final includePaid = ref.watch(calendarIncludePaidProvider); final now = DateTime.now(); return ref .watch(incomeApiProvider) .calendar( scope: scope, dateFrom: DateTime(now.year, now.month, now.day), dateTo: DateTime(now.year, now.month + months, now.day), includePaid: includePaid, ); }); enum CalendarView { month, list } /// The calendar opens as a month grid; the list of the coming payments is the other view. final calendarViewProvider = StateProvider( (ref) => CalendarView.month, ); /// The month the grid shows, as the first day of it. final calendarMonthProvider = StateProvider((ref) { final now = DateTime.now(); return DateTime(now.year, now.month); }); /// Every payment of one month, the paid ones included: a calendar of a month is the record of /// it as well as the plan. Keyed by the first day of the month. final incomeMonthProvider = FutureProvider.autoDispose .family, DateTime>((ref, month) async { final scope = ref.watch(scopeProvider); return ref .watch(incomeApiProvider) .calendar( scope: scope, dateFrom: DateTime(month.year, month.month, 1), dateTo: DateTime(month.year, month.month + 1, 0), includePaid: true, ); }); /// How far the history goes back, in months. final historyMonthsProvider = StateProvider((ref) => 24); final incomeHistoryProvider = FutureProvider.autoDispose>( (ref) async { final scope = ref.watch(scopeProvider); final months = ref.watch(historyMonthsProvider); final now = DateTime.now(); return ref .watch(incomeApiProvider) .history( scope: scope, dateFrom: DateTime(now.year, now.month - months + 1, 1), dateTo: DateTime(now.year, now.month + 1, 0), ); }, ); final forecastMonthsProvider = StateProvider((ref) => 12); final incomeForecastProvider = FutureProvider.autoDispose>((ref) async { final scope = ref.watch(scopeProvider); return ref .watch(incomeApiProvider) .forecast(scope: scope, months: ref.watch(forecastMonthsProvider)); }); void invalidateIncomeProviders(WidgetRef ref) { ref.invalidate(incomeCalendarProvider); ref.invalidate(incomeMonthProvider); ref.invalidate(incomeHistoryProvider); ref.invalidate(incomeForecastProvider); }