235 lines
8.6 KiB
Swift
235 lines
8.6 KiB
Swift
//
|
|
// P2POrder.swift
|
|
// Wallet
|
|
//
|
|
// Created by Saveliy Stavitsky on 7/30/21.
|
|
// Copyright © 2021 AM. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import Resolver
|
|
import RealmSwift
|
|
|
|
enum P2POrderStatus: String, PersistableEnum, Codable {
|
|
case active = "available"
|
|
case inactive = "unavailable"
|
|
case closed = "closed"
|
|
}
|
|
|
|
// swiftlint:disable identifier_name
|
|
class P2PRating: EmbeddedObject, Codable {
|
|
@Persisted private var completed_deals: Int?
|
|
@Persisted private var failed_deals: Int?
|
|
|
|
var requests: Int { (completed_deals ?? 0) + (failed_deals ?? 0) }
|
|
var rating: Decimal? { requests > 0 ? Decimal(completed_deals ?? 0) / Decimal(requests) : nil }
|
|
}
|
|
|
|
class P2POrder: Object, Decodable {
|
|
@Persisted var id: Int
|
|
@Persisted(indexed: true) var idText: String
|
|
@Persisted var uuid: String
|
|
@Persisted(primaryKey: true) var uniqueId: String
|
|
@Persisted(indexed: true) var owner: String
|
|
@Persisted var contentType: P2P.Model.ContentType
|
|
@Persisted(indexed: true) var status: P2POrderStatus
|
|
@Persisted(indexed: true) var symbol: String
|
|
@Persisted var precision: Int
|
|
@Persisted var volume: Decimal128
|
|
@Persisted var needClose: Bool
|
|
@Persisted var insurance: Decimal128
|
|
@Persisted var min: Decimal128
|
|
@Persisted var max: Decimal128
|
|
var hasEqualAmount: Bool { min == max && (min == volume || volume == 0) }
|
|
@Persisted(indexed: true) var kind: P2P.Model.Kind
|
|
@Persisted var createdAt: Date
|
|
@Persisted var rating: P2PRating?
|
|
@Persisted var ratingValue: Decimal128?
|
|
|
|
@Persisted var currencyId: Int
|
|
@Persisted var rate: Decimal128
|
|
@Persisted var rateIsReversed: Bool
|
|
@Persisted var cardNumber: String?
|
|
@Persisted var paymentUrl: String?
|
|
@Persisted var walletNumber: String?
|
|
@Persisted var walletAddress: String?
|
|
|
|
@Persisted var blockchainId: Int?
|
|
@Persisted var paymentSystemId: Int?
|
|
@Persisted var countryId: Int?
|
|
@Persisted var cityId: Int?
|
|
@Persisted var bankIds: List<Int>
|
|
|
|
@Persisted var cardName: String?
|
|
@Persisted var cardDate: String?
|
|
@Persisted var cvv: String?
|
|
|
|
@Persisted var memo: String?
|
|
|
|
// swiftlint:disable identifier_name
|
|
enum CodingKeys: String, CodingKey {
|
|
case id = "order_id"
|
|
case uuid
|
|
case owner
|
|
case data_type
|
|
case status
|
|
case volume
|
|
case insurance
|
|
case volume_balance
|
|
case insurance_balance
|
|
case min_package
|
|
case max_package
|
|
case order_type
|
|
case created_at
|
|
case rating
|
|
|
|
case currency_id
|
|
case rate
|
|
case rateIsReversed = "is_cash_rate"
|
|
case card_number
|
|
case payment_url
|
|
case wallet_number
|
|
case wallet_address
|
|
case blockchain_id
|
|
case payment_system_id
|
|
case country_id
|
|
case city_id
|
|
case bank_ids
|
|
case card_name
|
|
case card_expiry
|
|
case cvv
|
|
case memo
|
|
}
|
|
|
|
override required init() { }
|
|
|
|
required init(from decoder: Decoder) throws {
|
|
super.init()
|
|
|
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
if let orderId = Int(try values.decode(String.self, forKey: .id)) {
|
|
id = orderId
|
|
idText = "\(orderId)"
|
|
} else {
|
|
throw "P2POrder decoding error order id: \(try values.decode(String.self, forKey: .id)) is not Integer"
|
|
}
|
|
uuid = try values.decode(String.self, forKey: .uuid)
|
|
owner = try values.decode(String.self, forKey: .owner)
|
|
contentType = try values.decode(P2P.Model.ContentType.self, forKey: .data_type)
|
|
status = try values.decode(P2POrderStatus.self, forKey: .status)
|
|
symbol = try values.decode(String.self, forKey: .volume).symbol
|
|
precision = try values.decode(String.self, forKey: .volume).amount.precision
|
|
uniqueId = "\(symbol)#\(id)"
|
|
volume = try Decimal128(string: try values.decode(String.self, forKey: .volume_balance).amount)
|
|
insurance = try Decimal128(string: try values.decode(String.self, forKey: .insurance_balance).amount)
|
|
min = try Decimal128(string: try values.decode(String.self, forKey: .min_package).amount)
|
|
max = try Decimal128(string: try values.decode(String.self, forKey: .max_package).amount)
|
|
needClose = volume < min
|
|
// orderType = (try? values.decode(String.self, forKey: .order_type)) == "BUY" ? .buy : .sell
|
|
kind = (try? values.decode(String.self, forKey: .order_type))?.uppercased() ?? "BUY" == "BUY"
|
|
? .buy : .sell
|
|
|
|
createdAt = try values.decode(String.self, forKey: .created_at).serverDate() ?? Date()
|
|
rating = try? values.decode(P2PRating.self, forKey: .rating)
|
|
ratingValue = rating?.rating.map({ Decimal128(value: $0) })
|
|
|
|
currencyId = try values.decode(Int.self, forKey: .currency_id)
|
|
rate = try Decimal128(string: try values.decode(String.self, forKey: .rate))
|
|
rateIsReversed = !((try? values.decode(Bool.self, forKey: .rateIsReversed)) ?? true)
|
|
cardNumber = try? values.decode(String.self, forKey: .card_number)
|
|
paymentUrl = try? values.decode(String.self, forKey: .payment_url)
|
|
walletNumber = try? values.decode(String.self, forKey: .wallet_number)
|
|
walletAddress = try? values.decode(String.self, forKey: .wallet_address)
|
|
|
|
blockchainId = try? values.decode(Int.self, forKey: .blockchain_id)
|
|
paymentSystemId = try? values.decode(Int.self, forKey: .payment_system_id)
|
|
countryId = try? values.decode(Int.self, forKey: .country_id)
|
|
cityId = try? values.decode(Int.self, forKey: .city_id)
|
|
|
|
bankIds = List<Int>()
|
|
bankIds.append(objectsIn: (try? values.decode([Int].self, forKey: .bank_ids)) ?? [])
|
|
|
|
cardName = try? values.decode(String.self, forKey: .card_name)
|
|
cardDate = try? values.decode(String.self, forKey: .card_expiry)
|
|
cvv = try? values.decode(String.self, forKey: .cvv)
|
|
|
|
memo = try? values.decode(String.self, forKey: .memo)
|
|
}
|
|
}
|
|
|
|
extension P2POrder {
|
|
var currency: P2PCurrency? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PCurrency.self, forPrimaryKey: currencyId)
|
|
}
|
|
var blockchain: P2PBlockchain? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PBlockchain.self, forPrimaryKey: blockchainId ?? -1)
|
|
}
|
|
var paymentSystem: P2PPaymentSystem? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PPaymentSystem.self, forPrimaryKey: paymentSystemId ?? -1)
|
|
}
|
|
var country: P2PCountry? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PCountry.self, forPrimaryKey: countryId ?? -1)
|
|
}
|
|
var city: P2PCity? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PCity.self, forPrimaryKey: cityId ?? -1)
|
|
}
|
|
var bank: P2PBank? {
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PBank.self, forPrimaryKey: bankIds.first ?? -1)
|
|
}
|
|
var banks: [P2PBank] {
|
|
bankIds.compactMap({
|
|
Resolver.resolve(Realm.self, name: .realmP2PLists)
|
|
.object(ofType: P2PBank.self, forPrimaryKey: $0)
|
|
})
|
|
}
|
|
}
|
|
|
|
extension P2POrder {
|
|
#warning("""
|
|
Fix this use
|
|
@InjectedOptional(name: .realmOrders) var realm: Realm
|
|
try? realm.write {
|
|
realm.delete(self)
|
|
}
|
|
where needed after swift compiler bug fixed in swift 5.5
|
|
https://forums.swift.org/t/segmentation-fault-11-with-local-property-wrappers/47905/3
|
|
""")
|
|
func delete() throws {
|
|
if let realm = self.realm?.thaw(), let order = self.thaw() {
|
|
try realm.write {
|
|
realm.delete(order)
|
|
}
|
|
}
|
|
}
|
|
|
|
#warning("""
|
|
Fix this use
|
|
@InjectedOptional(name: .realmOrders) var realm: Realm
|
|
try? realm.write {
|
|
self.status = .active
|
|
}
|
|
where needed after swift compiler bug fixed in swift 5.5
|
|
https://forums.swift.org/t/segmentation-fault-11-with-local-property-wrappers/47905/3
|
|
""")
|
|
func modify(_ action: (P2POrder) -> Void) throws {
|
|
if let realm = self.realm?.thaw(), let order = self.thaw() {
|
|
try realm.write {
|
|
action(order)
|
|
}
|
|
} else if self.realm == nil {
|
|
@OptionalInjected(name: .realmOrders) var realm: Realm?
|
|
try realm?.write {
|
|
if let order = realm?.object(ofType: P2POrder.self, forPrimaryKey: self.uniqueId) {
|
|
action(order)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|