You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

629 lines
22 KiB

6 years ago
  1. //
  2. // KYCViewModel.swift
  3. // GMERemittance
  4. //
  5. // Created by Sujal on 12/20/17.
  6. // Copyright © 2017 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import Foundation
  9. import SwiftyJSON
  10. class KYCViewModel: SignUpViewModel {
  11. override init() {
  12. dateFormatter = DateFormatter()
  13. dateFormatter.dateFormat = "MM/dd/yyyy"
  14. }
  15. let minAgeRequirement: Int = 16
  16. var dateFormatter: DateFormatter
  17. var isSubmitted: Box<Bool?> = Box(nil)
  18. var countryAndOccupationFetched: Box<Int?> = Box(nil)
  19. var kycViewModelConnectionTimeOut: Box<Bool?> = Box(nil)
  20. private var countryList: [AgentCountryList] = [AgentCountryList]()
  21. private var nativeCountryList: [AgentCountryList] = [AgentCountryList]()
  22. private var cddOccupationList: [String] = [String] ()
  23. private var cddVerificationIDList: [String] = [String] ()
  24. private var cddGenderList: [String] = [String] ()
  25. private var cddPrimaryBankList: [String] = [String] ()
  26. private var cddSourceFundList: [String] = [String] ()
  27. private var cddProvinceList: [String] = [String] ()
  28. private var cddOccupationValueList: [String] = [String] ()
  29. private var cddVerificationIDValueList: [String] = [String] ()
  30. private var cddGenderValueList: [String] = [String] ()
  31. private var cddPrimaryBankValueList: [String] = [String] ()
  32. private var cddSourceFundValueList: [String] = [String] ()
  33. private var cddProvinceValueList: [String] = [String] ()
  34. private var indexForCountry: Int!
  35. private let countryImage: [String] = ["Korea"]
  36. private let nativeCountryImage: [String] = ["Nepal"]
  37. private let countryName: [String] = ["Korea"]
  38. private let nativeCountryName: [String] = ["Nepal"]
  39. var kycmodel = KYCModel()
  40. private var selfieSubmitted: Bool = false
  41. private var idFrontSubmitted: Bool = false
  42. private var idBackSubmitted: Bool = false
  43. private var passbookSubmitted: Bool = false
  44. private var passportSubmitted: Bool = false
  45. let user_id = UserDefaults.standard.object(forKey: "com.gmeremit.username") as? String
  46. func allFieldsFilled(arrayofInfo: [String]) -> Bool {
  47. for info in arrayofInfo {
  48. if info.isBlank {
  49. return false
  50. }
  51. }
  52. return true
  53. }
  54. func fetchRequiredCDDValues() {
  55. fetchCDDListFor(cddName: cddCode.Gender.rawValue, param: nil)
  56. fetchListOfCountry()
  57. fetchCDDListFor(cddName: cddCode.Occupation.rawValue, param: nil)
  58. fetchCDDListFor(cddName: cddCode.VerificationID.rawValue, param: nil)
  59. fetchCDDListFor(cddName: cddCode.PrimaryBankList.rawValue, param: nil)
  60. fetchCDDListFor(cddName: cddCode.SourceFund.rawValue, param: nil)
  61. }
  62. /**
  63. Api request to fetch data according cddCode
  64. - parameter cddName: cddCode
  65. - parameter param: country id in dictionary
  66. */
  67. private func fetchCDDListFor(cddName: String, param: [String: String]?) {
  68. if !Reachability.isConnectedToNetwork() {
  69. self.internetConnection.value = false
  70. } else {
  71. RestApiMananger.sharedInstance.getCDDListFor(cddCode: cddName, param: param) { result in
  72. switch result {
  73. case let .success(cddJSON):
  74. if cddJSON.count > 0 {
  75. for i in 0 ... (cddJSON.count-1) {
  76. do {
  77. let cddNameValuePair = try JSONDecoder().decode(Cdd.self, from: cddJSON[i].rawData())
  78. switch cddName {
  79. case cddCode.Occupation.rawValue:
  80. self.cddOccupationList.append(cddNameValuePair.name)
  81. self.cddOccupationValueList.append(cddNameValuePair.value)
  82. case cddCode.Gender.rawValue:
  83. self.cddGenderList.append(cddNameValuePair.name)
  84. self.cddGenderValueList.append(cddNameValuePair.value)
  85. case cddCode.PrimaryBankList.rawValue:
  86. self.cddPrimaryBankList.append(cddNameValuePair.name)
  87. self.cddPrimaryBankValueList.append(cddNameValuePair.value)
  88. case cddCode.VerificationID.rawValue:
  89. self.cddVerificationIDList.append(cddNameValuePair.name)
  90. self.cddVerificationIDValueList.append(cddNameValuePair.value)
  91. case cddCode.SourceFund.rawValue:
  92. self.cddSourceFundList.append(cddNameValuePair.name)
  93. self.cddSourceFundValueList.append(cddNameValuePair.value)
  94. case cddCode.Province.rawValue:
  95. self.cddProvinceList.append(cddNameValuePair.name)
  96. self.cddProvinceValueList.append(cddNameValuePair.value)
  97. default:
  98. return
  99. }
  100. } catch {
  101. self.setErrorMessage(message: "Error decoding JSON")
  102. break
  103. }
  104. }
  105. if cddName == cddCode.Occupation.rawValue {
  106. self.countryAndOccupationFetched.value = 2
  107. }
  108. }
  109. case .failure(_):
  110. return
  111. case .updateAccessCode:
  112. RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) {
  113. result in
  114. if result != "Error"{
  115. let uuid = RestApiMananger.sharedInstance.getUUID()
  116. UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode")
  117. self.fetchCDDListFor(cddName: cddName, param: param)
  118. }
  119. }
  120. case .logOutUser():
  121. RestApiMananger.sharedInstance.cancelExistingNetworkCalls()
  122. self.anotherLogin.value = true
  123. case .timeOut:
  124. self.kycViewModelConnectionTimeOut.value = false
  125. }
  126. }
  127. }
  128. }
  129. /**
  130. Api request for country list
  131. */
  132. func fetchListOfCountry() {
  133. if !Reachability.isConnectedToNetwork() {
  134. self.internetConnection.value = false
  135. } else {
  136. RestApiMananger.sharedInstance.fetchCountryList() { result in
  137. switch result {
  138. case let .success(countryListJSON):
  139. self.countryList.removeAll()
  140. if countryListJSON.count > 0 {
  141. for i in 0 ... (countryListJSON.count-1) {
  142. do {
  143. let country = try JSONDecoder().decode(AgentCountryList.self, from: countryListJSON[i].rawData())
  144. self.countryList.append(country)
  145. if country.country != "South Korea"{
  146. self.nativeCountryList.append(country)
  147. }
  148. } catch let err {
  149. self.setErrorMessage(message: err as! String)
  150. }
  151. }
  152. self.indexForCountry = self.countryList.index(where: {$0.country == "South Korea"})
  153. self.countryAndOccupationFetched.value = 1
  154. let countryId = self.countryList[self.indexForCountry].countryId!
  155. self.setCountry(countryId: countryId)
  156. self.fetchCDDListFor(cddName: cddCode.Province.rawValue, param: ["countryId": countryId])
  157. }
  158. case let .failure(errorJSON):
  159. self.setErrorMessage(message: errorJSON["message"].stringValue)
  160. case .updateAccessCode:
  161. RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) {
  162. result in
  163. if result != "Error"{
  164. let uuid = RestApiMananger.sharedInstance.getUUID()
  165. UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode")
  166. self.fetchListOfCountry()
  167. }
  168. }
  169. case .logOutUser():
  170. RestApiMananger.sharedInstance.cancelExistingNetworkCalls()
  171. self.anotherLogin.value = true
  172. case .timeOut:
  173. self.kycViewModelConnectionTimeOut.value = false
  174. }
  175. }
  176. }
  177. }
  178. /**
  179. Api Request to submit the KYC information
  180. */
  181. func submitInfo() {
  182. if !Reachability.isConnectedToNetwork() {
  183. self.internetConnection.value = false
  184. } else {
  185. var encodedKYCDictionary: [String: String]!
  186. do {
  187. let encodedKYC = try JSONEncoder().encode(kycmodel)
  188. encodedKYCDictionary = try JSONSerialization.jsonObject(with: encodedKYC, options: .allowFragments) as? [String: String]
  189. } catch {
  190. }
  191. guard encodedKYCDictionary != nil else {
  192. return
  193. }
  194. RestApiMananger.sharedInstance.submitKYCInfo(param: encodedKYCDictionary, userId: self.user_id!) { result in
  195. switch result {
  196. case let .success(kycJSON):
  197. self.saveUserData(loggedJSON: kycJSON)
  198. self.isSubmitted.value = true
  199. case let .failure(errorJSON):
  200. self.setErrorMessage(message: errorJSON["message"].stringValue)
  201. self.isSubmitted.value = false
  202. case .updateAccessCode:
  203. RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) {
  204. result in
  205. if result != "Error"{
  206. let uuid = RestApiMananger.sharedInstance.getUUID()
  207. UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode")
  208. self.submitInfo()
  209. }
  210. }
  211. case .logOutUser():
  212. RestApiMananger.sharedInstance.cancelExistingNetworkCalls()
  213. self.anotherLogin.value = true
  214. case .timeOut:
  215. self.kycViewModelConnectionTimeOut.value = false
  216. }
  217. }
  218. }
  219. }
  220. /**
  221. To save the value in user default
  222. */
  223. func saveUserData(loggedJSON: JSON) {
  224. let fullName = loggedJSON["firstName"].stringValue + " " + loggedJSON["middleName"].stringValue + " " + loggedJSON["lastName"].stringValue
  225. UserDefaults.standard.set(fullName, forKey: "com.gmeremit.fullName")
  226. UserDefaults.standard.set(loggedJSON["userId"].stringValue, forKey: "com.gmeremit.username")
  227. UserDefaults.standard.set(loggedJSON["nickName"].stringValue, forKey: "com.gmeremit.nickName")
  228. UserDefaults.standard.set(true, forKey: "com.gmeremit.isKYCSubmitted")
  229. UserDefaults.standard.set(loggedJSON["email"].stringValue, forKey: "com.gmeremit.email")
  230. UserDefaults.standard.set(loggedJSON["mobileNumber"].stringValue, forKey: "com.gmeremit.mobileNumber")
  231. UserDefaults.standard.set(loggedJSON["primaryBankName"].stringValue, forKey: "com.gmeremit.bankName")
  232. }
  233. func checkNetwork() {
  234. if Reachability.isConnectedToNetwork() {
  235. self.internetConnection.value = true
  236. } else {
  237. self.internetConnection.value = false
  238. }
  239. }
  240. /**
  241. To reset Image Submission, in case if any error occur on previous pages during submission of images
  242. */
  243. func resetImageSubmission() {
  244. self.selfieSubmitted = false
  245. self.idFrontSubmitted = false
  246. self.idBackSubmitted = false
  247. self.passbookSubmitted = false
  248. self.passportSubmitted = false
  249. }
  250. /**
  251. Api request to submit Image from kyc
  252. */
  253. func provideImageForSubmission(docType: String, imageBase64: String) {
  254. if !Reachability.isConnectedToNetwork() {
  255. self.internetConnection.value = false
  256. } else {
  257. let docParam = ["documentType": docType, "file": imageBase64]
  258. RestApiMananger.sharedInstance.submitDocument(param: docParam, userId: self.user_id!) { result in
  259. switch result {
  260. case let .success(documentJSON):
  261. switch docType {
  262. case kycCode.Selfie.rawValue:
  263. self.kycmodel.selfieUrl = documentJSON["documentUrl"].stringValue
  264. self.selfieSubmitted = true
  265. case kycCode.IDFront.rawValue:
  266. self.kycmodel.regIdcardFrontUrl = documentJSON["documentUrl"].stringValue
  267. self.idFrontSubmitted = true
  268. case kycCode.IDBack.rawValue:
  269. self.kycmodel.regIdcardBackUrl = documentJSON["documentUrl"].stringValue
  270. self.idBackSubmitted = true
  271. case kycCode.Passbook.rawValue:
  272. self.kycmodel.passbookUrl = documentJSON["documentUrl"].stringValue
  273. self.passbookSubmitted = true
  274. case kycCode.Passport.rawValue:
  275. self.kycmodel.passportUrl = documentJSON["documentUrl"].stringValue
  276. self.passportSubmitted = true
  277. case "KYC0005V":
  278. return
  279. default:
  280. return
  281. }
  282. if self.selfieSubmitted && self.idFrontSubmitted && self.idBackSubmitted && self.passbookSubmitted && self.passportSubmitted {
  283. self.submitInfo()
  284. }
  285. case let .failure(errorJSON):
  286. self.setErrorMessage(message: errorJSON["message"].stringValue)
  287. self.isSubmitted.value = false
  288. case .updateAccessCode:
  289. RestApiMananger.sharedInstance.updateAccessCode(userId: self.user_id!, password: self.getLoginPassword()) {
  290. result in
  291. if result != "Error"{
  292. let uuid = RestApiMananger.sharedInstance.getUUID()
  293. UserDefaults.standard.set((result + ":" + uuid).toBase64(), forKey: "com.gmeremit.accessCode")
  294. self.provideImageForSubmission(docType: docType, imageBase64: imageBase64)
  295. }
  296. }
  297. case .logOutUser():
  298. RestApiMananger.sharedInstance.cancelExistingNetworkCalls()
  299. self.anotherLogin.value = true
  300. case .timeOut:
  301. self.kycViewModelConnectionTimeOut.value = false
  302. }
  303. }
  304. }
  305. }
  306. /**
  307. Validate expire date
  308. - parameter expiryDate: date > current date
  309. */
  310. func isValidDate(expiryDate: String) -> Bool {
  311. let expdate = dateFormatter.date(from: expiryDate)!
  312. let currentDate = Date()
  313. if expdate <= currentDate {
  314. return false
  315. }
  316. return true
  317. }
  318. /**
  319. Validate age
  320. - parameter dob: date < minAgeRequirement
  321. */
  322. func isValidAge(dob: String) -> Bool {
  323. let now = Date()
  324. let birthday: Date = dateFormatter.date(from: dob)!
  325. let calendar = Calendar.current
  326. let ageComponents = calendar.dateComponents([.year], from: birthday, to: now)
  327. if ageComponents.year! < minAgeRequirement {
  328. return false
  329. }
  330. return true
  331. }
  332. /**
  333. To update the name in kyc
  334. - parameter namePart: name part
  335. - parameter inputString: updated name
  336. */
  337. func updateName(namePart: Int, inputString: String) {
  338. switch namePart {
  339. case 0:
  340. kycmodel.nickName = inputString
  341. case 1:
  342. kycmodel.firstName = inputString
  343. case 2:
  344. kycmodel.middleName = inputString
  345. case 3:
  346. kycmodel.lastName = inputString
  347. default:
  348. return
  349. }
  350. }
  351. /**
  352. To update the email in kyc
  353. - parameter email: updated email
  354. */
  355. func updateSetEmail(email: String) {
  356. kycmodel.email = email
  357. }
  358. /**
  359. To set the gender in kyc
  360. - parameter referenceIndex: position of selected gender
  361. */
  362. func setGender(referenceIndex: Int) {
  363. kycmodel.gender = cddGenderValueList[referenceIndex]
  364. }
  365. /**
  366. To set the DOB in kyc
  367. - parameter dob: dob
  368. */
  369. func setDOB(dob: String) {
  370. kycmodel.dateOfBirth = dob
  371. }
  372. /**
  373. To update the mobile nos. in kyc
  374. - parameter inputDigit: updated nos.
  375. */
  376. func updateSetMobileNumber(inputDigit: String) {
  377. kycmodel.mobileNumber = inputDigit
  378. }
  379. /**
  380. To set the country in kyc
  381. - parameter countryId: country id
  382. */
  383. func setCountry(countryId: String) {
  384. kycmodel.country = countryId
  385. }
  386. /**
  387. To set the native country in kyc
  388. - parameter referenceIndex: position of countryid in an array
  389. */
  390. func setNativeCountry(referenceIndex: Int) {
  391. kycmodel.nativeCountry = countryList[referenceIndex].countryId
  392. }
  393. /**
  394. To set the province in kyc
  395. - parameter referenceIndex: position of province id in an array
  396. */
  397. func setProvince(referenceIndex: Int) {
  398. kycmodel.provinceId = cddProvinceValueList[referenceIndex]
  399. }
  400. /**
  401. To set the occupation in kyc
  402. - parameter referenceIndex: position of occupation in an array
  403. */
  404. func setOccupation(referenceIndex: Int) {
  405. kycmodel.occupation = cddOccupationValueList[referenceIndex]
  406. }
  407. /**
  408. To set the primary bank in kyc
  409. - parameter referenceIndex: position of bank in an array
  410. */
  411. func setPrimaryBank(referenceIndex: Int) {
  412. kycmodel.primaryBankName = cddPrimaryBankValueList[referenceIndex]
  413. }
  414. /**
  415. To update the accountnos. in kyc
  416. - parameter inputString: updated account nos.
  417. */
  418. func updateAccountNumber(inputString: String) {
  419. kycmodel.primaryAccountNumber = inputString
  420. }
  421. /**
  422. To set the verification id in kyc
  423. - parameter referenceIndex: position of verificaiton id in an array
  424. */
  425. func setVerificationType(referenceIndex: Int) {
  426. kycmodel.verificationIdType = cddVerificationIDValueList[referenceIndex]
  427. }
  428. /**
  429. To update the verification id in kyc
  430. - parameter inputString: updated verification id
  431. */
  432. func updateVerificationIDNumber(inputString: String) {
  433. kycmodel.verificationIdNumber = inputString
  434. }
  435. /**
  436. To set the expire date in kyc
  437. - parameter expDate: date
  438. */
  439. func setExpiryDate(expDate: String) {
  440. kycmodel.expiryDate = expDate
  441. }
  442. /**
  443. To set the Source Fund in kyc
  444. - parameter referenceIndex: position of sourcefund id in an array
  445. */
  446. func setSourceFund(referenceIndex: Int) {
  447. kycmodel.sourceOfFund = cddSourceFundValueList[referenceIndex]
  448. }
  449. /**
  450. To set the referral code in kyc
  451. - parameter referralCode: referral code
  452. */
  453. func setReferralCode(referralCode: String) {
  454. kycmodel.referralCode = referralCode
  455. }
  456. /**
  457. - returns: gender list
  458. */
  459. func getCddGenderList() -> [String] {
  460. return cddGenderList
  461. }
  462. /**
  463. - returns: occupation list
  464. */
  465. func getCddOccupationList() -> [String] {
  466. return cddOccupationList
  467. }
  468. /**
  469. To set default occupation of user as salaried
  470. - returns: salaried index in array
  471. */
  472. func getIndexForDefaultOccupation() -> Int {
  473. return self.cddOccupationList.index(where: {$0 == "Salaried"})!
  474. }
  475. /**
  476. To gett default occupation of user
  477. - parameter index: position of default occupation
  478. - returns: salaried index in array
  479. */
  480. func getDefaultOccupation(index: Int) -> String {
  481. return self.cddOccupationList[index]
  482. }
  483. /**
  484. - returns: Primary bank list
  485. */
  486. func getCddPrimaryBankList() -> [String] {
  487. return cddPrimaryBankList
  488. }
  489. /**
  490. - returns: Verification id list
  491. */
  492. func getCddVerificationIDList() -> [String] {
  493. return cddVerificationIDList
  494. }
  495. /**
  496. - returns: Verification id value list
  497. */
  498. func getCddVerificationIDValueList() -> [String] {
  499. return cddVerificationIDValueList
  500. }
  501. /**
  502. - returns: country name
  503. */
  504. func getCountryName() -> [String] {
  505. return [countryList[indexForCountry].country!]
  506. }
  507. /**
  508. - returns: country flag url
  509. */
  510. func getCountryFlagUrl() -> String {
  511. if let flagUrl = countryList[indexForCountry].flagUrl{
  512. return flagUrl
  513. }
  514. return ""
  515. }
  516. /**
  517. - returns: Native country name
  518. */
  519. func getNativeCountryName() -> [String] {
  520. return nativeCountryList.map{$0.country!}
  521. }
  522. /**
  523. - returns: native country flag url
  524. */
  525. func getNativeCountryFlagUrl(index: Int) -> String {
  526. if let flagUrl = nativeCountryList[index].flagUrl{
  527. return flagUrl
  528. }
  529. return ""
  530. }
  531. /**
  532. - returns: province list
  533. */
  534. func getProvince() -> [String] {
  535. return cddProvinceList
  536. }
  537. /**
  538. - returns: sourcr fund list
  539. */
  540. func getCddSourceFund() -> [String] {
  541. return cddSourceFundList
  542. }
  543. }