Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -156,6 +156,10 @@ final class OrderListViewController: UIViewController, GhostableViewController {

configureViewModel()
configureSyncingCoordinator()

if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.IPPInAppFeedbackBanner) {
viewModel.displayIPPFeedbackBannerIfEligible()
}
}

override func viewWillAppear(_ animated: Bool) {
Expand Down
95 changes: 95 additions & 0 deletions WooCommerce/Classes/ViewRelated/Orders/OrderListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,47 @@ final class OrderListViewModel {
///
private var isAppActive: Bool = true

private var isCODEnabled: Bool {
guard let codGateway = storageManager.viewStorage.loadPaymentGateway(siteID: siteID, gatewayID: "cod")?.toReadOnly() else {
return false
}
return codGateway.enabled
}

private var isIPPSupportedCountry: Bool {
CardPresentConfigurationLoader().configuration.isSupportedCountry
}

/// Results controller that fetches any IPP transactions via WooCommerce Payments
///
private lazy var IPPOrdersResultsController: ResultsController<StorageOrder> = {
let paymentGateway = Constants.paymentMethodID
let predicate = NSPredicate(
format: "siteID == %lld AND paymentMethodID == %@",
argumentArray: [siteID, paymentGateway]
)
return ResultsController<StorageOrder>(storageManager: storageManager, matching: predicate, sortedBy: [])
}()

/// Results controller that fetches IPP transactions via WooCommerce Payments, within the last 30 days
///
private lazy var recentIPPOrdersResultsController: ResultsController<StorageOrder> = {
let today = Date()
let paymentGateway = Constants.paymentMethodID
let thirtyDaysBeforeToday = Calendar.current.date(
byAdding: .day,
value: -30,
to: today
) ?? Date()

let predicate = NSPredicate(
format: "siteID == %lld AND paymentMethodID == %@ AND datePaid >= %@",
argumentArray: [siteID, paymentGateway, thirtyDaysBeforeToday]
)

return ResultsController<StorageOrder>(storageManager: storageManager, matching: predicate, sortedBy: [])
}()

/// Used for looking up the `OrderStatus` to show in the `OrderTableViewCell`.
///
/// The `OrderStatus` data is fetched from the API by `OrdersTabbedViewModel`.
Expand Down Expand Up @@ -125,6 +166,10 @@ final class OrderListViewModel {
observeForegroundRemoteNotifications()
bindTopBannerState()
loadOrdersBannerVisibility()

if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.IPPInAppFeedbackBanner) {
fetchIPPTransactions()
}
}

func dismissOrdersBanner() {
Expand Down Expand Up @@ -192,6 +237,46 @@ final class OrderListViewModel {
completionHandler: completionHandler)
}

private func fetchIPPTransactions() {
do {
try IPPOrdersResultsController.performFetch()
try recentIPPOrdersResultsController.performFetch()
} catch {
DDLogError("Error fetching IPP transactions: \(error)")
}
}

func displayIPPFeedbackBannerIfEligible() {
if isCODEnabled && isIPPSupportedCountry {
let hasResults = IPPOrdersResultsController.fetchedObjects.isEmpty ? false : true

/// In order to filter WCPay transactions processed through IPP within the last 30 days,
/// we check if these contain `receipt_url` in their metadata, unlike those processed through a website,
/// which doesn't
///
let IPPTransactionsFound = recentIPPOrdersResultsController.fetchedObjects.filter({
$0.customFields.contains(where: {$0.key == Constants.receiptURLKey }) &&
$0.paymentMethodTitle == Constants.paymentMethodTitle})
let IPPresultsCount = IPPTransactionsFound.count

// TODO: Debug. Remove before merging
print("COD enabled? \(isCODEnabled) - Eligible Country? \(isIPPSupportedCountry)")
print("hasResults? \(hasResults)")
print("IPP transactions within 30 days: \(IPPresultsCount)")
print(recentIPPOrdersResultsController.fetchedObjects.map {
("OrderID: \($0.orderID) - PaymentMethodID: \($0.paymentMethodID) (\($0.paymentMethodTitle) - DatePaid: \(String(describing: $0.datePaid))")
})

if !hasResults {
print("0 transactions. Banner 1 shown")
} else if IPPresultsCount < Constants.numberOfTransactions {
print("< 10 transactions within 30 days. Banner 2 shown")
} else if IPPresultsCount >= Constants.numberOfTransactions {
print(">= 10 transactions within 30 days. Banner 3 shown")
}
}
}

private func createQuery() -> FetchResultSnapshotsProvider<StorageOrder>.Query {
let predicateStatus: NSPredicate = {
let excludeSearchCache = NSPredicate(format: "exclusiveForSearch = false")
Expand Down Expand Up @@ -337,3 +422,13 @@ extension OrderListViewModel {
case none
}
}

// MARK: IPP feedback constants
private extension OrderListViewModel {
enum Constants {
static let paymentMethodID = "woocommerce_payments"
static let paymentMethodTitle = "WooCommerce In-Person Payments"
static let receiptURLKey = "receipt_url"
static let numberOfTransactions = 10
}
}