@@ -36,14 +36,13 @@ class OrdersViewController: UIViewController {
3636 return ResultsController < StorageOrder > ( storageManager: storageManager, sectionNameKeyPath: " normalizedAgeAsString " , sortedBy: [ descriptor] )
3737 } ( )
3838
39- /// ResultsController: Surrounds us. Binds the galaxy together. And also, keeps the UITableView <> (Stored) OrderStatuses in sync.
39+ /// ResultsController: Handles all things order status
4040 ///
4141 private lazy var statusResultsController : ResultsController < StorageOrderStatus > = {
4242 let storageManager = AppDelegate . shared. storageManager
43- let predicate = NSPredicate ( format: " siteID == %lld " , StoresManager . shared. sessionManager. defaultStoreID ?? Int . min)
4443 let descriptor = NSSortDescriptor ( key: " slug " , ascending: true )
4544
46- return ResultsController < StorageOrderStatus > ( storageManager: storageManager, matching : predicate , sortedBy: [ descriptor] )
45+ return ResultsController < StorageOrderStatus > ( storageManager: storageManager, sortedBy: [ descriptor] )
4746 } ( )
4847
4948 /// SyncCoordinator: Keeps tracks of which pages have been refreshed, and encapsulates the "What should we sync now" logic.
@@ -66,6 +65,12 @@ class OrdersViewController: UIViewController {
6665 }
6766 }
6867
68+ /// The current list of order statuses for the default site
69+ ///
70+ private var currentSiteStatuses : [ OrderStatus ] {
71+ return statusResultsController. fetchedObjects
72+ }
73+
6974 /// Keep track of the (Autosizing Cell's) Height. This helps us prevent UI flickers, due to sizing recalculations.
7075 ///
7176 private var estimatedRowHeights = [ IndexPath: CGFloat] ( )
@@ -118,19 +123,22 @@ class OrdersViewController: UIViewController {
118123
119124 refreshTitle ( )
120125 refreshResultsPredicate ( )
126+ refreshStatusPredicate ( )
121127 registerTableViewCells ( )
122128
123129 configureSyncingCoordinator ( )
124130 configureNavigation ( )
125131 configureTableView ( )
126- configureResultsController ( )
132+ configureResultsControllers ( )
127133
128134 startListeningToNotifications ( )
129135 }
130136
131137 override func viewWillAppear( _ animated: Bool ) {
132138 super. viewWillAppear ( animated)
133139
140+ syncOrderStatus ( )
141+ resetStatusFilterIfNeeded ( )
134142 syncingCoordinator. synchronizeFirstPage ( )
135143 if AppRatingManager . shared. shouldPromptForAppReview ( ) {
136144 displayRatingPrompt ( )
@@ -164,7 +172,7 @@ private extension OrdersViewController {
164172 navigationItem. title = title
165173 }
166174
167- /// Setup: Filtering
175+ /// Setup: Order filtering
168176 ///
169177 func refreshResultsPredicate( ) {
170178 resultsController. predicate = {
@@ -184,6 +192,12 @@ private extension OrdersViewController {
184192 tableView. reloadData ( )
185193 }
186194
195+ /// Setup: Order status predicate
196+ ///
197+ func refreshStatusPredicate( ) {
198+ statusResultsController. predicate = NSPredicate ( format: " siteID == %lld " , StoresManager . shared. sessionManager. defaultStoreID ?? Int . min)
199+ }
200+
187201 /// Setup: Navigation Item
188202 ///
189203 func configureNavigation( ) {
@@ -225,9 +239,18 @@ private extension OrdersViewController {
225239
226240 /// Setup: Results Controller
227241 ///
228- func configureResultsController( ) {
242+ func configureResultsControllers( ) {
243+ // Orders FRC
229244 resultsController. startForwardingEvents ( to: tableView)
230245 try ? resultsController. performFetch ( )
246+
247+ // Order status FRC
248+ statusResultsController. onDidChangeContent = { [ weak self] in
249+ self ? . statusFilter = nil
250+ }
251+ statusResultsController. onDidResetContent = { [ weak self] in
252+ self ? . statusFilter = nil
253+ }
231254 try ? statusResultsController. performFetch ( )
232255 }
233256
@@ -285,6 +308,8 @@ extension OrdersViewController {
285308 /// Runs whenever the default Account is updated.
286309 ///
287310 @objc func defaultAccountWasUpdated( ) {
311+ statusFilter = nil
312+ refreshStatusPredicate ( )
288313 syncingCoordinator. resetInternalState ( )
289314 }
290315}
@@ -316,7 +341,7 @@ extension OrdersViewController {
316341 self ? . statusFilter = nil
317342 }
318343
319- for orderStatus in statusResultsController . fetchedObjects {
344+ for orderStatus in currentSiteStatuses {
320345 actionSheet. addDefaultActionWithTitle ( orderStatus. name) { [ weak self] _ in
321346 self ? . statusFilter = orderStatus
322347 }
@@ -331,6 +356,7 @@ extension OrdersViewController {
331356
332357 @IBAction func pullToRefresh( sender: UIRefreshControl ) {
333358 WooAnalytics . shared. track ( . ordersListPulledToRefresh)
359+ syncOrderStatus ( )
334360 syncingCoordinator. synchronizeFirstPage {
335361 sender. endRefreshing ( )
336362 }
@@ -373,6 +399,24 @@ private extension OrdersViewController {
373399 let action = OrderAction . resetStoredOrders ( onCompletion: onCompletion)
374400 StoresManager . shared. dispatch ( action)
375401 }
402+
403+ /// Reset the current status filter if needed (e.g. when changing stores and the currently
404+ /// selected filter does not exist in the new store)
405+ ///
406+ func resetStatusFilterIfNeeded( ) {
407+ guard let statusFilter = statusFilter else {
408+ // "All" is the current filter so bail
409+ return
410+ }
411+ guard currentSiteStatuses. isEmpty == false else {
412+ self . statusFilter = nil
413+ return
414+ }
415+
416+ if currentSiteStatuses. contains ( statusFilter) == false {
417+ self . statusFilter = nil
418+ }
419+ }
376420}
377421
378422
@@ -411,6 +455,26 @@ extension OrdersViewController: SyncingCoordinatorDelegate {
411455
412456 StoresManager . shared. dispatch ( action)
413457 }
458+
459+ func syncOrderStatus( onCompletion: ( ( Error ? ) -> Void ) ? = nil ) {
460+ guard let siteID = StoresManager . shared. sessionManager. defaultStoreID else {
461+ onCompletion ? ( nil )
462+ return
463+ }
464+
465+ // First, let's verify our FRC predicate is up to date
466+ refreshStatusPredicate ( )
467+
468+ let action = OrderStatusAction . retrieveOrderStatuses ( siteID: siteID) { [ weak self] ( _, error) in
469+ if let error = error {
470+ DDLogError ( " ⛔️ Order List — Error synchronizing order statuses: \( error) " )
471+ }
472+ self ? . resetStatusFilterIfNeeded ( )
473+ onCompletion ? ( error)
474+ }
475+
476+ StoresManager . shared. dispatch ( action)
477+ }
414478}
415479
416480
@@ -472,6 +536,7 @@ private extension OrdersViewController {
472536 let message = NSLocalizedString ( " Unable to refresh list " , comment: " Refresh Action Failed " )
473537 let actionTitle = NSLocalizedString ( " Retry " , comment: " Retry Action " )
474538 let notice = Notice ( title: message, feedbackType: . error, actionTitle: actionTitle) { [ weak self] in
539+ self ? . syncOrderStatus ( )
475540 self ? . sync ( pageNumber: pageNumber, pageSize: pageSize)
476541 }
477542
@@ -557,8 +622,7 @@ private extension OrdersViewController {
557622 }
558623
559624 func lookUpOrderStatus( for order: Order ) -> OrderStatus ? {
560- let listAll = statusResultsController. fetchedObjects
561- for orderStatus in listAll where orderStatus. slug == order. statusKey {
625+ for orderStatus in currentSiteStatuses where orderStatus. slug == order. statusKey {
562626 return orderStatus
563627 }
564628
0 commit comments