Files
FamilyMealPlanner/MealMood/Models/WeekPlan.swift
T
alexandrev-tibco 66128e7a5c premium: configurar días y comidas de una semana concreta
Hasta ahora includeWeekends y activeMealTypes vivían solo en AppSettings y
aplicaban a todo el calendario. WeekPlan puede ahora sobreescribirlos para su
semana (includeWeekendsOverride / mealTypesOverrideRaw) y WeekSchedule resuelve
qué manda en cada semana: su override si lo tiene, los ajustes globales si no.

Todo lo que pintaba días y comidas —planificador, exports, compartir texto,
widget, watch— pasa por settings.schedule(for:), así que una semana con fin de
semana añadido o con desayuno activo se ve igual en todas partes.

Crear o editar el override es premium; los ya guardados se respetan aunque la
suscripción caduque, para no borrar comidas ya planificadas. La hoja avisa y
pide confirmación cuando quitar un día o una comida se lleva por delante algo
ya planificado.

Refs #32

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 12:05:34 +02:00

76 lines
2.6 KiB
Swift

import Foundation
import SwiftData
// CloudKit-compatible (2.0): no unique constraints, inline defaults everywhere,
// and the relationship stored as optional (CloudKit requires it). `slots` keeps
// its name so existing stores lightweight-migrate; use `slotList` in code.
@Model
final class WeekPlan {
var id: UUID = UUID()
var weekStartDate: Date = Date()
var createdAt: Date = Date()
var updatedAt: Date = Date()
var userRating: Int = 0 // 0 = unrated, 1 = liked, -1 = disliked
/// Per-week overrides of the global schedule (2.1.1, premium). nil = follow
/// `AppSettings`. Optional so existing stores lightweight-migrate and
/// CloudKit accepts the new attributes.
var includeWeekendsOverride: Bool?
/// Comma-separated MealType raw values, chronological. nil = follow settings.
var mealTypesOverrideRaw: String?
@Relationship(deleteRule: .cascade)
var slots: [MealSlot]? = []
/// Non-optional facade over the CloudKit-required optional relationship.
var slotList: [MealSlot] {
get { slots ?? [] }
set { slots = newValue }
}
/// The meal types this week overrides the global setting with, or nil when
/// it follows `AppSettings.activeMealTypes`.
var mealTypesOverride: [MealType]? {
get {
guard let raw = mealTypesOverrideRaw else { return nil }
let types = raw.split(separator: ",").compactMap { MealType(rawValue: String($0)) }
guard !types.isEmpty else { return nil }
return MealType.allCases.filter { types.contains($0) }
}
set {
guard let newValue else {
mealTypesOverrideRaw = nil
return
}
let ordered = MealType.allCases.filter { newValue.contains($0) }
// An empty selection would leave the week with no slots at all;
// treat it as "no override" instead.
mealTypesOverrideRaw = ordered.isEmpty ? nil : ordered.map(\.rawValue).joined(separator: ",")
}
}
var hasScheduleOverride: Bool {
includeWeekendsOverride != nil || mealTypesOverrideRaw != nil
}
func clearScheduleOverride() {
includeWeekendsOverride = nil
mealTypesOverrideRaw = nil
}
init(
id: UUID = UUID(),
weekStartDate: Date,
slots: [MealSlot] = [],
createdAt: Date = Date(),
updatedAt: Date = Date()
) {
self.id = id
self.weekStartDate = weekStartDate
self.slots = slots
self.createdAt = createdAt
self.updatedAt = updatedAt
self.userRating = 0
}
}