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.

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