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.

525 lines
19 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. //
  2. // KycForm1ViewController.swift
  3. // GMERemittance
  4. //
  5. // Created by gme_2 on 12/09/2018.
  6. //Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import UIKit
  9. import XLPagerTabStrip
  10. class KycForm1Model {
  11. var firstName = ""
  12. var middleName = ""
  13. var lastName = ""
  14. var gender = ""
  15. // var dob = ""
  16. var mobile = ""
  17. var email = ""
  18. var nativeCountry = ""
  19. var country = ""
  20. var province = ""
  21. var occupation = ""
  22. }
  23. class Occupation {
  24. var title: String?
  25. var id: String?
  26. }
  27. struct KycForm1FieldKeys {
  28. static let firstName = "firstname"
  29. static let middleName = "middlename"
  30. static let lastName = "lastname"
  31. static let gender = "gender"
  32. // static let dob = "date of birth"
  33. static let mobileNumber = "mobile number"
  34. static let email = "email"
  35. static let nativeCountry = "native country"
  36. static let country = "address"
  37. static let province = "province"
  38. static let occupation = "occupation"
  39. }
  40. class KycForm1ViewController: UIViewController {
  41. struct Constants {
  42. static let segmentBackgroundViewColor = UIColor.init(hex: "E7EDF2")
  43. static let stateRedColor = UIColor.init(hex: "#EC1C24")
  44. static let errorBorderWidth = AppConstants.errorBorderWidth
  45. static let errorLabelFont = Fonts.Error.font
  46. static let clearColor = UIColor.clear
  47. static let male = "Male"
  48. static let female = "Female"
  49. static let other = "Other"
  50. static let cancelTitleString = "Cancel"
  51. }
  52. // MARK: IBOutlets
  53. @IBOutlet weak var scrollView: UIScrollView!
  54. // validation labels
  55. @IBOutlet weak var firstNameErrorLabel: UILabel!
  56. @IBOutlet weak var middleNameErrorLabel: UILabel!
  57. @IBOutlet weak var lastNameErrorLabel: UILabel!
  58. @IBOutlet weak var genderErrorLabel: UILabel!
  59. @IBOutlet weak var dobErrorLabel: UILabel!
  60. @IBOutlet weak var mobileNumberErrorLabel: UILabel!
  61. @IBOutlet weak var emailErrorLabel: UILabel!
  62. @IBOutlet weak var nativeCountryErrorLabel: UILabel!
  63. @IBOutlet weak var countryErrorLabel: UILabel!
  64. @IBOutlet weak var provinceErrorLabel: UILabel!
  65. @IBOutlet weak var occupationErrorLabel: UILabel!
  66. // textfields
  67. @IBOutlet weak var firstNameTextField: UITextField!
  68. @IBOutlet weak var middleNmaeTextField: UITextField!
  69. @IBOutlet weak var lastNameTextField: UITextField!
  70. @IBOutlet weak var genderTextField: UITextField!
  71. @IBOutlet weak var dobTextField: UITextField!
  72. @IBOutlet weak var mobileNumberTextField: UITextField!
  73. @IBOutlet weak var emailTextField: UITextField!
  74. @IBOutlet weak var nativeCountryTextField: UITextField!
  75. @IBOutlet weak var countryTextField: UITextField!
  76. @IBOutlet weak var provinceTextField: UITextField!
  77. @IBOutlet weak var occupationTextField: UITextField!
  78. // MARK: Properties
  79. var presenter: KycForm1ModuleInterface?
  80. var kycForm1Model: KycForm1Model = KycForm1Model()
  81. var continueActionInitiated = false
  82. let datePicker = UIDatePicker()
  83. var errorTextFieldDict: [String: UITextField] = [:]
  84. var errorLabelsDict: [String: UILabel] = [:]
  85. var errorLabels: [UILabel] = []
  86. var textfields: [UITextField] = []
  87. var delegate: KYCForm1Delegate?
  88. var countries: [KeyValueModel]?
  89. var occupations: [KeyValueModel]?
  90. var kycModel: KycModel? {
  91. didSet {
  92. self.countries = kycModel?.nativeCountry
  93. self.occupations = kycModel?.occupations
  94. self.proviences = kycModel?.city
  95. }
  96. }
  97. var proviences: [KeyValueModel]?
  98. var selectedCountry: SendMoneyCountryViewModel? {
  99. didSet {
  100. self.nativeCountryTextField.text = selectedCountry?.name
  101. self.kycForm1Model.nativeCountry = selectedCountry?.id ?? ""
  102. }
  103. }
  104. var selectedProvience: KeyValueModel? {
  105. didSet {
  106. self.provinceTextField.text = selectedProvience?.text
  107. self.kycForm1Model.province = selectedProvience?.id ?? ""
  108. }
  109. }
  110. var selectedOccupation: KeyValueModel? {
  111. didSet {
  112. self.occupationTextField.text = selectedOccupation?.text
  113. self.kycForm1Model.occupation = selectedOccupation?.id ?? ""
  114. }
  115. }
  116. // MARK: VC's Life cycle
  117. override func viewDidLoad() {
  118. super.viewDidLoad()
  119. self.setup()
  120. presenter?.viewIsReady()
  121. }
  122. override func viewWillAppear(_ animated: Bool) {
  123. super.viewWillAppear(animated)
  124. self.view.endEditing(true)
  125. removeFocus()
  126. }
  127. override func viewWillDisappear(_ animated: Bool) {
  128. super.viewWillDisappear(animated)
  129. self.view.endEditing(true)
  130. self.continueActionInitiated = false
  131. self.validate()
  132. }
  133. // MARK: IBActions
  134. @IBAction func save(_ sender: UIButton) {
  135. self.view.endEditing(true)
  136. self.continueActionInitiated = true
  137. self.delegate?._continue(model: self.kycForm1Model)
  138. // validate()
  139. }
  140. // MARK: Other Functions
  141. private func removeFocus() {
  142. self.textfields.forEach({
  143. $0.resignFirstResponder()
  144. })
  145. }
  146. private func createModel() {
  147. self.kycForm1Model.firstName = self.firstNameTextField.text!
  148. self.kycForm1Model.middleName = self.middleNmaeTextField.text!
  149. self.kycForm1Model.lastName = self.lastNameTextField.text!
  150. self.kycForm1Model.gender = self.genderTextField.text!
  151. // self.kycForm1Model.dob = self.dobTextField.text!
  152. self.kycForm1Model.mobile = self.mobileNumberTextField.text!
  153. self.kycForm1Model.email = self.emailTextField.text!
  154. self.kycForm1Model.country = self.countryTextField.text! // this is addres field
  155. }
  156. private func setup() {
  157. // all setup should be done here
  158. hideErrorLabels()
  159. setupErrorLabels()
  160. setupErrorTextFields()
  161. setupDelegates()
  162. self.setupDatePicker()
  163. self.setupEmail()
  164. }
  165. private func setupEmail() {
  166. if let email = UserDefaults.standard.string(forKey: UserKeys.email) {
  167. self.emailTextField.text = email
  168. self.emailTextField.isUserInteractionEnabled = false
  169. }
  170. }
  171. private func setupDelegates() {
  172. self.firstNameTextField.delegate = self
  173. self.lastNameTextField.delegate = self
  174. self.middleNmaeTextField.delegate = self
  175. self.genderTextField.delegate = self
  176. self.emailTextField.delegate = self
  177. self.dobTextField.delegate = self
  178. self.countryTextField.delegate = self
  179. self.nativeCountryTextField.delegate = self
  180. self.occupationTextField.delegate = self
  181. self.mobileNumberTextField.delegate = self
  182. self.provinceTextField.delegate = self
  183. }
  184. private func setupDatePicker() {
  185. self.datePicker.datePickerMode = .date
  186. self.dobTextField.inputView = datePicker
  187. datePicker.maximumDate = Date()
  188. self.datePicker.addTarget(self, action: #selector(handleDatePicker(sender:)), for: .valueChanged)
  189. }
  190. @objc private func handleDatePicker(sender: UIDatePicker) {
  191. let dateFormatter = DateFormatter()
  192. // test ccr
  193. dateFormatter.dateFormat = AppConstants.dateFormat
  194. self.dobTextField.text = dateFormatter.string(from: sender.date)
  195. }
  196. private func validate() {
  197. self.createModel()
  198. self.delegate?.addModel(model: self.kycForm1Model)
  199. }
  200. private func hideErrorLabels() {
  201. [firstNameErrorLabel, middleNameErrorLabel, lastNameErrorLabel, genderErrorLabel, dobErrorLabel, mobileNumberErrorLabel, emailErrorLabel, nativeCountryErrorLabel, countryErrorLabel, provinceErrorLabel, occupationErrorLabel].forEach({
  202. $0?.isHidden = true
  203. })
  204. }
  205. private func setupErrorLabels() {
  206. self.errorLabels = [firstNameErrorLabel, middleNameErrorLabel, lastNameErrorLabel, genderErrorLabel, dobErrorLabel, mobileNumberErrorLabel, emailErrorLabel, nativeCountryErrorLabel, nativeCountryErrorLabel, provinceErrorLabel, occupationErrorLabel, countryErrorLabel]
  207. self.errorLabels.forEach({
  208. $0.font = Constants.errorLabelFont
  209. })
  210. self.errorLabelsDict =
  211. [
  212. KycForm1FieldKeys.firstName: self.firstNameErrorLabel,
  213. KycForm1FieldKeys.middleName: self.middleNameErrorLabel,
  214. KycForm1FieldKeys.lastName: self.lastNameErrorLabel,
  215. KycForm1FieldKeys.gender: self.genderErrorLabel,
  216. // KycForm1FieldKeys.dob: self.dobErrorLabel,
  217. KycForm1FieldKeys.mobileNumber: self.mobileNumberErrorLabel,
  218. KycForm1FieldKeys.email: self.emailErrorLabel,
  219. KycForm1FieldKeys.nativeCountry: self.nativeCountryErrorLabel,
  220. KycForm1FieldKeys.country: self.countryErrorLabel,
  221. KycForm1FieldKeys.province: self.provinceErrorLabel,
  222. KycForm1FieldKeys.occupation: self.occupationErrorLabel
  223. ]
  224. }
  225. private func setupErrorTextFields() {
  226. self.textfields = [firstNameTextField, lastNameTextField, middleNmaeTextField, genderTextField, dobTextField, mobileNumberTextField, emailTextField, nativeCountryTextField, countryTextField, provinceTextField, occupationTextField]
  227. firstNameTextField.tag = 1
  228. middleNmaeTextField.tag = 2
  229. lastNameTextField.tag = 3
  230. genderTextField.tag = 4
  231. dobTextField.tag = 5
  232. mobileNumberTextField.tag = 6
  233. emailTextField.tag = 7
  234. nativeCountryTextField.tag = 8
  235. countryTextField.tag = 9
  236. provinceTextField.tag = 10
  237. occupationTextField.tag = 11
  238. self.errorTextFieldDict =
  239. [
  240. KycForm1FieldKeys.firstName: self.firstNameTextField,
  241. KycForm1FieldKeys.middleName: self.middleNmaeTextField,
  242. KycForm1FieldKeys.lastName: self.lastNameTextField,
  243. KycForm1FieldKeys.gender: self.genderTextField,
  244. // KycForm1FieldKeys.dob: self.dobTextField,
  245. KycForm1FieldKeys.mobileNumber: self.mobileNumberTextField,
  246. KycForm1FieldKeys.email: self.emailTextField,
  247. KycForm1FieldKeys.nativeCountry: self.nativeCountryTextField,
  248. KycForm1FieldKeys.country: self.countryTextField,
  249. KycForm1FieldKeys.province: self.provinceTextField,
  250. KycForm1FieldKeys.occupation: self.occupationTextField
  251. ]
  252. }
  253. private func showBorder(textfield :UITextField?) {
  254. guard let textfield = textfield else {return}
  255. textfield.layer.borderColor = Constants.stateRedColor.cgColor
  256. textfield.layer.borderWidth = Constants.errorBorderWidth
  257. textfield.layer.addShadow(with: Constants.stateRedColor)
  258. }
  259. private func show( error: String, label: UILabel?) {
  260. // scroll to the top of the view
  261. guard let label = label else {return}
  262. label.textColor = Constants.stateRedColor
  263. label.isHidden = false
  264. label.text = error
  265. }
  266. }
  267. // MARK: KycForm1ViewInterface
  268. extension KycForm1ViewController: KycForm1ViewInterface {
  269. // todo remove this from this viper flow. its now in parent
  270. func show(result: (doesNotSucks: Bool, errorsDick: [String : String])) {
  271. var position = 11
  272. if result.doesNotSucks { // if isValid
  273. // its is not valid, lets go to security page only if continue button was tapped
  274. if self.continueActionInitiated {
  275. self.delegate?._continue(model: self.kycForm1Model)
  276. }
  277. }else {
  278. result.errorsDick.forEach({
  279. let label = errorLabelsDict[$0.key]
  280. self.show(error: $0.value, label: label)
  281. let textfield = errorTextFieldDict[$0.key]
  282. self.showBorder(textfield: textfield)
  283. let tag = (textfield?.tag ?? position)
  284. position = tag < position ? tag : position
  285. if let topMostTextField = self.textfields.filter({
  286. $0.tag == tag
  287. }).first {
  288. // Todo
  289. // scroll to view here
  290. }
  291. })
  292. }
  293. }
  294. func show(model: KycModel) {
  295. self.delegate?.show(model: model)
  296. self.kycModel = model
  297. }
  298. func show(error: String) {
  299. self.alert(message: error)
  300. }
  301. func showLoading() {
  302. self.showProgressHud()
  303. }
  304. func hideLoading() {
  305. self.hideProgressHud()
  306. }
  307. }
  308. extension KycForm1ViewController: IndicatorInfoProvider {
  309. func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
  310. return IndicatorInfo.init(title: "Personal")
  311. }
  312. }
  313. extension KycForm1ViewController: UITextFieldDelegate {
  314. func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
  315. textField.layer.addShadow(with: Constants.clearColor)
  316. switch textField {
  317. case genderTextField:
  318. self.genderErrorLabel.isHidden = true
  319. genderTextField.layer.borderWidth = 0
  320. self.view.endEditing(true)
  321. self.showGenderPicker()
  322. return false
  323. case nativeCountryTextField:
  324. self.nativeCountryErrorLabel.isHidden = true
  325. nativeCountryTextField.layer.borderWidth = 0
  326. self.view.endEditing(true)
  327. self.showCountryPickerview()
  328. return false
  329. case provinceTextField:
  330. self.provinceErrorLabel.isHidden = true
  331. provinceTextField.layer.borderWidth = 0
  332. self.view.endEditing(true)
  333. self.showProviencePickerview()
  334. return false
  335. case occupationTextField:
  336. self.occupationErrorLabel.isHidden = true
  337. occupationTextField.layer.borderWidth = 0
  338. self.view.endEditing(true)
  339. self.showOccupationPickerView()
  340. return false
  341. default:
  342. return true
  343. }
  344. }
  345. func textFieldDidBeginEditing(_ textField: UITextField) {
  346. textField.layer.addShadow(with: Constants.clearColor)
  347. textField.layer.borderWidth = 0
  348. switch textField {
  349. case firstNameTextField:
  350. self.firstNameErrorLabel.isHidden = true
  351. case middleNmaeTextField:
  352. self.middleNameErrorLabel.isHidden = true
  353. case lastNameTextField:
  354. self.lastNameErrorLabel.isHidden = true
  355. case genderTextField:
  356. self.genderErrorLabel.isHidden = true
  357. case dobTextField:
  358. self.dobErrorLabel.isHidden = true
  359. case mobileNumberTextField:
  360. self.mobileNumberErrorLabel.isHidden = true
  361. case emailTextField:
  362. self.emailErrorLabel.isHidden = true
  363. case nativeCountryTextField:
  364. self.nativeCountryErrorLabel.isHidden = true
  365. case countryTextField:
  366. self.countryErrorLabel.isHidden = true
  367. case provinceTextField:
  368. self.provinceErrorLabel.isHidden = true
  369. case occupationTextField:
  370. self.occupationErrorLabel.isHidden = true
  371. default:
  372. break
  373. }
  374. }
  375. }
  376. extension KycForm1ViewController {
  377. private func showCountryPickerview() {
  378. let viewcontroller = UIStoryboard.init(name: "CountryPicker", bundle: nil).instantiateViewController(withIdentifier: "CountryPickerViewController") as! CountryPickerViewController
  379. let _countries = self.countries ?? []
  380. let data: [SendMoneyCountryViewModel] = _countries.map({
  381. let model = SendMoneyCountryViewModel()
  382. model.id = $0.id
  383. model.name = $0.text
  384. // model.code = $0.code
  385. return model
  386. })
  387. viewcontroller.data = data
  388. viewcontroller.doneAction = self.countrySelected
  389. viewcontroller.defaultSelectedData = [self.selectedCountry]
  390. viewcontroller.type = PickerTitle.country
  391. self.present(viewcontroller, animated: true, completion: nil)
  392. }
  393. func countrySelected(models: [SendMoneyCountryViewModel]) {
  394. self.selectedCountry = models.first
  395. }
  396. private func showGenderPicker() {
  397. let alertcontroller = UIAlertController.init(title: "Gender", message: nil, preferredStyle: .actionSheet)
  398. alertcontroller.view.tintColor = UIColor.init(hex: "#7b7a7a")
  399. let maleAction = UIAlertAction(title: Constants.male, style: .default, handler: { _ in
  400. self.genderTextField.text = Constants.male
  401. })
  402. let femaleAction = UIAlertAction(title: Constants.female, style: .default, handler: { _ in
  403. self.genderTextField.text = Constants.female
  404. })
  405. let otherAction = UIAlertAction(title: Constants.other, style: .default, handler: { _ in
  406. self.genderTextField.text = Constants.other
  407. })
  408. let cancelAction = UIAlertAction(title: Constants.cancelTitleString, style: .cancel, handler: nil)
  409. alertcontroller.addAction(maleAction)
  410. alertcontroller.addAction(femaleAction)
  411. alertcontroller.addAction(otherAction)
  412. alertcontroller.addAction(cancelAction)
  413. self.present(alertcontroller, animated: true, completion: nil)
  414. }
  415. private func showOccupationPickerView() {
  416. let viewcontroller = self.getPickerViewController()
  417. let occupations = self.occupations ?? []
  418. let names = occupations.compactMap({$0.text})
  419. viewcontroller.data = names
  420. viewcontroller.type = PickerTitle.occupation
  421. viewcontroller.doneAction = self.occupationSelected
  422. self.present(viewcontroller, animated: true, completion: nil)
  423. }
  424. private func getPickerViewController()-> ItemsPickerViewController {
  425. return UIStoryboard.init(name: "ItemsPicker", bundle: nil).instantiateViewController(withIdentifier: "ItemsPickerViewController") as! ItemsPickerViewController
  426. }
  427. func occupationSelected(occupations: [String]) {
  428. let _occupation = self.occupations?.filter({($0.text ?? "") == (occupations.first ?? "") }).first
  429. self.selectedOccupation = _occupation
  430. }
  431. private func showProviencePickerview() {
  432. let viewcontroller = self.getPickerViewController()
  433. let proviences = self.proviences
  434. let names = (proviences ?? []).compactMap({$0.text})
  435. viewcontroller.data = names
  436. viewcontroller.type = PickerTitle.state
  437. viewcontroller.doneAction = self.provienceSelected
  438. self.present(viewcontroller, animated: true, completion: nil)
  439. }
  440. func provienceSelected(provience: [String]) {
  441. let _provience = (self.proviences ?? []).filter({
  442. ($0.text ?? "") == (provience.first ?? "")
  443. })
  444. self.selectedProvience = _provience.first
  445. }
  446. }