Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Modules/Sources/Fakes/Networking.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,8 @@ extension Networking.POSProduct {
attributes: .fake(),
manageStock: .fake(),
stockQuantity: .fake(),
stockStatusKey: .fake()
stockStatusKey: .fake(),
variationIDs: .fake()
)
}
}
Expand Down
9 changes: 9 additions & 0 deletions Modules/Sources/Fakes/Yosemite.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ extension Yosemite.ProductReviewFromNoteParcel {
)
}
}
extension Yosemite.StoredBookingFilters {
/// Returns a "ready to use" type filled with fake values.
///
public static func fake() -> Yosemite.StoredBookingFilters {
.init(
filters: .fake()
)
}
}
extension Yosemite.SystemInformation {
/// Returns a "ready to use" type filled with fake values.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,8 @@ extension Networking.POSProduct {
attributes: CopiableProp<[ProductAttribute]> = .copy,
manageStock: CopiableProp<Bool> = .copy,
stockQuantity: NullableCopiableProp<Decimal> = .copy,
stockStatusKey: CopiableProp<String> = .copy
stockStatusKey: CopiableProp<String> = .copy,
variationIDs: CopiableProp<[Int64]> = .copy
) -> Networking.POSProduct {
let siteID = siteID ?? self.siteID
let productID = productID ?? self.productID
Expand All @@ -1385,6 +1386,7 @@ extension Networking.POSProduct {
let manageStock = manageStock ?? self.manageStock
let stockQuantity = stockQuantity ?? self.stockQuantity
let stockStatusKey = stockStatusKey ?? self.stockStatusKey
let variationIDs = variationIDs ?? self.variationIDs

return Networking.POSProduct(
siteID: siteID,
Expand All @@ -1402,7 +1404,8 @@ extension Networking.POSProduct {
attributes: attributes,
manageStock: manageStock,
stockQuantity: stockQuantity,
stockStatusKey: stockStatusKey
stockStatusKey: stockStatusKey,
variationIDs: variationIDs
)
}
}
Expand Down
13 changes: 11 additions & 2 deletions Modules/Sources/Networking/Model/POSProduct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public struct POSProduct: Codable, Equatable, GeneratedCopiable, GeneratedFakeab
public let stockQuantity: Decimal?
public let stockStatusKey: String

public let variationIDs: [Int64]

public init(siteID: Int64,
productID: Int64,
name: String,
Expand All @@ -58,7 +60,8 @@ public struct POSProduct: Codable, Equatable, GeneratedCopiable, GeneratedFakeab
attributes: [ProductAttribute],
manageStock: Bool,
stockQuantity: Decimal?,
stockStatusKey: String) {
stockStatusKey: String,
variationIDs: [Int64]) {
self.siteID = siteID
self.productID = productID
self.name = name
Expand All @@ -81,6 +84,8 @@ public struct POSProduct: Codable, Equatable, GeneratedCopiable, GeneratedFakeab
self.manageStock = manageStock
self.stockQuantity = stockQuantity
self.stockStatusKey = stockStatusKey

self.variationIDs = variationIDs
}

public init(from decoder: any Decoder) throws {
Expand Down Expand Up @@ -124,6 +129,8 @@ public struct POSProduct: Codable, Equatable, GeneratedCopiable, GeneratedFakeab
let stockQuantity = container.failsafeDecodeIfPresent(decimalForKey: .stockQuantity)
let stockStatusKey = try container.decode(String.self, forKey: .stockStatusKey)

let variationIDs = try container.decodeIfPresent([Int64].self, forKey: .variationIDs) ?? []

self.init(siteID: siteID,
productID: productID,
name: name,
Expand All @@ -139,7 +146,8 @@ public struct POSProduct: Codable, Equatable, GeneratedCopiable, GeneratedFakeab
attributes: attributes,
manageStock: manageStock,
stockQuantity: stockQuantity,
stockStatusKey: stockStatusKey)
stockStatusKey: stockStatusKey,
variationIDs: variationIDs)
}

static let requestFields: [String] = {
Expand Down Expand Up @@ -172,5 +180,6 @@ private extension POSProduct {
case manageStock = "manage_stock"
case stockQuantity = "stock_quantity"
case stockStatusKey = "stock_status"
case variationIDs = "variations"
}
}
6 changes: 6 additions & 0 deletions Modules/Sources/Storage/GRDB/Model/PersistedProduct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ extension PersistedProduct: FetchableRecord, PersistableRecord {
using: ForeignKey([PersistedProductAttribute.CodingKeys.siteID.stringValue,
PersistedProductAttribute.CodingKeys.productID.stringValue],
to: primaryKey))

