Skip to content

Commit 12c4369

Browse files
authored
[Order Details] Allow failed orders to show receipt if eligible (#15558)
2 parents 71ffd4e + 3862c54 commit 12c4369

File tree

5 files changed

+202
-95
lines changed

5 files changed

+202
-95
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
22.4
55
-----
6+
- [*] Payments: Receipts for failed transactions are now available in Order details [https://github.com/woocommerce/woocommerce-ios/pull/15558]
67
- [*] Order Details: Improvements to textfield capitalization rules [https://github.com/woocommerce/woocommerce-ios/pull/15611]
78
- [*] POS: Scrolling search results now dismisses the keyboard [https://github.com/woocommerce/woocommerce-ios/pull/15606]
89
- [*] POS: Product search shows popular products before a search is entered. [https://github.com/woocommerce/woocommerce-ios/pull/15625]

WooCommerce/Classes/ViewModels/Order Details/OrderDetailsDataSource.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,11 +1525,10 @@ extension OrderDetailsDataSource {
15251525

15261526
@MainActor
15271527
private func isEligibleForBackendReceipt() async -> Bool {
1528-
guard !isEligibleForPayment else { return false }
15291528
return await withCheckedContinuation { continuation in
1530-
receiptEligibilityUseCase.isEligibleForBackendReceipts { isEligible in
1529+
receiptEligibilityUseCase.isEligibleForReceipt(order.status, onCompletion: { isEligible in
15311530
continuation.resume(returning: isEligible)
1532-
}
1531+
})
15331532
}
15341533
}
15351534

@@ -1545,15 +1544,6 @@ extension OrderDetailsDataSource {
15451544
return refundFound
15461545
}
15471546

1548-
private func isEligibleForBackendReceipt(completion: @escaping (Bool) -> Void) {
1549-
guard !isEligibleForPayment else {
1550-
return completion(false)
1551-
}
1552-
receiptEligibilityUseCase.isEligibleForBackendReceipts { isEligibleForReceipt in
1553-
completion(isEligibleForReceipt)
1554-
}
1555-
}
1556-
15571547
private func updateOrderNoteAsyncDictionary(orderNotes: [OrderNote]) {
15581548
orderNoteAsyncDictionary.clear()
15591549
for orderNote in orderNotes {

WooCommerce/Classes/ViewModels/Order Details/Receipts/ReceiptEligibilityUseCase.swift

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ protocol ReceiptEligibilityUseCaseProtocol {
55
func isEligibleForBackendReceipts(onCompletion: @escaping (Bool) -> Void)
66
func isEligibleForSuccessfulPaymentEmailReceipts(onCompletion: @escaping (Bool) -> Void)
77
func isEligibleForFailedPaymentEmailReceipts(paymentGatewayID: String, onCompletion: @escaping (Bool) -> Void)
8+
func isEligibleForReceipt(_ orderStatus: OrderStatusEnum, onCompletion: @escaping (Bool) -> Void)
89
}
910

1011
final class ReceiptEligibilityUseCase: ReceiptEligibilityUseCaseProtocol {
@@ -27,15 +28,10 @@ final class ReceiptEligibilityUseCase: ReceiptEligibilityUseCaseProtocol {
2728
guard let wcPlugin = wcPlugin, wcPlugin.active else {
2829
return onCompletion(false)
2930
}
30-
// 2. If WooCommerce version is any of the specific API development branches, mark as eligible
31-
if Constants.BackendReceipt.wcPluginDevVersion.contains(wcPlugin.version) {
32-
onCompletion(true)
33-
} else {
34-
// 3. Else, if WooCommerce version is higher than minimum required version, mark as eligible
35-
let isSupported = VersionHelpers.isVersionSupported(version: wcPlugin.version,
36-
minimumRequired: Constants.BackendReceipt.wcPluginMinimumVersion)
37-
onCompletion(isSupported)
38-
}
31+
// 2. If WooCommerce version is higher than minimum required version, mark as eligible
32+
let isSupported = VersionHelpers.isVersionSupported(version: wcPlugin.version,
33+
minimumRequired: Constants.BackendReceipt.wcPluginMinimumVersion)
34+
onCompletion(isSupported)
3935
}
4036
stores.dispatch(action)
4137
}
@@ -90,6 +86,26 @@ final class ReceiptEligibilityUseCase: ReceiptEligibilityUseCaseProtocol {
9086
onCompletion(isWooCommerceSupported && isGatewaySupported)
9187
}
9288
}
89+
90+
func isEligibleForReceipt(_ orderStatus: OrderStatusEnum, onCompletion: @escaping (Bool) -> Void) {
91+
switch orderStatus {
92+
case .completed, .processing, .refunded:
93+
isEligibleForBackendReceipts { isEligibleForReceipt in
94+
onCompletion(isEligibleForReceipt)
95+
}
96+
case .failed:
97+
selectedPaymentGatewayID { [weak self] gatewayID in
98+
guard let gatewayID else {
99+
return onCompletion(false)
100+
}
101+
self?.isEligibleForFailedPaymentEmailReceipts(paymentGatewayID: gatewayID) { isEligibleForReceipt in
102+
onCompletion(isEligibleForReceipt)
103+
}
104+
}
105+
default:
106+
return onCompletion(false)
107+
}
108+
}
93109
}
94110

95111
private extension ReceiptEligibilityUseCase {
@@ -102,11 +118,6 @@ private extension ReceiptEligibilityUseCase {
102118
return continuation.resume(returning: false)
103119
}
104120

105-
// Checking for concrete versions to cover dev and beta versions
106-
if plugin.version.contains(minimumVersion) {
107-
return continuation.resume(returning: true)
108-
}
109-
110121
// If plugin version is higher than minimum required version, mark as eligible
111122
let isSupported = VersionHelpers.isVersionSupported(version: plugin.version,
112123
minimumRequired: minimumVersion)
@@ -115,6 +126,15 @@ private extension ReceiptEligibilityUseCase {
115126
stores.dispatch(action)
116127
}
117128
}
129+
130+
// Returns the current payment gateway ID, needed when checking if a transaction is eligible for receipts
131+
// based on which plugin and versions are active
132+
private func selectedPaymentGatewayID(onCompletion: @escaping (String?) -> Void) {
133+
let action = CardPresentPaymentAction.selectedPaymentGatewayAccount { paymentGatewayAccount in
134+
onCompletion(paymentGatewayAccount?.gatewayID)
135+
}
136+
stores.dispatch(action)
137+
}
118138
}
119139

120140
private extension ReceiptEligibilityUseCase {
@@ -123,7 +143,6 @@ private extension ReceiptEligibilityUseCase {
123143

124144
enum BackendReceipt {
125145
static let wcPluginMinimumVersion = "8.7.0"
126-
static let wcPluginDevVersion: [String] = ["8.7.0-dev", "8.6.0-dev"]
127146
}
128147

129148
enum ReceiptAfterPayment {

WooCommerce/WooCommerceTests/Mocks/MockReceiptEligibilityUseCase.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import enum Yosemite.OrderStatusEnum
12
@testable import WooCommerce
23

34
final class MockReceiptEligibilityUseCase: ReceiptEligibilityUseCaseProtocol {
45
var isEligibleForBackendReceipts: Bool = true
56
var isEligibleForSuccessfulPaymentEmailReceipts: Bool = false
67
var isEligibleForFailedPaymentEmailReceipts: Bool = false
8+
var isEligibleForReceipt: Bool = true
79

810
func isEligibleForBackendReceipts(onCompletion: @escaping (Bool) -> Void) {
911
onCompletion(isEligibleForBackendReceipts)
@@ -16,4 +18,8 @@ final class MockReceiptEligibilityUseCase: ReceiptEligibilityUseCaseProtocol {
1618
func isEligibleForFailedPaymentEmailReceipts(paymentGatewayID: String, onCompletion: @escaping (Bool) -> Void) {
1719
onCompletion(isEligibleForFailedPaymentEmailReceipts)
1820
}
21+
22+
func isEligibleForReceipt(_ orderStatus: OrderStatusEnum, onCompletion: @escaping (Bool) -> Void) {
23+
onCompletion(isEligibleForReceipt)
24+
}
1925
}

0 commit comments

Comments
 (0)