Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(GiniHealthSDK): Fix RC bugs reported #749

Merged
merged 24 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fc02ed8
fix(GiniHealthSDKExample): Fix brand view configuration option
razvancapra Nov 27, 2024
bd1d56a
Merge branch 'main' into fix-RC-bugs-reported
razvancapra Nov 28, 2024
df04307
fix(GiniHealthSDK): Fix No Open With Bottom Sheet is displayed after …
razvancapra Nov 28, 2024
f7561b3
fix(GiniInternalPaymentSDK): Fix Page Control Missing in Payment Revi…
razvancapra Nov 29, 2024
841dac4
fix(GiniInternalPaymentSDK): Fix payment review screen document heade…
razvancapra Nov 29, 2024
f7fec97
fix(GiniHealthSDK): Fix navigating to paymentinfo from paymentreview …
razvancapra Dec 2, 2024
b0ad33e
fix(GiniHealthSDK): Issues related to uploading non payable invoice
razvancapra Dec 2, 2024
47f952e
fix(GiniHealthSDK): Fix import two payable invoices should throw error
razvancapra Dec 2, 2024
41191eb
fix(GiniHealthSDK): Fix "FAQ" heading for the FAQ section
razvancapra Dec 2, 2024
9f6f0dd
fix(GiniMerchantSDK): Fix MerchantSDK failing test
razvancapra Dec 2, 2024
86c4ee0
fix(GiniHealthSDK): Fix GiniHealthSDK tests
razvancapra Dec 2, 2024
e79c67b
fix(GiniHealthSDK): Fix PR suggestions
razvancapra Dec 6, 2024
c3f7830
fix(GinIHealthSDK): Revert docId instead of documentId
razvancapra Dec 9, 2024
fc882e9
fix(GinIHealthSDK): Fix docId revert changes in tests
razvancapra Dec 9, 2024
4fba073
fix(GiniHealthExampleApp): Fix documentId revert fixes
razvancapra Dec 9, 2024
4d7be4f
fix(GiniHealthSDK): Handle edge case flow for PaymentReviewScreen
razvancapra Dec 9, 2024
9e58ce9
Merge branch 'main' into fix-RC-bugs-reported
razvancapra Dec 19, 2024
36e9498
fix(GiniHealthSDK): Lang fix
razvancapra Dec 19, 2024
cf61fc4
fix(GiniHealthSDK): Fix Sonarcloud suggestions
razvancapra Dec 19, 2024
d1215a0
fix(GiniHealthSDK): Fix edge case flow on payment info dissapearing f…
razvancapra Dec 19, 2024
6a608cf
fix(GiniHealthSDK): Fix pageControl visibility
razvancapra Dec 19, 2024
7941a91
feat(GiniUtilities): Bumps version 2.0.0
ValentinaIancu-Gini Dec 20, 2024
7859bb3
feat(GiniInternalPaymentSDK): Bumps version 1.1.0
ValentinaIancu-Gini Dec 20, 2024
5d1900a
feat(GiniHealthSDK): Bumps version 5.0.1
ValentinaIancu-Gini Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public struct PaymentInfoConfiguration {
}

