Files
FamilyMealPlanner/MealMood/Models/Tag.swift
T
alexandrev-tibco 7da7995538 Fix SwiftData migration crash on schema upgrades
Add = false/true defaults to all non-optional Bool properties so
SwiftData's lightweight migration knows what value to assign existing
rows. Replace try! ModelContainer with crash-safe do-catch that resets
the store on migration failure instead of crashing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 11:24:56 +02:00

94 lines
3.2 KiB
Swift

import Foundation
import SwiftData
@Model
final class Tag {
@Attribute(.unique) var id: UUID
var name: String
var nameEN: String
var color: String
var maxPerWeek: Int?
var noConsecutive: Bool = false
var noDuplicateInDay: Bool = false
var mealTypeRestriction: String? // "lunch", "dinner", nil
var dayRestriction: String? // nil = any day, "weekdays" = Mon-Fri, "weekend" = Sat-Sun
var isDefault: Bool = true
var sortOrder: Int
init(
id: UUID = UUID(),
name: String,
nameEN: String = "",
color: String,
maxPerWeek: Int? = nil,
noConsecutive: Bool = false,
noDuplicateInDay: Bool = false,
mealTypeRestriction: String? = nil,
dayRestriction: String? = nil,
isDefault: Bool = true,
sortOrder: Int = 0
) {
self.id = id
self.name = name
self.nameEN = nameEN
self.color = color
self.maxPerWeek = maxPerWeek
self.noConsecutive = noConsecutive
self.noDuplicateInDay = noDuplicateInDay
self.mealTypeRestriction = mealTypeRestriction
self.dayRestriction = dayRestriction
self.isDefault = isDefault
self.sortOrder = sortOrder
}
func localizedName(language: AppLanguage) -> String {
switch language.resolved() {
case .spanish: return name
case .english, .french, .german, .italian, .portugueseBrazil: return nameEN.isEmpty ? name : nameEN
case .system: return nameEN.isEmpty ? name : nameEN
}
}
var rulesDescription: String {
localizedRulesDescription(language: .spanish)
}
func localizedRulesDescription(language: AppLanguage) -> String {
let resolvedLanguage = language.resolved()
var parts: [String] = []
if let max = maxPerWeek {
switch resolvedLanguage {
case .spanish:
parts.append("Max \(max)/semana")
case .english, .french, .german, .italian, .portugueseBrazil:
parts.append("Max \(max)/week")
case .system:
parts.append("Max \(max)/week")
}
}
if noConsecutive {
parts.append(resolvedLanguage == .spanish ? "no consecutivo" : "no consecutive")
}
if noDuplicateInDay {
parts.append(resolvedLanguage == .spanish ? "no mismo día" : "no same day")
}
if let restriction = mealTypeRestriction {
if resolvedLanguage == .spanish {
parts.append(restriction == "lunch" ? "solo comida" : "solo cena")
} else {
parts.append(restriction == "lunch" ? "lunch only" : "dinner only")
}
}
if let day = dayRestriction {
switch (day, resolvedLanguage) {
case ("weekdays", .spanish): parts.append("entre semana")
case ("weekdays", _): parts.append("weekdays")
case ("weekend", .spanish): parts.append("fin de semana")
case ("weekend", _): parts.append("weekend")
default: break
}
}
return parts.isEmpty ? (resolvedLanguage == .spanish ? "Sin límite" : "No limit") : parts.joined(separator: ", ")
}
}