// // 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] } }