Skip to content

Commit e3ba777

Browse files
authored
Merge pull request #7802 from woocommerce/issue/6309-100-warning
Bulk Prices: Shows API limit warning
2 parents f440808 + 00d3f47 commit e3ba777

File tree

5 files changed

+116
-10
lines changed

5 files changed

+116
-10
lines changed

WooCommerce/Classes/ViewRelated/Products/Variations/Bulk Update/BulkUpdateViewController.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ final class BulkUpdateViewController: UIViewController, GhostableViewController
7777
self.sections = sections
7878
self.removeGhostContent()
7979
self.tableView.reloadData()
80+
self.displayTooManyVariationsWarningIfNeeded()
8081
case .error:
8182
self.removeGhostContent()
8283
self.displaySyncingError()
@@ -147,6 +148,26 @@ final class BulkUpdateViewController: UIViewController, GhostableViewController
147148
let viewController = BulkUpdatePriceViewController(viewModel: bulkUpdatePriceSettingsViewModel)
148149
show(viewController, sender: nil)
149150
}
151+
152+
/// Displays a warning informing the user that only the first 100 variations would be editted.
153+
/// This is due to API limitations.
154+
///
155+
private func displayTooManyVariationsWarningIfNeeded() {
156+
guard viewModel.shouldShowVariationLimitWarning else {
157+
return
158+
}
159+
160+
let bannerViewModel = TopBannerViewModel(title: nil,
161+
infoText: Localization.tooManyVariations,
162+
icon: .noticeImage,
163+
iconTintColor: .warning,
164+
isExpanded: false,
165+
topButton: .none,
166+
type: .warning)
167+
let banner = TopBannerView(viewModel: bannerViewModel)
168+
tableView.tableHeaderView = banner
169+
tableView.updateHeaderHeight()
170+
}
150171
}
151172

152173
// MARK: - UITableViewDataSource Conformance
@@ -267,6 +288,8 @@ private extension BulkUpdateViewController {
267288
static let noticeRetryAction = NSLocalizedString("Retry", comment: "Retry Action")
268289
static let pricesUpdated = NSLocalizedString("Prices updated successfully.",
269290
comment: "Notice title when updating the price via the bulk variation screen")
291+
static let tooManyVariations = NSLocalizedString("Only the first 100 variations will be updated.",
292+
comment: "Warning when trying to bulk edit more than 100 variations")
270293
}
271294
}
272295

