// // InboundReceiptViewController.swift // GME Remit // // Created by InKwon James Kim on 2019/11/14. //Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. // import UIKit import RxSwift import RxCocoa enum ReceiptDetailType { case inBound, reedem } class InboundReceiptViewController: UIViewController { // MARK: Properties var presenter: InboundReceiptPresenter! var receiptType: ReceiptDetailType = .inBound var password: String = ""{ didSet{ if password != ""{ self.presenter.redeem(password: self.password) } } } private let disposeBag = DisposeBag() // MARK: Computed Properties // MARK: IBOutlets @IBOutlet weak var contactNoView: UIView! @IBOutlet weak var transactionDateView: UIView! @IBOutlet weak var senderView: UIView! @IBOutlet weak var receiverView: UIView! @IBOutlet weak var addressView: UIView! @IBOutlet weak var mobileNoView: UIView! @IBOutlet weak var payoutAgentView: UIView! @IBOutlet weak var bankNameView: UIView! @IBOutlet weak var bankAccountView: UIView! @IBOutlet weak var totalReceivedAmountView: UIView! @IBOutlet weak var totalSentAmountView: UIView! @IBOutlet weak var serviceFeeView: UIView! @IBOutlet weak var exRateView: UIView! @IBOutlet private weak var statusTitleLabel: UILabel! @IBOutlet private weak var senderCountryImageView: UIImageView! @IBOutlet private weak var senderCountryNameLabel: UILabel! @IBOutlet private weak var receiveBankImageView: UIImageView! @IBOutlet private weak var receiverCountryNameLabel: UILabel! @IBOutlet private weak var messageContainerView: UIStackView! @IBOutlet private weak var messageTitleLabel: UILabel! @IBOutlet private weak var bankNameLabel: UILabel! @IBOutlet private weak var bankAccountLabel: UILabel! @IBOutlet private weak var senderToGMEProcess: UIView! @IBOutlet private weak var gmeToReceiverProcess: UIView! @IBOutlet private weak var controlTitleLabel: UILabel! @IBOutlet private weak var controlContentLabel: UILabel! @IBOutlet private weak var transactionDateTitleLabel: UILabel! @IBOutlet private weak var transactionDateContentLabel: UILabel! @IBOutlet private weak var senderNameTitleLabel: UILabel! @IBOutlet private weak var senderNameContentLabel: UILabel! @IBOutlet private weak var receiverNameTitleLabel: UILabel! @IBOutlet private weak var receiverNameContentLabel: UILabel! @IBOutlet private weak var addressTitleLabel: UILabel! @IBOutlet private weak var addressContentLabel: UILabel! @IBOutlet private weak var mobileTitleLabel: UILabel! @IBOutlet private weak var mobileContentLabel: UILabel! @IBOutlet private weak var payOutAgentTitleLabel: UILabel! @IBOutlet private weak var payOutAgentContentLabel: UILabel! @IBOutlet private weak var bankTitleLabel: UILabel! @IBOutlet private weak var bankContentLabel: UILabel! @IBOutlet private weak var bankAccountTitleLabel: UILabel! @IBOutlet private weak var bankAccountContentLabel: UILabel! @IBOutlet private weak var amountTitleLabel: UILabel! @IBOutlet private weak var amountContentsLabel: UILabel! @IBOutlet private weak var totalSentAmountTitleLabel: UILabel! @IBOutlet private weak var totalSentAmountContentLabel: UILabel! @IBOutlet private weak var serviceFeeTitleLabel: UILabel! @IBOutlet private weak var serviceFeeContentLabel: UILabel! @IBOutlet private weak var exRateTitleLabel: UILabel! @IBOutlet private weak var exRateContentLabel: UILabel! @IBOutlet private weak var cancelButton: UIButton! @IBOutlet private weak var registerButton: UIButton! @IBOutlet weak var reedemButton: UIButton! @IBOutlet private weak var bankMessageContainerView: UIStackView! @IBOutlet private weak var buttonContainerView: UIStackView! // MARK: VC's Life cycle override func viewDidLoad() { super.viewDidLoad() //In case of Inbound following are shown self.contactNoView.isHidden = !(self.receiptType == .inBound) self.senderView.isHidden = !(self.receiptType == .inBound) self.bankNameView.isHidden = !(self.receiptType == .inBound) self.bankAccountView.isHidden = !(self.receiptType == .inBound) self.totalReceivedAmountView.isHidden = !(self.receiptType == .inBound) self.cancelButton.isHidden = !(self.receiptType == .inBound) self.registerButton.isHidden = !(self.receiptType == .inBound) self.bankNameLabel.isHidden = !(self.receiptType == .inBound) self.bankAccountLabel.isHidden = !(self.receiptType == .inBound) //In case of Redeem following are shown self.receiverView.isHidden = !(self.receiptType == .reedem) self.addressView.isHidden = !(self.receiptType == .reedem) self.payoutAgentView.isHidden = true//!(self.receiptType == .reedem) self.totalSentAmountView.isHidden = !(self.receiptType == .reedem) self.exRateView.isHidden = !(self.receiptType == .reedem) setup() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) title = (self.receiptType == .inBound) ? "inbound_receipt_text".localized() : "redeem_cash_pickup_text".localized() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) title = "" } // MARK: IBActions @IBAction func redeem(_ sender: Any) { if let isUseBiometric = KeyChain.shared.get(key: .biometricAuth), isUseBiometric == "1" { let biometricAuthenticationWireframe = BiometricAuthenticationWireframe() biometricAuthenticationWireframe.openWithDelegate(on: self, delegate: self) } else { showSecureKeyPad() } } private func showSecureKeyPad() { self.openPasswordInput { (value) in self.password = value } } } // MARK: Other Functions extension InboundReceiptViewController { private func setup() { setUI() setBinding() } private func setUI() { messageContainerView.isHidden = true senderToGMEProcess.layer.cornerRadius = 2 gmeToReceiverProcess.layer.cornerRadius = 2 senderToGMEProcess.isHidden = true gmeToReceiverProcess.isHidden = true registerButton.isHidden = true cancelButton.isHidden = true reedemButton.isHidden = true if self.receiptType == .inBound{ receiverCountryNameLabel.text = GMEDB.shared.user.string(.fullName) }else{ receiverCountryNameLabel.text = "Mongolia" } registerButton.titleLabel?.minimumScaleFactor = 0.5 registerButton.titleLabel?.adjustsFontSizeToFitWidth = true registerButton.titleLabel?.numberOfLines = 2 registerButton.titleLabel?.textAlignment = .center registerButton.layer.cornerRadius = 5 DispatchQueue.main.async {[weak self] in self?.controlTitleLabel.text = "control_no_text".localized() self?.transactionDateTitleLabel.text = "transaction_date_text".localized() self?.senderNameTitleLabel.text = "sender_name_text".localized() self?.mobileTitleLabel.text = "mobile_number_text".localized() self?.bankTitleLabel.text = "bank_text".localized() self?.bankAccountTitleLabel.text = "account_text".localized() self?.amountTitleLabel.text = "received_amount_text".localized() self?.serviceFeeTitleLabel.text = "service_fee_text".localized() self?.registerButton.setTitle("register_account_text".localized(), for: .normal) self?.cancelButton.setTitle("cancel_text".localized(), for: .normal) self?.receiverNameTitleLabel.text = "receiver_text".localized() self?.addressTitleLabel.text = "address_text".localized() self?.payOutAgentTitleLabel.text = "payout_agent_text".localized() self?.totalSentAmountTitleLabel.text = "total_sent_amount_text".localized() self?.exRateTitleLabel.text = "ex_rate_text".localized() self?.reedemButton.setTitle("redeem_text".localized(), for: .normal) } } private func setBinding() { let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))) .mapToVoid() .asDriverOnErrorJustComplete() let input = InboundReceiptPresenter.Input( viewWillAppear: viewWillAppear, register: registerButton.rx.tap.asDriverOnErrorJustComplete(), cancel: cancelButton.rx.tap.asDriverOnErrorJustComplete() ) let output = presenter.transform(input: input) output.isError .drive( onNext: { self.alert(type: .error, message: $0.localizedDescription) } ).disposed(by: disposeBag) output.isProgress .drive( onNext: { $0 ? self.showProgressHud() : self.hideProgressHud() } ).disposed(by: disposeBag) output.model.map {$0.senderCountryName}.drive(senderCountryNameLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.controlNumber}.drive(controlContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.tranDate}.drive(transactionDateContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.senderName}.drive(senderNameContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.receiverName}.drive(receiverNameContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.receiverAddress}.drive(addressContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.receiverMobile}.drive(mobileContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.payOutMode}.drive(payOutAgentContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.bankName}.drive(bankContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.bankName}.drive(bankNameLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.accountNo}.drive(bankAccountContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.accountNo}.drive(bankAccountLabel.rx.text).disposed(by: disposeBag) output.model .map {$0.receivedAmount?.decimalToCurrency(as: .krw, isFront: false)} .drive(amountContentsLabel.rx.text).disposed(by: disposeBag) output.model .map {$0.receivedAmount?.decimalToCurrency(as: .krw, isFront: false)} .drive(totalSentAmountContentLabel.rx.text).disposed(by: disposeBag) output.model.map {$0.serviceFee?.decimalToCurrency(as: .krw, isFront: false)} .drive(serviceFeeContentLabel.rx.text).disposed(by: disposeBag) output.model .map {($0.exrate ?? "0").decimalToCurrency(as: .krw, isFront: false)} .drive(exRateContentLabel.rx.text).disposed(by: disposeBag) output.model.map {(self.receiptType == .inBound) ? BankEnum(rawValue: $0.bankCode ?? "")?.ciImage : CountryEnum.mn.flag} .drive(receiveBankImageView.rx.image).disposed(by: disposeBag) output.model.map {($0.isAccountReg ?? true) && self.receiptType == .reedem} .drive(bankMessageContainerView.rx.isHidden).disposed(by: disposeBag) output.model.map {CountryEnum(rawValue: $0.senderCountryCode?.lowercased() ?? "")?.flag} .drive(senderCountryImageView.rx.image).disposed(by: disposeBag) Driver.combineLatest(output.model.map { $0.isAccountReg ?? true}, output.model.map { $0.controlNumber }, output.status) .drive(onNext: {[weak self] (isRegister, controlNumber, status)in switch status { case .processing: let message = isRegister ? "transaction_will_be_processed_text".localized() : "you_have_to_register_text".localized() self?.messageContainerView.isHidden = false self?.messageTitleLabel.text = message self?.statusTitleLabel.text = "transfer_processing_text".localized() self?.senderToGMEProcess.isHidden = false self?.gmeToReceiverProcess.isHidden = true self?.registerButton.isHidden = isRegister self?.cancelButton.isHidden = isRegister case .paid: self?.statusTitleLabel.text = "transfer_success_text".localized() self?.senderToGMEProcess.isHidden = false self?.gmeToReceiverProcess.isHidden = false self?.messageContainerView.isHidden = true case .cancel: self?.statusTitleLabel.text = "transfer_canceled_text".localized() self?.senderToGMEProcess.isHidden = true self?.gmeToReceiverProcess.isHidden = true self?.messageContainerView.isHidden = true case .unpaid: self?.statusTitleLabel.text = "transfer_pending_text".localized() self?.senderToGMEProcess.isHidden = (self?.receiptType != .reedem) self?.gmeToReceiverProcess.isHidden = (self?.receiptType != .reedem) self?.messageContainerView.isHidden = (self?.receiptType != .reedem) self?.messageTitleLabel.text = "control_number_text".localized() + " \(controlNumber ?? "")" self?.reedemButton.isHidden = (self?.receiptType != .reedem) } } ).disposed(by: disposeBag) } } // MARK: - BiometricAuthenticationViewControllerDelegate extension InboundReceiptViewController: BiometricAuthenticationViewControllerDelegate { func viewController( _ viewController: BiometricAuthenticationViewController, didFailWithError error: BiometricAuthenticationError, errorMessage: String?) { print("BiometricAuthenticationWireframe Error: \(errorMessage ?? "")") viewController.dismiss(animated: true) { switch error { case .userFallback: self.showSecureKeyPad() case .authenticationFailed, .userCancel, .biometryNotAvailable, .biometryNotEnrolled, .biometryLockout, .notBeConfigured: self.alert(type: .error, message: error.message) } } } func doSelectLocalAuthenticationPolicy( _ viewController: BiometricAuthenticationViewController ) -> BiometricAuthenticationPolicy { return .deviceOwnerAuthenticationWithBiometrics } func didComplete(_ viewController: BiometricAuthenticationViewController) { viewController.dismiss(animated: true) { guard let encryptedPW = KeyChain.shared.get(key: .password) else { MainWireframe.logoutWarningAlert(message: "To use biometrics authentication you have to login again.") return } self.password = encryptedPW } } func viewController( _ viewController: BiometricAuthenticationViewController, informationTitleLabel titleLabel: UILabel, authenticationButton button: UIButton ) { titleLabel.text = "use_biometric_authentication_text".localized() button.setTitle("verify_account_button_text".localized(), for: .normal) } } // MARK: InboundReceiptViewInterface extension InboundReceiptViewController: InboundReceiptViewInterface { func showLoading() { self.showProgressHud() } func hideLoading() { self.hideProgressHud() } func show(error: String) { self.alert(type: .error, message: error) } func show(message: String) { self.alertWithOk( type: .success, message: message, title: "success_text".localized(), okTitle: "Ok" ) { self.navigationController?.popToRootViewController(animated: true) } } }