Files
raspberry/iOS/Wallet/Sources/Inheritance/Service/InheritanceServiceSetup.swift
Jura Shikin 9b34d78319 WiP
2023-01-23 23:15:06 +03:00

134 lines
4.5 KiB
Swift

//
// InheritanceServiceSetup.swift
// Wallet
//
// Created by Igor on 15.03.2021.
// Copyright © 2021 AM. All rights reserved.
//
import Foundation
extension Common.Service.Provider.Key {
static let period = Self("period")
static let percent = Self("percent")
}
extension Inheritance.Service.Setup {
typealias Contract = EOSContract
typealias Model = Inheritance.Model.Share
typealias Token = Network.Model.Token
typealias Information = Inheritance.Model.Information
}
extension Inheritance.Service {
final class Setup: Common.Service.Provider {
var didUpdate: (() -> Void)?
var didReload: (() -> Void)?
let contract: Contract
var period: Int = 0 { didSet { didUpdate?() } }
private(set) var collection = [Model]()
init(object: Information?, contract: Contract) {
self.contract = contract
if let object = object {
period = object.inactive_period/(3600*24)
collection = object.inheritors
.compactMap({ $0 })
.map({ .init(
account: $0.inheritor,
didChangeAccount: didChangeAccount(),
value: $0.share.amount.toDouble(),
didChangeValue: didChangeValue()
)})
} else { add() }
}
}
}
extension Inheritance.Service.Setup {
var totalPercent: Double { collection.map({ $0.value ?? 0 }).reduce(0, +) }
var errors: [Key: String] {
[
.period: period > 3650 ? L10n.Inheritance.Error.Setup.period : nil,
.percent: totalPercent > 100 ? L10n.Inheritance.Error.Setup.sum : nil
].compactMapValues({ $0 })
}
var isValid: Bool {
Int(totalPercent) == 100
&& collection.filter({ !$0.account.isEmpty }).count == collection.count
&& (period > 0 && period <= 3650)
}
}
extension Inheritance.Service.Setup {
var canAdd: Bool { collection.count < 3 }
func add() {
guard canAdd else { return }
let value = totalPercent >= 100 ? nil : 100 - totalPercent
collection.append(.init(didChangeAccount: didChangeAccount(), value: value, didChangeValue: didChangeValue()))
didReload?()
}
func delete(share: Model) {
collection.removeAll(where: { $0.uuid == share.uuid })
didReload?()
}
}
extension Inheritance.Service.Setup {
func submit(privateKey: String, completion: @escaping Completion.Network) {
Network.Service.Blockchain.execute(actions: [
(contract, .updinhdate, [
"owner": Accounts().current?.name ?? "",
"inactive_period": "\(period*3600*24)"
]),
(contract, .updtokeninhs, Submit(inheritors: collection.map({ .init(share: $0) })))
], privateKeys: [privateKey]) { result in
switch result {
case .success(let txnId):
Accounts().messageShelf.activeBook?.fetchUntil(trxId: txnId) { _ in
completion(nil)
}
case .failure:
completion(.error(result))
}
}
}
}
extension Inheritance.Service.Setup {
private func didChangeAccount() -> (Model) -> Void { { _ in self.didUpdate?() } }
private func didChangeValue() -> (Model) -> Void { { [weak self] share in
guard let self else { return }
if self.collection.count == 2, var index = self.collection.lastIndex(where: { $0.uuid == share.uuid }) {
index += (index == 0 ? 1 : -1)
let value = 100 - (share.value ?? 0)
let other = self.collection[index]
self.collection.remove(at: index)
self.collection.insert(.init(
account: other.account,
didChangeAccount: self.didChangeAccount(),
value: value == 0 ? nil : value,
didChangeValue: self.didChangeValue()
), at: index)
self.didReload?()
} else {
self.didUpdate?()
}
} }
private struct Submit: Encodable {
struct Inheritor: Encodable {
let inheritor: String
let share: String
init(share: Inheritance.Model.Share) {
self.inheritor = share.account
self.share = (share.value ?? 0).toString(precision: 1, symbol: "PERCENT")
}
}
let owner = Accounts().current?.name ?? ""
let inheritors: [Inheritor]
}
}