7cb5f92cf4
Deleted files: - AddTransactionView.swift - TransactionRepository.swift - Transaction+CoreDataClass.swift Cleaned files: - SourceDetailViewModel: removed transactions published property, showingAddTransaction flag, transactionRepository dependency, addTransaction() and deleteTransaction() methods - SourceDetailView: removed transactionsSection, TransactionRow struct, Add Transaction button from quickActions, sheet presentation - InvestmentSource+CoreDataClass: removed transactions NSManaged property, transactionsArray, totalInvested, totalDividends, totalFees computed properties, and all transaction Core Data accessors - SettingsViewModel: removed "Transaction" from resetAllData entity list - SampleDataService: removed transactionRepository and sample transaction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
138 lines
4.7 KiB
Swift
138 lines
4.7 KiB
Swift
import Foundation
|
|
import CoreData
|
|
|
|
class SampleDataService {
|
|
static let shared = SampleDataService()
|
|
|
|
private init() {}
|
|
|
|
func seedSampleData() {
|
|
let context = CoreDataStack.shared.viewContext
|
|
let sourceRepository = InvestmentSourceRepository(context: context)
|
|
guard sourceRepository.sourceCount == 0 else { return }
|
|
|
|
let categoryRepository = CategoryRepository(context: context)
|
|
categoryRepository.createDefaultCategoriesIfNeeded()
|
|
|
|
let accountRepository = AccountRepository(context: context)
|
|
let account = accountRepository.createDefaultAccountIfNeeded()
|
|
|
|
let snapshotRepository = SnapshotRepository(context: context)
|
|
let goalRepository = GoalRepository(context: context)
|
|
|
|
let categories = fetchCategories(in: context)
|
|
guard let fallbackCategory = categories.first else { return }
|
|
let stocksCategory = resolveCategory(
|
|
named: "Stocks",
|
|
fallback: fallbackCategory,
|
|
colorHex: "#3B82F6",
|
|
icon: "chart.line.uptrend.xyaxis",
|
|
repository: categoryRepository,
|
|
context: context
|
|
)
|
|
let cryptoCategory = resolveCategory(
|
|
named: "Crypto",
|
|
fallback: fallbackCategory,
|
|
colorHex: "#10B981",
|
|
icon: "bitcoinsign.circle.fill",
|
|
repository: categoryRepository,
|
|
context: context
|
|
)
|
|
let realEstateCategory = resolveCategory(
|
|
named: "Real Estate",
|
|
fallback: fallbackCategory,
|
|
colorHex: "#F59E0B",
|
|
icon: "house.fill",
|
|
repository: categoryRepository,
|
|
context: context
|
|
)
|
|
|
|
let stocks = sourceRepository.createSource(
|
|
name: "Index Fund",
|
|
category: stocksCategory,
|
|
account: account
|
|
)
|
|
let crypto = sourceRepository.createSource(
|
|
name: "BTC",
|
|
category: cryptoCategory,
|
|
account: account
|
|
)
|
|
let realEstate = sourceRepository.createSource(
|
|
name: "Rental Property",
|
|
category: realEstateCategory,
|
|
account: account
|
|
)
|
|
|
|
seedSnapshots(for: stocks, baseValue: 12000, monthlyIncrease: 450, repository: snapshotRepository)
|
|
seedSnapshots(for: crypto, baseValue: 3000, monthlyIncrease: 250, repository: snapshotRepository)
|
|
seedSnapshots(for: realEstate, baseValue: 80000, monthlyIncrease: 600, repository: snapshotRepository)
|
|
|
|
seedMonthlyNotes()
|
|
|
|
_ = goalRepository.createGoal(
|
|
name: "1M Goal",
|
|
targetAmount: 1_000_000,
|
|
targetDate: nil,
|
|
account: account
|
|
)
|
|
}
|
|
|
|
private func seedSnapshots(
|
|
for source: InvestmentSource,
|
|
baseValue: Decimal,
|
|
monthlyIncrease: Decimal,
|
|
repository: SnapshotRepository
|
|
) {
|
|
let calendar = Calendar.current
|
|
for monthOffset in (0..<6).reversed() {
|
|
let date = calendar.date(byAdding: .month, value: -monthOffset, to: Date()) ?? Date()
|
|
let value = baseValue + Decimal(monthOffset) * monthlyIncrease
|
|
repository.createSnapshot(
|
|
for: source,
|
|
date: date,
|
|
value: value,
|
|
contribution: monthOffset == 0 ? monthlyIncrease : nil,
|
|
notes: nil
|
|
)
|
|
}
|
|
}
|
|
|
|
private func seedMonthlyNotes() {
|
|
let calendar = Calendar.current
|
|
let notes = [
|
|
"Rebalanced slightly toward equities. Stayed calm despite noise.",
|
|
"Focused on contributions. No major changes.",
|
|
"Reviewed allocation drift and decided to hold positions."
|
|
]
|
|
|
|
for (index, note) in notes.enumerated() {
|
|
let date = calendar.date(byAdding: .month, value: -index, to: Date()) ?? Date()
|
|
MonthlyCheckInStore.setNote(note, for: date)
|
|
}
|
|
}
|
|
|
|
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 resolveCategory(
|
|
named name: String,
|
|
fallback: Category,
|
|
colorHex: String,
|
|
icon: String,
|
|
repository: CategoryRepository,
|
|
context: NSManagedObjectContext
|
|
) -> Category {
|
|
if let existing = fetchCategories(in: context)
|
|
.first(where: { $0.name == name }) {
|
|
return existing
|
|
}
|
|
return repository.createCategory(name: name, colorHex: colorHex, icon: icon)
|
|
}
|
|
}
|