initial version
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Combine
|
||||
|
||||
class AccountRepository: ObservableObject {
|
||||
private let context: NSManagedObjectContext
|
||||
|
||||
@Published private(set) var accounts: [Account] = []
|
||||
|
||||
init(context: NSManagedObjectContext = CoreDataStack.shared.viewContext) {
|
||||
self.context = context
|
||||
fetchAccounts()
|
||||
setupNotificationObserver()
|
||||
}
|
||||
|
||||
private func setupNotificationObserver() {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(contextDidChange),
|
||||
name: .NSManagedObjectContextObjectsDidChange,
|
||||
object: context
|
||||
)
|
||||
}
|
||||
|
||||
@objc private func contextDidChange(_ notification: Notification) {
|
||||
fetchAccounts()
|
||||
}
|
||||
|
||||
// MARK: - Fetch
|
||||
|
||||
func fetchAccounts() {
|
||||
context.perform { [weak self] in
|
||||
guard let self else { return }
|
||||
let request: NSFetchRequest<Account> = Account.fetchRequest()
|
||||
request.sortDescriptors = [
|
||||
NSSortDescriptor(keyPath: \Account.sortOrder, ascending: true),
|
||||
NSSortDescriptor(keyPath: \Account.createdAt, ascending: true)
|
||||
]
|
||||
|
||||
do {
|
||||
let fetched = try self.context.fetch(request)
|
||||
DispatchQueue.main.async {
|
||||
self.accounts = fetched
|
||||
}
|
||||
} catch {
|
||||
print("Failed to fetch accounts: \(error)")
|
||||
DispatchQueue.main.async {
|
||||
self.accounts = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchAccount(by id: UUID) -> Account? {
|
||||
let request: NSFetchRequest<Account> = Account.fetchRequest()
|
||||
request.predicate = NSPredicate(format: "id == %@", id as CVarArg)
|
||||
request.fetchLimit = 1
|
||||
return try? context.fetch(request).first
|
||||
}
|
||||
|
||||
// MARK: - Create
|
||||
|
||||
@discardableResult
|
||||
func createAccount(
|
||||
name: String,
|
||||
currency: String?,
|
||||
inputMode: InputMode,
|
||||
notificationFrequency: NotificationFrequency,
|
||||
customFrequencyMonths: Int = 1
|
||||
) -> Account {
|
||||
let account = Account(context: context)
|
||||
account.name = name
|
||||
account.currency = currency
|
||||
account.inputMode = inputMode.rawValue
|
||||
account.notificationFrequency = notificationFrequency.rawValue
|
||||
account.customFrequencyMonths = Int16(customFrequencyMonths)
|
||||
account.sortOrder = Int16(accounts.count)
|
||||
save()
|
||||
return account
|
||||
}
|
||||
|
||||
func createDefaultAccountIfNeeded() -> Account {
|
||||
if let existing = accounts.first {
|
||||
return existing
|
||||
}
|
||||
|
||||
let defaultCurrency = AppSettings.getOrCreate(in: context).currency
|
||||
let account = createAccount(
|
||||
name: "Personal",
|
||||
currency: defaultCurrency,
|
||||
inputMode: .simple,
|
||||
notificationFrequency: .monthly
|
||||
)
|
||||
|
||||
// Attach existing sources to the default account
|
||||
let request: NSFetchRequest<InvestmentSource> = InvestmentSource.fetchRequest()
|
||||
if let sources = try? context.fetch(request) {
|
||||
for source in sources where source.account == nil {
|
||||
source.account = account
|
||||
}
|
||||
save()
|
||||
}
|
||||
|
||||
return account
|
||||
}
|
||||
|
||||
// MARK: - Update
|
||||
|
||||
func updateAccount(
|
||||
_ account: Account,
|
||||
name: String? = nil,
|
||||
currency: String? = nil,
|
||||
inputMode: InputMode? = nil,
|
||||
notificationFrequency: NotificationFrequency? = nil,
|
||||
customFrequencyMonths: Int? = nil
|
||||
) {
|
||||
if let name = name {
|
||||
account.name = name
|
||||
}
|
||||
if let currency = currency {
|
||||
account.currency = currency
|
||||
}
|
||||
if let inputMode = inputMode {
|
||||
account.inputMode = inputMode.rawValue
|
||||
}
|
||||
if let notificationFrequency = notificationFrequency {
|
||||
account.notificationFrequency = notificationFrequency.rawValue
|
||||
}
|
||||
if let customMonths = customFrequencyMonths {
|
||||
account.customFrequencyMonths = Int16(customMonths)
|
||||
}
|
||||
save()
|
||||
}
|
||||
|
||||
// MARK: - Delete
|
||||
|
||||
func deleteAccount(_ account: Account) {
|
||||
context.delete(account)
|
||||
save()
|
||||
}
|
||||
|
||||
// MARK: - Save
|
||||
|
||||
private func save() {
|
||||
guard context.hasChanges else { return }
|
||||
do {
|
||||
try context.save()
|
||||
fetchAccounts()
|
||||
} catch {
|
||||
print("Failed to save accounts: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user