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:
parent
0001b77052
commit
a434d46b18
2 changed files with 170 additions and 0 deletions
125
Coinly/Features/Models/AccountModel.swift
Normal file
125
Coinly/Features/Models/AccountModel.swift
Normal 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())
|
||||
)
|
||||
]
|
||||
}
|
||||
45
Coinly/Features/Models/AccountsStore.swift
Normal file
45
Coinly/Features/Models/AccountsStore.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue