Skip to content

Commit 8eaabf7

Browse files
[CIAB] Hide split shipments for CIAB sites (#16105)
2 parents d17e8a4 + 1882771 commit 8eaabf7

File tree

7 files changed

+602
-18
lines changed

7 files changed

+602
-18
lines changed

WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@
33
import Foundation
44
import Yosemite
55

6-
protocol CIABEligibilityCheckerProtocol {
7-
var isCurrentSiteCIAB: Bool { get }
8-
9-
func isSiteCIAB(_ site: Site) -> Bool
10-
11-
func isFeatureSupportedForCurrentSite(_ feature: CIABAffectedFeature) -> Bool
12-
func isFeatureSupported(_ feature: CIABAffectedFeature, for site: Site) -> Bool
13-
}
14-
156
final class CIABEligibilityChecker {
167
private let stores: StoresManager
178

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Foundation
2+
import Yosemite
3+
4+
/// periphery: ignore - Will be used in upcoming changes for app feature gating
5+
protocol CIABEligibilityCheckerProtocol {
6+
var isCurrentSiteCIAB: Bool { get }
7+
8+
func isSiteCIAB(_ site: Site) -> Bool
9+
10+
func isFeatureSupportedForCurrentSite(_ feature: CIABAffectedFeature) -> Bool
11+
func isFeatureSupported(_ feature: CIABAffectedFeature, for site: Site) -> Bool
12+
}

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ private extension WooShippingCreateLabelsView {
182182
.padding(.horizontal)
183183
}
184184
.accessibilityHint(Localization.Accessibility.editButtonHint)
185-
.renderedIf(viewModel.hasUnfulfilledShipments)
185+
.renderedIf(viewModel.editSplitShipmentsOptionVisible)
186186
}
187187
.disabled(viewModel.isPurchasingLabel)
188188
}
@@ -191,7 +191,7 @@ private extension WooShippingCreateLabelsView {
191191
var mainView: some View {
192192
ScrollView {
193193
VStack(spacing: Layout.verticalSpacing) {
194-
if viewModel.splitShipmentsAvailable {
194+
if viewModel.splitShipmentsRowVisible {
195195
WooShippingSplitShipmentsRow(onShowingSplitShipments: {
196196
showingSplitShipments = true
197197
})

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,6 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
8080
/// View model for split shipments.
8181
private(set) var splitShipmentsViewModel: WooShippingSplitShipmentsViewModel
8282

83-
var splitShipmentsAvailable: Bool {
84-
itemsDataSource.items.map(\.quantity).reduce(0, +) > 1 &&
85-
shipments.count == 1 &&
86-
canViewLabel == false
87-
}
88-
8983
private(set) var shipmentDetailViewModels: [WooShippingShipmentDetailsViewModel] = []
9084

9185
var currentShipmentDetailsViewModel: WooShippingShipmentDetailsViewModel {
@@ -241,6 +235,10 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
241235
)
242236
}()
243237

238+
/// Provides checks for CIAB
239+
/// Used to determine "Split Shipments" feature availability
240+
private let siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol
241+
244242
/// Initialize the view model with or without an existing shipping label.
245243
init(order: Order,
246244
preselection: WooShippingCreateLabelSelection? = nil,
@@ -249,10 +247,15 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
249247
stores: StoresManager = ServiceLocator.stores,
250248
storageManager: StorageManagerType = ServiceLocator.storageManager,
251249
analytics: Analytics = ServiceLocator.analytics,
250+
siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol = CIABEligibilityChecker(),
252251
initialNoticeDelay: RunLoop.SchedulerTimeType.Stride = .seconds(2),
253252
onLabelPurchase: ((Bool) -> Void)? = nil) {
254253
self.order = order
255-
self.itemsDataSource = DefaultWooShippingItemsDataSource(order: order)
254+
self.itemsDataSource = DefaultWooShippingItemsDataSource(
255+
order: order,
256+
storageManager: storageManager,
257+
stores: stores
258+
)
256259
self.orderItems = WooShippingItemsViewModel(dataSource: itemsDataSource)
257260
self.onLabelPurchase = onLabelPurchase
258261
self.currencySettings = currencySettings
@@ -261,6 +264,7 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
261264
self.stores = stores
262265
self.storageManager = storageManager
263266
self.analytics = analytics
267+
self.siteCIABEligibilityChecker = siteCIABEligibilityChecker
264268
self.shippingSettingsService = shippingSettingsService
265269
self.weightUnit = shippingSettingsService.weightUnit ?? ""
266270
self.dimensionsUnit = shippingSettingsService.dimensionUnit ?? ""
@@ -504,6 +508,33 @@ private extension WooShippingCreateLabelsViewModel {
504508
}
505509
}
506510

511+
// MARK: Split Shipments
512+
// Accessors describing Split Shipments elements availability
513+
extension WooShippingCreateLabelsViewModel {
514+
private var hasMultipleProducts: Bool {
515+
return itemsDataSource.items.map(\.quantity).reduce(0, +) > 1
516+
}
517+
518+
private var splitShipmentsFeatureAvailable: Bool {
519+
return siteCIABEligibilityChecker.isFeatureSupportedForCurrentSite(.splitShipments)
520+
}
521+
522+
/// Determines if the "Edit split shipments" (pencil icon) is visible in top shipments bar.
523+
var editSplitShipmentsOptionVisible: Bool {
524+
splitShipmentsFeatureAvailable &&
525+
hasMultipleProducts &&
526+
hasUnfulfilledShipments
527+
}
528+
529+
/// Determines if the "Split Shipments" row is visible above the "Products" section
530+
var splitShipmentsRowVisible: Bool {
531+
splitShipmentsFeatureAvailable &&
532+
hasMultipleProducts &&
533+
shipments.count == 1 &&
534+
canViewLabel == false
535+
}
536+
}
537+
507538
// MARK: Utils
508539
private extension WooShippingCreateLabelsViewModel {
509540

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,8 @@
12451245
2DB8916E2E27F7840001B175 /* OrderListCellViewModel+Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB8916A2E27F6CE0001B175 /* OrderListCellViewModel+Localizations.swift */; };
12461246
2DCB54FA2E6AE8E100621F90 /* CIABEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */; };
12471247
2DCB54FC2E6AFE6A00621F90 /* CIABAffectedFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */; };
1248+
2DE9DDFB2E6EF4A500155408 /* MockCIABEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE9DDFA2E6EF4A300155408 /* MockCIABEligibilityChecker.swift */; };
1249+
2DE9DDFD2E6EF53C00155408 /* CIABEligibilityCheckerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */; };
12481250
2DF0D1BC2E2907C100F8995C /* MarkOrderAsReadUseCase+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB88DA32E27DD790001B175 /* MarkOrderAsReadUseCase+Woo.swift */; };
12491251
310D1B482734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310D1B472734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift */; };
12501252
311237EE2714DA240033C44E /* CardPresentModalDisplayMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311237ED2714DA240033C44E /* CardPresentModalDisplayMessage.swift */; };
@@ -4434,6 +4436,8 @@
44344436
2DB8916A2E27F6CE0001B175 /* OrderListCellViewModel+Localizations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderListCellViewModel+Localizations.swift"; sourceTree = "<group>"; };
44354437
2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABEligibilityChecker.swift; sourceTree = "<group>"; };
44364438
2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABAffectedFeature.swift; sourceTree = "<group>"; };
4439+
2DE9DDFA2E6EF4A300155408 /* MockCIABEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCIABEligibilityChecker.swift; sourceTree = "<group>"; };
4440+
2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABEligibilityCheckerProtocol.swift; sourceTree = "<group>"; };
44374441
310D1B472734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsLiveSiteInTestModeView.swift; sourceTree = "<group>"; };
44384442
311237ED2714DA240033C44E /* CardPresentModalDisplayMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalDisplayMessage.swift; sourceTree = "<group>"; };
44394443
311D21E7264AEDB900102316 /* CardPresentModalScanningForReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalScanningForReader.swift; sourceTree = "<group>"; };
@@ -9058,6 +9062,7 @@
90589062
2DCB54F82E6AE8C900621F90 /* CIAB */ = {
90599063
isa = PBXGroup;
90609064
children = (
9065+
2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */,
90619066
2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */,
90629067
2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */,
90639068
);
@@ -10093,6 +10098,7 @@
1009310098
746791642108D853007CF1DC /* Mocks */ = {
1009410099
isa = PBXGroup;
1009510100
children = (
10101+
2DE9DDFA2E6EF4A300155408 /* MockCIABEligibilityChecker.swift */,
1009610102
022900892E3019020028F6D7 /* MockPluginsService.swift */,
1009710103
02F36C3F2E0130E900DD8CB6 /* MockPOSEligibilityService.swift */,
1009810104
02B8E41A2DFBC33C001D01FD /* MockPOSEligibilityChecker.swift */,
@@ -16257,6 +16263,7 @@
1625716263
B626C71B287659D60083820C /* CustomFieldsListView.swift in Sources */,
1625816264
02ECD1E624FFB4E900735BE5 /* ProductFactory.swift in Sources */,
1625916265
260520F42B87BA23005D5D59 /* WooAnalyticsEvent+ConnectivityTool.swift in Sources */,
16266+
2DE9DDFD2E6EF53C00155408 /* CIABEligibilityCheckerProtocol.swift in Sources */,
1626016267
579CDEFF274D7E7900E8903D /* StoreStatsUsageTracksEventEmitter.swift in Sources */,
1626116268
203163AD2C1C5C54001C96DA /* PointOfSaleCardPresentPaymentConnectingFailedNonRetryableAlertViewModel.swift in Sources */,
1626216269
CEDBDA472B6BEF2E002047D4 /* AnalyticsWebReport.swift in Sources */,
@@ -17150,6 +17157,7 @@
1715017157
EE8B421B2C04D18B0077C4E7 /* LastOrdersDashboardCardViewModelTests.swift in Sources */,
1715117158
095A077E27CF486C007A61D2 /* ValueOneTableViewCellTests.swift in Sources */,
1715217159
E17E3BF9266917C10009D977 /* CardPresentModalScanningFailedTests.swift in Sources */,
17160+
2DE9DDFB2E6EF4A500155408 /* MockCIABEligibilityChecker.swift in Sources */,
1715317161
DE66C56F2978F24200DAA978 /* ApplicationPasswordDisabledViewModelTests.swift in Sources */,
1715417162
EE1905942B62AE9100617C53 /* BlazeCreateCampaignIntroViewModelTests.swift in Sources */,
1715517163
269098B627D2C09D001FEB07 /* ShippingInputTransformerTests.swift in Sources */,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Foundation
2+
import Yosemite
3+
@testable import WooCommerce
4+
5+
final class MockCIABEligibilityChecker: CIABEligibilityCheckerProtocol {
6+
private let mockedIsCurrentSiteCIAB: Bool
7+
private let mockedCIABSites: [Site]
8+
private let mockedCIABDisabledFeatures: [CIABAffectedFeature]
9+
10+
init(mockedIsCurrentSiteCIAB: Bool, mockedCIABSites: [Site] = [], mockedCIABDisabledFeatures: [CIABAffectedFeature] = CIABAffectedFeature.allCases) {
11+
self.mockedIsCurrentSiteCIAB = mockedIsCurrentSiteCIAB
12+
self.mockedCIABSites = mockedCIABSites
13+
self.mockedCIABDisabledFeatures = mockedCIABDisabledFeatures
14+
}
15+
16+
var isCurrentSiteCIAB: Bool {
17+
return mockedIsCurrentSiteCIAB
18+
}
19+
20+
func isSiteCIAB(_ site: Site) -> Bool {
21+
return mockedCIABSites.contains(site)
22+
}
23+
24+
func isFeatureSupportedForCurrentSite(_ feature: CIABAffectedFeature) -> Bool {
25+
return !mockedCIABDisabledFeatures.contains(feature)
26+
}
27+
28+
func isFeatureSupported(_ feature: CIABAffectedFeature, for site: Site) -> Bool {
29+
return !mockedCIABDisabledFeatures.contains(feature) && mockedCIABSites.contains(site)
30+
}
31+
}

0 commit comments

Comments
 (0)