Skip to content

Commit 6a89b29

Browse files
authored
[Woo POS][Surveys] Fix notification when user takes collect payment path. Enable feature flag. (#16325)
2 parents f4dd740 + b0d5bed commit 6a89b29

File tree

5 files changed

+63
-5
lines changed

5 files changed

+63
-5
lines changed

Modules/Sources/Experiments/DefaultFeatureFlagService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
9999
case .ciabBookings:
100100
return buildConfig == .localDeveloper || buildConfig == .alpha
101101
case .pointOfSaleSurveys:
102-
return buildConfig == .localDeveloper || buildConfig == .alpha
102+
return true
103103
case .pointOfSaleCatalogAPI:
104104
return false
105105
default:

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [**] We added support for collecting in-person payments (including Tap To Pay) using Stripe Payment Gateway extension in the UK. [https://github.com/woocommerce/woocommerce-ios/pull/16287]
77
- [*] Improve card payments onboarding error handling to show network errors correctly [https://github.com/woocommerce/woocommerce-ios/pull/16304]
88
- [*] Authenticate the admin page automatically for sites with SSO enabled in custom fields, in-person payment setup, and editing tax rates flows. [https://github.com/woocommerce/woocommerce-ios/pull/16318]
9+
- [*] Show POS feedback surveys for eligible merchants [https://github.com/woocommerce/woocommerce-ios/pull/16325]
910

1011
23.6
1112
-----

WooCommerce/Classes/POS/POSNotificationScheduler.swift

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import UserNotifications
33
import Yosemite
44
import Experiments
55

6-
// periphery: ignore - work in progress
76
protocol POSNotificationScheduling {
87
func scheduleLocalNotificationIfEligible(for merchantType: POSNotificationScheduler.MerchantType) async
98
}
109

11-
// periphery: ignore - work in progress
1210
final class POSNotificationScheduler: POSNotificationScheduling {
1311
enum MerchantType {
1412
case potentialMerchant
@@ -64,7 +62,7 @@ final class POSNotificationScheduler: POSNotificationScheduling {
6462
func scheduleLocalNotificationIfEligible(for merchantType: POSNotificationScheduler.MerchantType) async {
6563
guard featureFlagService.isFeatureFlagEnabled(.pointOfSaleSurveys) else { return }
6664

67-
let isScheduled = await isNotificationScheduled(for: merchantType)
65+
let isScheduled = await isNotificationAlreadyScheduled(for: merchantType)
6866
guard !isScheduled else { return }
6967
guard isCountryEligible() else { return }
7068

@@ -86,7 +84,23 @@ final class POSNotificationScheduler: POSNotificationScheduling {
8684
}
8785
}
8886

89-
private func isNotificationScheduled(for merchantType: MerchantType) async -> Bool {
87+
private func isNotificationAlreadyScheduled(for merchantType: MerchantType) async -> Bool {
88+
// Check if the specific notification type is already scheduled
89+
let isCurrentMerchantTypeScheduled = await checkIfScheduled(for: merchantType)
90+
if isCurrentMerchantTypeScheduled {
91+
return true
92+
}
93+
94+
// Don't schedule notification for potential merchant if the user is already marked as current merchant
95+
guard merchantType == .potentialMerchant else {
96+
return false
97+
}
98+
99+
let isCurrentMerchantScheduled = await checkIfScheduled(for: .currentMerchant)
100+
return isCurrentMerchantScheduled
101+
}
102+
103+
private func checkIfScheduled(for merchantType: MerchantType) async -> Bool {
90104
await withCheckedContinuation { continuation in
91105
let action: AppSettingsAction
92106
switch merchantType {

WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,9 @@ final class EditableOrderViewModel: ObservableObject {
10441044
guard let self else { return }
10451045
self.collectPayment(for: order)
10461046
self.trackCreateOrderSuccess(usesGiftCard: usesGiftCard)
1047+
Task {
1048+
await self.posNotificationScheduler.scheduleLocalNotificationIfEligible(for: .potentialMerchant)
1049+
}
10471050
} onFailure: { [weak self] error, usesGiftCard in
10481051
guard let self else { return }
10491052
self.fixedNotice = NoticeFactory.createOrderErrorNotice(error, order: self.orderSynchronizer.order)

WooCommerce/WooCommerceTests/POS/POSNotificationSchedulerTests.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,46 @@ struct POSNotificationSchedulerTests {
260260
#expect(mockPushNotesManager.requestedLocalNotifications.isEmpty)
261261
}
262262

263+
@Test func scheduleLocalNotificationIfEligible_when_currentMerchant_already_scheduled_then_potentialMerchant_cannot_be_scheduled() async throws {
264+
// Given
265+
let siteSettings = sampleSiteSettings(countryCode: "US")
266+
mockFeatureFlagService.isFeatureFlagEnabledReturnValue[.pointOfSaleSurveys] = true
267+
setupMockStores(isCurrentMerchantScheduled: true)
268+
269+
let scheduler = POSNotificationScheduler(
270+
stores: mockStores,
271+
siteSettings: siteSettings,
272+
featureFlagService: mockFeatureFlagService,
273+
pushNotificationsManager: mockPushNotesManager
274+
)
275+
276+
// When
277+
await scheduler.scheduleLocalNotificationIfEligible(for: .potentialMerchant)
278+
279+
// Then - No notification should be scheduled. Prevents backwards conversion from 'current' to 'potential' merchant.
280+
#expect(mockPushNotesManager.requestedLocalNotifications.isEmpty)
281+
}
282+
283+
@Test func scheduleLocalNotificationIfEligible_when_potentialMerchant_already_scheduled_then_does_not_duplicate_notification() async throws {
284+
// Given
285+
let siteSettings = sampleSiteSettings(countryCode: "US")
286+
mockFeatureFlagService.isFeatureFlagEnabledReturnValue[.pointOfSaleSurveys] = true
287+
setupMockStores(isPotentialMerchantScheduled: true)
288+
289+
let scheduler = POSNotificationScheduler(
290+
stores: mockStores,
291+
siteSettings: siteSettings,
292+
featureFlagService: mockFeatureFlagService,
293+
pushNotificationsManager: mockPushNotesManager
294+
)
295+
296+
// When
297+
await scheduler.scheduleLocalNotificationIfEligible(for: .potentialMerchant)
298+
299+
// Then - No duplicate notification should be scheduled
300+
#expect(mockPushNotesManager.requestedLocalNotifications.isEmpty)
301+
}
302+
263303
private func sampleSiteSettings(countryCode: String) -> [SiteSetting] {
264304
[
265305
SiteSetting.fake().copy(

0 commit comments

Comments
 (0)