Skip to content

Commit 3577381

Browse files
committed
fix: correctly update shipping labels in an order if the following sequence of events occurs:
- I open an order detail without shipping labels on mobile and then navigate back to the list. - I open the same order on the web, purchase a shipping label, and press the "update" button to refresh the order dates. - When I reopen the order on mobile, the purchased shipping label appears while the order is updating. However, once the response is received, the shipping label disappears.
1 parent e03de8d commit 3577381

File tree

4 files changed

+75
-25
lines changed

4 files changed

+75
-25
lines changed

WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,32 @@ extension OrderDetailsViewModel {
262262
self.syncSubscriptions { _ in
263263
group.leave()
264264
}
265+
266+
// Shipping labels need to be synced after the order but before we complete
267+
// the order sync group to ensure the UI shows the latest data
268+
group.enter()
269+
Task { @MainActor [weak self] in
270+
defer {
271+
group.leave()
272+
}
273+
// Check Woo Shipping support first, to ensure correct flows are enabled for shipping labels.
274+
self?.dataSource.isEligibleForWooShipping = ((await self?.isWooShippingSupported()) != nil)
275+
276+
// Check creation eligibility
277+
let isEligible = await self?.checkShippingLabelCreationEligibility()
278+
self?.dataSource.isEligibleForShippingLabelCreation = isEligible ?? false
279+
280+
// Sync shipping labels and update order with the result if available
281+
if let shippingLabels = await self?.syncShippingLabels() {
282+
// Update the order with the newly synced shipping labels
283+
if let updatedOrder = self?.order.copy(shippingLabels: shippingLabels) {
284+
self?.update(order: updatedOrder)
285+
}
286+
}
287+
288+
// Reload UI after shipping labels are synced
289+
onReloadSections?()
290+
}
265291
}
266292

267293
group.enter()
@@ -282,22 +308,6 @@ extension OrderDetailsViewModel {
282308
onReloadSections?()
283309
}
284310

285-
group.enter()
286-
Task { @MainActor in
287-
defer {
288-
onReloadSections?()
289-
group.leave()
290-
}
291-
// Check Woo Shipping support first, to ensure correct flows are enabled for shipping labels.
292-
dataSource.isEligibleForWooShipping = await isWooShippingSupported()
293-
294-
// Then sync shipping labels and check creation eligibility concurrently.
295-
async let syncShippingLabels: () = syncShippingLabels()
296-
async let isEligibleForShippingLabelCreation = checkShippingLabelCreationEligibility()
297-
_ = await syncShippingLabels
298-
dataSource.isEligibleForShippingLabelCreation = await isEligibleForShippingLabelCreation
299-
}
300-
301311
group.enter()
302312
syncSavedReceipts {_ in
303313
group.leave()
@@ -681,24 +691,24 @@ extension OrderDetailsViewModel {
681691
}
682692

683693
@MainActor
684-
func syncShippingLabels() async {
694+
func syncShippingLabels() async -> [ShippingLabel]? {
685695
guard await localRequirementsForShippingLabelsAreFulfilled() else {
686-
return
696+
return nil
687697
}
688698
return await withCheckedContinuation { continuation in
689699
stores.dispatch(ShippingLabelAction.synchronizeShippingLabels(siteID: order.siteID, orderID: order.orderID) { result in
690700
switch result {
691-
case .success:
701+
case .success(let shippingLabels):
692702
ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest(result: .success))
693-
continuation.resume(returning: ())
703+
continuation.resume(returning: shippingLabels)
694704
case .failure(let error):
695705
ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest(result: .failed(error: error)))
696706
if error as? DotcomError == .noRestRoute {
697707
DDLogError("⚠️ Endpoint for synchronizing shipping labels is unreachable. WC Shipping plugin may be missing.")
698708
} else {
699709
DDLogError("⛔️ Error synchronizing shipping labels: \(error)")
700710
}
701-
continuation.resume(returning: ())
711+
continuation.resume(returning: nil)
702712
}
703713
})
704714
}

Yosemite/Yosemite/Actions/ShippingLabelAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Networking
33
public enum ShippingLabelAction: Action {
44
/// Syncs shipping labels for a given order.
55
///
6-
case synchronizeShippingLabels(siteID: Int64, orderID: Int64, completion: (Result<Void, Error>) -> Void)
6+
case synchronizeShippingLabels(siteID: Int64, orderID: Int64, completion: (Result<[ShippingLabel], Error>) -> Void)
77

88
/// Generates a shipping label document for printing.
99
///

Yosemite/Yosemite/Model/Mocks/ActionHandlers/MockShippingLabelActionHandler.swift

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,47 @@ struct MockShippingLabelActionHandler: MockActionHandler {
1111
switch action {
1212
/// Not implemented
1313
case .synchronizeShippingLabels(_, _, let completion):
14-
success(completion)
14+
let mockShippingLabel = ShippingLabel(
15+
siteID: 0,
16+
orderID: 0,
17+
shippingLabelID: 0,
18+
carrierID: "",
19+
dateCreated: Date(),
20+
packageName: "",
21+
rate: 0.0,
22+
currency: "",
23+
trackingNumber: "",
24+
serviceName: "",
25+
refundableAmount: 0.0,
26+
status: .unknown,
27+
refund: nil,
28+
originAddress: ShippingLabelAddress(
29+
company: "",
30+
name: "",
31+
phone: "",
32+
country: "",
33+
state: "",
34+
address1: "",
35+
address2: "",
36+
city: "",
37+
postcode: ""
38+
),
39+
destinationAddress: ShippingLabelAddress(
40+
company: "",
41+
name: "",
42+
phone: "",
43+
country: "",
44+
state: "",
45+
address1: "",
46+
address2: "",
47+
city: "",
48+
postcode: ""
49+
),
50+
productIDs: [],
51+
productNames: [],
52+
commercialInvoiceURL: nil
53+
)
54+
completion(.success([mockShippingLabel]))
1555
case .checkCreationEligibility(_, _, let onCompletion):
1656
onCompletion(false)
1757
default: unimplementedAction(action: action)

Yosemite/Yosemite/Stores/ShippingLabelStore.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public final class ShippingLabelStore: Store {
8787
}
8888

8989
private extension ShippingLabelStore {
90-
func synchronizeShippingLabels(siteID: Int64, orderID: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
90+
func synchronizeShippingLabels(siteID: Int64, orderID: Int64, completion: @escaping (Result<[ShippingLabel], Error>) -> Void) {
9191
remote.loadShippingLabels(siteID: siteID, orderID: orderID) { [weak self] result in
9292
guard let self = self else { return }
9393

@@ -99,7 +99,7 @@ private extension ShippingLabelStore {
9999
orderID: orderID,
100100
shippingLabels: response.shippingLabels,
101101
settings: response.settings) {
102-
completion(.success(()))
102+
completion(.success(response.shippingLabels))
103103
}
104104
}
105105
}

0 commit comments

Comments
 (0)