Primera build enviada
This commit is contained in:
@@ -11,6 +11,7 @@ class ImportService {
|
||||
let accountsCreated: Int
|
||||
let sourcesCreated: Int
|
||||
let snapshotsCreated: Int
|
||||
let snapshotsUpdated: Int
|
||||
let errors: [String]
|
||||
}
|
||||
|
||||
@@ -385,11 +386,13 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
var accountsCreated = 0
|
||||
var sourcesCreated = 0
|
||||
var snapshotsCreated = 0
|
||||
var snapshotsUpdated = 0
|
||||
var errors: [String] = []
|
||||
|
||||
var categoryLookup = buildCategoryLookup(from: categoryRepository.categories)
|
||||
let otherCategory = resolveExistingCategory(named: "Other", lookup: categoryLookup) ??
|
||||
categoryRepository.createCategory(
|
||||
let existingCategories = fetchCategories(in: context)
|
||||
var categoryLookup = buildCategoryLookup(from: existingCategories)
|
||||
let otherCategory = resolveExistingCategory(named: "Other", lookup: categoryLookup)
|
||||
?? categoryRepository.createCategory(
|
||||
name: "Other",
|
||||
colorHex: "#64748B",
|
||||
icon: "ellipsis.circle.fill"
|
||||
@@ -398,17 +401,22 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
|
||||
var completionDatesByMonth: [String: Date] = [:]
|
||||
|
||||
for importedAccount in accounts {
|
||||
let existingAccount = accountRepository.accounts.first(where: { $0.name == importedAccount.name })
|
||||
let account = existingAccount ?? accountRepository.createAccount(
|
||||
name: importedAccount.name,
|
||||
currency: importedAccount.currency,
|
||||
inputMode: importedAccount.inputMode,
|
||||
notificationFrequency: importedAccount.notificationFrequency,
|
||||
customFrequencyMonths: importedAccount.customFrequencyMonths
|
||||
)
|
||||
// Build lookup of existing accounts by fetching directly from database
|
||||
let existingAccountsLookup = fetchAccountsLookup(in: context)
|
||||
|
||||
if existingAccount == nil {
|
||||
for importedAccount in accounts {
|
||||
let existingAccount = existingAccountsLookup[importedAccount.name]
|
||||
let account: Account
|
||||
if let existing = existingAccount {
|
||||
account = existing
|
||||
} else {
|
||||
account = accountRepository.createAccount(
|
||||
name: importedAccount.name,
|
||||
currency: importedAccount.currency,
|
||||
inputMode: importedAccount.inputMode,
|
||||
notificationFrequency: importedAccount.notificationFrequency,
|
||||
customFrequencyMonths: importedAccount.customFrequencyMonths
|
||||
)
|
||||
accountsCreated += 1
|
||||
}
|
||||
|
||||
@@ -431,8 +439,9 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
categoryLookup[normalizedCategoryName(category.name)] = category
|
||||
|
||||
for importedSource in importedCategory.sources {
|
||||
let accountId = account.safeId
|
||||
let existingSource = sourceRepository.sources.first(where: {
|
||||
$0.name == importedSource.name && $0.account?.id == account.id
|
||||
$0.name == importedSource.name && $0.account?.id == accountId
|
||||
})
|
||||
let source = existingSource ?? sourceRepository.createSource(
|
||||
name: importedSource.name,
|
||||
@@ -446,14 +455,30 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
}
|
||||
|
||||
for snapshot in importedSource.snapshots {
|
||||
snapshotRepository.createSnapshot(
|
||||
for: source,
|
||||
date: snapshot.date,
|
||||
value: snapshot.value,
|
||||
contribution: snapshot.contribution,
|
||||
notes: snapshot.notes
|
||||
)
|
||||
snapshotsCreated += 1
|
||||
// Check if a snapshot with the same date already exists for this source
|
||||
let existingSnapshot = fetchSnapshot(for: source, date: snapshot.date, in: context)
|
||||
|
||||
if let existing = existingSnapshot {
|
||||
// Update existing snapshot instead of creating a duplicate
|
||||
existing.value = NSDecimalNumber(decimal: snapshot.value)
|
||||
if let contribution = snapshot.contribution {
|
||||
existing.contribution = NSDecimalNumber(decimal: contribution)
|
||||
}
|
||||
if let notes = snapshot.notes, !notes.isEmpty {
|
||||
existing.notes = notes
|
||||
}
|
||||
snapshotsUpdated += 1
|
||||
} else {
|
||||
// Create new snapshot
|
||||
snapshotRepository.createSnapshot(
|
||||
for: source,
|
||||
date: snapshot.date,
|
||||
value: snapshot.value,
|
||||
contribution: snapshot.contribution,
|
||||
notes: snapshot.notes
|
||||
)
|
||||
snapshotsCreated += 1
|
||||
}
|
||||
snapshotProgress?(snapshotsCreated)
|
||||
|
||||
let monthKey = MonthlyCheckInStore.monthKey(for: snapshot.date)
|
||||
@@ -491,6 +516,7 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
accountsCreated: accountsCreated,
|
||||
sourcesCreated: sourcesCreated,
|
||||
snapshotsCreated: snapshotsCreated,
|
||||
snapshotsUpdated: snapshotsUpdated,
|
||||
errors: errors
|
||||
)
|
||||
}
|
||||
@@ -516,6 +542,50 @@ Personal,Real Estate,Rental Property,2024-01-01,82000,80000,Estimated value
|
||||
return lookup
|
||||
}
|
||||
|
||||
private func fetchCategories(in context: NSManagedObjectContext) -> [Category] {
|
||||
let request: NSFetchRequest<Category> = Category.fetchRequest()
|
||||
request.sortDescriptors = [
|
||||
NSSortDescriptor(keyPath: \Category.sortOrder, ascending: true),
|
||||
NSSortDescriptor(keyPath: \Category.name, ascending: true)
|
||||
]
|
||||
return (try? context.fetch(request)) ?? []
|
||||
}
|
||||
|
||||
private func fetchAccountsLookup(in context: NSManagedObjectContext) -> [String: Account] {
|
||||
let request: NSFetchRequest<Account> = Account.fetchRequest()
|
||||
request.sortDescriptors = [NSSortDescriptor(keyPath: \Account.createdAt, ascending: true)]
|
||||
let accounts = (try? context.fetch(request)) ?? []
|
||||
var lookup: [String: Account] = [:]
|
||||
for account in accounts {
|
||||
lookup[account.name] = account
|
||||
}
|
||||
return lookup
|
||||
}
|
||||
|
||||
/// Fetch a snapshot for a given source and date (same day)
|
||||
private func fetchSnapshot(
|
||||
for source: InvestmentSource,
|
||||
date: Date,
|
||||
in context: NSManagedObjectContext
|
||||
) -> Snapshot? {
|
||||
let request: NSFetchRequest<Snapshot> = Snapshot.fetchRequest()
|
||||
|
||||
// Match snapshots on the same day (ignore time component)
|
||||
let calendar = Calendar.current
|
||||
let startOfDay = calendar.startOfDay(for: date)
|
||||
let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)!
|
||||
|
||||
request.predicate = NSPredicate(
|
||||
format: "source == %@ AND date >= %@ AND date < %@",
|
||||
source,
|
||||
startOfDay as NSDate,
|
||||
endOfDay as NSDate
|
||||
)
|
||||
request.fetchLimit = 1
|
||||
|
||||
return try? context.fetch(request).first
|
||||
}
|
||||
|
||||
private func canonicalCategoryName(for rawName: String) -> String? {
|
||||
let normalized = normalizedCategoryName(rawName)
|
||||
for mapping in categoryAliasMappings {
|
||||
|
||||
Reference in New Issue
Block a user