public struct PaymentInfoStrings {
let giniWebsiteText : String
let giniWebsiteText: String
let giniURLText: String

let questionsTitleText: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ public final class PaymentInfoViewModel {
let attributedString = attributedString
let giniRange = (attributedString.string as NSString).range(of: strings.giniWebsiteText)
attributedString.addLinkToRange(link: strings.giniURLText,
color: configuration.linksColor,
range: giniRange,
linkFont: linkFont,
textToRemove: Constants.linkTextToRemove)
let privacyPolicyRange = (attributedString.string as NSString).range(of: strings.answerPrivacyPolicyText)
attributedString.addLinkToRange(link: strings.privacyPolicyURLText,
color: configuration.linksColor,
range: privacyPolicyRange,
linkFont: linkFont,
textToRemove: Constants.linkTextToRemove)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public protocol PaymentReviewActionProtocol {
func updatedPaymentProvider(_ paymentProvider: PaymentProvider)
func openMoreInformationViewController()
func presentShareInvoiceBottomSheet(paymentRequestId: String, paymentInfo: PaymentInfo)
func paymentReviewClosed(with previousPresentedView: PaymentComponentScreenType?)
}

/**
Expand Down Expand Up @@ -123,6 +124,7 @@ public class PaymentReviewModel: NSObject {
let bottomSheetConfiguration: BottomSheetConfiguration
let showPaymentReviewCloseButton: Bool
var displayMode: DisplayMode
var previousPaymentComponentScreenType: PaymentComponentScreenType?

public init(delegate: PaymentReviewProtocol,
bottomSheetsProvider: BottomSheetsProviderProtocol,
Expand All @@ -142,7 +144,8 @@ public class PaymentReviewModel: NSObject {
poweredByGiniConfiguration: PoweredByGiniConfiguration,
poweredByGiniStrings: PoweredByGiniStrings,
bottomSheetConfiguration: BottomSheetConfiguration,
showPaymentReviewCloseButton: Bool) {
showPaymentReviewCloseButton: Bool,
previousPaymentComponentScreenType: PaymentComponentScreenType?) {
self.delegate = delegate
self.bottomSheetsProvider = bottomSheetsProvider
self.configuration = configuration
Expand All @@ -164,6 +167,11 @@ public class PaymentReviewModel: NSObject {
self.selectionStyleInputFieldConfiguration = selectionStyleInputFieldConfiguration
self.bottomSheetConfiguration = bottomSheetConfiguration
self.displayMode = document != nil ? .documentCollection : .bottomSheet
self.previousPaymentComponentScreenType = previousPaymentComponentScreenType
}

func viewDidDisappear() {
delegate?.paymentReviewClosed(with: previousPaymentComponentScreenType)
}

func getCellViewModel(at indexPath: IndexPath) -> PageCollectionCellViewModel {
Expand Down Expand Up @@ -313,6 +321,7 @@ extension PaymentReviewModel: BanksSelectionProtocol {
This function notifies the delegate to open the "More Information" view controller.
*/
public func didTapOnMoreInformation() {
previousPaymentComponentScreenType = .bankPicker
delegate?.openMoreInformationViewController()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public final class PaymentReviewViewController: BottomSheetViewController, UIGes
private lazy var closeButton = buildCloseButton()
private lazy var infoBar = buildInfoBar()
private lazy var infoBarLabel = buildInfoBarLabel()
private lazy var containerCollectionView = buildContainerCollectionView()
private var isInfoBarHidden = true
lazy var paymentInfoContainerView = buildPaymentInfoContainerView()
lazy var collectionView = buildCollectionView()
Expand Down Expand Up @@ -62,6 +61,10 @@ public final class PaymentReviewViewController: BottomSheetViewController, UIGes
showInfoBar()
showInfoBarOnce = false
}
if model.previousPaymentComponentScreenType == .bankPicker {
model.openBankSelectionBottomSheet()
model.previousPaymentComponentScreenType = nil
}
}

fileprivate func setupViewModel() {
Expand Down Expand Up @@ -131,7 +134,9 @@ public final class PaymentReviewViewController: BottomSheetViewController, UIGes
}

override public func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
unsubscribeFromNotifications()
model.viewDidDisappear()
}