public static let variations = hasMany(PersistedProductVariation.self,
key: "variations",
using: ForeignKey([PersistedProductVariation.CodingKeys.siteID.stringValue,
PersistedProductVariation.CodingKeys.productID.stringValue],
to: primaryKey))
}

// MARK: - Point of Sale Requests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ public extension PersistedProductVariation {
}
}

// periphery:ignore - TODO: remove ignore when populating database
private extension PersistedProductVariation {
extension PersistedProductVariation {
enum CodingKeys: String, CodingKey {
case id
case siteID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension PersistedProduct {
)
}

func toPOSProduct(images: [ProductImage] = [], attributes: [ProductAttribute] = []) -> POSProduct {
func toPOSProduct(images: [ProductImage] = [], attributes: [ProductAttribute] = [], variationIDs: [Int64] = []) -> POSProduct {
return POSProduct(
siteID: siteID,
productID: id,
Expand All @@ -40,20 +40,24 @@ extension PersistedProduct {
attributes: attributes,
manageStock: manageStock,
stockQuantity: stockQuantity,
stockStatusKey: stockStatusKey
stockStatusKey: stockStatusKey,
variationIDs: variationIDs
)
}

func toPOSProduct(db: GRDBDatabaseConnection) throws -> POSProduct {
let (images, attributes) = try db.read { db in
let (images, attributes, variationIDs) = try db.read { db in
let images = try request(for: PersistedProduct.images).fetchAll(db)
let attributes = try request(for: PersistedProduct.attributes).fetchAll(db)
return (images, attributes)
let variations = try request(for: PersistedProduct.variations).fetchAll(db)
let variationIDs = variations.map(\.id)
return (images, attributes, variationIDs)
}

return toPOSProduct(
images: images.map { $0.toProductImage() },
attributes: attributes.map { $0.toProductAttribute(siteID: siteID) }
attributes: attributes.map { $0.toProductAttribute(siteID: siteID) },
variationIDs: variationIDs
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,52 +87,46 @@ final class POSCatalogPersistenceService: POSCatalogPersistenceServiceProtocol {
DDLogInfo("💾 Persisting incremental catalog with \(catalog.products.count) updated products and \(catalog.variations.count) updated variations")

try await grdbManager.databaseConnection.write { db in
for product in catalog.productsToPersist {
try product.insert(db, onConflict: .replace)

// Delete old join table entries for this product
try PersistedProductImage
.filter { $0.siteID == siteID && $0.productID == product.id }
.deleteAll(db)

try PersistedProductAttribute
.filter { $0.siteID == siteID && $0.productID == product.id }
.deleteAll(db)
for product in catalog.products {
try PersistedProduct(from: product).save(db)

// Delete variations that are no longer associated with this product
let existingVariations = try PersistedProductVariation
.filter(PersistedProductVariation.Columns.siteID == siteID)
.filter(PersistedProductVariation.Columns.productID == product.productID)
.fetchAll(db)

for variation in existingVariations {
if !product.variationIDs.contains(variation.id) {
try variation.delete(db)
}
}
}

for variation in catalog.variationsToPersist {
try variation.insert(db, onConflict: .replace)

// Delete old join table entries for this variation
try PersistedProductVariationImage
.filter { $0.siteID == siteID && $0.productVariationID == variation.id }
.deleteAll(db)

try PersistedProductVariationAttribute
.filter { $0.siteID == siteID && $0.productVariationID == variation.id }
.deleteAll(db)
try variation.save(db)
}

// Insert/update actual image data (shared by products and variations)
// Upsert actual image data (shared by products and variations)
for image in catalog.imagesToPersist {
try image.insert(db, onConflict: .replace)
try image.save(db)
}

// Insert new join table entries
// Upsert new join table entries
for image in catalog.productImagesToPersist {
try image.insert(db, onConflict: .replace)
try image.save(db)
}

for image in catalog.variationImagesToPersist {
try image.insert(db, onConflict: .replace)
try image.save(db)
}

for var attribute in catalog.productAttributesToPersist {
try attribute.insert(db, onConflict: .replace)
try attribute.save(db)
}

for var attribute in catalog.variationAttributesToPersist {
try attribute.insert(db, onConflict: .replace)
try attribute.save(db)
}

var site = try PersistedSite.fetchOne(db, key: siteID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ struct PersistedProductTests {
attributes: [],
manageStock: true,
stockQuantity: 5,
stockStatusKey: "instock"
stockStatusKey: "instock",
variationIDs: []
)

// When
Expand Down Expand Up @@ -508,7 +509,8 @@ struct PersistedProductTests {
],
manageStock: true,
stockQuantity: 50,
stockStatusKey: "instock"
stockStatusKey: "instock",
variationIDs: []
)

// When saving and loading back
Expand Down
Loading