WooCommerce/Classes/ViewRelated/Products/Variations/Bulk Update/BulkUpdateViewModel.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ final class BulkUpdateViewModel {
2626
private let currencyFormatter: CurrencyFormatter
2727
private var onCancelButtonTapped: () -> Void
2828

29+
/// Returns `true` if there are more than 100 variations to edit.
30+
///
31+
let shouldShowVariationLimitWarning: Bool
32+
2933
/// Product Variations Controller.
3034
///
3135
private lazy var resultsController: ResultsController<StorageProductVariation> = {
@@ -48,6 +52,7 @@ final class BulkUpdateViewModel {
4852

4953
init(siteID: Int64,
5054
productID: Int64,
55+
variationCount: Int,
5156
onCancelButtonTapped: @escaping () -> Void,
5257
storageManager: StorageManagerType = ServiceLocator.storageManager,
5358
storesManager: StoresManager = ServiceLocator.stores,
@@ -59,6 +64,7 @@ final class BulkUpdateViewModel {
5964
self.storesManager = storesManager
6065
self.currencySettings = currencySettings
6166
self.currencyFormatter = CurrencyFormatter(currencySettings: currencySettings)
67+
self.shouldShowVariationLimitWarning = variationCount > Constants.numberOfObjects
6268
syncState = .notStarted
6369
}
6470

WooCommerce/Classes/ViewRelated/Products/Variations/ProductVariationsViewController.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,10 @@ private extension ProductVariationsViewController {
575575
actionSheet.addDefaultActionWithTitle(ActionSheetStrings.bulkUpdate) { [weak self] _ in
576576
guard let self = self else { return }
577577

578-
let viewModel = BulkUpdateViewModel(siteID: self.siteID, productID: self.productID, onCancelButtonTapped: { [weak self] in
578+
let viewModel = BulkUpdateViewModel(siteID: self.siteID,
579+
productID: self.productID,
580+
variationCount: self.product.variations.count,
581+
onCancelButtonTapped: { [weak self] in
579582
self?.dismiss(animated: true)
580583
})
581584
let navigationController = WooNavigationController(rootViewController: BulkUpdateViewController(viewModel: viewModel))

WooCommerce/WooCommerceTests/ViewRelated/Products/Variations/Bulk Update/BulkUpdateViewControllerTests.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ final class BulkUpdateViewControllerTests: XCTestCase {
1414
let storageManager = MockStorageManager()
1515
let storesManager = MockStoresManager(sessionManager: SessionManager.makeForTesting())
1616
let noticePresenter = MockNoticePresenter()
17-
let viewModel = BulkUpdateViewModel(siteID: 0, productID: 0, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
17+
let viewModel = BulkUpdateViewModel(siteID: 0,
18+
productID: 0,
19+
variationCount: 10,
20+
onCancelButtonTapped: {},
21+
storageManager: storageManager,
22+
storesManager: storesManager)
1823
storesManager.whenReceivingAction(ofType: ProductVariationAction.self) { action in
1924
switch action {
2025
case let .synchronizeProductVariations(_, _, _, _, onCompletion):

WooCommerce/WooCommerceTests/ViewRelated/Products/Variations/Bulk Update/BulkUpdateViewModelTests.swift

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ final class BulkUpdateViewModelTests: XCTestCase {
3333
let expectedPageNumber = 1
3434
let viewModel = BulkUpdateViewModel(siteID: expectedSiteID,
3535
productID: expectedProductID,
36+
variationCount: 10,
3637
onCancelButtonTapped: {},
3738
storageManager: storageManager,
3839
storesManager: storesManager)
@@ -56,15 +57,25 @@ final class BulkUpdateViewModelTests: XCTestCase {
5657

5758
func test_initial_sync_state() throws {
5859
// Given
59-
let viewModel = BulkUpdateViewModel(siteID: 0, productID: 0, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
60+
let viewModel = BulkUpdateViewModel(siteID: 0,
61+
productID: 0,
62+
variationCount: 10,
63+
onCancelButtonTapped: {},
64+
storageManager: storageManager,
65+
storesManager: storesManager)
6066

6167
// Then
6268
XCTAssertEqual(viewModel.syncState, .notStarted)
6369
}
6470

6571
func test_sync_state_updates_to_loading_when_product_variations_syncing_starts() {
6672
// Given
67-
let viewModel = BulkUpdateViewModel(siteID: 0, productID: 0, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
73+
let viewModel = BulkUpdateViewModel(siteID: 0,
74+
productID: 0,
75+
variationCount: 10,
76+
onCancelButtonTapped: {},
77+
storageManager: storageManager,
78+
storesManager: storesManager)
6879
storesManager.whenReceivingAction(ofType: ProductVariationAction.self) { _ in
6980
// do nothing to stay in "syncing" state
7081
}
@@ -78,7 +89,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
7889

7990
func test_sync_state_updates_to_syncerror_when_product_variations_syncing_fails() {
8091
// Given
81-
let viewModel = BulkUpdateViewModel(siteID: 0, productID: 0, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
92+
let viewModel = BulkUpdateViewModel(siteID: 0,
93+
productID: 0,
94+
variationCount: 10,
95+
onCancelButtonTapped: {},
96+
storageManager: storageManager,
97+
storesManager: storesManager)
8298
storesManager.whenReceivingAction(ofType: ProductVariationAction.self) { action in
8399
switch action {
84100
case let .synchronizeProductVariations(_, _, _, _, onCompletion):
@@ -97,7 +113,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
97113

98114
func test_sync_state_updates_to_syncResults_when_product_variations_syncing_is_successful() {
99115
// Given
100-
let viewModel = BulkUpdateViewModel(siteID: 0, productID: 0, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
116+
let viewModel = BulkUpdateViewModel(siteID: 0,
117+
productID: 0,
118+
variationCount: 10,
119+
onCancelButtonTapped: {},
120+
storageManager: storageManager,
121+
storesManager: storesManager)
101122
storesManager.whenReceivingAction(ofType: ProductVariationAction.self) { action in
102123
switch action {
103124
case let .synchronizeProductVariations(_, _, _, _, onCompletion):
@@ -128,7 +149,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
128149
XCTFail("Unsupported Action")
129150
}
130151
}
131-
let viewModel = BulkUpdateViewModel(siteID: 1, productID: 1, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
152+
let viewModel = BulkUpdateViewModel(siteID: 1,
153+
productID: 1,
154+
variationCount: 10,
155+
onCancelButtonTapped: {},
156+
storageManager: storageManager,
157+
storesManager: storesManager)
132158

133159
// When
134160
viewModel.syncVariations()
@@ -161,6 +187,7 @@ final class BulkUpdateViewModelTests: XCTestCase {
161187
}
162188
let viewModel = BulkUpdateViewModel(siteID: 1,
163189
productID: 1,
190+
variationCount: 10,
164191
onCancelButtonTapped: {},
165192
storageManager: storageManager,
166193
storesManager: storesManager,
@@ -196,7 +223,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
196223
XCTFail("Unsupported Action")
197224
}
198225
}
199-
let viewModel = BulkUpdateViewModel(siteID: 1, productID: 1, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
226+
let viewModel = BulkUpdateViewModel(siteID: 1,
227+
productID: 1,
228+
variationCount: 10,
229+
onCancelButtonTapped: {},
230+
storageManager: storageManager,
231+
storesManager: storesManager)
200232

201233
// When
202234
viewModel.syncVariations()
@@ -228,7 +260,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
228260
XCTFail("Unsupported Action")
229261
}
230262
}
231-
let viewModel = BulkUpdateViewModel(siteID: 1, productID: 1, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
263+
let viewModel = BulkUpdateViewModel(siteID: 1,
264+
productID: 1,
265+
variationCount: 10,
266+
onCancelButtonTapped: {},
267+
storageManager: storageManager,
268+
storesManager: storesManager)
232269

233270
// When
234271
viewModel.syncVariations()
@@ -260,7 +297,12 @@ final class BulkUpdateViewModelTests: XCTestCase {
260297
XCTFail("Unsupported Action")
261298
}
262299
}
263-
let viewModel = BulkUpdateViewModel(siteID: 1, productID: 1, onCancelButtonTapped: {}, storageManager: storageManager, storesManager: storesManager)
300+
let viewModel = BulkUpdateViewModel(siteID: 1,
301+
productID: 1,
302+
variationCount: 10,
303+
onCancelButtonTapped: {},
304+
storageManager: storageManager,
305+
storesManager: storesManager)
264306

265307
// When
266308
viewModel.syncVariations()
@@ -281,6 +323,7 @@ final class BulkUpdateViewModelTests: XCTestCase {
281323
var onCancelButtonTappedInvoked = false
282324
let viewModel = BulkUpdateViewModel(siteID: 0,
283325
productID: 0,
326+
variationCount: 10,
284327
onCancelButtonTapped: {
285328
onCancelButtonTappedInvoked = true
286329
},
@@ -293,6 +336,32 @@ final class BulkUpdateViewModelTests: XCTestCase {
293336
// Then
294337
XCTAssertTrue(onCancelButtonTappedInvoked)
295338
}
339+
340+
func test_less_than_100_variations_does_not_shows_warning() throws {
341+
// Given
342+
let viewModel = BulkUpdateViewModel(siteID: 0,
343+
productID: 0,
344+
variationCount: 10,
345+
onCancelButtonTapped: {},
346+
storageManager: storageManager,
347+
storesManager: storesManager)
348+
349+
// Then
350+
XCTAssertFalse(viewModel.shouldShowVariationLimitWarning)
351+
}
352+
353+
func test_more_than_100_variations_shows_shows_warning() throws {
354+
// Given
355+
let viewModel = BulkUpdateViewModel(siteID: 0,
356+
productID: 0,
357+
variationCount: 101,
358+
onCancelButtonTapped: {},
359+
storageManager: storageManager,
360+
storesManager: storesManager)
361+
362+
// Then
363+
XCTAssertTrue(viewModel.shouldShowVariationLimitWarning)
364+
}
296365
}
297366

298367
private extension BulkUpdateViewModel.SyncState {

0 commit comments

Comments
 (0)