public override var preferredStatusBarStyle: UIStatusBarStyle {
Expand Down Expand Up @@ -354,14 +359,6 @@ fileprivate extension PaymentReviewViewController {

//MARK: - Collection View Container
fileprivate extension PaymentReviewViewController {
func buildContainerCollectionView() -> UIStackView {
let container = UIStackView(arrangedSubviews: [collectionView, pageControl])
container.spacing = 0
container.axis = .vertical
container.distribution = .fill
return container
}

func buildCollectionView() -> UICollectionView {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.minimumInteritemSpacing = Constants.collectionViewPadding
Expand All @@ -380,26 +377,34 @@ fileprivate extension PaymentReviewViewController {
let control = UIPageControl()
control.pageIndicatorTintColor = model.configuration.pageIndicatorTintColor
control.currentPageIndicatorTintColor = model.configuration.currentPageIndicatorTintColor
control.backgroundColor = model.configuration.backgroundColor
control.backgroundColor = .clear
control.hidesForSinglePage = true
control.numberOfPages = model.document?.pageCount ?? 0
return control
}

func layoutContainerCollectionView() {
containerCollectionView.translatesAutoresizingMaskIntoConstraints = false
mainView.addSubview(containerCollectionView)
mainView.sendSubviewToBack(containerCollectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
pageControl.translatesAutoresizingMaskIntoConstraints = false
mainView.addSubview(pageControl)
mainView.sendSubviewToBack(pageControl)

mainView.addSubview(collectionView)
mainView.sendSubviewToBack(collectionView)

let navigationBarHeight = self.navigationController?.navigationBar.frame.maxY ?? 0

NSLayoutConstraint.activate([
containerCollectionView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor),
containerCollectionView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor),
containerCollectionView.topAnchor.constraint(equalTo: mainView.topAnchor),
containerCollectionView.bottomAnchor.constraint(equalTo: paymentInfoContainerView.topAnchor, constant: Constants.collectionViewBottomPadding),
collectionView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: mainView.topAnchor, constant: navigationBarHeight),
collectionView.bottomAnchor.constraint(equalTo: paymentInfoContainerView.topAnchor, constant: Constants.collectionViewBottomPadding),

pageControl.heightAnchor.constraint(equalToConstant: Constants.pageControlHeight),
collectionView.widthAnchor.constraint(equalTo: containerCollectionView.widthAnchor),
collectionView.heightAnchor.constraint(equalTo: containerCollectionView.heightAnchor),
pageControl.bottomAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: -Constants.collectionViewPadding),
pageControl.centerXAnchor.constraint(equalTo: mainView.centerXAnchor),
collectionView.widthAnchor.constraint(equalTo: collectionView.widthAnchor),
collectionView.heightAnchor.constraint(equalTo: collectionView.heightAnchor),
paymentInfoContainerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
paymentInfoContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import UIKit

extension NSMutableAttributedString {
public func addLinkToRange(link: String, range: NSRange, linkFont: UIFont, textToRemove: String?) {
var attributes: [NSAttributedString.Key: Any] = [.font: linkFont]
public func addLinkToRange(link: String, color: UIColor, range: NSRange, linkFont: UIFont, textToRemove: String?) {
var attributes: [NSAttributedString.Key: Any] = [.font: linkFont, .foregroundColor: color]
if range.length > 0, let url = URL(string: link) {
attributes[.link] = url
self.addAttributes(attributes, range: range)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ extension PaymentComponentsController {
if previousPresentedViews.count > 0, previousPresentedViews.first != .paymentReview {
previousPresentedViews.removeAll()
}
previousPresentedViews.insert(.bankPicker)
let paymentProvidersBottomViewModel = BanksBottomViewModel(paymentProviders: paymentProviders,
selectedPaymentProvider: healthSelectedPaymentProvider,
configuration: configurationProvider.bankSelectionConfiguration,
Expand Down Expand Up @@ -182,7 +181,8 @@ extension PaymentComponentsController {
*/
func loadPaymentReviewScreenFor(trackingDelegate: GiniHealthTrackingDelegate?,
completion: @escaping (UIViewController?, GiniHealthError?) -> Void) {
previousPresentedViews.insert(.paymentReview)
previousPresentedViews.append(.paymentReview)
let previousPaymentComponentScreenType: PaymentComponentScreenType? = previousPresentedViews.contains(.bankPicker) ? .bankPicker : nil
if !GiniHealthConfiguration.shared.useInvoiceWithoutDocument {
guard let documentId else {
completion(nil, nil)
Expand All @@ -197,26 +197,35 @@ extension PaymentComponentsController {
completion(nil, nil)
return
}
self.preparePaymentReviewViewController(data: data, paymentInfo: nil, completion: completion)
self.preparePaymentReviewViewController(data: data,
paymentInfo: nil,
previousPaymentComponentScreenType: previousPaymentComponentScreenType,
completion: completion)
case .failure(let error):
completion(nil, error)
}
}
} else {
loadPaymentReviewScreenWithoutDocument(paymentInfo: paymentInfo, trackingDelegate: trackingDelegate, completion: completion)
loadPaymentReviewScreenWithoutDocument(paymentInfo: paymentInfo,
trackingDelegate: trackingDelegate,
previousPaymentComponentScreenType: previousPaymentComponentScreenType,
completion: completion)
}
}

private func loadPaymentReviewScreenWithoutDocument(paymentInfo: GiniInternalPaymentSDK.PaymentInfo?,
trackingDelegate: GiniHealthTrackingDelegate?,
previousPaymentComponentScreenType: PaymentComponentScreenType? = nil,
completion: @escaping (UIViewController?, GiniHealthError?) -> Void) {
preparePaymentReviewViewController(data: nil,
paymentInfo: paymentInfo,
previousPaymentComponentScreenType: previousPaymentComponentScreenType,
completion: completion)
}

private func preparePaymentReviewViewController(data: DataForReview?,
paymentInfo: GiniInternalPaymentSDK.PaymentInfo?,
previousPaymentComponentScreenType: PaymentComponentScreenType? = nil,
completion: @escaping (UIViewController?, GiniHealthError?) -> Void) {
guard let healthSelectedPaymentProvider else {
completion(nil, nil)
Expand All @@ -240,7 +249,8 @@ extension PaymentComponentsController {
poweredByGiniConfiguration: configurationProvider.poweredByGiniConfiguration,
poweredByGiniStrings: stringsProvider.poweredByGiniStrings,
bottomSheetConfiguration: configurationProvider.bottomSheetConfiguration,
showPaymentReviewCloseButton: configurationProvider.showPaymentReviewCloseButton)
showPaymentReviewCloseButton: configurationProvider.showPaymentReviewCloseButton,
previousPaymentComponentScreenType: previousPaymentComponentScreenType)

let vc = PaymentReviewViewController.instantiate(viewModel: viewModel,
selectedPaymentProvider: healthSelectedPaymentProvider)
Expand Down Expand Up @@ -309,6 +319,7 @@ extension PaymentComponentsController {
shareInvoiceBottomViewModel.viewDelegate = self
shareInvoiceBottomViewModel.documentId = documentId
let shareInvoiceBottomView = ShareInvoiceBottomView(viewModel: shareInvoiceBottomViewModel, bottomSheetConfiguration: configurationProvider.bottomSheetConfiguration)
shareInvoiceBottomSheet = shareInvoiceBottomView
return shareInvoiceBottomView
}

Expand All @@ -324,6 +335,18 @@ extension PaymentComponentsController {
storeDefaultPaymentProvider(paymentProvider: provider)
}
}

/**
Notifies the controller that the Payment Review Screen has closed, enabling the cleanup of stored data used to manage various flows.
*/
public func paymentReviewClosed(with previousPresentedView: PaymentComponentScreenType?) {
shareInvoiceBottomSheet = nil
if previousPresentedView == .bankPicker {
previousPresentedViews.append(.bankPicker)
} else {
previousPresentedViews.removeAll()
}
}

/**
Opens the more information view controller by notifying the view delegate. This method is used when opening the More Information screen inside the bank selection bottom sheet that's presented in the Payment Review Screen.
Expand Down Expand Up @@ -399,7 +422,12 @@ extension PaymentComponentsController {
return
}

self?.sharePDF(pdfURL: pdfPath, paymentRequestId: paymentRequestId, viewController: viewController) { [weak self] (activity, _, _, _) in
self?.sharePDF(pdfURL: pdfPath, paymentRequestId: paymentRequestId, viewController: viewController) { [weak self] (activity, actionOnShareSheet, _, _) in
if !actionOnShareSheet {
guard let shareInvoiceBottomSheet = self?.shareInvoiceBottomSheet else { return }
self?.dismissAndPresent(viewController: shareInvoiceBottomSheet, animated: false)
}

guard activity != nil else {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ protocol PaymentComponentsProtocol {
func checkIfDocumentIsPayable(docId: String, completion: @escaping (Result<Bool, GiniHealthError>) -> Void)
func paymentView() -> UIView
func bankSelectionBottomSheet() -> UIViewController
func loadPaymentReviewScreenFor(trackingDelegate: GiniHealthTrackingDelegate?, completion: @escaping (UIViewController?, GiniHealthError?) -> Void)
func loadPaymentReviewScreenFor(trackingDelegate: GiniHealthTrackingDelegate?,
previousPaymentComponentScreenType: PaymentComponentScreenType?,
completion: @escaping (UIViewController?, GiniHealthError?) -> Void)
func paymentInfoViewController() -> UIViewController
func paymentViewBottomSheet() -> UIViewController
}
Expand Down Expand Up @@ -98,7 +100,7 @@ public final class PaymentComponentsController: BottomSheetsProviderProtocol, Gi
}

/// Previous presented view
var previousPresentedViews: Set<PaymentComponentScreenType> = []
var previousPresentedViews: [PaymentComponentScreenType] = []
// Client's navigation controller provided in order to handle all HealthSDK flows
weak var navigationControllerProvided: UINavigationController?
// Payment Information from the invoice that contains a document or not
Expand All @@ -107,7 +109,9 @@ public final class PaymentComponentsController: BottomSheetsProviderProtocol, Gi
var documentId: String?
// Errors stack received from API. We will show them for the clients
var errors: [String] = []


// Store Share Bottom Sheet for dismissed native share modal
var shareInvoiceBottomSheet: ShareInvoiceBottomView?
/**
Initializer of the Payment Component Controller class.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"gini.health.paymentcomponent.payment.info.pay.bills.title.label" = "Pay bills easily with the banking app.";
"gini.health.paymentcomponent.payment.info.pay.bills.description.label" = "Medical bills and other submitted receipts can now be paid very easily.\nThe payment data such as IBAN, amount, recipient and purpose are seamlessly transferred to the banking app, and the payment only needs to be confirmed there.\nYou can also park the invoice and pay it within 3 months after uploading.\nThe data is encrypted and transferred securely to your banking app. The data protection regulations of your bank apply.\nSupported by the largest banks. Integration by Gini[LINK].";
"gini.health.paymentcomponent.payment.info.pay.bills.description.clickable.text" = "Gini[LINK]";
"gini.health.paymentcomponent.paymentinfo.questions.title.label" = "Frequently asked questions";
"gini.health.paymentcomponent.payment.info.questions.title.label" = "Frequently Asked Questions";
"gini.health.paymentcomponent.payment.info.questions.question.1" = "Can I submit invoices and pay them later?";
"gini.health.paymentcomponent.payment.info.questions.question.2" = "Is the service free of charge?";
"gini.health.paymentcomponent.payment.info.questions.question.3" = "Is my data secure?";
Expand Down
Loading