diff --git a/WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift b/WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift index 111f2c85cd8..40bb8587656 100644 --- a/WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift +++ b/WooCommerce/Classes/Analytics/WooAnalyticsEvent.swift @@ -223,6 +223,7 @@ extension WooAnalyticsEvent { static let serverTime = "time" static let errorDescription = "error_description" static let field = "field" + static let variationsCount = "variations_count" } enum BulkUpdateField: String { @@ -310,6 +311,26 @@ extension WooAnalyticsEvent { static func bulkUpdateFieldFailed(field: BulkUpdateField, error: Error) -> WooAnalyticsEvent { WooAnalyticsEvent(statName: .productVariationBulkUpdateFieldFail, properties: [Keys.field: field.rawValue], error: error) } + + static func productVariationGenerationRequested() -> WooAnalyticsEvent { + WooAnalyticsEvent(statName: .productVariationGenerationRequested, properties: [:]) + } + + static func productVariationGenerationConfirmed(count: Int64) -> WooAnalyticsEvent { + WooAnalyticsEvent(statName: .productVariationGenerationConfirmed, properties: [Keys.variationsCount: count]) + } + + static func productVariationGenerationLimitReached(count: Int64) -> WooAnalyticsEvent { + WooAnalyticsEvent(statName: .productVariationGenerationLimitReached, properties: [Keys.variationsCount: count]) + } + + static func productVariationGenerationSuccess() -> WooAnalyticsEvent { + WooAnalyticsEvent(statName: .productVariationGenerationSuccess, properties: [:]) + } + + static func productVariationGenerationFailure() -> WooAnalyticsEvent { + WooAnalyticsEvent(statName: .productVariationGenerationFailure, properties: [:]) + } } } diff --git a/WooCommerce/Classes/Analytics/WooAnalyticsStat.swift b/WooCommerce/Classes/Analytics/WooAnalyticsStat.swift index f533218e681..05f1ae7c74b 100644 --- a/WooCommerce/Classes/Analytics/WooAnalyticsStat.swift +++ b/WooCommerce/Classes/Analytics/WooAnalyticsStat.swift @@ -672,6 +672,12 @@ public enum WooAnalyticsStat: String { case editProductVariationAttributeOptionsRowTapped = "edit_product_variation_attribute_options_row_tapped" case editProductVariationAttributeOptionsDoneButtonTapped = "edit_product_variation_attribute_options_done_button_tapped" + case productVariationGenerationRequested = "product_variation_generation_requested" + case productVariationGenerationLimitReached = "product_variation_generation_limit_reached" + case productVariationGenerationConfirmed = "product_variation_generation_confirmed" + case productVariationGenerationSuccess = "product_variation_generation_success" + case productVariationGenerationFailure = "product_variation_generation_failure" + // MARK: What's New Component events // case featureAnnouncementShown = "feature_announcement_shown" diff --git a/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateAllVariationsUseCase.swift b/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateAllVariationsUseCase.swift index 9f08c50cb62..493dd9aad06 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateAllVariationsUseCase.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateAllVariationsUseCase.swift @@ -9,8 +9,13 @@ final class GenerateAllVariationsUseCase { /// private let stores: StoresManager - init(stores: StoresManager) { + /// Analytics tracker. + /// + private let analytics: Analytics + + init(stores: StoresManager, analytics: Analytics = ServiceLocator.analytics) { self.stores = stores + self.analytics = analytics } /// Generates all missing variations for a product. Up to 100 variations. @@ -22,7 +27,7 @@ final class GenerateAllVariationsUseCase { // Fetch Previous variations onStateChanged(.fetching) - fetchAllVariations(of: product) { result in + fetchAllVariations(of: product) { [analytics] result in switch result { case .success(let existingVariations): @@ -31,6 +36,7 @@ final class GenerateAllVariationsUseCase { // Guard for 100 variation limit guard variationsToGenerate.count <= 100 else { + analytics.track(event: .Variations.productVariationGenerationLimitReached(count: Int64(variationsToGenerate.count))) return onStateChanged(.error(.tooManyVariations(variationCount: variationsToGenerate.count))) } @@ -46,6 +52,8 @@ final class GenerateAllVariationsUseCase { return onStateChanged(.canceled) } + analytics.track(event: .Variations.productVariationGenerationConfirmed(count: Int64(variationsToGenerate.count))) + // Create variations remotely onStateChanged(.creating) self.createVariationsRemotely(for: product, variations: variationsToGenerate) { result in @@ -65,7 +73,8 @@ final class GenerateAllVariationsUseCase { case .failure(let error): onStateChanged(.error(.unableToFetchVariations)) - DDLogError("⛔️ Failed to create variations: \(error)") + DDLogError("⛔️ Failed to fetch variations: \(error)") + analytics.track(event: .Variations.productVariationGenerationFailure()) } } } @@ -88,13 +97,16 @@ private extension GenerateAllVariationsUseCase { onCompletion: @escaping (Result<[ProductVariation], GenerationError>) -> Void) { let action = ProductVariationAction.createProductVariations(siteID: product.siteID, productID: product.productID, - productVariations: variations, onCompletion: { result in + productVariations: variations, onCompletion: { [analytics] result in switch result { case .success(let variations): onCompletion(.success(variations)) + analytics.track(event: .Variations.productVariationGenerationSuccess()) + case .failure(let error): onCompletion(.failure(.unableToCreateVariations)) DDLogError("⛔️ Failed to create variations: \(error)") + analytics.track(event: .Variations.productVariationGenerationFailure()) } }) stores.dispatch(action) diff --git a/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateVariationsOptionPresenter.swift b/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateVariationsOptionPresenter.swift index 46b2081bf68..335dc0cb958 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateVariationsOptionPresenter.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Variations/GenerateVariationsOptionPresenter.swift @@ -16,8 +16,13 @@ final class GenerateVariationsOptionsPresenter { /// private let baseViewController: UIViewController - init(baseViewController: UIViewController) { + /// Analytics tracker. + /// + private let analytics: Analytics + + init(baseViewController: UIViewController, analytics: Analytics = ServiceLocator.analytics) { self.baseViewController = baseViewController + self.analytics = analytics } /// Displays a bottom sheet allowing the merchant to choose whether to generate one variation or to generate all variations. @@ -28,13 +33,14 @@ final class GenerateVariationsOptionsPresenter { } let viewProperties = BottomSheetListSelectorViewProperties(title: Localization.addVariationAction) - let command = GenerateVariationsSelectorCommand(selected: nil) { [baseViewController] option in + let command = GenerateVariationsSelectorCommand(selected: nil) { [analytics, baseViewController] option in baseViewController.dismiss(animated: true) switch option { case .single: onCompletion(.single) case .all: onCompletion(.all) + analytics.track(event: .Variations.productVariationGenerationRequested()) } } let bottomSheetPresenter = BottomSheetListSelectorPresenter(viewProperties: viewProperties, command: command)