Browse Source

Merge branch 'bug_fix'

pull/1/head
InKwon James Kim 5 years ago
parent
commit
0ba14e13f8
  1. BIN
      .DS_Store
  2. 28
      GME Remit.xcodeproj/project.pbxproj
  3. 9
      GME Remit/APIs/Router/APIRouter.swift
  4. 1
      GME Remit/Modules/Home/User Interface/Wireframe/HomeWireframe.swift
  5. 5
      GME Remit/Modules/RegisterModules/Register/User Interface/Wireframe/RegisterWireframe.swift
  6. 1
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/View/NewRegisterViewController.swift
  7. 10
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/Wireframe/NewRegisterWireframe.swift
  8. 16
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Interactor/NewRegisterStep1Interactor.swift
  9. 5
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Interactor/NewRegisterStep1InteractorIO.swift
  10. 34
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/KYCInfromation.swift
  11. 21
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/KeyValue.swift
  12. 79
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PersonalInformation.swift
  13. 23
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PictureInformation.swift
  14. 100
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PrimaryInformation.swift
  15. 12
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PropertyUtility.swift
  16. 7
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Service/NewRegisterStep1Service.swift
  17. 5
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Service/NewRegisterStep1ServiceType.swift
  18. 186
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/Presenter/NewRegisterStep1Presenter.swift
  19. 131
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/View/NewRegisterStep1.storyboard
  20. 284
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/View/NewRegisterStep1ViewController.swift
  21. 4
      GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/BalanceModel.swift
  22. 3
      GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModel.swift
  23. 1
      GME Remit/Modules/SplashScreen/User Interface/Wireframe/SplashScreenWireframe.swift
  24. 2
      GME Remit/MultiLanguages/ur-PK.lproj/Localizable.strings
  25. 8
      GME Remit/Utilities/CustomUI/ValidationTextField.swift
  26. 37
      GME Remit/Utilities/HotLine/Application Logic/Service/HotLineService.swift
  27. 2
      GME Remit/Utilities/TablePresenter/User Interface/View/TablePresenter.storyboard
  28. 20
      GME RemitTests/APITest.swift

BIN
.DS_Store

28
GME Remit.xcodeproj/project.pbxproj

@ -374,6 +374,10 @@
7389601422C2F208003FEA90 /* TablePresenterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7389600922C2F208003FEA90 /* TablePresenterViewController.swift */; };
7389601922C2FADD003FEA90 /* TableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7389601822C2FADD003FEA90 /* TableCell.swift */; };
738B3E4C233B56C6000EA5E5 /* UISearchBar+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738B3E4B233B56C6000EA5E5 /* UISearchBar+Ext.swift */; };
738D727F239F3089006B4EA7 /* KYCInfromation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D727E239F3089006B4EA7 /* KYCInfromation.swift */; };
738D7281239F31C4006B4EA7 /* PersonalInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D7280239F31C4006B4EA7 /* PersonalInformation.swift */; };
738D7283239F3243006B4EA7 /* PrimaryInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D7282239F3243006B4EA7 /* PrimaryInformation.swift */; };
738D7285239F32C7006B4EA7 /* PictureInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D7284239F32C7006B4EA7 /* PictureInformation.swift */; };
738DEC1B22D429AB00936C2C /* FunctionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738DEC1A22D429AB00936C2C /* FunctionTest.swift */; };
738F04B12316238600BA5EE7 /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738F04B02316238600BA5EE7 /* ShadowView.swift */; };
738FD48023038FDE008B144D /* UIFont+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738FD47F23038FDE008B144D /* UIFont+Ext.swift */; };
@ -469,6 +473,7 @@
73A6E20322CEE51600E9BC68 /* UIBarButtonItem+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A6E1FF22CEE51600E9BC68 /* UIBarButtonItem+Ext.swift */; };
73A6E20422CEE51600E9BC68 /* BadgeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A6E20022CEE51600E9BC68 /* BadgeLabel.swift */; };
73A6E20722CF2E2500E9BC68 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A6E20622CF2E2500E9BC68 /* CopyableLabel.swift */; };
73ABF00F23A06F0500E2C5B9 /* PropertyUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73ABF00E23A06F0500E2C5B9 /* PropertyUtility.swift */; };
73AEFF562334744E00A967FB /* DomesticRemitResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73AEFF552334744E00A967FB /* DomesticRemitResponseModel.swift */; };
73AEFF702334A13100A967FB /* TransactionHistoryGroupModuleInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73AEFF5B2334A13100A967FB /* TransactionHistoryGroupModuleInterface.swift */; };
73AEFF712334A13100A967FB /* TransactionHistoryGroupServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73AEFF5F2334A13100A967FB /* TransactionHistoryGroupServiceType.swift */; };
@ -2765,6 +2770,10 @@
7389600922C2F208003FEA90 /* TablePresenterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TablePresenterViewController.swift; sourceTree = "<group>"; };
7389601822C2FADD003FEA90 /* TableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableCell.swift; sourceTree = "<group>"; };
738B3E4B233B56C6000EA5E5 /* UISearchBar+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UISearchBar+Ext.swift"; sourceTree = "<group>"; };
738D727E239F3089006B4EA7 /* KYCInfromation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KYCInfromation.swift; sourceTree = "<group>"; };
738D7280239F31C4006B4EA7 /* PersonalInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersonalInformation.swift; sourceTree = "<group>"; };
738D7282239F3243006B4EA7 /* PrimaryInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryInformation.swift; sourceTree = "<group>"; };
738D7284239F32C7006B4EA7 /* PictureInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PictureInformation.swift; sourceTree = "<group>"; };
738DEC1A22D429AB00936C2C /* FunctionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionTest.swift; sourceTree = "<group>"; };
738F04B02316238600BA5EE7 /* ShadowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowView.swift; sourceTree = "<group>"; };
738FD47F23038FDE008B144D /* UIFont+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Ext.swift"; sourceTree = "<group>"; };
@ -2863,6 +2872,7 @@
73A6E1FF22CEE51600E9BC68 /* UIBarButtonItem+Ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+Ext.swift"; sourceTree = "<group>"; };
73A6E20022CEE51600E9BC68 /* BadgeLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BadgeLabel.swift; sourceTree = "<group>"; };
73A6E20622CF2E2500E9BC68 /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
73ABF00E23A06F0500E2C5B9 /* PropertyUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyUtility.swift; sourceTree = "<group>"; };
73AEFF552334744E00A967FB /* DomesticRemitResponseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticRemitResponseModel.swift; sourceTree = "<group>"; };
73AEFF5B2334A13100A967FB /* TransactionHistoryGroupModuleInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryGroupModuleInterface.swift; sourceTree = "<group>"; };
73AEFF5F2334A13100A967FB /* TransactionHistoryGroupServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryGroupServiceType.swift; sourceTree = "<group>"; };
@ -6912,6 +6922,11 @@
isa = PBXGroup;
children = (
737FB6552395DF8300EA4AED /* KeyValue.swift */,
738D727E239F3089006B4EA7 /* KYCInfromation.swift */,
738D7280239F31C4006B4EA7 /* PersonalInformation.swift */,
738D7282239F3243006B4EA7 /* PrimaryInformation.swift */,
738D7284239F32C7006B4EA7 /* PictureInformation.swift */,
73ABF00E23A06F0500E2C5B9 /* PropertyUtility.swift */,
);
path = Model;
sourceTree = "<group>";
@ -15793,6 +15808,7 @@
738B3E4C233B56C6000EA5E5 /* UISearchBar+Ext.swift in Sources */,
D97785AA215DD04400754079 /* TransactionHistoryTableViewCell.swift in Sources */,
73A621622330AD20000FFB5B /* RecentHistoriesInteractor.swift in Sources */,
738D7283239F3243006B4EA7 /* PrimaryInformation.swift in Sources */,
730D7894227A94E1007E517E /* RewardItemCollectionViewCell.swift in Sources */,
736A8C432277EB2A00337A50 /* BiometricNotificationInteractor.swift in Sources */,
D95B5E3921311057000C0B33 /* GmeContactsModuleInterface.swift in Sources */,
@ -15898,6 +15914,7 @@
739045B92378FC9500CD5D8A /* AddInboundAccountWireframeInput.swift in Sources */,
04E36E1D21AE585200783685 /* PennyTestSubmitInteractor.swift in Sources */,
BEC9B004224FC49C00A2DA06 /* BiometricAuthenticationViewInterface.swift in Sources */,
73ABF00F23A06F0500E2C5B9 /* PropertyUtility.swift in Sources */,
73BCCDD1228993040057B161 /* RewardGroupService.swift in Sources */,
73195AB522FD14D500151434 /* SetupRecipientInteractorIO.swift in Sources */,
733A3B9C23554DAF00E6B87E /* RechargePaymentWireframeInputOutput.swift in Sources */,
@ -15997,6 +16014,7 @@
73549BB2236FDD5600AD75D2 /* RechargeHistoryServiceType.swift in Sources */,
73AEFF762334A13100A967FB /* TransactionHistoryGroupWireframeInputOutput.swift in Sources */,
739045D7237921D500CD5D8A /* ManageAccountGroupInteractorIO.swift in Sources */,
738D7281239F31C4006B4EA7 /* PersonalInformation.swift in Sources */,
73D1683C2398D49900E3E01E /* NewRegisterStep3ServiceType.swift in Sources */,
734BF6882353F7D8004E8D60 /* PhoneCardRechargeWireframeInputOutput.swift in Sources */,
73A621642330AD20000FFB5B /* RecentHistoriesPresenter.swift in Sources */,
@ -16144,6 +16162,7 @@
734BF6832353F7D8004E8D60 /* PhoneCardRechargeService.swift in Sources */,
731703CC23221EA0005752DE /* SwipeNavigationController.swift in Sources */,
736A8C402277EB2A00337A50 /* BiometricNotificationModuleInterface.swift in Sources */,
738D727F239F3089006B4EA7 /* KYCInfromation.swift in Sources */,
73149F6422E5AF8000D66B26 /* LauncherScreenServiceType.swift in Sources */,
73EC6C18236984B200060448 /* InternationalTopupWireframeInput.swift in Sources */,
73071ACD2296CF9B008840FD /* HotLineViewInterface.swift in Sources */,
@ -16182,6 +16201,7 @@
D96848CC212D3F2300EF12B1 /* ExchangeRateApiService.swift in Sources */,
7310688623701A1800B6F28A /* RechargeHistory.swift in Sources */,
D9DC108421639E56008F3C51 /* SuccessMessage.swift in Sources */,
738D7285239F32C7006B4EA7 /* PictureInformation.swift in Sources */,
7318534E230EACA400BA9AE3 /* SendMoneyTransFerReasonViewModel.swift in Sources */,
73195ABB22FD14D500151434 /* SetupRecipientViewModelInterface.swift in Sources */,
7389601922C2FADD003FEA90 /* TableCell.swift in Sources */,
@ -16548,7 +16568,7 @@
CODE_SIGN_ENTITLEMENTS = "GME Remit.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 5QB497ZAGT;
ENABLE_BITCODE = NO;
@ -16563,7 +16583,7 @@
"$(inherited)",
"$(PROJECT_DIR)/GME\\ Remit/ThirdParty/virtualKeyboard/mtk_module",
);
MARKETING_VERSION = 2.8.0;
MARKETING_VERSION = 2.8.1;
PRODUCT_BUNDLE_IDENTIFIER = com.gme.gmeremit;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -16583,7 +16603,7 @@
CODE_SIGN_ENTITLEMENTS = "GME Remit.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 5QB497ZAGT;
ENABLE_BITCODE = NO;
@ -16599,7 +16619,7 @@
"$(inherited)",
"$(PROJECT_DIR)/GME\\ Remit/ThirdParty/virtualKeyboard/mtk_module",
);
MARKETING_VERSION = 2.8.0;
MARKETING_VERSION = 2.8.1;
PRODUCT_BUNDLE_IDENTIFIER = com.gme.gmeremit;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

