// // KYCViewModel.swift // GMERemittance // // Created by Sujal on 12/20/17. // Copyright © 2017 Gobal Money Express Co. Ltd. All rights reserved. // import Foundation import SwiftyJSON class KYCViewModel: SignUpViewModel { override init() { dateFormatter = DateFormatter() dateFormatter.dateFormat = "MM/dd/yyyy" } let minAgeRequirement: Int = 16 var dateFormatter: DateFormatter var isSubmitted: Box = Box(nil) var countryAndOccupationFetched: Box = Box(nil) var kycViewModelConnectionTimeOut: Box = Box(nil) private var countryList: [AgentCountryList] = [AgentCountryList]() private var nativeCountryList: [AgentCountryList] = [AgentCountryList]() private var cddOccupationList: [String] = [String] () private var cddVerificationIDList: [String] = [String] () private var cddGenderList: [String] = [String] () private var cddPrimaryBankList: [String] = [String] () private var cddSourceFundList: [String] = [String] () private var cddProvinceList: [String] = [String] () private var cddOccupationValueList: [String] = [String] () private var cddVerificationIDValueList: [String] = [String] () private var cddGenderValueList: [String] = [String] () private var cddPrimaryBankValueList: [String] = [String] () private var cddSourceFundValueList: [String] = [String] () private var cddProvinceValueList: [String] = [String] () private var indexForCountry: Int! private let countryImage: [String] = ["Korea"] private let nativeCountryImage: [String] = ["Nepal"] private let countryName: [String] = ["Korea"] private let nativeCountryName: [String] = ["Nepal"] var kycmodel = KYCModel() private var selfieSubmitted: Bool = false private var idFrontSubmitted: Bool = false private var idBackSubmitted: Bool = false private var passbookSubmitted: Bool = false private var passportSubmitted: Bool = false let user_id = UserDefaults.standard.object(forKey: "com.gmeremit.username") as? String func allFieldsFilled(arrayofInfo: [String]) -> Bool { for info in arrayofInfo { if info.isBlank { return false } } return true } func fetchRequiredCDDValues() { fetchCDDListFor(cddName: cddCode.Gender.rawValue, param: nil) fetchListOfCountry() fetchCDDListFor(cddName: cddCode.Occupation.rawValue, param: nil) fetchCDDListFor(cddName: cddCode.VerificationID.rawValue, param: nil) fetchCDDListFor(cddName: cddCode.PrimaryBankList.rawValue, param: nil) fetchCDDListFor(cddName: cddCode.SourceFund.rawValue, param: nil) } /** Api request to fetch data according cddCode - parameter cddName: cddCode - parameter param: country id in dictionary */ private func fetchCDDListFor(cddName: String, param: [String: String]?) { if !Reachability.isConnectedToNetwork() { self.internetConnection.value = false } else { RestApiMananger.sharedInstance.getCDDListFor(cddCode: cddName, param: param) { result in switch result { case let .success(cddJSON): if cddJSON.count > 0 { for i in 0 ... (cddJSON.count-1) { do { let cddNameValuePair = try JSONDecoder().decode(Cdd.self, from: cddJSON[i].rawData()) switch cddName { case cddCode.Occupation.rawValue: self.cddOccupationList.append(cddNameValuePair.name) self.cddOccupationValueList.append(cddNameValuePair.value) case cddCode.Gender.rawValue: self.cddGenderList.append(cddNameValuePair.name) self.cddGenderValueList.append(cddNameValuePair.value) case cddCode.PrimaryBankList.rawValue: self.cddPrimaryBankList.append(cddNameValuePair.name) self.cddPrimaryBankValueList.append(cddNameValuePair.value) case cddCode.VerificationID.rawValue: self.cddVerificationIDList.append(cddNameValuePair.name) self.cddVerificationIDValueList.append(cddNameValuePair.value) case cddCode.SourceFund.rawValue: self.cddSourceFundList.append(cddNameValuePair.name) self.cddSourceFundValueList.append(cddNameValuePair.value) case cddCode.Province.rawValue: self.cddProvinceList.append(cddNameValuePair.name) self.cddProvinceValueList.append(cddNameValuePair.value) default: return } } catch { self.setErrorMessage(message: "Error decoding JSON") break } } if cddName == cddCode.Occupation.rawValue { self.countryAndOccupationFetched.value = 2 } } case .failure(_): return case .updateAccessCode: RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) { result in if result != "Error"{ let uuid = RestApiMananger.sharedInstance.getUUID() UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode") self.fetchCDDListFor(cddName: cddName, param: param) } } case .logOutUser(): RestApiMananger.sharedInstance.cancelExistingNetworkCalls() self.anotherLogin.value = true case .timeOut: self.kycViewModelConnectionTimeOut.value = false } } } } /** Api request for country list */ func fetchListOfCountry() { if !Reachability.isConnectedToNetwork() { self.internetConnection.value = false } else { RestApiMananger.sharedInstance.fetchCountryList() { result in switch result { case let .success(countryListJSON): self.countryList.removeAll() if countryListJSON.count > 0 { for i in 0 ... (countryListJSON.count-1) { do { let country = try JSONDecoder().decode(AgentCountryList.self, from: countryListJSON[i].rawData()) self.countryList.append(country) if country.country != "South Korea"{ self.nativeCountryList.append(country) } } catch let err { self.setErrorMessage(message: err as! String) } } self.indexForCountry = self.countryList.index(where: {$0.country == "South Korea"}) self.countryAndOccupationFetched.value = 1 let countryId = self.countryList[self.indexForCountry].countryId! self.setCountry(countryId: countryId) self.fetchCDDListFor(cddName: cddCode.Province.rawValue, param: ["countryId": countryId]) } case let .failure(errorJSON): self.setErrorMessage(message: errorJSON["message"].stringValue) case .updateAccessCode: RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) { result in if result != "Error"{ let uuid = RestApiMananger.sharedInstance.getUUID() UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode") self.fetchListOfCountry() } } case .logOutUser(): RestApiMananger.sharedInstance.cancelExistingNetworkCalls() self.anotherLogin.value = true case .timeOut: self.kycViewModelConnectionTimeOut.value = false } } } } /** Api Request to submit the KYC information */ func submitInfo() { if !Reachability.isConnectedToNetwork() { self.internetConnection.value = false } else { var encodedKYCDictionary: [String: String]! do { let encodedKYC = try JSONEncoder().encode(kycmodel) encodedKYCDictionary = try JSONSerialization.jsonObject(with: encodedKYC, options: .allowFragments) as? [String: String] } catch { } guard encodedKYCDictionary != nil else { return } RestApiMananger.sharedInstance.submitKYCInfo(param: encodedKYCDictionary, userId: self.user_id!) { result in switch result { case let .success(kycJSON): self.saveUserData(loggedJSON: kycJSON) self.isSubmitted.value = true case let .failure(errorJSON): self.setErrorMessage(message: errorJSON["message"].stringValue) self.isSubmitted.value = false case .updateAccessCode: RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) { result in if result != "Error"{ let uuid = RestApiMananger.sharedInstance.getUUID() UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode") self.submitInfo() } } case .logOutUser(): RestApiMananger.sharedInstance.cancelExistingNetworkCalls() self.anotherLogin.value = true case .timeOut: self.kycViewModelConnectionTimeOut.value = false } } } } /** To save the value in user default */ func saveUserData(loggedJSON: JSON) { let fullName = loggedJSON["firstName"].stringValue + " " + loggedJSON["middleName"].stringValue + " " + loggedJSON["lastName"].stringValue UserDefaults.standard.set(fullName, forKey: "com.gmeremit.fullName") UserDefaults.standard.set(loggedJSON["userId"].stringValue, forKey: "com.gmeremit.username") UserDefaults.standard.set(loggedJSON["nickName"].stringValue, forKey: "com.gmeremit.nickName") UserDefaults.standard.set(true, forKey: "com.gmeremit.isKYCSubmitted") UserDefaults.standard.set(loggedJSON["email"].stringValue, forKey: "com.gmeremit.email") UserDefaults.standard.set(loggedJSON["mobileNumber"].stringValue, forKey: "com.gmeremit.mobileNumber") UserDefaults.standard.set(loggedJSON["primaryBankName"].stringValue, forKey: "com.gmeremit.bankName") } func checkNetwork() { if Reachability.isConnectedToNetwork() { self.internetConnection.value = true } else { self.internetConnection.value = false } } /** To reset Image Submission, in case if any error occur on previous pages during submission of images */ func resetImageSubmission() { self.selfieSubmitted = false self.idFrontSubmitted = false self.idBackSubmitted = false self.passbookSubmitted = false self.passportSubmitted = false } /** Api request to submit Image from kyc */ func provideImageForSubmission(docType: String, imageBase64: String) { if !Reachability.isConnectedToNetwork() { self.internetConnection.value = false } else { let docParam = ["documentType": docType, "file": imageBase64] RestApiMananger.sharedInstance.submitDocument(param: docParam, userId: self.user_id!) { result in switch result { case let .success(documentJSON): switch docType { case kycCode.Selfie.rawValue: self.kycmodel.selfieUrl = documentJSON["documentUrl"].stringValue self.selfieSubmitted = true case kycCode.IDFront.rawValue: self.kycmodel.regIdcardFrontUrl = documentJSON["documentUrl"].stringValue self.idFrontSubmitted = true case kycCode.IDBack.rawValue: self.kycmodel.regIdcardBackUrl = documentJSON["documentUrl"].stringValue self.idBackSubmitted = true case kycCode.Passbook.rawValue: self.kycmodel.passbookUrl = documentJSON["documentUrl"].stringValue self.passbookSubmitted = true case kycCode.Passport.rawValue: self.kycmodel.passportUrl = documentJSON["documentUrl"].stringValue self.passportSubmitted = true case "KYC0005V": return default: return } if self.selfieSubmitted && self.idFrontSubmitted && self.idBackSubmitted && self.passbookSubmitted && self.passportSubmitted { self.submitInfo() } case let .failure(errorJSON): self.setErrorMessage(message: errorJSON["message"].stringValue) self.isSubmitted.value = false case .updateAccessCode: RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) { result in if result != "Error"{ let uuid = RestApiMananger.sharedInstance.getUUID() UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode") self.provideImageForSubmission(docType: docType, imageBase64: imageBase64) } } case .logOutUser(): RestApiMananger.sharedInstance.cancelExistingNetworkCalls() self.anotherLogin.value = true case .timeOut: self.kycViewModelConnectionTimeOut.value = false } } } } /** Validate expire date - parameter expiryDate: date > current date */ func isValidDate(expiryDate: String) -> Bool { let expdate = dateFormatter.date(from: expiryDate)! let currentDate = Date() if expdate <= currentDate { return false } return true } /** Validate age - parameter dob: date < minAgeRequirement */ func isValidAge(dob: String) -> Bool { let now = Date() let birthday: Date = dateFormatter.date(from: dob)! let calendar = Calendar.current let ageComponents = calendar.dateComponents([.year], from: birthday, to: now) if ageComponents.year! < minAgeRequirement { return false } return true } /** To update the name in kyc - parameter namePart: name part - parameter inputString: updated name */ func updateName(namePart: Int, inputString: String) { switch namePart { case 0: kycmodel.nickName = inputString case 1: kycmodel.firstName = inputString case 2: kycmodel.middleName = inputString case 3: kycmodel.lastName = inputString default: return } } /** To update the email in kyc - parameter email: updated email */ func updateSetEmail(email: String) { kycmodel.email = email } /** To set the gender in kyc - parameter referenceIndex: position of selected gender */ func setGender(referenceIndex: Int) { kycmodel.gender = cddGenderValueList[referenceIndex] } /** To set the DOB in kyc - parameter dob: dob */ func setDOB(dob: String) { kycmodel.dateOfBirth = dob } /** To update the mobile nos. in kyc - parameter inputDigit: updated nos. */ func updateSetMobileNumber(inputDigit: String) { kycmodel.mobileNumber = inputDigit } /** To set the country in kyc - parameter countryId: country id */ func setCountry(countryId: String) { kycmodel.country = countryId } /** To set the native country in kyc - parameter referenceIndex: position of countryid in an array */ func setNativeCountry(referenceIndex: Int) { kycmodel.nativeCountry = countryList[referenceIndex].countryId } /** To set the province in kyc - parameter referenceIndex: position of province id in an array */ func setProvince(referenceIndex: Int) { kycmodel.provinceId = cddProvinceValueList[referenceIndex] } /** To set the occupation in kyc - parameter referenceIndex: position of occupation in an array */ func setOccupation(referenceIndex: Int) { kycmodel.occupation = cddOccupationValueList[referenceIndex] } /** To set the primary bank in kyc - parameter referenceIndex: position of bank in an array */ func setPrimaryBank(referenceIndex: Int) { kycmodel.primaryBankName = cddPrimaryBankValueList[referenceIndex] } /** To update the accountnos. in kyc - parameter inputString: updated account nos. */ func updateAccountNumber(inputString: String) { kycmodel.primaryAccountNumber = inputString } /** To set the verification id in kyc - parameter referenceIndex: position of verificaiton id in an array */ func setVerificationType(referenceIndex: Int) { kycmodel.verificationIdType = cddVerificationIDValueList[referenceIndex] } /** To update the verification id in kyc - parameter inputString: updated verification id */ func updateVerificationIDNumber(inputString: String) { kycmodel.verificationIdNumber = inputString } /** To set the expire date in kyc - parameter expDate: date */ func setExpiryDate(expDate: String) { kycmodel.expiryDate = expDate } /** To set the Source Fund in kyc - parameter referenceIndex: position of sourcefund id in an array */ func setSourceFund(referenceIndex: Int) { kycmodel.sourceOfFund = cddSourceFundValueList[referenceIndex] } /** To set the referral code in kyc - parameter referralCode: referral code */ func setReferralCode(referralCode: String) { kycmodel.referralCode = referralCode } /** - returns: gender list */ func getCddGenderList() -> [String] { return cddGenderList } /** - returns: occupation list */ func getCddOccupationList() -> [String] { return cddOccupationList } /** To set default occupation of user as salaried - returns: salaried index in array */ func getIndexForDefaultOccupation() -> Int { return self.cddOccupationList.index(where: {$0 == "Salaried"})! } /** To gett default occupation of user - parameter index: position of default occupation - returns: salaried index in array */ func getDefaultOccupation(index: Int) -> String { return self.cddOccupationList[index] } /** - returns: Primary bank list */ func getCddPrimaryBankList() -> [String] { return cddPrimaryBankList } /** - returns: Verification id list */ func getCddVerificationIDList() -> [String] { return cddVerificationIDList } /** - returns: Verification id value list */ func getCddVerificationIDValueList() -> [String] { return cddVerificationIDValueList } /** - returns: country name */ func getCountryName() -> [String] { return [countryList[indexForCountry].country!] } /** - returns: country flag url */ func getCountryFlagUrl() -> String { if let flagUrl = countryList[indexForCountry].flagUrl{ return flagUrl } return "" } /** - returns: Native country name */ func getNativeCountryName() -> [String] { return nativeCountryList.map{$0.country!} } /** - returns: native country flag url */ func getNativeCountryFlagUrl(index: Int) -> String { if let flagUrl = nativeCountryList[index].flagUrl{ return flagUrl } return "" } /** - returns: province list */ func getProvince() -> [String] { return cddProvinceList } /** - returns: sourcr fund list */ func getCddSourceFund() -> [String] { return cddSourceFundList } }