Add account management models: AccountModel and AccountsStore. Implement different account types (wallet, bank account, credit card, deposit, debt) with their specific properties

This commit is contained in:
“SamoilenkoVadym” 2025-03-02 19:50:51 +00:00
parent 0001b77052
commit a434d46b18
2 changed files with 170 additions and 0 deletions

View file

@ -0,0 +1,125 @@
//
// AccountType.swift
// Coinly
//
// Created by Vadym Samoilenko on 02/03/2025.
//
import Foundation
enum AccountType: String, Codable, CaseIterable {
case wallet = "Wallet" // Наличные/кошелек
case bankAccount = "Bank" // Банковский счет
case creditCard = "Credit" // Кредитная карта
case deposit = "Deposit" // Депозит
case debt = "Debt" // Долг
var icon: String {
switch self {
case .wallet: return "wallet.pass"
case .bankAccount: return "building.columns"
case .creditCard: return "creditcard"
case .deposit: return "banknote"
case .debt: return "exclamationmark.circle"
}
}
}
struct AccountModel: Identifiable, Codable {
let id: String
var name: String
var type: AccountType
var currency: AppSettings.Currency
var balance: Double
var initialBalance: Double
// Для кредитных карт
var creditLimit: Double?
var interestRate: Double?
var dueDate: Date?
// Для депозитов
var depositInterestRate: Double?
var depositEndDate: Date?
// Для долгов
var debtInterestRate: Double?
var debtDueDate: Date?
var creditorName: String?
init(
name: String,
type: AccountType,
currency: AppSettings.Currency,
balance: Double,
initialBalance: Double = 0,
creditLimit: Double? = nil,
interestRate: Double? = nil,
dueDate: Date? = nil,
depositInterestRate: Double? = nil,
depositEndDate: Date? = nil,
debtInterestRate: Double? = nil,
debtDueDate: Date? = nil,
creditorName: String? = nil
) {
self.id = UUID().uuidString
self.name = name
self.type = type
self.currency = currency
self.balance = balance
self.initialBalance = initialBalance
self.creditLimit = creditLimit
self.interestRate = interestRate
self.dueDate = dueDate
self.depositInterestRate = depositInterestRate
self.depositEndDate = depositEndDate
self.debtInterestRate = debtInterestRate
self.debtDueDate = debtDueDate
self.creditorName = creditorName
}
// Вычисляемые свойства
var availableCredit: Double? {
guard type == .creditCard, let limit = creditLimit else { return nil }
return limit - balance
}
var isOverdue: Bool {
guard let dueDate = dueDate ?? debtDueDate else { return false }
return Date() > dueDate
}
// Sample Data
static let sampleData = [
AccountModel(
name: "Cash Wallet",
type: .wallet,
currency: .usd,
balance: 500
),
AccountModel(
name: "Main Bank Account",
type: .bankAccount,
currency: .usd,
balance: 2500
),
AccountModel(
name: "Credit Card",
type: .creditCard,
currency: .usd,
balance: 1000,
creditLimit: 5000,
interestRate: 19.9,
dueDate: Calendar.current.date(byAdding: .day, value: 15, to: Date())
),
AccountModel(
name: "Savings Deposit",
type: .deposit,
currency: .usd,
balance: 10000,
depositInterestRate: 5.5,
depositEndDate: Calendar.current.date(byAdding: .month, value: 12, to: Date())
)
]
}

View file

@ -0,0 +1,45 @@
//
// AccountsStore.swift
// Coinly
//
// Created by Vadym Samoilenko on 02/03/2025.
//
import Foundation
class AccountsStore: ObservableObject {
@Published private(set) var accounts: [AccountModel] = AccountModel.sampleData
func addAccount(_ account: AccountModel) {
accounts.append(account)
}
func updateAccount(_ account: AccountModel) {
if let index = accounts.firstIndex(where: { $0.id == account.id }) {
accounts[index] = account
}
}
func deleteAccount(at indexSet: IndexSet) {
accounts.remove(atOffsets: indexSet)
}
func getAccount(by id: String) -> AccountModel? {
accounts.first { $0.id == id }
}
// Получение счетов по типу
func getAccounts(of type: AccountType) -> [AccountModel] {
accounts.filter { $0.type == type }
}
// Общий баланс всех счетов в выбранной валюте
func totalBalance(in currency: AppSettings.Currency) -> Double {
accounts.reduce(0) { total, account in
let settings = AppSettings.shared
let convertedBalance = settings.convert(account.balance, from: account.currency, to: currency)
return total + convertedBalance
}
}
}