glp-companion/lib/features/meal_planner/domain/entities/meal_plan_slot.dart

64 lines
1.9 KiB
Dart

import '../../../nutrition/domain/entities/meal_type.dart';
/// One slot of the weekly meal plan: a calendar day plus a meal slot
/// (breakfast, lunch, dinner, snack) that either references a saved [Recipe]
/// by id or carries a free-text description.
///
/// Pure Dart (no framework imports). The meal vocabulary reuses the
/// nutrition feature's [MealType] so planner slots and food-diary entries
/// stay aligned across bounded contexts.
class MealPlanSlot {
const MealPlanSlot({
required this.id,
required this.date,
required this.mealType,
this.recipeId,
this.customDescription,
this.isPrepared = false,
});
/// UUID primary key assigned when the slot is first created.
final String id;
/// Calendar day the slot belongs to (stored at local start-of-day).
final DateTime date;
/// Meal slot within the day.
final MealType mealType;
/// Saved recipe assigned to this slot; `null` for custom entries.
final String? recipeId;
/// Free-text meal description for custom entries (or a note alongside an
/// assigned recipe).
final String? customDescription;
/// Whether the meal has been prepared / logged as done.
final bool isPrepared;
/// `true` when the slot renders as an empty cell (no recipe and no text).
bool get isEmpty =>
recipeId == null && (customDescription ?? '').trim().isEmpty;
MealPlanSlot copyWith({
String? id,
DateTime? date,
MealType? mealType,
String? recipeId,
String? customDescription,
bool? isPrepared,
}) =>
MealPlanSlot(
id: id ?? this.id,
date: date ?? this.date,
mealType: mealType ?? this.mealType,
recipeId: recipeId ?? this.recipeId,
customDescription: customDescription ?? this.customDescription,
isPrepared: isPrepared ?? this.isPrepared,
);
@override
String toString() => 'MealPlanSlot($id, ${date.year}-${date.month}-'
'${date.day} ${mealType.name}, recipe: ${recipeId ?? '-'})';
}