Skip to content

Commit 5ccab86

Browse files
committed
Don’t show unsupported products in search results
1 parent 4ee1f12 commit 5ccab86

File tree

2 files changed

+126
-14
lines changed

2 files changed

+126
-14
lines changed

Modules/Sources/Storage/GRDB/Model/PersistedProduct.swift

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,8 @@ public extension PersistedProduct {
105105
/// Returns a request for POS-supported products (simple and variable, non-downloadable) for a given site, ordered by name
106106
/// Filters out products with trash, draft, pending, or private status to ensure only published and 3rd party custom status products are shown
107107
static func posProductsRequest(siteID: Int64) -> QueryInterfaceRequest<PersistedProduct> {
108-
let excludedStatuses = [
109-
"trash",
110-
"draft",
111-
"pending"
112-
]
113-
114-
return PersistedProduct
115-
.filter(Columns.siteID == siteID)
116-
.filter([ProductType.simple.rawValue, ProductType.variable.rawValue].contains(Columns.productTypeKey))
117-
.filter(Columns.downloadable == false)
118-
.filter(!excludedStatuses.contains(Columns.statusKey))
108+
PersistedProduct
109+
.baseQuery(siteID: siteID)
119110
.order(Columns.name.collating(.localizedCaseInsensitiveCompare))
120111
}
121112

@@ -124,6 +115,7 @@ public extension PersistedProduct {
124115
/// - siteID: The site ID
125116
/// - globalUniqueID: The global unique ID (barcode) to search for
126117
/// - Returns: A query request that matches products with the given global unique ID
118+
/// Note that this may return unsupported products, so they can be shown as errors in the UI
127119
static func posProductByGlobalUniqueID(siteID: Int64, globalUniqueID: String) -> QueryInterfaceRequest<PersistedProduct> {
128120
return PersistedProduct
129121
.filter(Columns.siteID == siteID)
@@ -140,9 +132,7 @@ public extension PersistedProduct {
140132
let likePattern = "%\(escapedTerm)%"
141133

142134
return PersistedProduct
143-
.filter(Columns.siteID == siteID)
144-
.filter([ProductType.simple.rawValue, ProductType.variable.rawValue].contains(Columns.productTypeKey))
145-
.filter(Columns.downloadable == false)
135+
.baseQuery(siteID: siteID)
146136
.filter(
147137
Columns.name.like(likePattern, escape: "\\") ||
148138
Columns.sku.like(likePattern, escape: "\\") ||
@@ -160,6 +150,20 @@ public extension PersistedProduct {
160150
.replacingOccurrences(of: "%", with: "\\%")
161151
.replacingOccurrences(of: "_", with: "\\_")
162152
}
153+
154+
private static func baseQuery(siteID: Int64) -> QueryInterfaceRequest<PersistedProduct> {
155+
let excludedStatuses = [
156+
"trash",
157+
"draft",
158+
"pending"
159+
]
160+
161+
return PersistedProduct
162+
.filter(Columns.siteID == siteID)
163+
.filter([ProductType.simple.rawValue, ProductType.variable.rawValue].contains(Columns.productTypeKey))
164+
.filter(Columns.downloadable == false)
165+
.filter(!excludedStatuses.contains(Columns.statusKey))
166+
}
163167
}
164168

165169
// periphery:ignore - TODO: remove ignore when populating database

Modules/Tests/StorageTests/GRDB/PersistedProductSearchQueryTests.swift

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,114 @@ struct PersistedProductSearchQueryTests {
330330
#expect(!results.contains(where: { $0.productTypeKey == "grouped" }))
331331
}
332332

333+
@Test("posProductSearch filters out unsupported product statuses")
334+
func test_search_only_returns_pos_supported_product_statuses() async throws {
335+
// Given
336+
let trashedProduct = PersistedProduct(
337+
id: 10,
338+
siteID: siteID,
339+
name: "Search Test Trash",
340+
productTypeKey: "simple",
341+
fullDescription: nil,
342+
shortDescription: nil,
343+
sku: nil,
344+
globalUniqueID: nil,
345+
price: "10.00",
346+
downloadable: false,
347+
parentID: 0,
348+
manageStock: false,
349+
stockQuantity: nil,
350+
stockStatusKey: "instock",
351+
statusKey: "trash"
352+
)
353+
let draftProduct = PersistedProduct(
354+
id: 11,
355+
siteID: siteID,
356+
name: "Search Test Draft",
357+
productTypeKey: "variable",
358+
fullDescription: nil,
359+
shortDescription: nil,
360+
sku: nil,
361+
globalUniqueID: nil,
362+
price: "20.00",
363+
downloadable: false,
364+
parentID: 0,
365+
manageStock: false,
366+
stockQuantity: nil,
367+
stockStatusKey: "instock",
368+
statusKey: "draft"
369+
)
370+
let pendingProduct = PersistedProduct(
371+
id: 12,
372+
siteID: siteID,
373+
name: "Search Test Pending",
374+
productTypeKey: "simple",
375+
fullDescription: nil,
376+
shortDescription: nil,
377+
sku: nil,
378+
globalUniqueID: nil,
379+
price: "0.00",
380+
downloadable: false,
381+
parentID: 0,
382+
manageStock: false,
383+
stockQuantity: nil,
384+
stockStatusKey: "instock",
385+
statusKey: "pending"
386+
)
387+
let publishedProduct = PersistedProduct(
388+
id: 13,
389+
siteID: siteID,
390+
name: "Search Test Published",
391+
productTypeKey: "simple",
392+
fullDescription: nil,
393+
shortDescription: nil,
394+
sku: nil,
395+
globalUniqueID: nil,
396+
price: "0.00",
397+
downloadable: false,
398+
parentID: 0,
399+
manageStock: false,
400+
stockQuantity: nil,
401+
stockStatusKey: "instock",
402+
statusKey: "publish"
403+
)
404+
let privateProduct = PersistedProduct(
405+
id: 14,
406+
siteID: siteID,
407+
name: "Search Test Private",
408+
productTypeKey: "simple",
409+
fullDescription: nil,
410+
shortDescription: nil,
411+
sku: nil,
412+
globalUniqueID: nil,
413+
price: "0.00",
414+
downloadable: false,
415+
parentID: 0,
416+
manageStock: false,
417+
stockQuantity: nil,
418+
stockStatusKey: "instock",
419+
statusKey: "private"
420+
)
421+
try await insertProduct(trashedProduct)
422+
try await insertProduct(draftProduct)
423+
try await insertProduct(pendingProduct)
424+
try await insertProduct(publishedProduct)
425+
try await insertProduct(privateProduct)
426+
427+
// When
428+
let results = try await grdbManager.databaseConnection.read { db in
429+
try PersistedProduct.posProductSearch(siteID: siteID, searchTerm: "Search Test").fetchAll(db)
430+
}
431+
432+
// Then
433+
#expect(results.count == 2)
434+
#expect(results.contains(where: { $0.statusKey == "publish" }))
435+
#expect(results.contains(where: { $0.statusKey == "private" }))
436+
#expect(!results.contains(where: { $0.statusKey == "trash" }))
437+
#expect(!results.contains(where: { $0.statusKey == "draft" }))
438+
#expect(!results.contains(where: { $0.statusKey == "pending" }))
439+
}
440+
333441
// MARK: - Site Isolation Tests
334442

335443
@Test("posProductSearch only returns products from specified site")

0 commit comments

Comments
 (0)