leafittome/lib/features/today/application/due_tasks_provider.dart
cschlaefke 6e22d9c3aa Projekt-Gerüst: Flutter-App mit Heute-Checkliste, Pflanzenverwaltung, Stellplätzen und Einstellungen
- Flutter/Dart (iOS + Android), Riverpod, go_router, i18n via ARB (deutsch)
- Feature-Struktur: today, plants, locations, household (V2-Platzhalter), settings
- Intervall-Modell: Aufgaben werden aus lastWatered/lastFertilized + Intervall berechnet
- In-Memory-Demo-Daten, Firebase-Anbindung folgt im nächsten Block
- Doku: Architektur, Firebase-Einrichtung, Forgejo-Git-Hosting

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 21:13:18 +02:00

61 lines
2.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../plants/data/plants_provider.dart';
import '../../plants/domain/plant.dart';
import '../domain/due_task.dart';
DateTime _dateOnly(DateTime dt) => DateTime(dt.year, dt.month, dt.day);
DateTime? _nextDue(DateTime? lastDone, int intervalDays, DateTime today) {
// Noch nie erledigt → sofort fällig.
if (lastDone == null) return today;
return _dateOnly(lastDone).add(Duration(days: intervalDays));
}
Iterable<DueTask> _tasksForPlant(Plant plant, DateTime today) sync* {
final watering = _nextDue(plant.lastWatered, plant.wateringIntervalDays, today);
if (watering != null && !watering.isAfter(today)) {
yield DueTask(plant: plant, type: CareTaskType.watering, dueDate: watering);
}
final fertilizing =
_nextDue(plant.lastFertilized, plant.fertilizingIntervalDays, today);
if (fertilizing != null && !fertilizing.isAfter(today)) {
yield DueTask(
plant: plant, type: CareTaskType.fertilizing, dueDate: fertilizing);
}
}
/// Alle heute fälligen und überfälligen Aufgaben, Überfälliges zuerst.
final dueTasksProvider = Provider<List<DueTask>>((ref) {
final plants = ref.watch(plantsProvider);
final today = _dateOnly(DateTime.now());
final tasks = [
for (final plant in plants) ..._tasksForPlant(plant, today),
];
tasks.sort((a, b) {
final byDate = a.dueDate.compareTo(b.dueDate);
if (byDate != 0) return byDate;
return a.plant.nickname.compareTo(b.plant.nickname);
});
return tasks;
});
/// Das nächste zukünftige Fälligkeitsdatum für den "Alles versorgt"-Screen
/// ("Nächste Aufgabe: Freitag").
final nextDueDateProvider = Provider<DateTime?>((ref) {
final plants = ref.watch(plantsProvider);
final today = _dateOnly(DateTime.now());
DateTime? next;
for (final plant in plants) {
for (final candidate in [
_nextDue(plant.lastWatered, plant.wateringIntervalDays, today),
_nextDue(plant.lastFertilized, plant.fertilizingIntervalDays, today),
]) {
if (candidate == null || !candidate.isAfter(today)) continue;
if (next == null || candidate.isBefore(next)) next = candidate;
}
}
return next;
});