@@ -220,6 +220,27 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
220220 return ResultsController < StorageWooShippingShipment > ( storageManager: storageManager, matching: predicate, sortedBy: [ descriptor] )
221221 } ( )
222222
223+ /// Origin addresses Results Controller.
224+ ///
225+ private lazy var originAddressResultsController : ResultsController < StorageWooShippingOriginAddress > = {
226+ let predicate = NSPredicate ( format: " siteID = %ld " , self . order. siteID)
227+ let descriptor = NSSortDescriptor ( keyPath: \StorageWooShippingOriginAddress . id, ascending: true )
228+
229+ return ResultsController < StorageWooShippingOriginAddress > ( storageManager: storageManager, matching: predicate, sortedBy: [ descriptor] )
230+ } ( )
231+
232+ /// Shipping Label Account Settings ResultsController
233+ ///
234+ private lazy var accountSettingsResultsController : ResultsController < StorageShippingLabelAccountSettings > = {
235+ let predicate = NSPredicate ( format: " siteID == %lld " , order. siteID)
236+ return ResultsController < StorageShippingLabelAccountSettings > (
237+ storageManager: storageManager,
238+ matching: predicate,
239+ fetchLimit: 1 ,
240+ sortedBy: [ ]
241+ )
242+ } ( )
243+
223244 /// Initialize the view model with or without an existing shipping label.
224245 init ( order: Order ,
225246 preselection: WooShippingCreateLabelSelection ? = nil ,
@@ -241,6 +262,8 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
241262 self . storageManager = storageManager
242263 self . analytics = analytics
243264 self . shippingSettingsService = shippingSettingsService
265+ self . weightUnit = shippingSettingsService. weightUnit ?? " "
266+ self . dimensionsUnit = shippingSettingsService. dimensionUnit ?? " "
244267 self . initialNoticeDelay = initialNoticeDelay
245268 self . isOrderCompleted = order. status == . completed
246269
@@ -267,6 +290,8 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
267290 observeViewStates ( )
268291 observePaymentMethod ( )
269292 configureShipmentResultsController ( )
293+ configureOriginAddressResultsController ( )
294+ configureAccountSettingsResultsController ( )
270295
271296 Task { @MainActor in
272297 await loadRequiredData ( )
@@ -291,16 +316,24 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
291316 func loadRequiredData( ) async {
292317 state = . loading
293318 await withTaskGroup ( of: Void . self) { group in
319+ /// Only load store options synchronously if no settings have been saved in storage yet.
294320 if isMissingStoreSettings {
295321 group. addTask {
296322 await self . loadStoreOptions ( )
297323 }
324+ } else {
325+ /// load asynchronously to update the local storage and unblock UI
326+ stores. dispatch ( WooShippingAction . loadAccountSettings ( siteID: order. siteID, completion: { _ in } ) )
298327 }
299328
300- if hasUnfulfilledShipments {
329+ /// Only load origin addresses synchronously if no addresses have been saved in storage yet.
330+ if hasUnfulfilledShipments, originAddress. isEmpty {
301331 group. addTask {
302332 await self . loadOriginAddresses ( )
303333 }
334+ } else if hasUnfulfilledShipments {
335+ /// load asynchronously to update the local storage and unblock UI
336+ stores. dispatch ( WooShippingAction . loadOriginAddresses ( siteID: order. siteID, completion: { _ in } ) )
304337 }
305338 }
306339
@@ -418,12 +451,7 @@ private extension WooShippingCreateLabelsViewModel {
418451 }
419452 weightUnit = settings? . storeOptions. weightUnit ?? shippingSettingsService. weightUnit ?? " "
420453 dimensionsUnit = settings? . storeOptions. dimensionUnit ?? shippingSettingsService. dimensionUnit ?? " "
421- markOrderComplete = settings? . accountSettings. lastOrderCompleted ?? false
422-
423- if let accountSettings = settings? . accountSettings {
424- paymentMethodsViewModel = ShippingLabelPaymentMethodsViewModel ( accountSettings: accountSettings)
425- }
426- setupPaymentMethod ( accountSettings: settings? . accountSettings)
454+ updateAccountSettings ( accountSettings: settings? . accountSettings)
427455 }
428456
429457 /// Syncs origin addresses to use for shipping label from remote.
@@ -442,12 +470,7 @@ private extension WooShippingCreateLabelsViewModel {
442470 }
443471 stores. dispatch ( action)
444472 }
445- selectedOriginAddress = addresses. first ( where: \. defaultAddress)
446- originAddresses = WooShippingOriginAddressListViewModel ( addresses: addresses,
447- selectedAddressID: selectedOriginAddress? . id)
448- originAddresses. onSelect = { [ weak self] selectedAddress in
449- self ? . selectedOriginAddress = selectedAddress
450- }
473+ updateSelectedOriginAddress ( addresses: addresses)
451474 }
452475
453476 /// Loads destination address of the order from remote.
@@ -673,6 +696,70 @@ private extension WooShippingCreateLabelsViewModel {
673696 DDLogError ( " ⛔️ Unable to fetch shipments: \( error) " )
674697 }
675698 }
699+
700+ func configureOriginAddressResultsController( ) {
701+ let updateSelectedAddress = { [ weak self] in
702+ guard let self else { return }
703+ let addresses = originAddressResultsController. fetchedObjects
704+ updateSelectedOriginAddress ( addresses: addresses)
705+ }
706+ originAddressResultsController. onDidChangeContent = {
707+ updateSelectedAddress ( )
708+ }
709+
710+ originAddressResultsController. onDidResetContent = {
711+ updateSelectedAddress ( )
712+ }
713+
714+ do {
715+ try originAddressResultsController. performFetch ( )
716+ updateSelectedAddress ( )
717+ } catch {
718+ DDLogError ( " ⛔️ Unable to fetch origin addresses: \( error) " )
719+ }
720+ }
721+
722+ func updateSelectedOriginAddress( addresses: [ WooShippingOriginAddress ] ) {
723+ selectedOriginAddress = addresses. first ( where: \. defaultAddress)
724+ originAddresses = WooShippingOriginAddressListViewModel ( addresses: addresses,
725+ selectedAddressID: selectedOriginAddress? . id)
726+ originAddresses. onSelect = { [ weak self] selectedAddress in
727+ self ? . selectedOriginAddress = selectedAddress
728+ }
729+ }
730+
731+ /// Shipping Label Account Settings ResultsController monitoring
732+ ///
733+ func configureAccountSettingsResultsController( ) {
734+ let updateSettings = { [ weak self] in
735+ guard let self else { return }
736+ let settings = accountSettingsResultsController. fetchedObjects. first
737+ updateAccountSettings ( accountSettings: settings)
738+ }
739+ accountSettingsResultsController. onDidChangeContent = {
740+ updateSettings ( )
741+ }
742+
743+ accountSettingsResultsController. onDidResetContent = {
744+ updateSettings ( )
745+ }
746+
747+ do {
748+ try accountSettingsResultsController. performFetch ( )
749+ updateSettings ( )
750+ } catch {
751+ DDLogError ( " ⛔️ Unable to fetch woo shipping account settings: \( error) " )
752+ }
753+ }
754+
755+ func updateAccountSettings( accountSettings: ShippingLabelAccountSettings ? ) {
756+ markOrderComplete = accountSettings? . lastOrderCompleted ?? false
757+
758+ if let accountSettings {
759+ paymentMethodsViewModel = ShippingLabelPaymentMethodsViewModel ( accountSettings: accountSettings)
760+ }
761+ setupPaymentMethod ( accountSettings: accountSettings)
762+ }
676763}
677764
678765private extension WooShippingCreateLabelsViewModel {
0 commit comments