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.

440 lines
15 KiB

6 years ago
  1. //
  2. // WalletViewController.swift
  3. // GMERemittance
  4. //
  5. // Created by Sujal on 2/3/18.
  6. // Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import UIKit
  9. class WalletViewController: UIViewController, UIScrollViewDelegate {
  10. @IBOutlet weak var segmentedControl: UISegmentedControl!
  11. @IBOutlet weak var stackView: UIStackView!
  12. @IBOutlet weak var scrollView: UIScrollView!
  13. @IBOutlet weak var contentView: UIView!
  14. @IBOutlet weak var labelID: UILabel!
  15. @IBOutlet weak var textFieldID: UITextField!
  16. @IBOutlet weak var textFieldAmount: UITextField!
  17. @IBOutlet weak var textFieldMessage: UITextField!
  18. @IBOutlet weak var buttonSubmit: UIButton!
  19. @IBOutlet weak var buttonMoneyRequestCount: UIButton!
  20. private var activeTextField: UITextField?
  21. private var walletviewmodel = WalletViewModel()
  22. private var profileviewmodel = ProfileViewModel()
  23. private var tracktransactionviewmodel = TrackTransactionViewModel()
  24. public var transaction: Transaction?
  25. private var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
  26. private var moneyRequestAccepted: Bool = false
  27. public static var notificationCode: String = ""
  28. private var isScrolled: Bool = false
  29. public static var walletConnectionTimeOutCheck = 0
  30. @objc func appMovedToForeground() {
  31. activeTextField?.resignFirstResponder()
  32. if isScrolled {
  33. isScrolled = !isScrolled
  34. }
  35. }
  36. override func viewDidAppear(_ animated: Bool) {
  37. setUpAnotherLoginListener(genericviewmodel: walletviewmodel)
  38. setUpAnotherLoginListener(genericviewmodel: tracktransactionviewmodel)
  39. setUpAnotherLoginListener(genericviewmodel: profileviewmodel)
  40. profileviewmodel.profileConnectionTimeOut.value = nil
  41. /**
  42. connection timeout
  43. */
  44. profileviewmodel.profileConnectionTimeOut.bind { [unowned self] in
  45. guard $0 != nil else {
  46. return
  47. }
  48. self.stopLoading()
  49. if WalletViewController.walletConnectionTimeOutCheck == 0{
  50. WalletViewController.walletConnectionTimeOutCheck = WalletViewController.walletConnectionTimeOutCheck+1
  51. self.popUpMessage(value: 31)
  52. }
  53. }
  54. tracktransactionviewmodel.transactionListConnectionTimeOut.value = nil
  55. /**
  56. connection timeout
  57. */
  58. tracktransactionviewmodel.transactionListConnectionTimeOut.bind { [unowned self] in
  59. guard $0 != nil else {
  60. return
  61. }
  62. self.stopLoading()
  63. if WalletViewController.walletConnectionTimeOutCheck == 0{
  64. WalletViewController.walletConnectionTimeOutCheck = WalletViewController.walletConnectionTimeOutCheck+1
  65. self.popUpMessage(value: 31)
  66. }
  67. }
  68. walletviewmodel.walletConnectionTimeOut.value = nil
  69. /**
  70. connection timeout
  71. */
  72. walletviewmodel.walletConnectionTimeOut.bind { [unowned self] in
  73. guard $0 != nil else {
  74. return
  75. }
  76. self.stopLoading()
  77. if WalletViewController.walletConnectionTimeOutCheck == 0{
  78. WalletViewController.walletConnectionTimeOutCheck = WalletViewController.walletConnectionTimeOutCheck+1
  79. self.popUpMessage(value: 31)
  80. }
  81. }
  82. setUpNetworkListener()
  83. setUpNetworkListenerForProfile()
  84. setUpProfileListener()
  85. setUpTransactionListener()
  86. setUpWalletDetailsListener()
  87. /*so that the value is reset and no error message is seen when going back and froth in error case*/
  88. self.walletviewmodel.walletActionPerformed.value = nil
  89. self.buttonMoneyRequestCount.setTitle("", for: .normal)
  90. self.buttonMoneyRequestCount.isUserInteractionEnabled = false
  91. tracktransactionviewmodel.fetchTransactionListForTrackAndWallet(recipientId: "", recipientName: "", transactionType: "moneyRequest", startDate: nil, endDate: nil, txPage: nil, txSize: nil)
  92. }
  93. override func viewDidLoad() {
  94. super.viewDidLoad()
  95. setUpNavBar(id: 201, title: "Wallet to Wallet Transfer")
  96. NotificationCenter.default.addObserver(self, selector: #selector(appMovedToForeground), name: Notification.Name.UIApplicationWillEnterForeground, object: nil)
  97. registerTapListener()
  98. self.startLoading()
  99. walletviewmodel.getTransactionInfo()
  100. scrollView.delegate = self
  101. scrollView.addSubview(contentView)
  102. scrollView.contentSize = CGSize(width: 2000, height:2000)
  103. if transaction != nil {
  104. moneyRequestAccepted = true
  105. segmentedControl.isUserInteractionEnabled = false
  106. walletviewmodel.setMode(segmentIndex: 2)
  107. walletviewmodel.setMoneyRequestTransactionID(id: transaction!.transactionId)
  108. textFieldID.text = transaction!.receiverId
  109. textFieldAmount.text = transaction!.payoutAmountOriginal
  110. textFieldID.isUserInteractionEnabled = false
  111. }
  112. textFieldID.delegate = self
  113. textFieldAmount.delegate = self
  114. textFieldMessage.delegate = self
  115. segmentedControl.selectedSegmentIndex = 0
  116. segmentedControl.addTarget(self, action: #selector(modeChanged(_:)), for: .valueChanged)
  117. walletviewmodel.setMode(segmentIndex: 0)
  118. }
  119. /**
  120. Disable user interaction while fetching data from api
  121. */
  122. func startLoading(){
  123. self.showActivityIndicator(activityIndicator: self.activityIndicator)
  124. self.disableUserInteractions()
  125. }
  126. /**
  127. Enable user interaction while fetching data from api
  128. */
  129. func stopLoading(){
  130. self.dismissActivityIndicator(activityIndicator: self.activityIndicator)
  131. self.enableUserInteractions()
  132. }
  133. /**
  134. Check internet connection
  135. */
  136. func setUpNetworkListener() {
  137. walletviewmodel.internetConnection.bind { [unowned self] in
  138. guard $0 != nil else {
  139. return
  140. }
  141. self.walletviewmodel.internetConnection.value = nil
  142. self.stopLoading()
  143. self.popUpMessage(value: 15)
  144. }
  145. }
  146. func setUpNetworkListenerForProfile() {
  147. profileviewmodel.internetConnection.bind { [unowned self] in
  148. guard $0 != nil else {
  149. return
  150. }
  151. self.profileviewmodel.internetConnection.value = nil
  152. self.stopLoading()
  153. self.popUpMessage(value: 15)
  154. }
  155. }
  156. /**
  157. Set GMEUser name
  158. */
  159. func setUpProfileListener() {
  160. profileviewmodel.userDataAvailable.bind { [unowned self] in
  161. guard $0 != nil else {
  162. return
  163. }
  164. self.stopLoading()
  165. if !($0!) {
  166. if WalletViewController.walletConnectionTimeOutCheck == 0{
  167. WalletViewController.walletConnectionTimeOutCheck = WalletViewController.walletConnectionTimeOutCheck+1
  168. self.popUpMessageError(value: 10, message: self.profileviewmodel.getErrorMessage())
  169. }
  170. } else {
  171. if !self.profileviewmodel.hasFilledKYC() {
  172. self.popUpMessageError(value: 11, message: "User has not filled KYC form")
  173. } else {
  174. self.walletviewmodel.setGMEUsername(fullName: self.profileviewmodel.getFullName())
  175. self.performSegue(withIdentifier: "walletReview", sender: nil)
  176. }
  177. }
  178. self.profileviewmodel.userDataAvailable.value = nil
  179. }
  180. }
  181. /**
  182. Update the view with the transaction count
  183. */
  184. func setUpTransactionListener() {
  185. tracktransactionviewmodel.transactionListObtained.bind{ [weak self] in
  186. guard $0 != nil else {
  187. return
  188. }
  189. guard $0! else {
  190. return
  191. }
  192. let requestCount = self?.tracktransactionviewmodel.getCount()
  193. self?.buttonMoneyRequestCount.setTitle(String(requestCount!), for: .normal)
  194. if requestCount != nil {
  195. if requestCount! > 0 {
  196. self?.buttonMoneyRequestCount.isUserInteractionEnabled = true
  197. }
  198. }
  199. }
  200. }
  201. /**
  202. Set maximum amount
  203. */
  204. func setUpWalletDetailsListener() {
  205. walletviewmodel.walletLimitsFetched.bind{ [unowned self] in
  206. guard $0 != nil else {
  207. return
  208. }
  209. self.stopLoading()
  210. guard $0! else {
  211. if WalletViewController.walletConnectionTimeOutCheck == 0{
  212. WalletViewController.walletConnectionTimeOutCheck = WalletViewController.walletConnectionTimeOutCheck+1
  213. self.popUpMessageError(value: 10, message: self.walletviewmodel.getErrorMessage())
  214. }
  215. self.walletviewmodel.walletLimitsFetched.value = nil
  216. self.buttonSubmit.isUserInteractionEnabled = false
  217. return
  218. }
  219. self.textFieldAmount.placeholder = "Maximum Amount" + " " + self.walletviewmodel.getMaximumTransferLimit() + " " + "KRW"
  220. self.walletviewmodel.walletLimitsFetched.value = nil
  221. }
  222. }
  223. @objc func modeChanged(_ segControl: UISegmentedControl) {
  224. textFieldID.text = ""
  225. textFieldMessage.text = ""
  226. textFieldAmount.text = ""
  227. switch segControl.selectedSegmentIndex {
  228. case 0:
  229. labelID.text = "GME User ID of Receiver"
  230. buttonSubmit.setTitle("Transfer", for: .normal)
  231. walletviewmodel.setMode(segmentIndex: 0)
  232. case 1:
  233. labelID.text = "GME User ID of Sender"
  234. buttonSubmit.setTitle("Request", for: .normal)
  235. walletviewmodel.setMode(segmentIndex: 1)
  236. default:
  237. break
  238. }
  239. }
  240. @IBAction func reviewTransferDetails(_ sender: Any) {
  241. activeTextField?.resignFirstResponder()
  242. walletviewmodel.setParam(amount: textFieldAmount.text!,
  243. gmeID: textFieldID.text!,
  244. message: textFieldMessage.text!)
  245. switch walletviewmodel.validateFields() {
  246. case .Valid:
  247. self.startLoading()
  248. profileviewmodel.fetchUserInfo(userId: walletviewmodel.getGMEID())
  249. case .InValid(let validationError):
  250. self.popUpMessageError(value: 11, message: validationError)
  251. }
  252. }
  253. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  254. switch segue.identifier {
  255. case "walletReview"?:
  256. let walletReviewViewController
  257. = segue.destination as! WalletReviewViewController
  258. walletReviewViewController.walletviewmodel = self.walletviewmodel
  259. walletReviewViewController.moneyRequestAccepted = self.moneyRequestAccepted
  260. case "walletTransfer"?:
  261. activeTextField?.resignFirstResponder()
  262. let walletTransactionListViewController
  263. = segue.destination as! WalletTransactionListViewController
  264. walletTransactionListViewController.walletStatus = "walletTransfer"
  265. case "walletBorrow"?:
  266. activeTextField?.resignFirstResponder()
  267. let walletTransactionListViewController
  268. = segue.destination as! WalletTransactionListViewController
  269. walletTransactionListViewController.walletStatus = "walletBorrow"
  270. case "moneyRequest"?:
  271. activeTextField?.resignFirstResponder()
  272. let moneyRequestViewController
  273. = segue.destination as! MoneyRequestViewController
  274. moneyRequestViewController.moneyRequests = tracktransactionviewmodel.getTransactions()
  275. default:
  276. return
  277. }
  278. }
  279. }
  280. extension WalletViewController: UITextFieldDelegate {
  281. func textFieldDidBeginEditing(_ textField: UITextField) {
  282. activeTextField = textField
  283. checkScroll()
  284. if textField == textFieldAmount {
  285. if textField.text!.contains("KRW") {
  286. textField.text = textField.text!.replacingOccurrences(of: " KRW", with: "", options: NSString.CompareOptions.literal, range: nil)
  287. }
  288. }
  289. }
  290. func textFieldDidEndEditing(_ textField: UITextField) {
  291. checkScroll()
  292. if textField == textFieldAmount {
  293. if textField.text != "" && !textField.text!.contains("KRW") {
  294. textField.text!.append(" KRW")
  295. }
  296. }
  297. }
  298. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  299. let inputText = (textField.text! as NSString).replacingCharacters(in: range, with: string)
  300. if textField == textFieldAmount {
  301. //^[0-9]+$
  302. if NSPredicate(format:"SELF MATCHES %@", "[0-9]*$").evaluate(with: inputText) {
  303. return true
  304. }
  305. return false
  306. }
  307. return true
  308. }
  309. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  310. switch textField {
  311. case textFieldID:
  312. textFieldAmount.becomeFirstResponder()
  313. case textFieldMessage:
  314. textFieldMessage.resignFirstResponder()
  315. default:
  316. return false
  317. }
  318. return true
  319. }
  320. }
  321. extension WalletViewController: ScrollableProtocol {
  322. var offset: CGFloat {
  323. get {
  324. return stackView.frame.origin.y - 20
  325. }
  326. }
  327. var viewScrolled: Bool {
  328. get {
  329. return isScrolled
  330. }
  331. }
  332. /**
  333. Scroll logic
  334. */
  335. func checkScroll() {
  336. if !viewScrolled {
  337. performScroll(direction: 0)
  338. isScrolled = !isScrolled
  339. } else {
  340. performScroll(direction: 1)
  341. isScrolled = !isScrolled
  342. }
  343. }
  344. func registerTapListener() {
  345. let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(clearKeyboard))
  346. view.addGestureRecognizer(tap)
  347. }
  348. /**
  349. Dismiss keypad
  350. */
  351. @objc func clearKeyboard() {
  352. activeTextField?.resignFirstResponder()
  353. if viewScrolled {
  354. performScroll(direction: 1)
  355. isScrolled = !isScrolled
  356. }
  357. }
  358. /**
  359. Active keypad if direction is equal to 0
  360. - parameter direction: display keypad if direction is equal to 0
  361. */
  362. func performScroll(direction: Int) {
  363. if direction == 0 {
  364. UIView.animate(withDuration: 0.3, animations: {
  365. self.view.frame = self.view.frame.offsetBy(dx: 0, dy: self.offset * -1)
  366. })
  367. } else if direction == 1 {
  368. UIView.animate(withDuration: 0.3, animations: {
  369. self.view.frame = self.view.frame.offsetBy(dx: 0, dy: self.offset)
  370. })
  371. }
  372. }
  373. }