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.

449 lines
19 KiB

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