leafittome/lib/features/plants/domain/plant.dart
cschlaefke 81d990dd7e V3: Umtopf-Erinnerungen (opt-in, Intervall in Monaten)
Dritter Aufgabentyp repotting im Intervall-Modell: optionales
repottingIntervalMonths + lastRepotted/By am Pflanzenprofil, Formular
mit Intervall-Feld und Datums-Auswahl, Umtopf-Zeile im Detail,
Aufgaben in Checkliste und Sammel-Push (reminders.ts gespiegelt),
Sitter dürfen bestätigen (Rules-Allowlist). Monats-Arithmetik kürzt
den 31. auf den Monatsletzten. Ende-zu-Ende-Widget-Test.

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

109 lines
3.6 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/foundation.dart';
/// Eine Pflanze im Haushalt.
///
/// Das Modell ist bewusst haushaltszentriert gedacht: Sobald das
/// Firebase-Backend angebunden ist, leben Pflanzen unter
/// `households/{householdId}/plants/{plantId}`.
@immutable
class Plant {
const Plant({
required this.id,
required this.nickname,
required this.species,
required this.wateringIntervalDays,
required this.fertilizingIntervalDays,
this.locationId,
this.description = '',
this.careNotes = '',
this.photoUrl,
this.lastWatered,
this.lastFertilized,
this.lastWateredBy,
this.lastFertilizedBy,
this.repottingIntervalMonths,
this.lastRepotted,
this.lastRepottedBy,
});
final String id;
/// Vom Nutzer vergebener Name, z. B. "Omas Monstera".
final String nickname;
/// Pflanzenart (deutsch und/oder botanisch). Wird später von der
/// PlantNet-Erkennung befüllt, kann aber auch frei eingegeben werden.
final String species;
/// Referenz auf einen Stellplatz des Haushalts (optional).
final String? locationId;
/// Beschreibung und Pflegehinweise von der KI erzeugt oder leer.
final String description;
final String careNotes;
/// Download-URL des Pflanzenfotos in Firebase Storage (optional).
final String? photoUrl;
final int wateringIntervalDays;
final int fertilizingIntervalDays;
/// `null` bedeutet: noch nie erledigt → Aufgabe ist sofort fällig.
final DateTime? lastWatered;
final DateTime? lastFertilized;
/// Wer zuletzt bestätigt hat (Anzeigename) für den Haushalt sichtbar.
final String? lastWateredBy;
final String? lastFertilizedBy;
/// Umtopf-Erinnerung (V3), optional: `null` = keine Erinnerung gewünscht.
/// Bei gesetztem Intervall und `lastRepotted == null` ist die Aufgabe
/// sofort fällig (wie bei Gießen/Düngen: „noch nie erledigt").
final int? repottingIntervalMonths;
final DateTime? lastRepotted;
final String? lastRepottedBy;
Plant copyWith({
String? nickname,
String? species,
String? Function()? locationId,
String? description,
String? careNotes,
String? photoUrl,
int? wateringIntervalDays,
int? fertilizingIntervalDays,
DateTime? lastWatered,
DateTime? lastFertilized,
String? lastWateredBy,
String? lastFertilizedBy,
// Als Getter, damit sich die Felder auch auf null zurücksetzen lassen
// (Intervall entfernen = Erinnerung abschalten).
int? Function()? repottingIntervalMonths,
DateTime? Function()? lastRepotted,
}) {
return Plant(
id: id,
nickname: nickname ?? this.nickname,
species: species ?? this.species,
locationId: locationId != null ? locationId() : this.locationId,
description: description ?? this.description,
careNotes: careNotes ?? this.careNotes,
photoUrl: photoUrl ?? this.photoUrl,
wateringIntervalDays: wateringIntervalDays ?? this.wateringIntervalDays,
fertilizingIntervalDays:
fertilizingIntervalDays ?? this.fertilizingIntervalDays,
lastWatered: lastWatered ?? this.lastWatered,
lastFertilized: lastFertilized ?? this.lastFertilized,
lastWateredBy: lastWateredBy ?? this.lastWateredBy,
lastFertilizedBy: lastFertilizedBy ?? this.lastFertilizedBy,
repottingIntervalMonths: repottingIntervalMonths != null
? repottingIntervalMonths()
: this.repottingIntervalMonths,
lastRepotted:
lastRepotted != null ? lastRepotted() : this.lastRepotted,
// Bewusst nicht per copyWith änderbar — wird nur beim Bestätigen
// einer Umtopf-Aufgabe direkt in Firestore gesetzt.
lastRepottedBy: lastRepottedBy,
);
}
}