Files
InvestmentTrackerApp/PortfolioJournal/Services/SampleDataService.swift
T
2026-01-19 14:40:43 +01:00

149 lines
5.1 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 transactionRepository = TransactionRepository(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()
transactionRepository.createTransaction(
source: stocks,
type: .buy,
date: Calendar.current.date(byAdding: .month, value: -3, to: Date()) ?? Date(),
shares: 10,
price: 400,
amount: nil,
notes: "Sample buy"
)
_ = 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)
}
}