|
@ -11,343 +11,351 @@ import RxCocoa |
|
|
import CoreLocation |
|
|
import CoreLocation |
|
|
|
|
|
|
|
|
class NewRegisterStep1Presenter: ViewModelType { |
|
|
class NewRegisterStep1Presenter: ViewModelType { |
|
|
enum Step: Int { |
|
|
|
|
|
case innerStep1 |
|
|
|
|
|
case innerStep2 |
|
|
|
|
|
case innerStep3 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var interactor: NewRegisterStep1InteractorInput? |
|
|
|
|
|
var wireframe: NewRegisterStep1WireframeInput? |
|
|
|
|
|
|
|
|
|
|
|
struct Input { |
|
|
|
|
|
let viewWillAppear: Driver<Void> |
|
|
|
|
|
let sendLocation: Driver<CLLocation> |
|
|
|
|
|
|
|
|
|
|
|
let name: Driver<String> |
|
|
|
|
|
let gender: Driver<KeyValue?> |
|
|
|
|
|
let dob: Driver<String> |
|
|
|
|
|
let email: Driver<String> |
|
|
|
|
|
let city: Driver<KeyValue?> |
|
|
|
|
|
let address: Driver<String> |
|
|
|
|
|
let occupation: Driver<KeyValue?> |
|
|
|
|
|
let isValidPersonalInfo: Driver<Bool> |
|
|
|
|
|
let personalInfoSave: Driver<Void> |
|
|
|
|
|
let editingPersonalInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let bankName: Driver<KJBank?> |
|
|
|
|
|
let bankAccount: Driver<String> |
|
|
|
|
|
let passportNumber: Driver<String> |
|
|
|
|
|
let passportIssueDate: Driver<String> |
|
|
|
|
|
let passportExpiryDate: Driver<String> |
|
|
|
|
|
let anotherIDType: Driver<KeyValue?> |
|
|
|
|
|
let anotherIDNumber: Driver<String> |
|
|
|
|
|
let anotherIDIssueDate: Driver<String> |
|
|
|
|
|
let anotherIDExpiryDate: Driver<String> |
|
|
|
|
|
|
|
|
|
|
|
let branch: Driver<KeyValue?> |
|
|
|
|
|
let referralCode: Driver<String> |
|
|
|
|
|
let isValidPrimaryInfo: Driver<Bool> |
|
|
|
|
|
let primaryInfoSave: Driver<Void> |
|
|
|
|
|
let editingPrimaryInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let passportImage: Driver<String?> |
|
|
|
|
|
let anotherIDImage: Driver<String?> |
|
|
|
|
|
let isValidPictures: Driver<Bool> |
|
|
|
|
|
let editingPictureInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let submit: Driver<Void> |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct Output { |
|
|
|
|
|
let isError: Driver<Error> |
|
|
|
|
|
let isProgress: Driver<Bool> |
|
|
|
|
|
let gpsAddress: Driver<String> |
|
|
|
|
|
let model: Driver<KYCInformation> |
|
|
|
|
|
|
|
|
|
|
|
let cities: Driver<[KeyValue]?> |
|
|
|
|
|
let banks: Driver<[KJBank]?> |
|
|
|
|
|
let idTypes: Driver<[KeyValue]?> |
|
|
|
|
|
let branches: Driver<[KeyValue]?> |
|
|
|
|
|
let occupations: Driver<[KeyValue]?> |
|
|
|
|
|
|
|
|
|
|
|
let isSetPersonalInformation: Driver<Bool> |
|
|
|
|
|
let isSetPrimaryInformation: Driver<Bool> |
|
|
|
|
|
let isSetPictureInformation: Driver<Bool> |
|
|
|
|
|
|
|
|
|
|
|
let storedSuccess: Driver<String> |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private let disposeBag = DisposeBag() |
|
|
|
|
|
|
|
|
|
|
|
private let progressLinker = PublishSubject<Bool>() |
|
|
|
|
|
private let errorLinker = PublishSubject<Error>() |
|
|
|
|
|
private let gpsAddress = PublishSubject<String>() |
|
|
|
|
|
private let model = PublishSubject<KYCInformation>() |
|
|
|
|
|
|
|
|
|
|
|
private var storedPersonalInfo = PublishSubject<PersonalInformation?>() |
|
|
|
|
|
private var storedPrimaryInfo = PublishSubject<PrimaryInformation?>() |
|
|
|
|
|
private var storedPictureInformation = PublishSubject<PictureInformation?>() |
|
|
|
|
|
private let storedSuccess = PublishSubject<String>() |
|
|
|
|
|
|
|
|
|
|
|
func transform(input: Input) -> Output { |
|
|
|
|
|
let newPersonalInfo = Driver.combineLatest( |
|
|
|
|
|
input.isValidPersonalInfo, |
|
|
|
|
|
Driver.combineLatest( |
|
|
|
|
|
input.name, |
|
|
|
|
|
input.gender, |
|
|
|
|
|
input.dob, |
|
|
|
|
|
input.email, |
|
|
|
|
|
input.city, |
|
|
|
|
|
input.address, |
|
|
|
|
|
input.occupation, |
|
|
|
|
|
model.map {$0.personalInformation?.nativeCountry}.asDriverOnErrorJustComplete() |
|
|
|
|
|
).map {(name, gender, dob, email, city, address, occupation, nativeCountry) -> PersonalInformation in |
|
|
|
|
|
return PersonalInformation( |
|
|
|
|
|
fullName: name, |
|
|
|
|
|
gender: gender?.id, |
|
|
|
|
|
dob: dob, |
|
|
|
|
|
email: email, |
|
|
|
|
|
city: city?.id, |
|
|
|
|
|
address: address, |
|
|
|
|
|
occupation: occupation?.id, |
|
|
|
|
|
nativeCountry: nativeCountry |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
.map { (isValid, info) -> PersonalInformation? in |
|
|
|
|
|
return isValid ? info : nil |
|
|
|
|
|
|
|
|
enum Step: Int { |
|
|
|
|
|
case innerStep1 |
|
|
|
|
|
case innerStep2 |
|
|
|
|
|
case innerStep3 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let newPrimaryInfo = Driver.combineLatest( |
|
|
|
|
|
Driver.combineLatest( |
|
|
|
|
|
input.isValidPrimaryInfo, |
|
|
|
|
|
input.bankName, |
|
|
|
|
|
input.bankAccount, |
|
|
|
|
|
input.passportNumber, |
|
|
|
|
|
input.passportIssueDate, |
|
|
|
|
|
input.passportExpiryDate |
|
|
|
|
|
).map { (isValid, bank, account, passportNumber, passportIssue, passportExpiry) -> |
|
|
|
|
|
PrimaryInformation? in return isValid ? PrimaryInformation( |
|
|
|
|
|
bankName: bank?.value, |
|
|
|
|
|
bankID: bank?.id, |
|
|
|
|
|
bankAccount: account, |
|
|
|
|
|
passportNumber: passportNumber, |
|
|
|
|
|
passportIssueDate: passportIssue, |
|
|
|
|
|
passportExpiryDate: passportExpiry, |
|
|
|
|
|
anotherIDType: nil, |
|
|
|
|
|
anotherIDNumber: nil, |
|
|
|
|
|
anotherIDIssueDate: nil, |
|
|
|
|
|
anotherIDExpiryDate: nil, |
|
|
|
|
|
branchID: nil, |
|
|
|
|
|
refferalCode: nil |
|
|
|
|
|
) : nil |
|
|
|
|
|
}, |
|
|
|
|
|
input.anotherIDType, |
|
|
|
|
|
input.anotherIDNumber, |
|
|
|
|
|
input.anotherIDIssueDate, |
|
|
|
|
|
input.anotherIDExpiryDate, |
|
|
|
|
|
input.branch, |
|
|
|
|
|
input.referralCode |
|
|
|
|
|
).map { (info, idType, idNumber, issueDate, expiryDate, branch, referralCode) -> PrimaryInformation? in |
|
|
|
|
|
var primaryInfo = info |
|
|
|
|
|
primaryInfo?.anotherIDType = idType?.id ?? "" |
|
|
|
|
|
primaryInfo?.anotherIDNumber = idNumber |
|
|
|
|
|
primaryInfo?.anotherIDIssueDate = issueDate |
|
|
|
|
|
primaryInfo?.anotherIDExpiryDate = expiryDate |
|
|
|
|
|
primaryInfo?.branchID = branch?.id |
|
|
|
|
|
primaryInfo?.refferalCode = referralCode |
|
|
|
|
|
return primaryInfo |
|
|
|
|
|
|
|
|
var interactor: NewRegisterStep1InteractorInput? |
|
|
|
|
|
var wireframe: NewRegisterStep1WireframeInput? |
|
|
|
|
|
|
|
|
|
|
|
struct Input { |
|
|
|
|
|
let viewWillAppear: Driver<Void> |
|
|
|
|
|
let sendLocation: Driver<CLLocation> |
|
|
|
|
|
|
|
|
|
|
|
let name: Driver<String> |
|
|
|
|
|
let gender: Driver<KeyValue?> |
|
|
|
|
|
let dob: Driver<String> |
|
|
|
|
|
let email: Driver<String> |
|
|
|
|
|
let city: Driver<KeyValue?> |
|
|
|
|
|
let address: Driver<String> |
|
|
|
|
|
let occupation: Driver<KeyValue?> |
|
|
|
|
|
let isValidPersonalInfo: Driver<Bool> |
|
|
|
|
|
let personalInfoSave: Driver<Void> |
|
|
|
|
|
let editingPersonalInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let bankName: Driver<KJBank?> |
|
|
|
|
|
let bankAccount: Driver<String> |
|
|
|
|
|
let passportNumber: Driver<String> |
|
|
|
|
|
let passportIssueDate: Driver<String> |
|
|
|
|
|
let passportExpiryDate: Driver<String> |
|
|
|
|
|
let anotherIDType: Driver<KeyValue?> |
|
|
|
|
|
let anotherIDNumber: Driver<String> |
|
|
|
|
|
let anotherIDIssueDate: Driver<String> |
|
|
|
|
|
let anotherIDExpiryDate: Driver<String> |
|
|
|
|
|
|
|
|
|
|
|
let branch: Driver<KeyValue?> |
|
|
|
|
|
let referralCode: Driver<String> |
|
|
|
|
|
let isValidPrimaryInfo: Driver<Bool> |
|
|
|
|
|
let primaryInfoSave: Driver<Void> |
|
|
|
|
|
let editingPrimaryInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let passportImage: Driver<String?> |
|
|
|
|
|
let anotherIDImage: Driver<String?> |
|
|
|
|
|
let isValidPictures: Driver<Bool> |
|
|
|
|
|
let editingPictureInfo: Driver<Void> |
|
|
|
|
|
|
|
|
|
|
|
let submit: Driver<Void> |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let newPicturesInfo = Driver.combineLatest( |
|
|
|
|
|
input.isValidPictures, |
|
|
|
|
|
input.passportImage, |
|
|
|
|
|
input.anotherIDImage |
|
|
|
|
|
).map { (isValid, passportImage, anotherImage) -> PictureInformation? in |
|
|
|
|
|
return isValid ? PictureInformation( |
|
|
|
|
|
passportPicture: passportImage, |
|
|
|
|
|
anotherIDPicture: anotherImage |
|
|
|
|
|
) : nil |
|
|
|
|
|
|
|
|
struct Output { |
|
|
|
|
|
let isError: Driver<Error> |
|
|
|
|
|
let isProgress: Driver<Bool> |
|
|
|
|
|
let gpsAddress: Driver<String> |
|
|
|
|
|
let model: Driver<KYCInformation> |
|
|
|
|
|
|
|
|
|
|
|
let cities: Driver<[KeyValue]?> |
|
|
|
|
|
let banks: Driver<[KJBank]?> |
|
|
|
|
|
let idTypes: Driver<[KeyValue]?> |
|
|
|
|
|
let branches: Driver<[KeyValue]?> |
|
|
|
|
|
let occupations: Driver<[KeyValue]?> |
|
|
|
|
|
|
|
|
|
|
|
let isSetPersonalInformation: Driver<Bool> |
|
|
|
|
|
let isSetPrimaryInformation: Driver<Bool> |
|
|
|
|
|
let isSetPictureInformation: Driver<Bool> |
|
|
|
|
|
let storePrimarySuccess: Driver<Bool> |
|
|
|
|
|
let storedSuccess: Driver<String> |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let isSetPersonalInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPersonalInfo, storedPersonalInfo.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map { $0 && $1 != nil } |
|
|
|
|
|
|
|
|
|
|
|
let isSetPrimaryInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPrimaryInfo, storedPrimaryInfo.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map { $0 && $1 != nil } |
|
|
|
|
|
|
|
|
|
|
|
let isSetPictureInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPictures, storedPictureInformation.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map {$0 && $1 != nil} |
|
|
|
|
|
|
|
|
|
|
|
input.viewWillAppear.drive(onNext: { [weak self] in |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.fetchInformation() |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.sendLocation.drive(onNext: { [weak self] in |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
let geocoder = CLGeocoder() |
|
|
|
|
|
let locale = Locale(identifier: "en-US") |
|
|
|
|
|
|
|
|
|
|
|
geocoder.reverseGeocodeLocation($0, preferredLocale: locale) {(placemarks, error) in |
|
|
|
|
|
if let error = error { |
|
|
|
|
|
self?.progressLinker.onNext(false) |
|
|
|
|
|
self?.errorLinker.onNext(error) |
|
|
|
|
|
|
|
|
private let disposeBag = DisposeBag() |
|
|
|
|
|
|
|
|
|
|
|
private let progressLinker = PublishSubject<Bool>() |
|
|
|
|
|
private let errorLinker = PublishSubject<Error>() |
|
|
|
|
|
private let gpsAddress = PublishSubject<String>() |
|
|
|
|
|
private let model = PublishSubject<KYCInformation>() |
|
|
|
|
|
|
|
|
|
|
|
private var storedPersonalInfo = PublishSubject<PersonalInformation?>() |
|
|
|
|
|
private var storedPrimaryInfo = PublishSubject<PrimaryInformation?>() |
|
|
|
|
|
private var storedPictureInformation = PublishSubject<PictureInformation?>() |
|
|
|
|
|
private let storedPrimarySuccess = PublishSubject<String?>() |
|
|
|
|
|
private let storedSuccess = PublishSubject<String>() |
|
|
|
|
|
|
|
|
|
|
|
func transform(input: Input) -> Output { |
|
|
|
|
|
let newPersonalInfo = Driver.combineLatest( |
|
|
|
|
|
input.isValidPersonalInfo, |
|
|
|
|
|
Driver.combineLatest( |
|
|
|
|
|
input.name, |
|
|
|
|
|
input.gender, |
|
|
|
|
|
input.dob, |
|
|
|
|
|
input.email, |
|
|
|
|
|
input.city, |
|
|
|
|
|
input.address, |
|
|
|
|
|
input.occupation, |
|
|
|
|
|
model.map {$0.personalInformation?.nativeCountry}.asDriverOnErrorJustComplete() |
|
|
|
|
|
).map {(name, gender, dob, email, city, address, occupation, nativeCountry) -> PersonalInformation in |
|
|
|
|
|
return PersonalInformation( |
|
|
|
|
|
fullName: name, |
|
|
|
|
|
gender: gender?.id, |
|
|
|
|
|
dob: dob, |
|
|
|
|
|
email: email, |
|
|
|
|
|
city: city?.id, |
|
|
|
|
|
address: address, |
|
|
|
|
|
occupation: occupation?.id, |
|
|
|
|
|
nativeCountry: nativeCountry |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
.map { (isValid, info) -> PersonalInformation? in |
|
|
|
|
|
return isValid ? info : nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if let address: [CLPlacemark] = placemarks { |
|
|
|
|
|
let name = address.last?.name ?? "" |
|
|
|
|
|
let locality = address.last?.locality ?? "" |
|
|
|
|
|
self?.progressLinker.onNext(false) |
|
|
|
|
|
|
|
|
|
|
|
let mergedAddress = "\(name) \(locality)"//.extract(regex: "[A-Z0-9a-z\\s]") |
|
|
|
|
|
self?.gpsAddress.onNext(mergedAddress) |
|
|
|
|
|
|
|
|
let newPrimaryInfo = Driver.combineLatest( |
|
|
|
|
|
Driver.combineLatest( |
|
|
|
|
|
input.isValidPrimaryInfo, |
|
|
|
|
|
input.bankName, |
|
|
|
|
|
input.bankAccount, |
|
|
|
|
|
input.passportNumber, |
|
|
|
|
|
input.passportIssueDate, |
|
|
|
|
|
input.passportExpiryDate |
|
|
|
|
|
).map { (isValid, bank, account, passportNumber, passportIssue, passportExpiry) -> |
|
|
|
|
|
PrimaryInformation? in return isValid ? PrimaryInformation( |
|
|
|
|
|
bankName: bank?.value, |
|
|
|
|
|
bankID: bank?.id, |
|
|
|
|
|
bankAccount: account, |
|
|
|
|
|
passportNumber: passportNumber, |
|
|
|
|
|
passportIssueDate: passportIssue, |
|
|
|
|
|
passportExpiryDate: passportExpiry, |
|
|
|
|
|
anotherIDType: nil, |
|
|
|
|
|
anotherIDNumber: nil, |
|
|
|
|
|
anotherIDIssueDate: nil, |
|
|
|
|
|
anotherIDExpiryDate: nil, |
|
|
|
|
|
branchID: nil, |
|
|
|
|
|
refferalCode: nil |
|
|
|
|
|
) : nil |
|
|
|
|
|
}, |
|
|
|
|
|
input.anotherIDType, |
|
|
|
|
|
input.anotherIDNumber, |
|
|
|
|
|
input.anotherIDIssueDate, |
|
|
|
|
|
input.anotherIDExpiryDate, |
|
|
|
|
|
input.branch, |
|
|
|
|
|
input.referralCode |
|
|
|
|
|
).map { (info, idType, idNumber, issueDate, expiryDate, branch, referralCode) -> PrimaryInformation? in |
|
|
|
|
|
var primaryInfo = info |
|
|
|
|
|
primaryInfo?.anotherIDType = idType?.id ?? "" |
|
|
|
|
|
primaryInfo?.anotherIDNumber = idNumber |
|
|
|
|
|
primaryInfo?.anotherIDIssueDate = issueDate |
|
|
|
|
|
primaryInfo?.anotherIDExpiryDate = expiryDate |
|
|
|
|
|
primaryInfo?.branchID = branch?.id |
|
|
|
|
|
primaryInfo?.refferalCode = referralCode |
|
|
|
|
|
return primaryInfo |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPersonalInfo |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPersonalInfo.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPersonalInfo.onNext(nil) |
|
|
|
|
|
|
|
|
let newPicturesInfo = Driver.combineLatest( |
|
|
|
|
|
input.isValidPictures, |
|
|
|
|
|
input.passportImage, |
|
|
|
|
|
input.anotherIDImage |
|
|
|
|
|
).map { (isValid, passportImage, anotherImage) -> PictureInformation? in |
|
|
|
|
|
return isValid ? PictureInformation( |
|
|
|
|
|
passportPicture: passportImage, |
|
|
|
|
|
anotherIDPicture: anotherImage |
|
|
|
|
|
) : nil |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPrimaryInfo |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPrimaryInfo.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPrimaryInfo.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPictureInfo |
|
|
|
|
|
.withLatestFrom(newPicturesInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPictureInformation.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPictureInformation.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.personalInfoSave.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep1.rawValue, |
|
|
|
|
|
personalInformation: $0, |
|
|
|
|
|
primaryInformation: nil, |
|
|
|
|
|
pictures: nil |
|
|
|
|
|
) |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.primaryInfoSave |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { ($0, $1) } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep2.rawValue, |
|
|
|
|
|
personalInformation: $0, |
|
|
|
|
|
primaryInformation: $1, |
|
|
|
|
|
pictures: nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let isSetPersonalInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPersonalInfo, storedPersonalInfo.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map { $0 && $1 != nil } |
|
|
|
|
|
|
|
|
|
|
|
let isSetPrimaryInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPrimaryInfo, storedPrimaryInfo.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map { $0 && $1 != nil } |
|
|
|
|
|
|
|
|
|
|
|
let isSetPictureInformation = Driver |
|
|
|
|
|
.combineLatest(input.isValidPictures, storedPictureInformation.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map {$0 && $1 != nil} |
|
|
|
|
|
|
|
|
|
|
|
let storePrimarySuccess = Driver |
|
|
|
|
|
.combineLatest(input.isValidPrimaryInfo, storedPrimarySuccess.asDriverOnErrorJustComplete()) |
|
|
|
|
|
.map {$0 && $1 != nil} |
|
|
|
|
|
|
|
|
|
|
|
input.viewWillAppear.drive(onNext: { [weak self] in |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.fetchInformation() |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.sendLocation.drive(onNext: { [weak self] in |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
let geocoder = CLGeocoder() |
|
|
|
|
|
let locale = Locale(identifier: "en-US") |
|
|
|
|
|
|
|
|
|
|
|
geocoder.reverseGeocodeLocation($0, preferredLocale: locale) {(placemarks, error) in |
|
|
|
|
|
if let error = error { |
|
|
|
|
|
self?.progressLinker.onNext(false) |
|
|
|
|
|
self?.errorLinker.onNext(error) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if let address: [CLPlacemark] = placemarks { |
|
|
|
|
|
let name = address.last?.name ?? "" |
|
|
|
|
|
let locality = address.last?.locality ?? "" |
|
|
|
|
|
self?.progressLinker.onNext(false) |
|
|
|
|
|
|
|
|
|
|
|
let mergedAddress = "\(name) \(locality)"//.extract(regex: "[A-Z0-9a-z\\s]") |
|
|
|
|
|
self?.gpsAddress.onNext(mergedAddress) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPersonalInfo |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPersonalInfo.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPersonalInfo.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPrimaryInfo |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPrimaryInfo.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPrimaryInfo.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.editingPictureInfo |
|
|
|
|
|
.withLatestFrom(newPicturesInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(storedPictureInformation.asDriverOnErrorJustComplete()) {($0, $1)} |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
guard let new = $0, let stored = $1 else { return } |
|
|
|
|
|
if new != stored { |
|
|
|
|
|
self?.storedPictureInformation.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
.disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.personalInfoSave.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep1.rawValue, |
|
|
|
|
|
personalInformation: $0, |
|
|
|
|
|
primaryInformation: nil, |
|
|
|
|
|
pictures: nil |
|
|
|
|
|
) |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.primaryInfoSave |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { ($0, $1) } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep2.rawValue, |
|
|
|
|
|
personalInformation: $0, |
|
|
|
|
|
primaryInformation: $1, |
|
|
|
|
|
pictures: nil |
|
|
|
|
|
) |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.submit |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { ($0, $1) } |
|
|
|
|
|
.withLatestFrom(newPicturesInfo) { ($0, $1) } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep3.rawValue, |
|
|
|
|
|
personalInformation: $0.0, |
|
|
|
|
|
primaryInformation: $0.1, |
|
|
|
|
|
pictures: $1 |
|
|
|
|
|
) |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
return Output( |
|
|
|
|
|
isError: errorLinker.asDriverOnErrorJustComplete(), |
|
|
|
|
|
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|
|
|
|
|
gpsAddress: gpsAddress.asDriverOnErrorJustComplete(), |
|
|
|
|
|
model: model.asDriverOnErrorJustComplete(), |
|
|
|
|
|
cities: model.map {$0.cities}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
banks: model.map {$0.banks}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
idTypes: model.map {$0.idTypes}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
branches: model.map {$0.branches}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
occupations: model.map {$0.occupations}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
isSetPersonalInformation: isSetPersonalInformation, |
|
|
|
|
|
isSetPrimaryInformation: isSetPrimaryInformation, |
|
|
|
|
|
isSetPictureInformation: isSetPictureInformation, |
|
|
|
|
|
storePrimarySuccess: storePrimarySuccess, |
|
|
|
|
|
storedSuccess: storedSuccess.asDriverOnErrorJustComplete() |
|
|
) |
|
|
) |
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
input.submit |
|
|
|
|
|
.withLatestFrom(newPersonalInfo) { $1 } |
|
|
|
|
|
.withLatestFrom(newPrimaryInfo) { ($0, $1) } |
|
|
|
|
|
.withLatestFrom(newPicturesInfo) { ($0, $1) } |
|
|
|
|
|
.drive(onNext: {[weak self] in |
|
|
|
|
|
let saveModel = KYCSave( |
|
|
|
|
|
type: Step.innerStep3.rawValue, |
|
|
|
|
|
personalInformation: $0.0, |
|
|
|
|
|
primaryInformation: $0.1, |
|
|
|
|
|
pictures: $1 |
|
|
|
|
|
) |
|
|
|
|
|
self?.progressLinker.onNext(true) |
|
|
|
|
|
self?.interactor?.saveInformation(with: saveModel) |
|
|
|
|
|
}).disposed(by: disposeBag) |
|
|
|
|
|
|
|
|
|
|
|
return Output( |
|
|
|
|
|
isError: errorLinker.asDriverOnErrorJustComplete(), |
|
|
|
|
|
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|
|
|
|
|
gpsAddress: gpsAddress.asDriverOnErrorJustComplete(), |
|
|
|
|
|
model: model.asDriverOnErrorJustComplete(), |
|
|
|
|
|
cities: model.map {$0.cities}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
banks: model.map {$0.banks}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
idTypes: model.map {$0.idTypes}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
branches: model.map {$0.branches}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
occupations: model.map {$0.occupations}.asDriverOnErrorJustComplete(), |
|
|
|
|
|
isSetPersonalInformation: isSetPersonalInformation, |
|
|
|
|
|
isSetPrimaryInformation: isSetPrimaryInformation, |
|
|
|
|
|
isSetPictureInformation: isSetPictureInformation, |
|
|
|
|
|
storedSuccess: storedSuccess.asDriverOnErrorJustComplete() |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// MARK: NewRegisterStep1 interactor output interface |
|
|
// MARK: NewRegisterStep1 interactor output interface |
|
|
extension NewRegisterStep1Presenter: NewRegisterStep1InteractorOutput { |
|
|
extension NewRegisterStep1Presenter: NewRegisterStep1InteractorOutput { |
|
|
func setModel(with model: KYCInformation) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
self.model.onNext(model) |
|
|
|
|
|
|
|
|
|
|
|
guard let personalInformation = model.personalInformation, !personalInformation.isHasEmptyValue() else { |
|
|
|
|
|
storedPersonalInfo.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func setModel(with model: KYCInformation) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
self.model.onNext(model) |
|
|
|
|
|
guard let personalInformation = model.personalInformation, !personalInformation.isHasEmptyValue() else { |
|
|
|
|
|
storedPersonalInfo.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
storedPersonalInfo.onNext(model.personalInformation) |
|
|
|
|
|
|
|
|
storedPersonalInfo.onNext(model.personalInformation) |
|
|
|
|
|
|
|
|
guard let primaryInformation = model.primaryInformation, !primaryInformation.isHasEmptyValue() else { |
|
|
|
|
|
storedPrimaryInfo.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
guard let primaryInformation = model.primaryInformation, !primaryInformation.isHasEmptyValue() else { |
|
|
|
|
|
storedPrimaryInfo.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
storedPrimaryInfo.onNext(primaryInformation) |
|
|
|
|
|
|
|
|
storedPrimaryInfo.onNext(primaryInformation) |
|
|
|
|
|
|
|
|
guard let pictures = model.pictures, !pictures.isHasEmptyValue() else { |
|
|
|
|
|
storedPictureInformation.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
guard let pictures = model.pictures, !pictures.isHasEmptyValue() else { |
|
|
|
|
|
storedPictureInformation.onNext(nil) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
storedPictureInformation.onNext(pictures) |
|
|
} |
|
|
} |
|
|
storedPictureInformation.onNext(pictures) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func setSaveResult(with storedModel: KYCSave?, message: String) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
|
|
|
|
|
|
guard let storedModel = storedModel, let type = Step(rawValue: storedModel.type) else { return } |
|
|
|
|
|
|
|
|
|
|
|
switch type { |
|
|
|
|
|
case .innerStep1: |
|
|
|
|
|
storedPersonalInfo.onNext(storedModel.personalInformation) |
|
|
|
|
|
case .innerStep2: |
|
|
|
|
|
storedPrimaryInfo.onNext(storedModel.primaryInformation) |
|
|
|
|
|
case .innerStep3: |
|
|
|
|
|
storedPictureInformation.onNext(storedModel.pictures) |
|
|
|
|
|
storedSuccess.onNext(message) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func setSaveResult(with storedModel: KYCSave?, message: String) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
|
|
|
|
|
|
guard let storedModel = storedModel, let type = Step(rawValue: storedModel.type) else { return } |
|
|
|
|
|
switch type { |
|
|
|
|
|
case .innerStep1: |
|
|
|
|
|
storedPersonalInfo.onNext(storedModel.personalInformation) |
|
|
|
|
|
case .innerStep2: |
|
|
|
|
|
storedPrimaryInfo.onNext(storedModel.primaryInformation) |
|
|
|
|
|
storedPrimarySuccess.onNext(message) |
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { |
|
|
|
|
|
self.storedPrimarySuccess.onNext(nil) |
|
|
|
|
|
} |
|
|
|
|
|
case .innerStep3: |
|
|
|
|
|
storedPictureInformation.onNext(storedModel.pictures) |
|
|
|
|
|
storedSuccess.onNext(message) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func setError(with error: Error) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
errorLinker.onNext(error) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func setError(with error: Error) { |
|
|
|
|
|
progressLinker.onNext(false) |
|
|
|
|
|
errorLinker.onNext(error) |
|
|
|
|
|
} |
|
|
} |
|
|
} |