initial version
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Combine
|
||||
|
||||
class GoalRepository: ObservableObject {
|
||||
private let context: NSManagedObjectContext
|
||||
|
||||
@Published private(set) var goals: [Goal] = []
|
||||
|
||||
init(context: NSManagedObjectContext = CoreDataStack.shared.viewContext) {
|
||||
self.context = context
|
||||
fetchGoals()
|
||||
setupNotificationObserver()
|
||||
}
|
||||
|
||||
private func setupNotificationObserver() {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(contextDidChange),
|
||||
name: .NSManagedObjectContextObjectsDidChange,
|
||||
object: context
|
||||
)
|
||||
}
|
||||
|
||||
@objc private func contextDidChange(_ notification: Notification) {
|
||||
fetchGoals()
|
||||
}
|
||||
|
||||
// MARK: - Fetch
|
||||
|
||||
func fetchGoals(for account: Account? = nil) {
|
||||
context.perform { [weak self] in
|
||||
guard let self else { return }
|
||||
let request: NSFetchRequest<Goal> = Goal.fetchRequest()
|
||||
if let account = account {
|
||||
request.predicate = NSPredicate(format: "account == %@", account)
|
||||
}
|
||||
request.sortDescriptors = [
|
||||
NSSortDescriptor(keyPath: \Goal.createdAt, ascending: true)
|
||||
]
|
||||
|
||||
do {
|
||||
self.goals = try self.context.fetch(request)
|
||||
} catch {
|
||||
print("Failed to fetch goals: \(error)")
|
||||
self.goals = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Create
|
||||
|
||||
@discardableResult
|
||||
func createGoal(
|
||||
name: String,
|
||||
targetAmount: Decimal,
|
||||
targetDate: Date? = nil,
|
||||
account: Account?
|
||||
) -> Goal {
|
||||
let goal = Goal(context: context)
|
||||
goal.name = name
|
||||
goal.targetAmount = NSDecimalNumber(decimal: targetAmount)
|
||||
goal.targetDate = targetDate
|
||||
goal.account = account
|
||||
save()
|
||||
return goal
|
||||
}
|
||||
|
||||
// MARK: - Update
|
||||
|
||||
func updateGoal(
|
||||
_ goal: Goal,
|
||||
name: String? = nil,
|
||||
targetAmount: Decimal? = nil,
|
||||
targetDate: Date? = nil,
|
||||
clearTargetDate: Bool = false,
|
||||
isActive: Bool? = nil
|
||||
) {
|
||||
if let name = name {
|
||||
goal.name = name
|
||||
}
|
||||
if let targetAmount = targetAmount {
|
||||
goal.targetAmount = NSDecimalNumber(decimal: targetAmount)
|
||||
}
|
||||
if clearTargetDate {
|
||||
goal.targetDate = nil
|
||||
} else if let targetDate = targetDate {
|
||||
goal.targetDate = targetDate
|
||||
}
|
||||
if let isActive = isActive {
|
||||
goal.isActive = isActive
|
||||
}
|
||||
save()
|
||||
}
|
||||
|
||||
func deleteGoal(_ goal: Goal) {
|
||||
context.delete(goal)
|
||||
save()
|
||||
}
|
||||
|
||||
// MARK: - Save
|
||||
|
||||
private func save() {
|
||||
guard context.hasChanges else { return }
|
||||
do {
|
||||
try context.save()
|
||||
fetchGoals()
|
||||
} catch {
|
||||
print("Failed to save goals: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user