9
GME Remit/APIs/Router/APIRouter.swift

@ -75,6 +75,10 @@ enum APIRouter {
case fetchInboundAccounts
case fetchInboundTransactionHistory(from: String, to: String)
case deleteInboundAccount(model: InboundAccount)
// MARK: - New Registration
case loadKYCInformation
}
// MARK: - Request
@ -486,6 +490,9 @@ extension APIRouter {
case .deleteInboundAccount(let model):
let senderId = GMEDB.shared.user.string(.senderId) ?? ""
return "\(baseUrl)/inbound/mobile/deleteInboundAccount/\(senderId)/\(model.id ?? "")"
case .loadKYCInformation:
let userID = GMEDB.shared.user.string(.userId) ?? ""
return "\(baseUrlWithoutVersion)/v4/Mobile/loadform/\(userID)/kyc"
}
}
}
@ -566,6 +573,8 @@ extension APIRouter {
return .post
case .deleteInboundAccount:
return .post
case .loadKYCInformation:
return .get
}
}

1
GME Remit/Modules/Home/User Interface/Wireframe/HomeWireframe.swift

@ -78,6 +78,7 @@ extension HomeWireframe: HomeWireframeInput {
viewController: KycWireframe().getMainView(),
source: view
)
// NewRegisterWireframe().open(on: view, step: .first)
}
func showPennyTestSubmit() {

5
GME Remit/Modules/RegisterModules/Register/User Interface/Wireframe/RegisterWireframe.swift

@ -51,7 +51,8 @@ extension RegisterWireframe: RegisterWireframeInput {
func showKyc() {
view.navigationController?.pushViewController(KycWireframe().getMainView(), animated: true)
// FIXME: FOR NEW REGISTRATION
// view.navigationController?.pushViewController(NewRegisterWireframe().getMainView(), animated: true)
// if let navigation = self.view.navigationController {
// NewRegisterWireframe().pushMainView(in: navigation)
// }
}
}

1
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/View/NewRegisterViewController.swift

@ -57,6 +57,7 @@ class NewRegisterViewController: UIViewController {
title = "For remittance"
setupNormalNavigation()
setupNavigationShadow(isUse: true)
navigationItem.setHidesBackButton(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {

10
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/Wireframe/NewRegisterWireframe.swift

@ -45,6 +45,16 @@ extension NewRegisterWireframe: NewRegisterWireframeInput {
return viewController
}
func open(on viewcontroller: UIViewController, step: NewRegisterViewController.Step) {
let vc = getMainView()
let naviVC = UINavigationController(rootViewController: vc)
naviVC.modalPresentationStyle = .fullScreen
stepper?.onNext(step)
viewcontroller.present(naviVC, animated: true, completion: nil)
}
func moveStep(to step: NewRegisterViewController.Step) {
switch step {
case .first: move(step1VC)

16
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Interactor/NewRegisterStep1Interactor.swift

@ -15,11 +15,6 @@ class NewRegisterStep1Interactor {
weak var output: NewRegisterStep1InteractorOutput?
private let service: NewRegisterStep1ServiceType
private let genders = [
KeyValue(id: "male", value: "male_text".localized()),
KeyValue(id: "female", value: "female_text".localized()),
KeyValue(id: "other", value: "other_text".localized())
]
// MARK: Initialization
init(service: NewRegisterStep1ServiceType) {
@ -31,7 +26,14 @@ class NewRegisterStep1Interactor {
// MARK: NewRegisterStep1 interactor input interface
extension NewRegisterStep1Interactor: NewRegisterStep1InteractorInput {
func fetchGenders() {
output?.setGenders(genders)
func fetchInformation() {
service.fetchInformation(
success: {[weak self] in
self?.output?.setModel(with: $0)
},
failure: {[weak self] in
self?.output?.setError(with: $0)
}
)
}
}

5
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Interactor/NewRegisterStep1InteractorIO.swift

@ -7,9 +7,10 @@
//
protocol NewRegisterStep1InteractorInput: class {
func fetchGenders()
func fetchInformation()
}
protocol NewRegisterStep1InteractorOutput: class {
func setGenders(_ genders: [KeyValue])
func setModel(with model: KYCInformation)
func setError(with error: Error)
}

34
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/KYCInfromation.swift

@ -0,0 +1,34 @@
//
// KYCInfromation.swift
// GME Remit
//
// Created by InKwon James Kim on 2019/12/10.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
import ObjectMapper
struct KYCInformation: Mappable {
var cities: [KeyValue]?
var banks: [KeyValue]?
var idTypes: [KeyValue]?
var branches: [KeyValue]?
var personalInformation: PersonalInformation?
var primaryInformation: PrimaryInformation?
var pictures: PictureInformation?
init?(map: Map) {
}
mutating func mapping(map: Map) {
cities <- map["City"]
banks <- map["Bank"]
idTypes <- map["IdType"]
branches <- map["Branch"]
personalInformation <- map["personalInformation"]
primaryInformation <- map["primaryInformation"]
pictures <- map["pictures"]
}
}

21
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/KeyValue.swift

@ -6,9 +6,24 @@
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
struct KeyValue {
let id: String
let value: String
import ObjectMapper
struct KeyValue: Mappable {
var id: String?
var value: String?
var dependent: [String]?
init(id: String, value: String) {
self.id = id
self.value = value
}
init?(map: Map) {}
mutating func mapping(map: Map) {
id <- map["id"]
value <- map["text"]
dependent <- map["dependent"]
}
}
extension KeyValue: TablePresenterProtocol {

79
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PersonalInformation.swift

@ -0,0 +1,79 @@
//
// PersonalInformation.swift
// GME Remit
//
// Created by InKwon James Kim on 2019/12/10.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
import ObjectMapper
struct PersonalInformation: Mappable {
var fullName: String?
var gender: String?
var dob: String?
var email: String?
var city: String?
var address: String?
init(
fullName: String?,
gender: String?,
dob: String?,
email: String?,
city: String?,
address: String?
) {
self.fullName = fullName
self.gender = gender
self.dob = dob
self.email = email
self.city = city
self.address = address
}
init?(map: Map) {
}
mutating func mapping(map: Map) {
fullName <- map["fullName"]
gender <- map["gender"]
dob <- map["dob"]
email <- map["email"]
city <- map["city"]
address <- map["address"]
}
}
extension PersonalInformation: Equatable {
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.fullName == rhs.fullName &&
lhs.fullName == rhs.fullName &&
lhs.gender == rhs.gender &&
lhs.dob == rhs.dob &&
lhs.email == rhs.email &&
lhs.city == rhs.city &&
lhs.address == rhs.address
}
}
extension PersonalInformation: PropertyUtility {
func isFilledFully() -> Bool {
return fullName != nil &&
gender != nil &&
dob != nil &&
email != nil &&
city != nil &&
address != nil
}
func isNilFully() -> Bool {
return fullName == nil &&
gender == nil &&
dob == nil &&
email == nil &&
city == nil &&
address == nil
}
}

23
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PictureInformation.swift

@ -0,0 +1,23 @@
//
// PictureInformation.swift
// GME Remit
//
// Created by InKwon James Kim on 2019/12/10.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
import ObjectMapper
struct PictureInformation: Mappable {
var passportPicture: String?
var anotherIDPicture: String?
init?(map: Map) {
}
mutating func mapping(map: Map) {
passportPicture <- map["bankName"]
anotherIDPicture <- map["bankAccount"]
}
}

100
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PrimaryInformation.swift

@ -0,0 +1,100 @@
//
// PrimaryInformation.swift
// GME Remit
//
// Created by InKwon James Kim on 2019/12/10.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
import ObjectMapper
struct PrimaryInformation: Mappable {
var bankID: String?
var bankAccount: String?
var passportNumber: String?
var passportIssueDate: String?
var passportExpiryDate: String?
var anotherIDType: String?
var anotherIDNumber: String?
var anotherIDIssueDate: String?
var anotherIDExpiryDate: String?
var branchID: String?
var refferalCode: String?
init(
bankID: String?,
bankAccount: String?,
passportNumber: String?,
passportIssueDate: String?,
passportExpiryDate: String?,
anotherIDType: String?,
anotherIDNumber: String?,
anotherIDIssueDate: String?,
anotherIDExpiryDate: String?,
branchID: String?,
refferalCode: String?
) {
self.bankID = bankID
self.bankAccount = bankAccount
self.passportNumber = passportNumber
self.passportIssueDate = passportIssueDate
self.passportExpiryDate = passportExpiryDate
self.anotherIDType = anotherIDType
self.anotherIDNumber = anotherIDNumber
self.branchID = branchID
self.refferalCode = refferalCode
}
init?(map: Map) { }
mutating func mapping(map: Map) {
bankID <- map["bankID"]
bankAccount <- map["bankAccount"]
passportNumber <- map["passportNumber"]
passportIssueDate <- map["passportIssueDate"]
passportExpiryDate <- map["passportExpiryDate"]
anotherIDType <- map["anotherIDType"]
anotherIDNumber <- map["anotherIDNumber"]
anotherIDIssueDate <- map["anotherIDIssueDate"]
anotherIDExpiryDate <- map["anotherIDExpiryDate"]
branchID <- map["branchID"]
refferalCode <- map["refferalCode"]
}
}
extension PrimaryInformation: Equatable {
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.bankID == rhs.bankID &&
lhs.bankAccount == rhs.bankAccount &&
lhs.passportNumber == rhs.passportNumber &&
lhs.passportIssueDate == rhs.passportIssueDate &&
lhs.passportExpiryDate == rhs.passportExpiryDate &&
lhs.anotherIDType == rhs.anotherIDType &&
lhs.anotherIDNumber == rhs.anotherIDNumber &&
lhs.branchID == rhs.branchID &&
lhs.refferalCode == rhs.refferalCode
}
}
extension PrimaryInformation: PropertyUtility {
func isFilledFully() -> Bool {
return bankID != nil &&
bankAccount != nil &&
passportNumber != nil &&
passportIssueDate != nil &&
passportExpiryDate != nil &&
branchID != nil
}
func isNilFully() -> Bool {
return bankID == nil &&
bankAccount == nil &&
passportNumber == nil &&
passportIssueDate == nil &&
passportExpiryDate == nil &&
anotherIDType == nil &&
anotherIDNumber == nil &&
branchID == nil &&
refferalCode == nil
}
}

12
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Model/PropertyUtility.swift

@ -0,0 +1,12 @@
//
// IsNilProtocol.swift
// GME Remit
//
// Created by InKwon James Kim on 2019/12/11.
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
//
protocol PropertyUtility {
func isFilledFully() -> Bool
func isNilFully() -> Bool
}

7
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Service/NewRegisterStep1Service.swift

@ -9,5 +9,10 @@
import Foundation
class NewRegisterStep1Service: NewRegisterStep1ServiceType {
func fetchInformation(
success: @escaping (KYCInformation) -> Void,
failure: @escaping (Error) -> Void
) {
APIRouter.loadKYCInformation.json(success: success, failure: failure)
}
}

5
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/Application Logic/Service/NewRegisterStep1ServiceType.swift

@ -7,5 +7,8 @@
//
protocol NewRegisterStep1ServiceType: class {
func fetchInformation(
success: @escaping (KYCInformation) -> Void,
failure: @escaping (Error) -> Void
)
}

186
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/Presenter/NewRegisterStep1Presenter.swift

@ -11,19 +11,63 @@ import RxCocoa
import CoreLocation
class NewRegisterStep1Presenter: ViewModelType {
enum Step {
case innerStep1
case innerStep2
case innerStep3
}
var interactor: NewRegisterStep1InteractorInput?
var wireframe: NewRegisterStep1WireframeInput?
struct Input {
let viewWillAppear: Driver<Void>
let sendLocation: Driver<CLLocation>
let name: Driver<String>
let gender: Driver<KeyValue?>
let dob: Driver<String>
let email: Driver<String>
let city: Driver<KeyValue?>
let address: Driver<String>
let isValidPersonalInfo: Driver<Bool>
let personalInfoSave: Driver<Void>
let bankName: Driver<KeyValue?>
let bankAccount: Driver<String>
let passportNumber: Driver<String>
let passportIssueDate: Driver<String>
let passportExpiryDate: Driver<String>
let anotherIDType: Driver<KeyValue?>
let anotherIDNumber: Driver<String>
let anotherIDIssueDate: Driver<String>
let anotherIDExpiryDate: Driver<String>
let branch: Driver<KeyValue?>
let referralCode: Driver<String>
let isValidPrimaryInfo: Driver<Bool>
let primaryInfoSave: Driver<Void>
let passportImage: Driver<String>
let anotherIDImage: Driver<String>
let isValidPictures: Driver<Bool>
let submit: Driver<Void>
}
struct Output {
let isError: Driver<Error>
let isProgress: Driver<Bool>
let gpsAddress: Driver<String>
let genders: Driver<[KeyValue]>
let model: Driver<KYCInformation>
let cities: Driver<[KeyValue]?>
let banks: Driver<[KeyValue]?>
let idTypes: Driver<[KeyValue]?>
let branches: Driver<[KeyValue]?>
let isSetPersonalInformation: Driver<Bool>
let isSetPrimaryInformation: Driver<Bool>
let isSetPictureInformation: Driver<Bool>
}
private let disposeBag = DisposeBag()
@ -31,11 +75,15 @@ class NewRegisterStep1Presenter: ViewModelType {
private let progressLinker = PublishSubject<Bool>()
private let errorLinker = PublishSubject<Error>()
private let gpsAddress = PublishSubject<String>()
private let genders = PublishSubject<[KeyValue]>()
private let model = PublishSubject<KYCInformation>()
private var storedPersonalInfo = PublishSubject<PersonalInformation?>()
private var storedPrimaryInfo = PublishSubject<PrimaryInformation?>()
private var pictureInformation = PublishSubject<PictureInformation?>()
func transform(input: Input) -> Output {
input.viewWillAppear.drive(onNext: { [weak self] in
self?.interactor?.fetchGenders()
self?.interactor?.fetchInformation()
}).disposed(by: disposeBag)
input.sendLocation.drive(onNext: { [weak self] in
@ -52,26 +100,148 @@ class NewRegisterStep1Presenter: ViewModelType {
if let address: [CLPlacemark] = placemarks {
let name = address.last?.name ?? ""
let locality = address.last?.locality ?? ""
let administrativeArea = address.last?.administrativeArea ?? ""
self?.progressLinker.onNext(false)
self?.gpsAddress.onNext("\(name), \(locality), \(administrativeArea)")
let mergedAddress = "\(name) \(locality)".extract(regex: "[A-Z0-9a-z\\s]")
self?.gpsAddress.onNext(mergedAddress)
}
}
}).disposed(by: disposeBag)
let personalInfo = Driver.combineLatest(
input.isValidPersonalInfo,
input.name,
input.gender,
input.dob,
input.email,
input.city,
input.address
)
.map { (isValid, name, gender, dob, email, city, address) -> PersonalInformation? in
return isValid ? PersonalInformation(
fullName: name,
gender: gender?.id,
dob: dob,
email: email,
city: city?.id,
address: address
) : nil
}
.withLatestFrom(storedPersonalInfo.asDriverOnErrorJustComplete()) { [weak self] (new, stored)
-> PersonalInformation? in
guard let newInfo = new, let storedInfo = stored else {
return new
}
if newInfo == storedInfo {
self?.storedPersonalInfo.onNext(newInfo)
} else {
self?.storedPersonalInfo.onNext(nil)
}
return new
}
let primaryInfo = Driver.combineLatest(
Driver.combineLatest(
input.isValidPrimaryInfo,
input.bankName,
input.bankAccount,
input.passportNumber,
input.passportIssueDate,
input.passportExpiryDate,
input.anotherIDType,
input.anotherIDNumber
).map { (isValid, bank, account, passportNumber, passportIssue, passportExpiry, idType, idNumber) ->
PrimaryInformation? in
return isValid ? PrimaryInformation(
bankID: bank?.id,
bankAccount: account,
passportNumber: passportNumber,
passportIssueDate: passportIssue,
passportExpiryDate: passportExpiry,
anotherIDType: idType?.id,
anotherIDNumber: idNumber,
anotherIDIssueDate: nil,
anotherIDExpiryDate: nil,
branchID: nil,
refferalCode: nil
) : nil
},
input.anotherIDIssueDate,
input.anotherIDExpiryDate,
input.branch,
input.referralCode
).map { (info, issueDate, expiryDate, branch, referralCode) -> PrimaryInformation? in
var primaryInfo = info
primaryInfo?.anotherIDIssueDate = issueDate
primaryInfo?.anotherIDExpiryDate = expiryDate
primaryInfo?.branchID = branch?.id
primaryInfo?.refferalCode = referralCode
return primaryInfo
}
.withLatestFrom(storedPrimaryInfo.asDriverOnErrorJustComplete()) { [weak self] (new, stored)
-> PrimaryInformation? in
guard let newInfo = new, let storedInfo = stored else {
return new
}
if newInfo == storedInfo {
self?.storedPrimaryInfo.onNext(new)
} else {
self?.storedPrimaryInfo.onNext(nil)
}
return new
}
input.personalInfoSave.withLatestFrom(personalInfo) { $1 }
.drive(onNext: {[weak self] in
// TODO: try to save to server the personal information.
// if success save then set personalInformation.
self?.storedPersonalInfo.onNext($0)
}).disposed(by: disposeBag)
input.primaryInfoSave.withLatestFrom(primaryInfo) { $1 }
.drive(onNext: {[weak self] in
// TODO: try to save to server the primary information.
// if success save then set personalInformation.
self?.storedPrimaryInfo.onNext($0)
}).disposed(by: disposeBag)
return Output(
isError: errorLinker.asDriverOnErrorJustComplete(),
isProgress: progressLinker.asDriverOnErrorJustComplete(),
gpsAddress: gpsAddress.asDriverOnErrorJustComplete(),
genders: genders.asDriverOnErrorJustComplete()
model: model.asDriverOnErrorJustComplete(),
cities: model.map {$0.cities}.asDriverOnErrorJustComplete(),
banks: model.map {$0.banks}.asDriverOnErrorJustComplete(),
idTypes: model.map {$0.idTypes}.asDriverOnErrorJustComplete(),
branches: model.map {$0.branches}.asDriverOnErrorJustComplete(),
isSetPersonalInformation: storedPersonalInfo.map {$0 != nil}.asDriverOnErrorJustComplete(),
isSetPrimaryInformation: storedPrimaryInfo.map {$0 != nil}.asDriverOnErrorJustComplete(),
isSetPictureInformation: pictureInformation.map {$0 != nil}.asDriverOnErrorJustComplete()
)
}
}
// MARK: NewRegisterStep1 interactor output interface
extension NewRegisterStep1Presenter: NewRegisterStep1InteractorOutput {
func setGenders(_ genders: [KeyValue]) {
self.genders.onNext(genders)
func setModel(with model: KYCInformation) {
if let personalInfo = model.personalInformation, personalInfo.isFilledFully() {
storedPersonalInfo.onNext(personalInfo)
}
if let primaryInfo = model.primaryInformation, primaryInfo.isFilledFully() {
storedPrimaryInfo.onNext(primaryInfo)
}
self.model.onNext(model)
}
func setError(with error: Error) {
errorLinker.onNext(error)
}
}

131
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/View/NewRegisterStep1.storyboard

@ -29,13 +29,13 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="2200"/>
<subviews>
<view contentMode="scaleToFill" placeholderIntrinsicWidth="375" placeholderIntrinsicHeight="594.5" translatesAutoresizingMaskIntoConstraints="NO" id="Eo4-5K-LDm">
<rect key="frame" x="0.0" y="0.0" width="375" height="1816"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="1922"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CjJ-RL-q3P">
<rect key="frame" x="10" y="10" width="355" height="1796"/>
<rect key="frame" x="10" y="10" width="355" height="1902"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="2uA-JL-3Oz">
<rect key="frame" x="20" y="20" width="315" height="1756"/>
<rect key="frame" x="20" y="20" width="315" height="1862"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="WvQ-u9-oWm">
<rect key="frame" x="0.0" y="0.0" width="315" height="448"/>
@ -71,7 +71,7 @@
</constraints>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<textInputTraits key="textInputTraits" autocapitalizationType="allCharacters" keyboardType="alphabet" textContentType="name"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
@ -123,10 +123,24 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PQu-1T-DIt">
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="City" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="WWd-SN-faL" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="212" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PQu-1T-DIt">
<rect key="frame" x="0.0" y="265" width="315" height="45"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="City" textAlignment="natural" minimumFontSize="12" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="0zs-zK-6RT" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Address" textAlignment="natural" minimumFontSize="12" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="0zs-zK-6RT" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="283" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
@ -166,20 +180,6 @@
</view>
</subviews>
</stackView>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="WWd-SN-faL" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="265" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KNi-XU-GwS">
<rect key="frame" x="0.0" y="318" width="315" height="45"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -209,48 +209,6 @@
</label>
</subviews>
</stackView>
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="WUI-HZ-QMr">
<rect key="frame" x="0.0" y="395.5" width="315" height="155"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="ID" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="arj-sv-FoI" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="315" height="45"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="Wou-NI-wCE"/>
</constraints>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vD6-pU-McH" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="55" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4ZE-9r-JIT">
<rect key="frame" x="0.0" y="110" width="315" height="45"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Qut-dC-Nuf">
<rect key="frame" x="0.0" y="398" width="315" height="50"/>
<color key="backgroundColor" name="ThemeRed"/>
@ -265,7 +223,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="j3E-yb-vrP">
<rect key="frame" x="0.0" y="453" width="315" height="851"/>
<rect key="frame" x="0.0" y="453" width="315" height="957"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="kgU-ls-fiI">
<rect key="frame" x="0.0" y="0.0" width="315" height="25"/>
@ -441,7 +399,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="XyN-QT-Wpa">
<rect key="frame" x="0.0" y="455" width="315" height="151"/>
<rect key="frame" x="0.0" y="455" width="315" height="257"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="ID Type" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="Vhd-vk-O8D" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="315" height="45"/>
@ -474,8 +432,36 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WUg-li-0jE">
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="ID Issue Date" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="uW4-Ta-5m9" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="106" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="ID Expiry Date" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Uyq-gz-9We" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="159" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WUg-li-0jE">
<rect key="frame" x="0.0" y="212" width="315" height="45"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -483,7 +469,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="ZdE-rZ-CFi">
<rect key="frame" x="0.0" y="611" width="315" height="25"/>
<rect key="frame" x="0.0" y="717" width="315" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Information" translatesAutoresizingMaskIntoConstraints="NO" id="SDN-v0-IIX">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
@ -504,7 +490,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="oqJ-jz-Odt">
<rect key="frame" x="0.0" y="641" width="315" height="155"/>
<rect key="frame" x="0.0" y="747" width="315" height="155"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Branch" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Vos-oh-AKP" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="315" height="45"/>
@ -546,7 +532,7 @@
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2bu-5I-m19">
<rect key="frame" x="0.0" y="801" width="315" height="50"/>
<rect key="frame" x="0.0" y="907" width="315" height="50"/>
<color key="backgroundColor" name="ThemeRed"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="3Il-I1-F0E"/>
@ -559,7 +545,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="1qD-b2-Vjx">
<rect key="frame" x="0.0" y="1309" width="315" height="447"/>
<rect key="frame" x="0.0" y="1415" width="315" height="447"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Z47-9g-KfX">
<rect key="frame" x="0.0" y="0.0" width="315" height="25"/>
@ -810,23 +796,24 @@
</view>
<size key="freeformSize" width="375" height="2200"/>
<connections>
<outlet property="addressTextField" destination="0zs-zK-6RT" id="lij-eS-DuP"/>
<outlet property="addressTextField" destination="0zs-zK-6RT" id="zmJ-9P-PB1"/>
<outlet property="bankAccountTextField" destination="df7-Dx-in0" id="Vcf-ph-Lcg"/>
<outlet property="bankInformationContainerView" destination="j3E-yb-vrP" id="bbW-J1-wfS"/>
<outlet property="bankSaveButton" destination="2bu-5I-m19" id="aD6-kc-HTT"/>
<outlet property="bankTextField" destination="0XK-To-osD" id="mCc-YE-RCE"/>
<outlet property="branchTextField" destination="Vos-oh-AKP" id="Yq9-z2-JO3"/>
<outlet property="cityTextField" destination="WWd-SN-faL" id="OYK-e2-57d"/>
<outlet property="dobTextField" destination="aqN-64-wvm" id="oSh-6h-FQH"/>
<outlet property="emailTextField" destination="ci5-SP-G1k" id="tTo-Oz-404"/>
<outlet property="genderTextField" destination="Z0K-Lz-Cz8" id="91L-iH-oaP"/>
<outlet property="gpsButton" destination="PB1-h0-XyN" id="T5g-gF-12i"/>
<outlet property="idExpiryDateTextField" destination="Uyq-gz-9We" id="uer-Xm-y6b"/>
<outlet property="idIssueDateTextField" destination="uW4-Ta-5m9" id="emZ-oc-XVx"/>
<outlet property="idNumberTextField" destination="eJY-lP-END" id="b0Y-YN-uhy"/>
<outlet property="idTextField" destination="arj-sv-FoI" id="I6x-x8-jtV"/>
<outlet property="idTypeTextField" destination="Vhd-vk-O8D" id="p5d-BX-7Hf"/>
<outlet property="passportExpiryDateTextField" destination="Mu4-CD-K1w" id="aXS-DF-nL9"/>
<outlet property="passportIssueDateTextField" destination="XR0-EY-ObA" id="YbT-PY-mCh"/>
<outlet property="passportNumberTextField" destination="Saz-Yf-6le" id="Ahb-ME-Xiv"/>
<outlet property="passwordTextField" destination="vD6-pU-McH" id="hlu-AJ-vnr"/>
<outlet property="personalSaveButton" destination="Qut-dC-Nuf" id="8oa-Vw-76Q"/>
<outlet property="picturesSaveButton" destination="7Mi-XW-eEl" id="Yqy-m3-I5p"/>
<outlet property="referralTextField" destination="fSE-TQ-HgI" id="v8E-Vs-fIk"/>

284
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegisterStep1/User Interface/View/NewRegisterStep1ViewController.swift

@ -20,6 +20,13 @@ class NewRegisterStep1ViewController: UIViewController {
private let disposeBag = DisposeBag()
private let sendLocation = PublishSubject<CLLocation>()
private let locationManager = CLLocationManager()
private let genders = [
KeyValue(id: "M", value: "male_text".localized()),
KeyValue(id: "F", value: "female_text".localized()),
KeyValue(id: "O", value: "other_text".localized())
]
// MARK: Computed Properties
// MARK: IBOutlets
@ -30,13 +37,11 @@ class NewRegisterStep1ViewController: UIViewController {
@IBOutlet private weak var dobTextField: ValidationTextField!
@IBOutlet private weak var emailTextField: ValidationTextField!
@IBOutlet private weak var cityTextField: ValidationTextField!
@IBOutlet private weak var addressTextField: ValidationTextField!
@IBOutlet private weak var gpsButton: UIButton!
@IBOutlet private weak var idTextField: ValidationTextField!
@IBOutlet private weak var passwordTextField: ValidationTextField!
@IBOutlet private weak var bankInformationContainerView: UIStackView!
@IBOutlet private weak var uploadPicturesContainerView: UIStackView!
@ -53,6 +58,8 @@ class NewRegisterStep1ViewController: UIViewController {
@IBOutlet private weak var idTypeTextField: ValidationTextField!
@IBOutlet private weak var idNumberTextField: ValidationTextField!
@IBOutlet private weak var idIssueDateTextField: ValidationTextField!
@IBOutlet private weak var idExpiryDateTextField: ValidationTextField!
@IBOutlet private weak var branchTextField: ValidationTextField!
@IBOutlet private weak var referralTextField: ValidationTextField!
@ -112,50 +119,140 @@ extension NewRegisterStep1ViewController {
}
private func setUI() {
dobTextField.useAsDropDown(items: nil)
bankTextField.useAsDropDown(items: nil)
passportIssueDateTextField.useAsDropDown(items: nil)
passportExpiryDateTextField.useAsDropDown(items: nil)
idTypeTextField.useAsDropDown(items: nil)
branchTextField.useAsDropDown(items: nil)
// continueButton.layer.cornerRadius = 5
dobTextField.useAsDropDown(items: nil)
passportIssueDateTextField.useAsDropDown(items: nil)
passportExpiryDateTextField.useAsDropDown(items: nil)
idIssueDateTextField.useAsDropDown(items: nil)
idExpiryDateTextField.useAsDropDown(items: nil)
personalSaveButton.layer.cornerRadius = 5
bankSaveButton.layer.cornerRadius = 5
picturesSaveButton.layer.cornerRadius = 5
bankInformationContainerView.isHidden = true
uploadPicturesContainerView.isHidden = true
}
private func setUIBinding() {
personalSaveButton.rx.tap.bind {[weak self] in
guard let `self` = self else { return }
self.personalSaveButton.animateHidden(isHidden: true) {
self.bankInformationContainerView.animateHidden(isHidden: false)
}
}.disposed(by: disposeBag)
idIssueDateTextField.isHidden = true
idExpiryDateTextField.isHidden = true
let genderConfigure = TablePresenterConfiguration(presenterTitle: "Select Gender")
genderTextField.useAsDropDown(
with: genderConfigure,
items: genders
)
userNameTextField.validCondition = {!$0.isEmpty && $0.count > 1}
genderTextField.validCondition = {!$0.isEmpty}
dobTextField.validCondition = {!$0.isEmpty}
emailTextField.validCondition = {$0.isEmail()}
cityTextField.validCondition = {!$0.isEmpty}
addressTextField.validCondition = {!$0.isEmpty && $0.count < 50}
bankTextField.validCondition = {!$0.isEmpty}
bankAccountTextField.validCondition = {!$0.isEmpty && $0.count > 9}
passportNumberTextField.validCondition = {!$0.isEmpty && $0.count > 3}
passportIssueDateTextField.validCondition = {!$0.isEmpty}
passportExpiryDateTextField.validCondition = {!$0.isEmpty}
branchTextField.validCondition = {!$0.isEmpty}
bankSaveButton.rx.tap.bind {[weak self] in
guard let `self` = self else { return }
self.bankSaveButton.animateHidden(isHidden: true) {
self.uploadPicturesContainerView.animateHidden(isHidden: false)
}
}.disposed(by: disposeBag)
private func setUIBinding() {
picturesSaveButton.rx.tap.bind {[weak self] in
guard let `self` = self else { return }
self.delegate?.newRegister(self, currentStep: .first, nextStep: .second)
}.disposed(by: disposeBag)
idTypeTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete()
.drive(onNext: { [weak self] idType in
self?.idIssueDateTextField.isHidden = true
self?.idExpiryDateTextField.isHidden = true
idType?.dependent?.forEach {
switch $0 {
case "docIssueDate" :
self?.idIssueDateTextField.isHidden = false
case "docExpiryDate":
self?.idExpiryDateTextField.isHidden = false
default :
self?.idIssueDateTextField.isHidden = true
self?.idExpiryDateTextField.isHidden = true
}
}
}).disposed(by: disposeBag)
setDatePicker(textField: dobTextField, useMaximum: true)
setDatePicker(textField: passportIssueDateTextField, useMaximum: true)
setDatePicker(textField: passportExpiryDateTextField, useMaximum: false, useMinimum: true)
setDatePicker(textField: idIssueDateTextField, useMaximum: true)
setDatePicker(textField: idExpiryDateTextField, useMaximum: false, useMinimum: true)
}
private func setBinding() {
let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))).mapToVoid()
.asDriverOnErrorJustComplete()
let isValidPersonalInfo = Observable.combineLatest(
[
userNameTextField.valid,
genderTextField.valid,
dobTextField.valid,
emailTextField.valid,
cityTextField.valid,
addressTextField.valid
]
).map { $0.allSatisfy { $0 } }
let isValidPrimaryInfo = Observable.combineLatest(
[
bankTextField.valid,
bankAccountTextField.valid,
passportNumberTextField.valid,
passportIssueDateTextField.valid,
passportExpiryDateTextField.valid,
idTypeTextField.valid,
idNumberTextField.valid,
branchTextField.valid,
referralTextField.valid
]
).map { $0.allSatisfy { $0 } }
let input = NewRegisterStep1Presenter.Input(
viewWillAppear: viewWillAppear,
sendLocation: sendLocation.asDriverOnErrorJustComplete()
sendLocation: sendLocation.asDriverOnErrorJustComplete(),
name: userNameTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
gender: genderTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
dob: dobTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
email: emailTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
city: cityTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
address: addressTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
isValidPersonalInfo: isValidPersonalInfo.asDriverOnErrorJustComplete(),
personalInfoSave: personalSaveButton.rx.tap.asDriverOnErrorJustComplete(),
bankName: bankTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
bankAccount: bankAccountTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
passportNumber: passportNumberTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
passportIssueDate: passportIssueDateTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
passportExpiryDate: passportExpiryDateTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
anotherIDType: idTypeTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
anotherIDNumber: idNumberTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
anotherIDIssueDate: idIssueDateTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
anotherIDExpiryDate: idExpiryDateTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
branch: branchTextField.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
referralCode: referralTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
isValidPrimaryInfo: isValidPrimaryInfo.asDriverOnErrorJustComplete(),
primaryInfoSave: bankSaveButton.rx.tap.asDriverOnErrorJustComplete(),
passportImage: userNameTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
anotherIDImage: userNameTextField.rx.text.orEmpty.asDriverOnErrorJustComplete(),
isValidPictures: isValidPrimaryInfo.asDriverOnErrorJustComplete(),
submit: picturesSaveButton.rx.tap.asDriverOnErrorJustComplete()
)
let output = presenter.transform(input: input)
@ -169,17 +266,150 @@ extension NewRegisterStep1ViewController {
onNext: { $0 ? self.showProgressHud() : self.hideProgressHud() }
).disposed(by: disposeBag)
output.gpsAddress.drive(addressTextField.rx.text).disposed(by: disposeBag)
output.gpsAddress.drive(onNext: {[weak self] in
self?.addressTextField.text = $0
self?.addressTextField.sendActions(for: .editingChanged)
}).disposed(by: disposeBag)
output.genders.drive(onNext: { [weak self] in
let genderConfigure = TablePresenterConfiguration(presenterTitle: "Select Gender")
self?.genderTextField.useAsDropDown(
with: genderConfigure,
items: $0
output.cities.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "Select City")
self?.cityTextField.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.banks.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "Select Bank")
self?.bankTextField.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.idTypes.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "Select ID Type")
self?.idTypeTextField.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.branches.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "Select Branch")
self?.branchTextField.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.model.drive(onNext: {[weak self] model in
self?.userNameTextField.text = model.personalInformation?.fullName
self?.userNameTextField.sendActions(for: .editingChanged)
self?.dobTextField.text = model.personalInformation?.dob
self?.dobTextField.sendActions(for: .editingChanged)
self?.emailTextField.text = model.personalInformation?.email
self?.emailTextField.sendActions(for: .editingChanged)
self?.addressTextField.text = model.personalInformation?.address
self?.addressTextField.sendActions(for: .editingChanged)
self?.bankAccountTextField.text = model.primaryInformation?.bankAccount
self?.bankAccountTextField.sendActions(for: .editingChanged)
self?.passportNumberTextField.text = model.primaryInformation?.passportNumber
self?.passportNumberTextField.sendActions(for: .editingChanged)
self?.passportIssueDateTextField.text = model.primaryInformation?.passportIssueDate
self?.passportIssueDateTextField.sendActions(for: .editingChanged)
self?.passportExpiryDateTextField.text = model.primaryInformation?.passportExpiryDate
self?.passportExpiryDateTextField.sendActions(for: .editingChanged)
self?.idNumberTextField.text = model.primaryInformation?.anotherIDNumber
self?.idNumberTextField.sendActions(for: .editingChanged)
self?.referralTextField.text = model.primaryInformation?.refferalCode
self?.referralTextField.sendActions(for: .editingChanged)
self?.genderTextField.didSelect(
item: self?.genders.first {$0.id == model.personalInformation?.gender}
)
self?.cityTextField.didSelect(
item: model.cities?.first {$0.value == model.personalInformation?.city}
)
self?.bankTextField.didSelect(
item: model.banks?.first {$0.id == model.primaryInformation?.bankID}
)
self?.idTypeTextField.didSelect(
item: model.idTypes?.first {$0.id == model.primaryInformation?.anotherIDType}
)
self?.branchTextField.didSelect(
item: model.branches?.first {$0.id == model.primaryInformation?.branchID}
)
}).disposed(by: disposeBag)
output.isSetPersonalInformation
.distinctUntilChanged()
.drive(onNext: {[weak self] isSet in
DispatchQueue.main.async {
if isSet {
self?.personalSaveButton.animateHidden(isHidden: true) {
self?.bankInformationContainerView.animateHidden(isHidden: false)
}
} else {
self?.bankInformationContainerView.animateHidden(isHidden: true) {
self?.personalSaveButton.animateHidden(isHidden: false)
}
}
}
}).disposed(by: disposeBag)
output.isSetPrimaryInformation
.distinctUntilChanged()
.drive(onNext: {[weak self] isSet in
DispatchQueue.main.async {
if isSet {
self?.bankSaveButton.animateHidden(isHidden: true) {
self?.uploadPicturesContainerView.animateHidden(isHidden: false)
}
} else {
self?.uploadPicturesContainerView.animateHidden(isHidden: true) {
self?.bankSaveButton.animateHidden(isHidden: false)
}
}
}
}).disposed(by: disposeBag)
isValidPersonalInfo
.distinctUntilChanged()
.asDriverOnErrorJustComplete().drive(onNext: {[weak self] isEnable in
DispatchQueue.main.async {
self?.personalSaveButton.isEnabled = isEnable
self?.personalSaveButton.backgroundColor = isEnable ? .themeRed : .lightGray
}
}).disposed(by: disposeBag)
isValidPrimaryInfo
.distinctUntilChanged()
.asDriverOnErrorJustComplete().drive(onNext: {[weak self] isEnable in
DispatchQueue.main.async {
self?.bankSaveButton.isEnabled = isEnable
self?.bankSaveButton.backgroundColor = isEnable ? .themeRed : .lightGray
}
}).disposed(by: disposeBag)
}
private func setDatePicker(textField: UITextField, useMaximum: Bool = false, useMinimum: Bool = false) {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
if useMaximum {
datePicker.maximumDate = Date()
}
if useMinimum {
datePicker.minimumDate = Date()
}
textField.inputView = datePicker
datePicker.rx.controlEvent(.valueChanged).withLatestFrom(datePicker.rx.date) {$1}
.asDriverOnErrorJustComplete()
.drive(onNext: {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
textField.text = dateFormatter.string(from: $0)
textField.sendActions(for: .editingChanged)
}).disposed(by: disposeBag)
}
}

4
GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/BalanceModel.swift

@ -29,6 +29,10 @@ struct BalanceModel: Mappable {
var accountType: String?
var productName: String?
init(balance: String?) {
self.balance = balance
}
init?(map: Map) {
}

3
GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModel.swift

@ -228,6 +228,9 @@ extension DomesticRemitViewModel: DomesticRemitViewModelInterface {
if model?.type == "wallet" {
let serviceFee = (try? getInitialDataLinker.value())?.serviceFeeWallet
selectedServiceFeeLinker.onNext(serviceFee)
setBalance(with: BalanceModel(
balance: GMEDB.shared.user.string(.availableBalance)?.currencyToDecimal())
)
} else {
let serviceFee = (try? getInitialDataLinker.value())?.serviceFee
selectedServiceFeeLinker.onNext(serviceFee)

1
GME Remit/Modules/SplashScreen/User Interface/Wireframe/SplashScreenWireframe.swift

@ -43,7 +43,6 @@ extension SplashScreenWireframe: SplashScreenWireframeInput {
func register() {
if let navigation = self.view.navigationController {
registerWireFrame.openRegistrationFromSplash(source: navigation)
// NewRegisterWireframe().pushMainView(in: navigation)
}
}
}

2
GME Remit/MultiLanguages/ur-PK.lproj/Localizable.strings

@ -494,7 +494,7 @@
"address_text" = "پتہ";
"relation_text" = "تعلق";
"reason_text" = "منتقلی کی وجہ";
"payout_country_placeholder_text" = "ادائیگی کا ملک منتخب کریں";
"country_placeholder_text" = "ادائیگی کا ملک منتخب کریں";
"native_country_placeholder_text" = "وصول کنندہ کا آبائی ملک منتخب کریں";
"payment_mode_placeholder_text" = "ادائیگی کا طریقہ منتخب کریں";
"bank_placeholder_text" = "بینک منتخب کریں";

8
GME Remit/Utilities/CustomUI/ValidationTextField.swift

@ -203,11 +203,9 @@ import RxSwift
switch type {
case .default:
inputView = nil
keyboardToolbar.isHidden = false
tintColor = .themeText
case .dropdown:
inputView = UIView()
keyboardToolbar.isHidden = true
tintColor = .clear
let dropdownImage = UIImageView()
@ -251,13 +249,15 @@ import RxSwift
@objc private func editingDidBegin() {
switch type {
case .dropdown:
guard let parentVC = parentContainerViewController() else {
guard let parentVC = parentContainerViewController(), let item = dropwDownItems else {
return
}
keyboardToolbar.isHidden = true
tablePresenterWireframe.openWith(
delegate: self,
model: dropwDownItems,
model: item,
source: parentVC
)
default: ()

37
GME Remit/Utilities/HotLine/Application Logic/Service/HotLineService.swift

@ -20,7 +20,7 @@ class HotLineService: HotLineServiceType {
{
"countryName": "Nepal",
"countryCode": "np",
"remitPhoneNumberNumber": "1811-2934",
"remitPhoneNumber": "1811-2934",
"remitFacebookURL": "https://www.facebook.com/gmenepal/",
"loanPhoneNumber": "010-6584-6864",
"loanFacebookURL": "https://www.facebook.com/gmeloannepal/"
@ -170,7 +170,7 @@ class HotLineService: HotLineServiceType {
{
"countryName": "Nepal",
"countryCode": "np",
"remitPhoneNumberNumber": "1811-2934",
"remitPhoneNumber": "1811-2934",
"remitFacebookURL": "https://www.facebook.com/gmenepal/",
"loanPhoneNumber": "010-6584-6864",
"loanFacebookURL": "https://www.facebook.com/gmeloannepal/"
@ -270,6 +270,39 @@ class HotLineService: HotLineServiceType {
"remitFacebookURL": "https://www.facebook.com/GME-Remittance-Myanmar-295378281070768/",
"loanPhoneNumber": "1811-2938",
"loanFacebookURL": "https://www.facebook.com/GME-Loan-Myanmar-1065401266975499/"
},
{
"countryName": "Kazakhstan",
"countryCode": "kz",
"remitPhoneNumber": "010-2960-6864",
"remitFacebookURL": "https://www.facebook.com/gmerussia/",
"loanPhoneNumber": "010-2960-6864",
"loanFacebookURL": "https://www.facebook.com/GME-Loan-Uzbekistan-307204249997604/"
},
{
"countryName": "Russian Federation",
"countryCode": "ru",
"remitPhoneNumber": "010-2960-6864",
"remitFacebookURL": "https://www.facebook.com/gmerussia/",
"loanPhoneNumber": "010-2960-6864",
"loanFacebookURL": "https://www.facebook.com/GME-Loan-Uzbekistan-307204249997604/"
},
{
"countryName": "Tajikistan",
"countryCode": "tj",
"remitPhoneNumber": "010-2960-6864",
"remitFacebookURL": "https://www.facebook.com/gmerussia/",
"loanPhoneNumber": "010-2960-6864",
"loanFacebookURL": "https://www.facebook.com/GME-Loan-Uzbekistan-307204249997604/"
},
{
"countryName": "Kyrgyzstan",
"countryCode": "kg",
"remitPhoneNumber": "010-2968-6864",
"remitFacebookURL": "https://www.facebook.com/gmerussia/",
"loanPhoneNumber": "010-2968-6864",
"loanFacebookURL": "https://www.facebook.com/GME-Loan-Uzbekistan-307204249997604/"
}
]
}

2
GME Remit/Utilities/TablePresenter/User Interface/View/TablePresenter.storyboard

@ -143,7 +143,7 @@
<constraint firstAttribute="width" secondItem="dLg-4E-6az" secondAttribute="height" multiplier="4:3" id="z1Q-3T-hlB"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Cell Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="J9n-Ka-9S8">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Cell Title" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.80000000000000004" translatesAutoresizingMaskIntoConstraints="NO" id="J9n-Ka-9S8">
<rect key="frame" x="63.5" y="0.0" width="251.5" height="40"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="16"/>

20
GME RemitTests/APITest.swift

@ -296,7 +296,25 @@ class APITest: XCTestCase {
wait(for: [expt], timeout: 5.0)
}
func testTotalAccounts() {
func testLoadFormKYC() {
let service = NewRegisterStep1Service()
let expt = expectation(description: "testLoadFormKYC")
server = .uat
service.fetchInformation(
success: {
XCTAssert($0.cities?.count != 0 , "cities data is wrong")
XCTAssert($0.idTypes?.count != 0 , "idTypes data is wrong")
XCTAssert($0.branches?.count != 0 , "branches data is wrong")
XCTAssert($0.banks?.count != 0 , "banks data is wrong")
expt.fulfill()
},
failure: {
XCTAssert(false, $0.localizedDescription)
expt.fulfill()
}
)
wait(for: [expt], timeout: 5.0)
}
}
Loading…
Cancel
Save