@@ -6,17 +6,21 @@ import Storage
66//
77public class BookingStore : Store {
88 private let remote : BookingsRemoteProtocol
9+ private let ordersRemote : OrdersRemoteProtocol
910
1011 public override convenience init ( dispatcher: Dispatcher , storageManager: StorageManagerType , network: Network ) {
1112 let remote = BookingsRemote ( network: network)
12- self . init ( dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote)
13+ let ordersRemote = OrdersRemote ( network: network)
14+ self . init ( dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote, ordersRemote: ordersRemote)
1315 }
1416
1517 public init ( dispatcher: Dispatcher ,
1618 storageManager: StorageManagerType ,
1719 network: Network ,
18- remote: BookingsRemoteProtocol ) {
20+ remote: BookingsRemoteProtocol ,
21+ ordersRemote: OrdersRemoteProtocol ) {
1922 self . remote = remote
23+ self . ordersRemote = ordersRemote
2024 super. init ( dispatcher: dispatcher, storageManager: storageManager, network: network)
2125 }
2226
@@ -43,6 +47,8 @@ public class BookingStore: Store {
4347 startDateAfter: startDateAfter,
4448 shouldClearCache: shouldClearCache,
4549 onCompletion: onCompletion)
50+ case . synchronizeBooking( siteID: let siteID, bookingID: let bookingID, onCompletion: let onCompletion) :
51+ synchronizeBooking ( siteID: siteID, bookingID: bookingID, onCompletion: onCompletion)
4652 case let . checkIfStoreHasBookings( siteID, onCompletion) :
4753 checkIfStoreHasBookings ( siteID: siteID, onCompletion: onCompletion)
4854 case let . searchBookings( siteID, searchQuery, pageNumber, pageSize, startDateBefore, startDateAfter, onCompletion) :
@@ -79,8 +85,15 @@ private extension BookingStore {
7985 startDateBefore: startDateBefore,
8086 startDateAfter: startDateAfter,
8187 searchQuery: nil )
88+
89+ let orders = try await ordersRemote. loadOrders (
90+ for: siteID,
91+ orderIDs: bookings. map { $0. orderID }
92+ )
93+
8294 await upsertStoredBookingsInBackground (
8395 readOnlyBookings: bookings,
96+ readOnlyOrders: orders,
8497 siteID: siteID,
8598 shouldDeleteExistingBookings: shouldClearCache
8699 )
@@ -92,6 +105,45 @@ private extension BookingStore {
92105 }
93106 }
94107
108+ func synchronizeBooking(
109+ siteID: Int64 ,
110+ bookingID: Int64 ,
111+ onCompletion: @escaping ( Result < Void , Error > ) -> Void
112+ ) {
113+ enum SynchronizeBookingError : Error {
114+ case bookingIsMissing
115+ }
116+
117+ Task { @MainActor in
118+ do {
119+ let booking = try await remote. loadBooking (
120+ bookingID: bookingID,
121+ siteID: siteID
122+ )
123+
124+ guard let booking else {
125+ onCompletion ( . failure( SynchronizeBookingError . bookingIsMissing) )
126+ return
127+ }
128+
129+ let orders = try await ordersRemote. loadOrders (
130+ for: siteID,
131+ orderIDs: [ booking. orderID]
132+ )
133+
134+ await upsertStoredBookingsInBackground (
135+ readOnlyBookings: [ booking] ,
136+ readOnlyOrders: orders,
137+ siteID: siteID
138+ )
139+
140+ onCompletion ( . success( ( ) ) )
141+ } catch {
142+ onCompletion ( . failure( error) )
143+ }
144+ }
145+ }
146+
95147 /// Checks if the store already has any bookings.
96148 /// Returns `false` if the store has no bookings.
97149 ///
@@ -149,18 +201,21 @@ private extension BookingStore {
149201
150202// MARK: - Storage: Booking
151203//
152- extension BookingStore {
204+ private extension BookingStore {
153205
154206 /// Updates (OR Inserts) the specified ReadOnly Booking Entities *in a background thread* async.
155207 /// Also deletes existing bookings if requested.
156208 func upsertStoredBookingsInBackground( readOnlyBookings: [ Yosemite . Booking ] ,
209+ readOnlyOrders: [ Yosemite . Order ] ,
157210 siteID: Int64 ,
158211 shouldDeleteExistingBookings: Bool = false ) async {
159212 await withCheckedContinuation { [ weak self] continuation in
160213 guard let self else {
161214 return continuation. resume ( )
162215 }
216+
163217 upsertStoredBookingsInBackground ( readOnlyBookings: readOnlyBookings,
218+ readOnlyOrders: readOnlyOrders,
164219 siteID: siteID,
165220 shouldDeleteExistingBookings: shouldDeleteExistingBookings) {
166221 continuation. resume ( )
@@ -173,6 +228,7 @@ extension BookingStore {
173228 /// `onCompletion` will be called on the main thread!
174229 ///
175230 func upsertStoredBookingsInBackground( readOnlyBookings: [ Yosemite . Booking ] ,
231+ readOnlyOrders: [ Yosemite . Order ] ,
176232 siteID: Int64 ,
177233 shouldDeleteExistingBookings: Bool = false ,
178234 onCompletion: @escaping ( ) -> Void ) {
@@ -183,17 +239,18 @@ extension BookingStore {
183239 if shouldDeleteExistingBookings {
184240 storage. deleteBookings ( siteID: siteID)
185241 }
186- upsertStoredBookings ( readOnlyBookings: readOnlyBookings, in: storage)
242+ upsertStoredBookings ( readOnlyBookings: readOnlyBookings, readOnlyOrders : readOnlyOrders , in: storage)
187243 } , completion: onCompletion, on: . main)
188244 }
189245
190246 /// Updates (OR Inserts) the specified ReadOnly Booking Entities into the Storage Layer.
191247 ///
192248 /// - Parameters:
193249 /// - readOnlyBookings: Remote Bookings to be persisted.
250+ /// - readOnlyOrders: Remote Orders associated with bookings.
194251 /// - storage: Where we should save all the things!
195252 ///
196- func upsertStoredBookings( readOnlyBookings: [ Networking . Booking ] , in storage: StorageType ) {
253+ func upsertStoredBookings( readOnlyBookings: [ Networking . Booking ] , readOnlyOrders : [ Yosemite . Order ] , in storage: StorageType ) {
197254 // Fetch all existing bookings for the site at once
198255 let bookingIDs = readOnlyBookings. map { $0. bookingID }
199256 let siteID = readOnlyBookings. first? . siteID ?? 0
@@ -204,6 +261,14 @@ extension BookingStore {
204261 let storageBooking = storedBookings. first { $0. bookingID == readOnlyBooking. bookingID } ??
205262 storage. insertNewObject ( ofType: StorageBooking . self)
206263
264+ // TODO: - Apply new Booking specific models
265+ if let associatedOrder = readOnlyOrders. first ( where: { $0. orderID == readOnlyBooking. orderID } ) {
266+ /// 1. Convert `Order` into `Booking` specific order, product and customer
267+ /// 2. Obtain corresponding associated `Storage` models from `storageBooking` or create new ones.
268+ /// 3. Update the above models with values from `associatedOrder`
269+ print ( " The order for the booking \( readOnlyBooking. bookingID) : \( associatedOrder) " )
270+ }
271+
207272 storageBooking. update ( with: readOnlyBooking)
208273 }
209274 }
0 commit comments