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.

495 lines
21 KiB

6 years ago
6 years ago
  1. //
  2. // ExchangeRatesViewController.swift
  3. // GMERemittance
  4. //
  5. // Created by gme_2 on 24/08/2018.
  6. //Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import UIKit
  9. import Hex
  10. enum PaymentMode: String {
  11. case cashDelivery = "1"
  12. case bankDeposite = "2"
  13. case homeDelivery = "12"
  14. case mobileWallet = "13"
  15. }
  16. class ExchangeRatesViewController: UIViewController {
  17. struct Constants {
  18. static let transferFeeDetailText = "Transfer Fee Included"
  19. static let currentExchangeRateText = "Current Exchange Rate"
  20. static let paymentModeHeightConstant: CGFloat = 154
  21. }
  22. struct ApiConstants {
  23. static let recieverCountryId = "pCountry"
  24. static let senderCurrency = "sCurrency"
  25. static let recieverCurrency = "pCurrency"
  26. static let senderAmount = "cAmount"
  27. static let recieverAmount = "pAmount"
  28. static let paymentMethod = "serviceType"
  29. static let calcBy = "calcBy"
  30. static let recieverCountryName = "pCountryName"
  31. static let senderCountryId = "sCountry"
  32. }
  33. // MARK: IBOutlets
  34. @IBOutlet weak var scrollView: UIScrollView!
  35. @IBOutlet weak var collectionView: UICollectionView!
  36. @IBOutlet weak var exchangeBackground1: UIView!
  37. @IBOutlet weak var exchangeBackground2: UIView!
  38. @IBOutlet weak var dropDownImageView: UIImageView!
  39. @IBOutlet weak var backgroundViewCountryLabel1: UIView!
  40. @IBOutlet weak var backgroundViewCountryLabel2: UIView!
  41. @IBOutlet weak var countryListStackView: UIStackView!
  42. @IBOutlet weak var countryCodeLabel: UILabel!
  43. @IBOutlet weak var countryFlagImage: UIImageView!
  44. @IBOutlet weak var paymentModeStackViewConstraint: NSLayoutConstraint!
  45. @IBOutlet weak var paymentModeStackView: UIStackView!
  46. @IBOutlet weak var senderTextField: UITextField!
  47. @IBOutlet weak var reciepientTextField: UITextField!
  48. @IBOutlet weak var transferFeeInfoLabel: UILabel!
  49. @IBOutlet weak var exchangeRateInfoLabel: UILabel!
  50. var presenter: ExchangeRatesModuleInterface?
  51. var countryListTapGuesture: UITapGestureRecognizer?
  52. var selectedPaymentIndex: IndexPath = IndexPath.init(row: 0, section: 0)
  53. var translated: Bool = false
  54. var nativeCountryCode: String? = "np"
  55. var calcBy = ""
  56. var exchangeRateModels: [ExchangeRateModel]? {
  57. didSet {
  58. if let _ = CountryInfo().defaultCountryCodes.filter({$0.lowercased() == (self.nativeCountryCode ?? "").lowercased()}).first {
  59. if let defaultExchangeRate = self.exchangeRateModels?.filter({
  60. ($0.countryCode ?? "").lowercased() == (self.nativeCountryCode ?? "").lowercased()
  61. }).first {
  62. // there is native country, defaultExchangeRate is the information for that country
  63. self.setCountryFlag(countryCode: defaultExchangeRate.countryCode ?? "")
  64. self.setCurrencyLabel(currency: defaultExchangeRate.currency ?? "")
  65. // set the default amount for this country. there are some default values in CountryInfo
  66. self.selectedExchageRateModel = defaultExchangeRate
  67. self.collectionView.reloadData()
  68. showPaymentModeView()
  69. self.populateDefaultAmounts()
  70. }
  71. } else {
  72. self.setDefaultValuesForCountriesNotHavingDefaultValue()
  73. showPaymentModeView()
  74. }
  75. }
  76. }
  77. var selectedExchageRateModel: ExchangeRateModel? {
  78. didSet {
  79. self.setCurrencyLabel(currency: self.selectedExchageRateModel?.currency ?? "")
  80. self.setCountryFlag(countryCode: self.selectedExchageRateModel?.countryCode ?? "")
  81. // self.reciepientTextField.text = ""
  82. // calcBy = "c"
  83. collectionView.reloadData()
  84. DispatchQueue.main.async {
  85. self.reciepientTextField.resignFirstResponder()
  86. self.senderTextField.resignFirstResponder()
  87. }
  88. }
  89. }
  90. // MARK: VC's Life cycle
  91. override func viewDidLoad() {
  92. super.viewDidLoad()
  93. setup()
  94. setupDelegates()
  95. setupTargets()
  96. setupNavigation()
  97. setupDefaultCountryFlagandCurrency()
  98. // todo: show default native country and falg
  99. // Do any additional setup after loading the view.
  100. // populateDefaultAmounts()
  101. fetchExchangeRateInformation()
  102. }
  103. func setupDefaultCountryFlagandCurrency() {
  104. if let defaultExchangeRate = self.exchangeRateModels?.filter({
  105. ($0.country ?? "").lowercased() == (self.nativeCountryCode ?? "").lowercased()
  106. }).first {
  107. // there is native country, defaultExchangeRate is the information for that country
  108. self.setCountryFlag(countryCode: defaultExchangeRate.countryCode ?? "")
  109. self.setCurrencyLabel(currency: defaultExchangeRate.currency ?? "")
  110. }
  111. }
  112. override func viewWillAppear(_ animated: Bool) {
  113. super.viewWillAppear(animated)
  114. self.title = "Today's Rate"
  115. }
  116. // IBActions
  117. @IBAction func calculateExchangeRate(_ sender: Any?) {
  118. let senderAmount = self.senderTextField.text!
  119. let reciepientAmount = self.reciepientTextField.text!
  120. let recipientCurrency = self.selectedExchageRateModel?.currency
  121. let reciepientCountryId = self.selectedExchageRateModel?.countryId
  122. let paymentMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: selectedPaymentIndex.row)
  123. let reciepientCountryName = self.selectedExchageRateModel?.country
  124. self.calculate(senderAmt: senderAmount, recieverAmt: reciepientAmount, recieverCurrency: recipientCurrency, recieverCountryName: reciepientCountryName, recieverCountryId: reciepientCountryId, paymentMethod: paymentMethod?.id, calcBy: self.calcBy)
  125. // call calculate( ... ) function
  126. // todo send to api for calculation
  127. }
  128. func calculate(senderAmt: String?, senderCurrency: String? = "KRW", recieverAmt: String?, recieverCurrency: String?, recieverCountryName: String?, recieverCountryId: String?, paymentMethod: String?, calcBy: String?, senderCountryId: String? = "118", shouldShowLoading: Bool = true ) {
  129. let param: [String: String] =
  130. [
  131. ApiConstants.senderAmount : senderAmt ?? "",
  132. ApiConstants.senderCurrency : senderCurrency ?? "",
  133. ApiConstants.recieverAmount : recieverAmt ?? "",
  134. ApiConstants.recieverCurrency : recieverCurrency ?? "",
  135. ApiConstants.recieverCountryId : recieverCountryId ?? "",
  136. ApiConstants.paymentMethod: paymentMethod ?? "",
  137. ApiConstants.calcBy : calcBy ?? "",
  138. ApiConstants.senderCountryId : senderCountryId ?? "",
  139. ApiConstants.recieverCountryName: recieverCountryName ?? ""
  140. ]
  141. // print(param)
  142. // todo
  143. if shouldShowLoading { self.showProgressHud() }
  144. self.getExchangeRateInformation(params: param, success: { (exchageRateDetail) in
  145. self.senderTextField.text = Utility.getCommaSeperatedStringWithDecimal(numberString: exchageRateDetail?.senderAmount ?? "")
  146. self.reciepientTextField.text = Utility.getCommaSeperatedStringWithDecimal(numberString: exchageRateDetail?.recipientAmount ?? "")
  147. let transferFee = exchageRateDetail?.transferFee ?? ""
  148. let currency = exchageRateDetail?.senderCurrency ?? ""
  149. self.transferFeeInfoLabel.text = "\(transferFee) \(currency) (\(Constants.transferFeeDetailText))"
  150. let exchangeRate = exchageRateDetail?.exchangeRate ?? ""
  151. self.exchangeRateInfoLabel.text = "\(exchangeRate) (\(Constants.currentExchangeRateText))"
  152. self.hideProgressHud()
  153. }) { (error) in
  154. self.hideProgressHud()
  155. self.view.endEditing(true)
  156. self.alert(message: error.localizedDescription)
  157. }
  158. // call api with these params
  159. }
  160. @objc func showCountryList(_ sender: UITapGestureRecognizer) {
  161. DispatchQueue.main.async {
  162. self.reciepientTextField.resignFirstResponder()
  163. self.senderTextField.resignFirstResponder()
  164. }
  165. let viewcontroller = UIStoryboard.init(name: "TableViewPicker", bundle: nil).instantiateViewController(withIdentifier: "TablePickerViewController") as! TablePickerViewController
  166. viewcontroller.data = self.exchangeRateModels ?? []
  167. viewcontroller.type = TablePickerViewTitle.currency
  168. viewcontroller.doneAction = self.countrySelected
  169. // viewcontroller.defaultSelectedData = [self.selectedExchageRateModel]
  170. self.present(viewcontroller, animated: true, completion: nil)
  171. }
  172. // other function
  173. func showPaymentModeView() {
  174. UIView.animate(withDuration: 0.33) {
  175. self.paymentModeStackViewConstraint.constant = Constants.paymentModeHeightConstant
  176. self.paymentModeStackView.alpha = 1
  177. self.view.layoutIfNeeded()
  178. }
  179. }
  180. func countrySelected(model: [ExchangeRateModel]) {
  181. self.selectedExchageRateModel = model.first
  182. self.calculateExchangeRate(nil)
  183. // show country with flag.
  184. }
  185. @objc private func textChanged(sender: UITextField) {
  186. switch sender {
  187. case senderTextField:
  188. self.reciepientTextField.text = ""
  189. self.calcBy = "c"
  190. senderTextField.text = Utility.getCommaSeperatedString(numberString: senderTextField.text!)
  191. case reciepientTextField:
  192. self.senderTextField.text = ""
  193. self.calcBy = "p"
  194. reciepientTextField.text = Utility.getCommaSeperatedString(numberString: reciepientTextField.text!)
  195. default:
  196. break
  197. }
  198. }
  199. private func setCountryFlag(countryCode: String) {
  200. let flag = CountryInfo().getFlag(for: countryCode)
  201. self.countryFlagImage.image = flag
  202. }
  203. private func setCurrencyLabel(currency: String) {
  204. self.countryCodeLabel.text = currency.uppercased()
  205. }
  206. private func populateDefaultAmounts() {
  207. guard let nativeCountry = self.nativeCountryCode else {return}
  208. // todo: native country cha bhane tesko CountryInfo class ma defaullt value cha ki chaina herne
  209. // CountryInfo class ma defaullt value cha bhane tyo value rakhera second api hit garna paryo ani aako data dekhaune
  210. // natra bhane tesko 1000000 kwr ko native ma kati huncha teti populate garaune
  211. guard let exchangeModel = self.exchangeRateModels?.filter({
  212. $0.countryCode?.lowercased() == nativeCountry.lowercased() // countryCode
  213. }).first else {return}
  214. // self.selectedExchageRateModel = exchangeModel
  215. // if there is no default amount, then we have to calculate from korean won. so guard ma rakhna thik nahola, yo case hereko chaina
  216. if let recievingAmount = CountryInfo().getDefaultSendingAmount(for: exchangeModel.countryCode ?? "") {
  217. self.setDefaultValuesForCountriesHavingDefaultValue(recievingAmount: recievingAmount, exchangeModel: exchangeModel)
  218. }
  219. // else {
  220. // setDefaultValuesForCountriesNotHavingDefaultValue()
  221. // }
  222. }
  223. private func setDefaultValuesForCountriesNotHavingDefaultValue() {
  224. self.selectedExchageRateModel = self.exchangeRateModels?.first
  225. let senderAmount = CountryInfo().getDefaultSendingMoneyInKoreanWon()
  226. self.senderTextField.text = Utility.getCommaSeperatedStringWithDecimal(numberString: senderAmount ?? "")
  227. let senderCurrency = "KWR"
  228. let recieverCurrency = self.selectedExchageRateModel?.currency
  229. let recieverCountryId = self.selectedExchageRateModel?.countryId
  230. let paymentMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: selectedPaymentIndex.row)
  231. let reciepientCountryName = self.selectedExchageRateModel?.country ?? ""
  232. let calcBy = "c"
  233. let senderCountryName = "KOREA"
  234. self.calculate(senderAmt: senderAmount, senderCurrency: senderCurrency, recieverAmt: nil, recieverCurrency: recieverCurrency, recieverCountryName: reciepientCountryName, recieverCountryId: recieverCountryId, paymentMethod: paymentMethod?.id, calcBy: calcBy, shouldShowLoading: false)
  235. }
  236. private func setDefaultValuesForCountriesHavingDefaultValue(recievingAmount: String, exchangeModel: ExchangeRateModel) {
  237. guard let recievingCurrency = CountryInfo().getDefaultSendingCurrency(for: exchangeModel.countryCode ?? ""),
  238. let recievingCountryId = exchangeModel.countryId,
  239. let paymentMethod = exchangeModel.availableServices?.elementAt(index: selectedPaymentIndex.row)
  240. else {
  241. // do something if you have to do
  242. return
  243. }
  244. self.calcBy = "p"
  245. self.reciepientTextField.text = Utility.getCommaSeperatedStringWithDecimal(numberString: recievingAmount)
  246. let reciepientCountryName = exchangeModel.country
  247. self.calculate(senderAmt: nil, senderCurrency: "KRW", recieverAmt: recievingAmount, recieverCurrency: recievingCurrency, recieverCountryName: reciepientCountryName, recieverCountryId: recievingCountryId, paymentMethod: paymentMethod.id, calcBy: calcBy, shouldShowLoading: false)
  248. }
  249. private func fetchExchangeRateInformation() {
  250. self.showProgressHud()
  251. self.fetchCountryCurrencyInfo(success: { (models) in
  252. self.exchangeRateModels = models
  253. }) { (error) in
  254. self.hideProgressHud()
  255. self.view.endEditing(true)
  256. self.alert(message: error.localizedDescription)
  257. }
  258. }
  259. private func setupTargets() {
  260. let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(self.showCountryList(_:)))
  261. self.countryListTapGuesture = tapGuesture
  262. self.countryListStackView.addGestureRecognizer(self.countryListTapGuesture!)
  263. self.reciepientTextField.addTarget(self, action: #selector(self.textChanged(sender:)), for: UIControlEvents.editingChanged)
  264. self.senderTextField.addTarget(self, action: #selector(self.textChanged(sender:)), for: UIControlEvents.editingChanged)
  265. self.reciepientTextField.addTarget(self, action: #selector(self.textFieldSelected(sender:)), for: UIControlEvents.editingDidBegin)
  266. self.senderTextField.addTarget(self, action: #selector(self.textFieldSelected(sender:)), for: UIControlEvents.editingDidBegin)
  267. }
  268. @objc private func textFieldSelected(sender: UITextField) {
  269. switch sender {
  270. case senderTextField:
  271. if Utility.getDeviceModel() == .iphone678 {
  272. let x = self.scrollView.contentOffset.x
  273. let y = self.scrollView.contentOffset.y
  274. let newOffset = CGPoint.init(x: x, y: y + 100)
  275. scrollView.setContentOffset(newOffset, animated: true)
  276. }
  277. if Utility.getDeviceModel() == .iphone5 {
  278. let x = self.scrollView.contentOffset.x
  279. let y = self.scrollView.contentOffset.y
  280. let newOffset = CGPoint.init(x: x, y: y + 150)
  281. scrollView.setContentOffset(newOffset, animated: true)
  282. }
  283. case reciepientTextField:
  284. break
  285. default:
  286. break
  287. }
  288. }
  289. private func setupDelegates() {
  290. self.collectionView.delegate = self
  291. self.collectionView.dataSource = self
  292. }
  293. private func setup() {
  294. let dropDownImage = #imageLiteral(resourceName: "dropdown_white").withRenderingMode(UIImageRenderingMode.alwaysTemplate)
  295. let image = dropDownImage
  296. self.dropDownImageView.image = image
  297. self.dropDownImageView.tintColor = UIColor.white
  298. self.paymentModeStackViewConstraint.constant = 0
  299. self.paymentModeStackView.alpha = 0
  300. self.senderTextField.delegate = self
  301. self.reciepientTextField.delegate = self
  302. // corner Radius
  303. [backgroundViewCountryLabel1, backgroundViewCountryLabel2].forEach({
  304. $0?.layer.cornerRadius = 5
  305. })
  306. [exchangeBackground1, exchangeBackground2].forEach({
  307. $0?.layer.borderWidth = 1
  308. $0?.layer.borderColor = UIColor.init(hex: "#E0E0E0").cgColor
  309. $0?.layer.cornerRadius = 5
  310. })
  311. }
  312. func show(error: String) {
  313. self.view.endEditing(true)
  314. self.alert(message: error)
  315. }
  316. func showLoading() {
  317. self.showProgressHud()
  318. }
  319. func hideLoading() {
  320. self.hideProgressHud()
  321. }
  322. private func setupNavigation() {
  323. self.setupNormalNavigation()
  324. }
  325. }
  326. extension ExchangeRatesViewController: UICollectionViewDelegate {
  327. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  328. let cell = collectionView.cellForItem(at: indexPath) as! ExchangeRateCollectionViewCell
  329. self.selectedPaymentIndex = indexPath
  330. self.collectionView.reloadData()
  331. self.calculateExchangeRate(nil)
  332. }
  333. }
  334. extension ExchangeRatesViewController: UICollectionViewDataSource {
  335. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  336. return self.selectedExchageRateModel?.availableServices?.count ?? 0
  337. }
  338. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  339. let service = self.selectedExchageRateModel?.availableServices?.elementAt(index: indexPath.row)
  340. guard let index = PaymentMode.init(rawValue: service?.id ?? "") else {
  341. return UICollectionViewCell()
  342. }
  343. switch index {
  344. case .bankDeposite:
  345. return configureBankDepositeCell(collectionView: collectionView, indexPath: indexPath)
  346. case .cashDelivery:
  347. return configureCashDeliveryCell(collectionView: collectionView, indexPath: indexPath)
  348. case .homeDelivery:
  349. return configureHomeDeliveryCell(collectionView: collectionView, indexPath: indexPath)
  350. case .mobileWallet:
  351. return configureWalletDeliveryCell(collectionView: collectionView, indexPath: indexPath)
  352. }
  353. }
  354. func configureBankDepositeCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
  355. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExchangeRateCollectionViewCell", for: indexPath) as! ExchangeRateCollectionViewCell
  356. cell.cellSelected = self.selectedPaymentIndex == indexPath
  357. cell.paymentServiceMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: indexPath.row)
  358. cell.image = #imageLiteral(resourceName: "ic_bank")
  359. cell.setup()
  360. return cell
  361. }
  362. func configureWalletDeliveryCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
  363. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExchangeRateCollectionViewCell", for: indexPath) as! ExchangeRateCollectionViewCell
  364. cell.cellSelected = self.selectedPaymentIndex == indexPath
  365. cell.paymentServiceMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: indexPath.row)
  366. cell.image = #imageLiteral(resourceName: "wallet-transfer")
  367. cell.setup()
  368. return cell
  369. }
  370. func configureCashDeliveryCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
  371. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExchangeRateCollectionViewCell", for: indexPath) as! ExchangeRateCollectionViewCell
  372. cell.cellSelected = self.selectedPaymentIndex == indexPath
  373. cell.paymentServiceMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: indexPath.row)
  374. cell.image = #imageLiteral(resourceName: "ic_cash")
  375. cell.setup()
  376. return cell
  377. }
  378. func configureHomeDeliveryCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
  379. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExchangeRateCollectionViewCell", for: indexPath) as! ExchangeRateCollectionViewCell
  380. cell.cellSelected = self.selectedPaymentIndex == indexPath
  381. cell.paymentServiceMethod = self.selectedExchageRateModel?.availableServices?.elementAt(index: indexPath.row)
  382. cell.image = #imageLiteral(resourceName: "ic_homeDelivery")
  383. cell.setup()
  384. return cell
  385. }
  386. }
  387. extension ExchangeRatesViewController: FetchCountryCurrencyInformation, getExchangeRateInformation {}
  388. extension ExchangeRatesViewController: UITextFieldDelegate {
  389. func textFieldDidEndEditing(_ textField: UITextField) {
  390. self.calculateExchangeRate(nil)
  391. }
  392. }
  393. // MARK: ExchangeRatesViewInterface
  394. extension ExchangeRatesViewController: ExchangeRatesViewInterface {
  395. }