diff --git a/Storage/Storage/Tools/StorageType+Extensions.swift b/Storage/Storage/Tools/StorageType+Extensions.swift index 10fe92f1b3c..6f9213218ea 100644 --- a/Storage/Storage/Tools/StorageType+Extensions.swift +++ b/Storage/Storage/Tools/StorageType+Extensions.swift @@ -35,6 +35,14 @@ public extension StorageType { // MARK: - Orders + /// Retrieves the Stored Orders given the IDs. + /// + func loadOrders(siteID: Int64, orderIDs: [Int64]) -> [Order] { + let predicate = NSPredicate(format: "siteID == %lld && orderID in %@", siteID, orderIDs) + let descriptor = NSSortDescriptor(keyPath: \Order.orderID, ascending: false) + return allObjects(ofType: Order.self, matching: predicate, sortedBy: [descriptor]) + } + /// Retrieves the Stored Order. /// func loadOrder(siteID: Int64, orderID: Int64) -> Order? { diff --git a/Storage/StorageTests/Tools/StorageTypeExtensionsTests.swift b/Storage/StorageTests/Tools/StorageTypeExtensionsTests.swift index d66cb439270..a085a6ae067 100644 --- a/Storage/StorageTests/Tools/StorageTypeExtensionsTests.swift +++ b/Storage/StorageTests/Tools/StorageTypeExtensionsTests.swift @@ -66,6 +66,34 @@ final class StorageTypeExtensionsTests: XCTestCase { XCTAssertEqual(site, storedSite) } + func test_loadOrders_list_by_siteID_and_orderIDs() { + // Given + let orderID1: Int64 = 123 + let order1 = storage.insertNewObject(ofType: Order.self) + order1.siteID = sampleSiteID + order1.orderID = orderID1 + + let orderID2: Int64 = 125 + let order2 = storage.insertNewObject(ofType: Order.self) + order2.siteID = sampleSiteID + order2.orderID = orderID2 + + let orderID3: Int64 = 126 + let order3 = storage.insertNewObject(ofType: Order.self) + order3.siteID = sampleSiteID + order3.orderID = orderID3 + + let order4 = storage.insertNewObject(ofType: Order.self) + order4.siteID = 0 + order4.orderID = orderID3 + + // When + let storedOrders = storage.loadOrders(siteID: sampleSiteID, orderIDs: [orderID1, orderID3]) + + // Then + XCTAssertEqual(storedOrders, [order3, order1]) + } + func test_loadOrder_by_siteID_and_orderID() throws { // Given let orderID: Int64 = 123 diff --git a/Yosemite/Yosemite/Stores/Order/OrdersUpsertUseCase.swift b/Yosemite/Yosemite/Stores/Order/OrdersUpsertUseCase.swift index d6e4d673b9d..777df415358 100644 --- a/Yosemite/Yosemite/Stores/Order/OrdersUpsertUseCase.swift +++ b/Yosemite/Yosemite/Stores/Order/OrdersUpsertUseCase.swift @@ -69,12 +69,10 @@ struct OrdersUpsertUseCase { /// private func handleOrderItems(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { var storageItem: Storage.OrderItem - let siteID = readOnlyOrder.siteID - let orderID = readOnlyOrder.orderID // Upsert the items from the read-only order for readOnlyItem in readOnlyOrder.items { - if let existingStorageItem = storage.loadOrderItem(siteID: siteID, orderID: orderID, itemID: readOnlyItem.itemID) { + if let existingStorageItem = storageOrder.orderItemsArray.first(where: { $0.itemID == readOnlyItem.itemID }) { existingStorageItem.update(with: readOnlyItem) storageItem = existingStorageItem } else { @@ -137,11 +135,10 @@ struct OrdersUpsertUseCase { /// Updates, inserts, or prunes the provided StorageOrderItem's taxes using the provided read-only OrderItem /// private func handleOrderItemTaxes(_ readOnlyItem: Networking.OrderItem, _ storageItem: Storage.OrderItem, _ storage: StorageType) { - let itemID = readOnlyItem.itemID // Upsert the taxes from the read-only orderItem for readOnlyTax in readOnlyItem.taxes { - if let existingStorageTax = storage.loadOrderItemTax(itemID: itemID, taxID: readOnlyTax.taxID) { + if let existingStorageTax = storageItem.taxes?.first(where: { $0.taxID == readOnlyTax.taxID }) { existingStorageTax.update(with: readOnlyTax) } else { let newStorageTax = storage.insertNewObject(ofType: Storage.OrderItemTax.self) @@ -164,7 +161,7 @@ struct OrdersUpsertUseCase { private func handleOrderCoupons(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { // Upsert the coupons from the read-only order for readOnlyCoupon in readOnlyOrder.coupons { - if let existingStorageCoupon = storage.loadOrderCoupon(siteID: readOnlyOrder.siteID, couponID: readOnlyCoupon.couponID) { + if let existingStorageCoupon = storageOrder.coupons?.first(where: { $0.couponID == readOnlyCoupon.couponID }) { existingStorageCoupon.update(with: readOnlyCoupon) } else { let newStorageCoupon = storage.insertNewObject(ofType: Storage.OrderCoupon.self) @@ -187,7 +184,7 @@ struct OrdersUpsertUseCase { private func handleOrderFees(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { // Upsert the coupons from the read-only order for readOnlyFee in readOnlyOrder.fees { - if let existingStorageFee = storage.loadOrderFeeLine(siteID: readOnlyOrder.siteID, feeID: readOnlyFee.feeID) { + if let existingStorageFee = storageOrder.fees?.first(where: { $0.feeID == readOnlyFee.feeID }) { existingStorageFee.update(with: readOnlyFee) } else { let newStorageFee = storage.insertNewObject(ofType: Storage.OrderFeeLine.self) @@ -210,7 +207,7 @@ struct OrdersUpsertUseCase { private func handleOrderRefundsCondensed(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { // Upsert the refunds from the read-only order for readOnlyRefund in readOnlyOrder.refunds { - if let existingStorageRefund = storage.loadOrderRefundCondensed(siteID: readOnlyOrder.siteID, refundID: readOnlyRefund.refundID) { + if let existingStorageRefund = storageOrder.refunds?.first(where: { $0.refundID == readOnlyRefund.refundID }) { existingStorageRefund.update(with: readOnlyRefund) } else { let newStorageRefund = storage.insertNewObject(ofType: Storage.OrderRefundCondensed.self) @@ -233,7 +230,7 @@ struct OrdersUpsertUseCase { private func handleOrderShippingLines(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { // Upsert the shipping lines from the read-only order for readOnlyShippingLine in readOnlyOrder.shippingLines { - if let existingStorageShippingLine = storage.loadOrderShippingLine(siteID: readOnlyOrder.siteID, shippingID: readOnlyShippingLine.shippingID) { + if let existingStorageShippingLine = storageOrder.shippingLines?.first(where: { $0.shippingID == readOnlyShippingLine.shippingID }) { existingStorageShippingLine.update(with: readOnlyShippingLine) handleShippingLineTaxes(readOnlyShippingLine, existingStorageShippingLine, storage) } else { @@ -256,11 +253,10 @@ struct OrdersUpsertUseCase { /// Updates, inserts, or prunes the provided StorageShippingLine's taxes using the provided read-only ShippingLine /// private func handleShippingLineTaxes(_ readOnlyItem: Networking.ShippingLine, _ storageItem: Storage.ShippingLine, _ storage: StorageType) { - let shippingID = readOnlyItem.shippingID // Upsert the taxes from the read-only orderItem for readOnlyTax in readOnlyItem.taxes { - if let existingStorageTax = storage.loadShippingLineTax(shippingID: shippingID, taxID: readOnlyTax.taxID) { + if let existingStorageTax = storageItem.taxes?.first(where: { $0.taxID == readOnlyTax.taxID }) { existingStorageTax.update(with: readOnlyTax) } else { let newStorageTax = storage.insertNewObject(ofType: Storage.ShippingLineTax.self) @@ -283,7 +279,7 @@ struct OrdersUpsertUseCase { private func handleOrderTaxes(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) { // Upsert the `taxes` from the `readOnlyOrder` readOnlyOrder.taxes.forEach { readOnlyTax in - if let existingStorageTax = storage.loadOrderTaxLine(siteID: readOnlyOrder.siteID, taxID: readOnlyTax.taxID) { + if let existingStorageTax = storageOrder.taxes?.first(where: { $0.taxID == readOnlyTax.taxID }) { existingStorageTax.update(with: readOnlyTax) } else { let newStorageTax = storage.insertNewObject(ofType: Storage.OrderTaxLine.self) diff --git a/Yosemite/Yosemite/Stores/OrderStore.swift b/Yosemite/Yosemite/Stores/OrderStore.swift index fc067a692d8..23d933a4eff 100644 --- a/Yosemite/Yosemite/Stores/OrderStore.swift +++ b/Yosemite/Yosemite/Stores/OrderStore.swift @@ -119,7 +119,7 @@ private extension OrderStore { return } - self?.upsertSearchResultsInBackground(keyword: keyword, readOnlyOrders: orders) { + self?.upsertSearchResultsInBackground(for: siteID, keyword: keyword, readOnlyOrders: orders) { onCompletion(nil) } } @@ -579,8 +579,8 @@ extension OrderStore { /// Unit Testing Helper: Updates or Inserts a given Search Results page /// - func upsertStoredResults(keyword: String, readOnlyOrder: Networking.Order, in storage: StorageType) { - upsertStoredResults(keyword: keyword, readOnlyOrders: [readOnlyOrder], in: storage) + func upsertStoredResults(for siteID: Int64, keyword: String, readOnlyOrder: Networking.Order, in storage: StorageType) { + upsertStoredResults(for: siteID, keyword: keyword, readOnlyOrders: [readOnlyOrder], in: storage) } } @@ -609,22 +609,24 @@ private extension OrderStore { /// Upserts the Orders, and associates them to the SearchResults Entity (in Background) /// - func upsertSearchResultsInBackground(keyword: String, readOnlyOrders: [Networking.Order], onCompletion: @escaping () -> Void) { + func upsertSearchResultsInBackground(for siteID: Int64, keyword: String, readOnlyOrders: [Networking.Order], onCompletion: @escaping () -> Void) { storageManager.performAndSave({ [weak self] derivedStorage in guard let self else { return } upsertStoredOrders(readOnlyOrders: readOnlyOrders, insertingSearchResults: true, in: derivedStorage) - upsertStoredResults(keyword: keyword, readOnlyOrders: readOnlyOrders, in: derivedStorage) + upsertStoredResults(for: siteID, keyword: keyword, readOnlyOrders: readOnlyOrders, in: derivedStorage) }, completion: onCompletion, on: .main) } /// Upserts the Orders, and associates them to the Search Results Entity (in the specified Storage) /// - func upsertStoredResults(keyword: String, readOnlyOrders: [Networking.Order], in storage: StorageType) { + func upsertStoredResults(for siteID: Int64, keyword: String, readOnlyOrders: [Networking.Order], in storage: StorageType) { let searchResults = storage.loadOrderSearchResults(keyword: keyword) ?? storage.insertNewObject(ofType: Storage.OrderSearchResults.self) searchResults.keyword = keyword - for readOnlyOrder in readOnlyOrders { - guard let storedOrder = storage.loadOrder(siteID: readOnlyOrder.siteID, orderID: readOnlyOrder.orderID) else { + let orderIDs = readOnlyOrders.map { $0.orderID } + let storedOrders = storage.loadOrders(siteID: siteID, orderIDs: orderIDs) + for orderID in orderIDs { + guard let storedOrder = storedOrders.first(where: { $0.orderID == orderID }) else { continue } diff --git a/Yosemite/YosemiteTests/Stores/OrderStoreTests.swift b/Yosemite/YosemiteTests/Stores/OrderStoreTests.swift index f351a56de20..b4ab54ee9b1 100644 --- a/Yosemite/YosemiteTests/Stores/OrderStoreTests.swift +++ b/Yosemite/YosemiteTests/Stores/OrderStoreTests.swift @@ -647,7 +647,7 @@ final class OrderStoreTests: XCTestCase { let remoteOrder = sampleOrder() orderStore.upsertStoredOrder(readOnlyOrder: remoteOrder, insertingSearchResults: true, in: viewStorage) - orderStore.upsertStoredResults(keyword: defaultSearchKeyword, readOnlyOrder: remoteOrder, in: viewStorage) + orderStore.upsertStoredResults(for: sampleSiteID, keyword: defaultSearchKeyword, readOnlyOrder: remoteOrder, in: viewStorage) let storageSearchResults = viewStorage.loadOrderSearchResults(keyword: defaultSearchKeyword) let storageOrder = viewStorage.loadOrder(siteID: sampleSiteID, orderID: remoteOrder.orderID)