diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubView.swift index 6bd2b581793..764e73af59e 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubView.swift @@ -5,8 +5,8 @@ import SwiftUI /// Hosting Controller for the `AnalyticsHubView` view. /// final class AnalyticsHubHostingViewController: UIHostingController { - init(timeRange: StatsTimeRangeV4) { - let viewModel = AnalyticsHubViewModel() + init(siteID: Int64, timeRange: StatsTimeRangeV4) { + let viewModel = AnalyticsHubViewModel(siteID: siteID) super.init(rootView: AnalyticsHubView(viewModel: viewModel)) } @@ -81,7 +81,7 @@ private extension AnalyticsHubView { struct AnalyticsHubPreview: PreviewProvider { static var previews: some View { NavigationView { - AnalyticsHubView(viewModel: AnalyticsHubViewModel()) + AnalyticsHubView(viewModel: AnalyticsHubViewModel(siteID: 123)) } } } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubViewModel.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubViewModel.swift index 98386dfbc63..6eef390b127 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubViewModel.swift @@ -5,6 +5,23 @@ import Yosemite /// final class AnalyticsHubViewModel: ObservableObject { + private let siteID: Int64 + private let stores: StoresManager + + init(siteID: Int64, + stores: StoresManager = ServiceLocator.stores) { + self.siteID = siteID + self.stores = stores + + Task.init { + do { + try await retrieveOrderStats() + } catch { + DDLogWarn("⚠️ Error fetching analytics data: \(error)") + } + } + } + /// Revenue Card ViewModel /// @Published var revenueCard = AnalyticsReportCardViewModel(title: "REVENUE", @@ -39,3 +56,44 @@ final class AnalyticsHubViewModel: ObservableObject { /// @Published private var previousOrderStats: OrderStatsV4? = nil } + +private extension AnalyticsHubViewModel { + + @MainActor + func retrieveOrderStats() async throws { + // TODO: get dates from the selected period + let currentMonthDate = Date() + let previousMonthDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())! + + async let currentPeriodRequest = retrieveStats(earliestDateToInclude: currentMonthDate.startOfMonth(timezone: .current), + latestDateToInclude: currentMonthDate.endOfMonth(timezone: .current), + forceRefresh: true) + async let previousPeriodRequest = retrieveStats(earliestDateToInclude: previousMonthDate.startOfMonth(timezone: .current), + latestDateToInclude: previousMonthDate.endOfMonth(timezone: .current), + forceRefresh: true) + let (currentPeriodStats, previousPeriodStats) = try await (currentPeriodRequest, previousPeriodRequest) + self.currentOrderStats = currentPeriodStats + self.previousOrderStats = previousPeriodStats + } + + @MainActor + func retrieveStats(earliestDateToInclude: Date, + latestDateToInclude: Date, + forceRefresh: Bool) async throws -> OrderStatsV4 { + try await withCheckedThrowingContinuation { continuation in + // TODO: get unit and quantity from the selected period + let unit: StatsGranularityV4 = .daily + let quantity = 31 + + let action = StatsActionV4.retrieveCustomStats(siteID: siteID, + unit: unit, + earliestDateToInclude: earliestDateToInclude, + latestDateToInclude: latestDateToInclude, + quantity: quantity, + forceRefresh: forceRefresh) { result in + continuation.resume(with: result) + } + stores.dispatch(action) + } + } +} diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Stats v4/StoreStatsAndTopPerformersPeriodViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Stats v4/StoreStatsAndTopPerformersPeriodViewController.swift index 2872284acda..9772a546e78 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Stats v4/StoreStatsAndTopPerformersPeriodViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Stats v4/StoreStatsAndTopPerformersPeriodViewController.swift @@ -357,7 +357,7 @@ private extension StoreStatsAndTopPerformersPeriodViewController { } @objc func seeMoreButtonTapped() { - let analyticsHubVC = AnalyticsHubHostingViewController(timeRange: timeRange) + let analyticsHubVC = AnalyticsHubHostingViewController(siteID: siteID, timeRange: timeRange) show(analyticsHubVC, sender: self) } } diff --git a/Yosemite/Yosemite/Actions/StatsActionV4.swift b/Yosemite/Yosemite/Actions/StatsActionV4.swift index cf6ddc18508..670d9eef1c3 100644 --- a/Yosemite/Yosemite/Actions/StatsActionV4.swift +++ b/Yosemite/Yosemite/Actions/StatsActionV4.swift @@ -19,6 +19,16 @@ public enum StatsActionV4: Action { forceRefresh: Bool, onCompletion: (Result) -> Void) + /// Retrieves `OrderStats` for the provided siteID, and time range, without saving them to the Storage layer. + /// + case retrieveCustomStats(siteID: Int64, + unit: StatsGranularityV4, + earliestDateToInclude: Date, + latestDateToInclude: Date, + quantity: Int, + forceRefresh: Bool, + onCompletion: (Result) -> Void) + /// Synchronizes `SiteVisitStats` for the provided siteID, time range, and date. /// case retrieveSiteVisitStats(siteID: Int64, diff --git a/Yosemite/Yosemite/Stores/StatsStoreV4.swift b/Yosemite/Yosemite/Stores/StatsStoreV4.swift index 8c6144b42c8..1a82e2a879a 100644 --- a/Yosemite/Yosemite/Stores/StatsStoreV4.swift +++ b/Yosemite/Yosemite/Stores/StatsStoreV4.swift @@ -50,6 +50,20 @@ public final class StatsStoreV4: Store { quantity: quantity, forceRefresh: forceRefresh, onCompletion: onCompletion) + case .retrieveCustomStats(let siteID, + let unit, + let earliestDateToInclude, + let latestDateToInclude, + let quantity, + let forceRefresh, + let onCompletion): + retrieveCustomStats(siteID: siteID, + unit: unit, + earliestDateToInclude: earliestDateToInclude, + latestDateToInclude: latestDateToInclude, + quantity: quantity, + forceRefresh: forceRefresh, + onCompletion: onCompletion) case .retrieveSiteVisitStats(let siteID, let siteTimezone, let timeRange, @@ -120,6 +134,24 @@ private extension StatsStoreV4 { } } + /// Retrieves the order stats for the provided siteID, and time range, without saving them to the Storage layer. + /// + func retrieveCustomStats(siteID: Int64, + unit: StatsGranularityV4, + earliestDateToInclude: Date, + latestDateToInclude: Date, + quantity: Int, + forceRefresh: Bool, + onCompletion: @escaping (Result) -> Void) { + orderStatsRemote.loadOrderStats(for: siteID, + unit: unit, + earliestDateToInclude: earliestDateToInclude, + latestDateToInclude: latestDateToInclude, + quantity: quantity, + forceRefresh: forceRefresh, + completion: onCompletion) + } + /// Retrieves the site visit stats associated with the provided Site ID (if any!). /// func retrieveSiteVisitStats(siteID: Int64,