Skip to content

Commit d6b4570

Browse files
authored
Merge pull request #5889 from woocommerce/issue/5847-revert-reusable-addproducttoorder-view
Order Creation: Revert reusable Add Product view
2 parents 424cf9e + 2a2fab2 commit d6b4570

File tree

7 files changed

+105
-154
lines changed

7 files changed

+105
-154
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Creation/ProductsSection/AddProductToOrder.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import SwiftUI
22

3-
/// View showing a list of products or product variations to add to an order.
3+
/// View showing a list of products to add to an order.
44
///
5-
struct AddProductToOrder<ViewModel: AddProductToOrderViewModelProtocol>: View {
5+
struct AddProductToOrder: View {
66
/// Defines whether the view is presented.
77
///
88
@Binding var isPresented: Bool
99

1010
/// View model to drive the view.
1111
///
12-
@ObservedObject var viewModel: ViewModel
12+
@ObservedObject var viewModel: AddProductToOrderViewModel
1313

1414
var body: some View {
1515
NavigationView {
@@ -20,7 +20,7 @@ struct AddProductToOrder<ViewModel: AddProductToOrderViewModelProtocol>: View {
2020
ForEach(viewModel.productRows) { rowViewModel in
2121
ProductRow(viewModel: rowViewModel)
2222
.onTapGesture {
23-
viewModel.selectProductOrVariation(rowViewModel.productOrVariationID)
23+
viewModel.selectProduct(rowViewModel.productOrVariationID)
2424
isPresented.toggle()
2525
}
2626
}
@@ -88,11 +88,13 @@ private struct InfiniteScrollIndicator: View {
8888
}
8989
}
9090

91-
private enum Localization {
92-
static let title = NSLocalizedString("Add Product", comment: "Title for the screen to add a product to an order")
93-
static let close = NSLocalizedString("Close", comment: "Text for the close button in the Add Product screen")
94-
static let emptyStateMessage = NSLocalizedString("No products found",
95-
comment: "Message displayed if there are no products to display in the Add Product screen")
91+
private extension AddProductToOrder {
92+
enum Localization {
93+
static let title = NSLocalizedString("Add Product", comment: "Title for the screen to add a product to an order")
94+
static let close = NSLocalizedString("Close", comment: "Text for the close button in the Add Product screen")
95+
static let emptyStateMessage = NSLocalizedString("No products found",
96+
comment: "Message displayed if there are no products to display in the Add Product screen")
97+
}
9698
}
9799

98100
struct AddProduct_Previews: PreviewProvider {

WooCommerce/Classes/ViewRelated/Orders/Order Creation/ProductsSection/AddProductToOrderViewModel.swift

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Yosemite
22
import protocol Storage.StorageManagerType
33

4-
/// View model for `AddProductToOrder` with a list of products.
4+
/// View model for `AddProductToOrder`.
55
///
6-
final class AddProductToOrderViewModel: AddProductToOrderViewModelProtocol {
6+
final class AddProductToOrderViewModel: ObservableObject {
77
private let siteID: Int64
88

99
/// Storage to fetch product list
@@ -48,7 +48,7 @@ final class AddProductToOrderViewModel: AddProductToOrderViewModelProtocol {
4848

4949
/// Current sync status; used to determine what list view to display.
5050
///
51-
@Published private(set) var syncStatus: AddProductToOrderSyncStatus?
51+
@Published private(set) var syncStatus: SyncStatus?
5252

5353
/// SyncCoordinator: Keeps tracks of which pages have been refreshed, and encapsulates the "What should we sync now" logic.
5454
///
@@ -58,6 +58,14 @@ final class AddProductToOrderViewModel: AddProductToOrderViewModelProtocol {
5858
///
5959
@Published private(set) var shouldShowScrollIndicator = false
6060

61+
/// View models of the ghost rows used during the loading process.
62+
///
63+
var ghostRows: [ProductRowViewModel] {
64+
return Array(0..<6).map { index in
65+
ghostProductRow(id: index)
66+
}
67+
}
68+
6169
/// Products Results Controller.
6270
///
6371
private lazy var productsResultsController: ResultsController<StorageProduct> = {
@@ -82,7 +90,7 @@ final class AddProductToOrderViewModel: AddProductToOrderViewModelProtocol {
8290

8391
/// Select a product to add to the order
8492
///
85-
func selectProductOrVariation(_ productID: Int64) {
93+
func selectProduct(_ productID: Int64) {
8694
guard let selectedProduct = products.first(where: { $0.productID == productID }) else {
8795
return
8896
}
@@ -178,3 +186,28 @@ private extension AddProductToOrderViewModel {
178186
syncingCoordinator.delegate = self
179187
}
180188
}
189+
190+
// MARK: - Utils
191+
extension AddProductToOrderViewModel {
192+
/// Represents possible statuses for syncing products
193+
///
194+
enum SyncStatus {
195+
case firstPageSync
196+
case results
197+
case empty
198+
}
199+
200+
/// Used for ghost list view while syncing
201+
///
202+
private func ghostProductRow(id: Int64) -> ProductRowViewModel {
203+
ProductRowViewModel(productOrVariationID: id,
204+
name: "Ghost Product",
205+
sku: nil,
206+
price: "20",
207+
stockStatusKey: ProductStockStatus.inStock.rawValue,
208+
stockQuantity: 1,
209+
manageStock: false,
210+
canChangeQuantity: false,
211+
imageURL: nil)
212+
}
213+
}

WooCommerce/Classes/ViewRelated/Orders/Order Creation/ProductsSection/AddProductToOrderViewModelProtocol.swift

Lines changed: 0 additions & 116 deletions
This file was deleted.

WooCommerce/Classes/ViewRelated/Orders/Order Creation/ProductsSection/AddProductVariationToOrderViewModel.swift

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Yosemite
22
import protocol Storage.StorageManagerType
33

4-
/// View model for `AddProductToOrder` with a list of product variations for a product.
4+
/// View model for `AddProductVariationToOrder`.
55
///
6-
final class AddProductVariationToOrderViewModel: AddProductToOrderViewModelProtocol {
6+
final class AddProductVariationToOrderViewModel: ObservableObject {
77
private let siteID: Int64
88

99
/// Storage to fetch product variation list
@@ -24,17 +24,17 @@ final class AddProductVariationToOrderViewModel: AddProductToOrderViewModelProto
2424
productVariationsResultsController.fetchedObjects.filter { $0.purchasable }
2525
}
2626

27-
/// View models for each product row
27+
/// View models for each product variation row
2828
///
29-
var productRows: [ProductRowViewModel] {
29+
var productVariationRows: [ProductRowViewModel] {
3030
productVariations.map { .init(productVariation: $0, allAttributes: product.attributesForVariations, canChangeQuantity: false) }
3131
}
3232

3333
// MARK: Sync & Storage properties
3434

3535
/// Current sync status; used to determine what list view to display.
3636
///
37-
@Published private(set) var syncStatus: AddProductToOrderSyncStatus?
37+
@Published private(set) var syncStatus: SyncStatus?
3838

3939
/// SyncCoordinator: Keeps tracks of which pages have been refreshed, and encapsulates the "What should we sync now" logic.
4040
///
@@ -44,6 +44,14 @@ final class AddProductVariationToOrderViewModel: AddProductToOrderViewModelProto
4444
///
4545
@Published private(set) var shouldShowScrollIndicator = false
4646

47+
/// View models of the ghost rows used during the loading process.
48+
///
49+
var ghostRows: [ProductRowViewModel] {
50+
return Array(0..<6).map { index in
51+
ghostProductRow(id: index)
52+
}
53+
}
54+
4755
/// Product Variations Results Controller.
4856
///
4957
private lazy var productVariationsResultsController: ResultsController<StorageProductVariation> = {
@@ -68,7 +76,7 @@ final class AddProductVariationToOrderViewModel: AddProductToOrderViewModelProto
6876

6977
/// Select a product variation to add to the order
7078
///
71-
func selectProductOrVariation(_ productID: Int64) {
79+
func selectVariation(_ productID: Int64) {
7280
// TODO: Add the selected product variation to the order
7381
}
7482
}
@@ -155,3 +163,28 @@ private extension AddProductVariationToOrderViewModel {
155163
syncingCoordinator.delegate = self
156164
}
157165
}
166+
167+
// MARK: - Utils
168+
extension AddProductVariationToOrderViewModel {
169+
/// Represents possible statuses for syncing product variations
170+
///
171+
enum SyncStatus {
172+
case firstPageSync
173+
case results
174+
case empty
175+
}
176+
177+
/// Used for ghost list view while syncing
178+
///
179+
private func ghostProductRow(id: Int64) -> ProductRowViewModel {
180+
ProductRowViewModel(productOrVariationID: id,
181+
name: "Ghost Variation",
182+
sku: nil,
183+
price: "20",
184+
stockStatusKey: ProductStockStatus.inStock.rawValue,
185+
stockQuantity: 1,
186+
manageStock: false,
187+
canChangeQuantity: false,
188+
imageURL: nil)
189+
}
190+
}

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,6 @@
11391139
CC0324A3263AD9F40056C6B7 /* MockShippingLabelAccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0324A2263AD9F40056C6B7 /* MockShippingLabelAccountSettings.swift */; };
11401140
CC078531266E706300BA9AC1 /* ErrorTopBannerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC078530266E706300BA9AC1 /* ErrorTopBannerFactory.swift */; };
11411141
CC07860526736B6500BA9AC1 /* ErrorTopBannerFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC07860426736B6500BA9AC1 /* ErrorTopBannerFactoryTests.swift */; };
1142-
CC13C0C9278DE76A00C0B5B5 /* AddProductToOrderViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC13C0C8278DE76A00C0B5B5 /* AddProductToOrderViewModelProtocol.swift */; };
11431142
CC13C0CB278E021300C0B5B5 /* AddProductVariationToOrderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC13C0CA278E021300C0B5B5 /* AddProductVariationToOrderViewModel.swift */; };
11441143
CC13C0CD278E086D00C0B5B5 /* AddProductVariationToOrderViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC13C0CC278E086D00C0B5B5 /* AddProductVariationToOrderViewModelTests.swift */; };
11451144
CC200BB127847DE300EC5884 /* OrderPaymentSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC200BB027847DE300EC5884 /* OrderPaymentSection.swift */; };
@@ -2730,7 +2729,6 @@
27302729
CC0324A2263AD9F40056C6B7 /* MockShippingLabelAccountSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockShippingLabelAccountSettings.swift; sourceTree = "<group>"; };
27312730
CC078530266E706300BA9AC1 /* ErrorTopBannerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTopBannerFactory.swift; sourceTree = "<group>"; };
27322731
CC07860426736B6500BA9AC1 /* ErrorTopBannerFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTopBannerFactoryTests.swift; sourceTree = "<group>"; };
2733-
CC13C0C8278DE76A00C0B5B5 /* AddProductToOrderViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProductToOrderViewModelProtocol.swift; sourceTree = "<group>"; };
27342732
CC13C0CA278E021300C0B5B5 /* AddProductVariationToOrderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProductVariationToOrderViewModel.swift; sourceTree = "<group>"; };
27352733
CC13C0CC278E086D00C0B5B5 /* AddProductVariationToOrderViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddProductVariationToOrderViewModelTests.swift; sourceTree = "<group>"; };
27362734
CC200BB027847DE300EC5884 /* OrderPaymentSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderPaymentSection.swift; sourceTree = "<group>"; };
@@ -6139,7 +6137,6 @@
61396137
CC53FB372755213900C4CA4F /* AddProductToOrder.swift */,
61406138
CC53FB3B2757EC7200C4CA4F /* AddProductToOrderViewModel.swift */,
61416139
CC13C0CA278E021300C0B5B5 /* AddProductVariationToOrderViewModel.swift */,
6142-
CC13C0C8278DE76A00C0B5B5 /* AddProductToOrderViewModelProtocol.swift */,
61436140
CC53FB3427551A6E00C4CA4F /* ProductRow.swift */,
61446141
CC53FB39275697B000C4CA4F /* ProductRowViewModel.swift */,
61456142
CCC284102768C18500F6CC8B /* ProductInOrder.swift */,
@@ -8180,7 +8177,6 @@
81808177
029BFD4F24597D4B00FDDEEC /* UIButton+TitleAndImage.swift in Sources */,
81818178
B5A8F8AD20B88D9900D211DE /* LoginPrologueViewController.swift in Sources */,
81828179
B5D1AFC620BC7B7300DB0E8C /* StorePickerViewController.swift in Sources */,
8183-
CC13C0C9278DE76A00C0B5B5 /* AddProductToOrderViewModelProtocol.swift in Sources */,
81848180
02DD81FB242CAA400060E50B /* WordPressMediaLibraryPickerDataSource.swift in Sources */,
81858181
0240B3AC230A910C000A866C /* StoreStatsV4ChartAxisHelper.swift in Sources */,
81868182
31579028273EE2B1008CA3AF /* VersionHelpers.swift in Sources */,

WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/AddProductVariationToOrderViewModelTests.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class AddProductVariationToOrderViewModelTests: XCTestCase {
2424
super.tearDown()
2525
}
2626

27-
func test_view_model_adds_product_rows_with_unchangeable_quantity() {
27+
func test_view_model_adds_product_variation_rows_with_unchangeable_quantity() {
2828
// Given
2929
let product = Product.fake().copy(productID: sampleProductID)
3030
let productVariation = ProductVariation.fake().copy(siteID: sampleSiteID, productID: sampleProductID, purchasable: true)
@@ -34,13 +34,14 @@ class AddProductVariationToOrderViewModelTests: XCTestCase {
3434
let viewModel = AddProductVariationToOrderViewModel(siteID: sampleSiteID, product: product, storageManager: storageManager)
3535

3636
// Then
37-
XCTAssertEqual(viewModel.productRows.count, 1)
37+
XCTAssertEqual(viewModel.productVariationRows.count, 1)
3838

39-
let productRow = viewModel.productRows[0]
40-
XCTAssertFalse(productRow.canChangeQuantity, "Product row canChangeQuantity property should be false but is true instead")
39+
let productVariationRow = viewModel.productVariationRows[0]
40+
XCTAssertFalse(productVariationRow.canChangeQuantity,
41+
"Product variation row canChangeQuantity property should be false but is true instead")
4142
}
4243

43-
func test_product_rows_only_include_purchasable_product_variations() {
44+
func test_product_variation_rows_only_include_purchasable_product_variations() {
4445
// Given
4546
let product = Product.fake().copy(productID: sampleProductID)
4647
let purchasableProductVariation = ProductVariation.fake().copy(siteID: sampleSiteID,
@@ -54,8 +55,10 @@ class AddProductVariationToOrderViewModelTests: XCTestCase {
5455
let viewModel = AddProductVariationToOrderViewModel(siteID: sampleSiteID, product: product, storageManager: storageManager)
5556

5657
// Then
57-
XCTAssertTrue(viewModel.productRows.contains(where: { $0.productOrVariationID == 1 }), "Product rows do not include purchasable product variation")
58-
XCTAssertFalse(viewModel.productRows.contains(where: { $0.productOrVariationID == 2 }), "Product rows include non-purchasable product variation")
58+
XCTAssertTrue(viewModel.productVariationRows.contains(where: { $0.productOrVariationID == 1 }),
59+
"Product variation rows do not include purchasable product variation")
60+
XCTAssertFalse(viewModel.productVariationRows.contains(where: { $0.productOrVariationID == 2 }),
61+
"Product variation rows include non-purchasable product variation")
5962
}
6063

6164
func test_scrolling_indicator_appears_only_during_sync() {

0 commit comments

Comments
 (0)