Skip to content

Commit b8f95ef

Browse files
committed
Update Yosemite to fetch resource
1 parent 5755898 commit b8f95ef

File tree

14 files changed

+147
-15
lines changed

14 files changed

+147
-15
lines changed

Modules/Sources/Fakes/Networking.generated.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ extension Networking.BookingResource {
350350
public static func fake() -> Networking.BookingResource {
351351
.init(
352352
siteID: .fake(),
353-
bookingID: .fake(),
353+
resourceID: .fake(),
354354
name: .fake(),
355355
quantity: .fake(),
356356
role: .fake(),

Modules/Sources/Networking/Model/Bookings/BookingResource.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Foundation
33

44
public struct BookingResource: Hashable, Decodable, GeneratedFakeable, GeneratedCopiable {
55
public let siteID: Int64
6-
public let bookingID: Int64
6+
public let resourceID: Int64
77
public let name: String
88
public let quantity: Int64
99
public let role: String
@@ -14,7 +14,7 @@ public struct BookingResource: Hashable, Decodable, GeneratedFakeable, Generated
1414
public let description: String?
1515

1616
public init(siteID: Int64,
17-
bookingID: Int64,
17+
resourceID: Int64,
1818
name: String,
1919
quantity: Int64,
2020
role: String,
@@ -24,7 +24,7 @@ public struct BookingResource: Hashable, Decodable, GeneratedFakeable, Generated
2424
imageURL: String?,
2525
description: String?) {
2626
self.siteID = siteID
27-
self.bookingID = bookingID
27+
self.resourceID = resourceID
2828
self.name = name
2929
self.quantity = quantity
3030
self.role = role
@@ -42,7 +42,7 @@ public struct BookingResource: Hashable, Decodable, GeneratedFakeable, Generated
4242

4343
let container = try decoder.container(keyedBy: CodingKeys.self)
4444

45-
let bookingID = try container.decode(Int64.self, forKey: .bookingID)
45+
let resourceID = try container.decode(Int64.self, forKey: .resourceID)
4646
let name = try container.decode(String.self, forKey: .name)
4747
let quantity = try container.decode(Int64.self, forKey: .quantity)
4848
let role = try container.decode(String.self, forKey: .role)
@@ -53,7 +53,7 @@ public struct BookingResource: Hashable, Decodable, GeneratedFakeable, Generated
5353
let description = try container.decodeIfPresent(String.self, forKey: .description)
5454

5555
self.init(siteID: siteID,
56-
bookingID: bookingID,
56+
resourceID: resourceID,
5757
name: name,
5858
quantity: quantity,
5959
role: role,
@@ -67,7 +67,7 @@ public struct BookingResource: Hashable, Decodable, GeneratedFakeable, Generated
6767

6868
private extension BookingResource {
6969
enum CodingKeys: String, CodingKey {
70-
case bookingID = "id"
70+
case resourceID = "id"
7171
case name
7272
case quantity = "qty"
7373
case role

Modules/Sources/Networking/Model/Copiable/Models+Copiable.generated.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ extension Networking.Booking {
497497
extension Networking.BookingResource {
498498
public func copy(
499499
siteID: CopiableProp<Int64> = .copy,
500-
bookingID: CopiableProp<Int64> = .copy,
500+
resourceID: CopiableProp<Int64> = .copy,
501501
name: CopiableProp<String> = .copy,
502502
quantity: CopiableProp<Int64> = .copy,
503503
role: CopiableProp<String> = .copy,
@@ -508,7 +508,7 @@ extension Networking.BookingResource {
508508
description: NullableCopiableProp<String> = .copy
509509
) -> Networking.BookingResource {
510510
let siteID = siteID ?? self.siteID
511-
let bookingID = bookingID ?? self.bookingID
511+
let resourceID = resourceID ?? self.resourceID
512512
let name = name ?? self.name
513513
let quantity = quantity ?? self.quantity
514514
let role = role ?? self.role
@@ -520,7 +520,7 @@ extension Networking.BookingResource {
520520

521521
return Networking.BookingResource(
522522
siteID: siteID,
523-
bookingID: bookingID,
523+
resourceID: resourceID,
524524
name: name,
525525
quantity: quantity,
526526
role: role,

Modules/Sources/Storage/Model/Booking/BookingResource+CoreDataProperties.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import CoreData
33

44
extension BookingResource {
55
@NSManaged public var siteID: Int64
6-
@NSManaged public var bookingID: Int64
6+
@NSManaged public var resourceID: Int64
77
@NSManaged public var name: String?
88
@NSManaged public var quantity: Int64
99
@NSManaged public var role: String?

Modules/Sources/Storage/Resources/WooCommerce.xcdatamodeld/Model 128.xcdatamodel/contents

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@
118118
<relationship name="orderInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BookingOrderInfo" inverseName="productInfo" inverseEntity="BookingOrderInfo"/>
119119
</entity>
120120
<entity name="BookingResource" representedClassName="BookingResource" syncable="YES">
121-
<attribute name="bookingID" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
122121
<attribute name="descriptionText" optional="YES" attributeType="String"/>
123122
<attribute name="email" optional="YES" attributeType="String"/>
124123
<attribute name="imageID" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
125124
<attribute name="imageURL" optional="YES" attributeType="String"/>
126125
<attribute name="name" attributeType="String" defaultValueString=""/>
127126
<attribute name="phoneNumber" optional="YES" attributeType="String"/>
128127
<attribute name="quantity" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
128+
<attribute name="resourceID" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
129129
<attribute name="role" attributeType="String" defaultValueString=""/>
130130
<attribute name="siteID" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
131131
</entity>

Modules/Sources/Storage/Tools/StorageType+Extensions.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,4 +966,10 @@ public extension StorageType {
966966
let objects = allObjects(ofType: Booking.self, matching: predicate, sortedBy: [descriptor])
967967
return objects.isEmpty ? nil : objects
968968
}
969+
970+
/// Retrieves the store booking resource
971+
func loadBookingResource(siteID: Int64, resourceID: Int64) -> BookingResource? {
972+
let predicate = \BookingResource.resourceID == resourceID && \BookingResource.siteID == siteID
973+
return firstObject(ofType: BookingResource.self, matching: predicate)
974+
}
969975
}

Modules/Sources/Yosemite/Actions/BookingAction.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,12 @@ public enum BookingAction: Action {
4444
startDateAfter: String? = nil,
4545
order: BookingsRemote.Order = .descending,
4646
onCompletion: (Result<[Booking], Error>) -> Void)
47+
48+
/// Fetches a booking resource by resource ID.
49+
///
50+
/// - Parameter onCompletion: called when fetch completes, returns an error or the booking resource.
51+
///
52+
case fetchResource(siteID: Int64,
53+
resourceID: Int64,
54+
onCompletion: (Result<BookingResource, Error>) -> Void)
4755
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import Foundation
2+
import Storage
3+
4+
// MARK: - Storage.BookingResource: ReadOnlyConvertible
5+
//
6+
extension Storage.BookingResource: ReadOnlyConvertible {
7+
8+
/// Updates the Storage.BookingResource with the a ReadOnly.
9+
///
10+
public func update(with resource: Yosemite.BookingResource) {
11+
siteID = resource.siteID
12+
resourceID = resource.resourceID
13+
name = resource.name
14+
quantity = resource.quantity
15+
role = resource.role
16+
email = resource.email
17+
phoneNumber = resource.phoneNumber
18+
imageID = resource.imageID
19+
imageURL = resource.imageURL
20+
descriptionText = resource.description
21+
}
22+
23+
/// Returns a ReadOnly version of the receiver.
24+
///
25+
public func toReadOnly() -> Yosemite.BookingResource {
26+
BookingResource(siteID: siteID,
27+
resourceID: resourceID,
28+
name: name ?? "",
29+
quantity: quantity,
30+
role: role ?? "",
31+
email: email,
32+
phoneNumber: phoneNumber,
33+
imageID: imageID,
34+
imageURL: imageURL,
35+
description: descriptionText)
36+
}
37+
}
38+
39+
extension Yosemite.BookingResource: ReadOnlyType {
40+
/// Indicates if the receiver is a representation of a specified Storage.Entity instance.
41+
///
42+
public func isReadOnlyRepresentation(of storageEntity: Any) -> Bool {
43+
guard let storageResource = storageEntity as? Storage.BookingResource else {
44+
return false
45+
}
46+
47+
return siteID == Int(storageResource.siteID) && resourceID == Int(storageResource.resourceID)
48+
}
49+
}

Modules/Sources/Yosemite/Model/Model.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public typealias BookingOrderInfo = Networking.BookingOrderInfo
3030
public typealias BookingCustomerInfo = Networking.BookingCustomerInfo
3131
public typealias BookingPaymentInfo = Networking.BookingPaymentInfo
3232
public typealias BookingProductInfo = Networking.BookingProductInfo
33+
public typealias BookingResource = Networking.BookingResource
3334
public typealias CreateBlazeCampaign = Networking.CreateBlazeCampaign
3435
public typealias FallibleCancelable = Hardware.FallibleCancelable
3536
public typealias CommentStatus = Networking.CommentStatus

Modules/Sources/Yosemite/Stores/BookingStore.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class BookingStore: Store {
6161
startDateAfter: startDateAfter,
6262
order: order,
6363
onCompletion: onCompletion)
64+
case let .fetchResource(siteID, resourceID, onCompletion):
65+
fetchResource(siteID: siteID, resourceID: resourceID, onCompletion: onCompletion)
6466
}
6567
}
6668
}
@@ -214,6 +216,36 @@ private extension BookingStore {
214216
}
215217
}
216218
}
219+
220+
/// Fetches a booking resource by resource ID and saves it to storage.
221+
///
222+
func fetchResource(siteID: Int64,
223+
resourceID: Int64,
224+
onCompletion: @escaping (Result<BookingResource, Error>) -> Void) {
225+
enum FetchResourceError: Error {
226+
case resourceIsMissing
227+
}
228+
229+
Task { @MainActor in
230+
do {
231+
let resource = try await remote.fetchResource(
232+
resourceID: resourceID,
233+
siteID: siteID
234+
)
235+
236+
guard let resource else {
237+
onCompletion(.failure(FetchResourceError.resourceIsMissing))
238+
return
239+
}
240+
241+
await upsertBookingResourceInBackground(readOnlyBookingResource: resource)
242+
243+
onCompletion(.success(resource))
244+
} catch {
245+
onCompletion(.failure(error))
246+
}
247+
}
248+
}
217249
}
218250

219251

@@ -309,4 +341,21 @@ private extension BookingStore {
309341
storageBooking.update(with: readOnlyBooking)
310342
}
311343
}
344+
345+
/// Updates (OR Inserts) the specified ReadOnly BookingResource Entities *in a background thread* async.
346+
func upsertBookingResourceInBackground(readOnlyBookingResource: BookingResource) async {
347+
await withCheckedContinuation { [weak self] continuation in
348+
guard let self else {
349+
return continuation.resume()
350+
}
351+
352+
storageManager.performAndSave({ storage in
353+
let storedItem = storage.loadBookingResource(siteID: readOnlyBookingResource.siteID, resourceID: readOnlyBookingResource.resourceID)
354+
let storageResource = storedItem ?? storage.insertNewObject(ofType: Storage.BookingResource.self)
355+
storageResource.update(with: readOnlyBookingResource)
356+
}, completion: {
357+
continuation.resume()
358+
}, on: .main)
359+
}
360+
}
312361
}

0 commit comments

Comments
 (0)