diff --git a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/GiniHealthConfiguration.swift b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/GiniHealthConfiguration.swift index 37010d28a..1986bb893 100644 --- a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/GiniHealthConfiguration.swift +++ b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/GiniHealthConfiguration.swift @@ -37,6 +37,9 @@ public final class GiniHealthConfiguration: NSObject { */ public override init() { super.init() + DispatchQueue.main.async { + self.paymentPDFFileName = NSLocalizedStringPreferredFormat(Constants.defaultPaymentPDFFileKey, comment: "") + } } // MARK: - Payment component view @@ -160,11 +163,34 @@ public final class GiniHealthConfiguration: NSObject { Client's configuration provided from the server */ var clientConfiguration: ClientConfiguration? + + /** + Custom payment information pdf file provided through the QR code flow. + Customization rulles: + - Number of characters for the file name: 25 + - Limit characters to letters, numbers, underscore and dash + */ + public var paymentPDFFileName: String = "" { + didSet { + if !isValidPDFFilename(paymentPDFFileName) { + paymentPDFFileName = NSLocalizedStringPreferredFormat(Constants.defaultPaymentPDFFileKey, comment: "") + } + } + } +} + +extension GiniHealthConfiguration { + private func isValidPDFFilename(_ fileName: String) -> Bool { + let regex = "^[a-zA-Z0-9_-]{1,25}$" // Allows letters, numbers, underscore, and dash, max 25 characters + let response = NSPredicate(format: "SELF MATCHES %@", regex).evaluate(with: fileName) + return response + } } extension GiniHealthConfiguration { private enum Constants { static let defaultButtonsHeight = 56.0 static let minimumButtonsHeight = 44.0 + static let defaultPaymentPDFFileKey = "gini.health.paymentcomponent.share.invoice.pdf.filename.default" } } diff --git a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/PaymentComponentsController+Helpers.swift b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/PaymentComponentsController+Helpers.swift index 7bb600974..2c7fffc00 100644 --- a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/PaymentComponentsController+Helpers.swift +++ b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/PaymentComponentsController+Helpers.swift @@ -462,7 +462,7 @@ extension PaymentComponentsController { do { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) guard let docDirectoryPath = paths.first else { return nil} - let pdfFileName = fileName + Constants.pdfExtension + let pdfFileName = GiniHealthConfiguration.shared.paymentPDFFileName + Constants.pdfExtension let pdfPath = docDirectoryPath.appendingPathComponent(pdfFileName) try data.write(to: pdfPath) return pdfPath diff --git a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de.lproj/Localizable.strings b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de.lproj/Localizable.strings index 882533890..93565aaa1 100644 --- a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de.lproj/Localizable.strings +++ b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de.lproj/Localizable.strings @@ -59,3 +59,4 @@ "gini.health.paymentcomponent.share.invoice.bottom.sheet.title" = "Teilen Sie diesen QR-Zahlungscode mit Ihrer Banking-App"; "gini.health.paymentcomponent.share.invoice.bottom.sheet.description" = "Alternativ können Sin ein Screenshot von dieser Seite machen mit der Fotoüberweisung Funktion der [BANK] öffnen."; "gini.health.paymentcomponent.share.invoice.bottom.sheet.continue.button.text" = "Mit der [BANK]-App teilen"; +"gini.health.paymentcomponent.share.invoice.pdf.filename.default" = "Zahlungsinformationen"; diff --git a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de_informal.lproj/Localizable.strings b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de_informal.lproj/Localizable.strings index b64862f45..033805410 100644 --- a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de_informal.lproj/Localizable.strings +++ b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/de_informal.lproj/Localizable.strings @@ -60,3 +60,4 @@ "gini.health.paymentcomponent.share.invoice.bottom.sheet.title" = "Teile diesen QR-Zahlungscode mit deiner Banking-App"; "gini.health.paymentcomponent.share.invoice.bottom.sheet.description" = "Alternativ kannst du ein Screenshot von dieser Seite machen und mit der Fotoüberweisung Funktion der [BANK] öffnen."; "gini.health.paymentcomponent.share.invoice.bottom.sheet.continue.button.text" = "Mit der [BANK]-App teilen"; +"gini.health.paymentcomponent.share.invoice.pdf.filename.default" = "Zahlungsinformationen"; diff --git a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/en.lproj/Localizable.strings b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/en.lproj/Localizable.strings index fbd4466e1..4d6a38b21 100644 --- a/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/en.lproj/Localizable.strings +++ b/HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Resources/en.lproj/Localizable.strings @@ -59,3 +59,4 @@ "gini.health.paymentcomponent.share.invoice.bottom.sheet.title" = "Share this QR payment code with your banking app"; "gini.health.paymentcomponent.share.invoice.bottom.sheet.description" = "Or take a screenshot and upload it directly in your [BANK] app using the Photo Payment functionality"; "gini.health.paymentcomponent.share.invoice.bottom.sheet.continue.button.text" = "Share with [BANK] app"; +"gini.health.paymentcomponent.share.invoice.pdf.filename.default" = "payment-information"; diff --git a/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/AppCoordinator.swift b/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/AppCoordinator.swift index 917bfdc0a..1f792ee9a 100644 --- a/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/AppCoordinator.swift +++ b/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/AppCoordinator.swift @@ -428,4 +428,9 @@ extension AppCoordinator: DebugMenuDelegate { giniHealthConfiguration.customLocalization = localization health.setConfiguration(giniHealthConfiguration) } + + func didCustomizeQRCodePDFFilename(filename: String) { + giniHealthConfiguration.paymentPDFFileName = filename + health.setConfiguration(giniHealthConfiguration) + } } diff --git a/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/DebugMenuViewController.swift b/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/DebugMenuViewController.swift index 5378ba388..a32e61b14 100644 --- a/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/DebugMenuViewController.swift +++ b/HealthSDK/GiniHealthSDKExample/GiniHealthSDKExample/DebugMenuViewController.swift @@ -19,6 +19,7 @@ enum SwitchType { protocol DebugMenuDelegate: AnyObject { func didChangeSwitchValue(type: SwitchType, isOn: Bool) func didPickNewLocalization(localization: GiniLocalization) + func didCustomizeQRCodePDFFilename(filename: String) // New delegate method } class DebugMenuViewController: UIViewController { @@ -58,6 +59,17 @@ class DebugMenuViewController: UIViewController { private var closeButtonSwitch: UISwitch! private lazy var closeButtonRow: UIStackView = stackView(axis: .horizontal, subviews: [closeButtonOptionLabel, closeButtonSwitch]) + private lazy var qrFilenameOptionLabel: UILabel = rowTitle("QR PDF Filename") + private lazy var qrFilenameTextField: UITextField = { + let textField = UITextField() + textField.translatesAutoresizingMaskIntoConstraints = false + textField.placeholder = "Enter filename" + textField.borderStyle = .roundedRect + textField.addTarget(self, action: #selector(qrFilenameTextFieldChanged(_:)), for: .editingChanged) + return textField + }() + private lazy var qrFilenameRow: UIStackView = stackView(axis: .horizontal, subviews: [qrFilenameOptionLabel, qrFilenameTextField]) + weak var delegate: DebugMenuDelegate? init(showReviewScreen: Bool, @@ -92,7 +104,7 @@ class DebugMenuViewController: UIViewController { view.backgroundColor = UIColor(named: "background") let spacer = UIView() - let mainStackView = stackView(axis: .vertical, subviews: [titleLabel, localizationRow, reviewScreenRow, bottomPaymentComponentEditableRow, closeButtonRow, spacer]) + let mainStackView = stackView(axis: .vertical, subviews: [titleLabel, localizationRow, reviewScreenRow, bottomPaymentComponentEditableRow, closeButtonRow, qrFilenameRow, spacer]) view.addSubview(mainStackView) NSLayoutConstraint.activate([ @@ -104,9 +116,16 @@ class DebugMenuViewController: UIViewController { localizationRow.heightAnchor.constraint(equalToConstant: rowHeight), reviewScreenRow.heightAnchor.constraint(equalToConstant: rowHeight), bottomPaymentComponentEditableRow.heightAnchor.constraint(equalToConstant: rowHeight), - closeButtonRow.heightAnchor.constraint(equalToConstant: rowHeight) + closeButtonRow.heightAnchor.constraint(equalToConstant: rowHeight), + qrFilenameRow.heightAnchor.constraint(equalToConstant: rowHeight) ]) } + + @objc private func qrFilenameTextFieldChanged(_ sender: UITextField) { + if let filename = sender.text { + delegate?.didCustomizeQRCodePDFFilename(filename: filename) + } + } } private extension DebugMenuViewController {