Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Modules/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ let package = Package(
name: "Yosemite",
targets: ["Yosemite"]
),
.library(
name: "PointOfSale",
targets: ["PointOfSale"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire", from: "5.2.0"),
Expand Down Expand Up @@ -224,6 +228,15 @@ let package = Package(
.product(name: "WordPressEditor", package: "AztecEditor-iOS"),
]
),
.target(
name: "PointOfSale",
dependencies: [
"Experiments",
"WooFoundation",
"Yosemite"
// Additional dependencies will be added as needed when moving files
]
),
.testTarget(
name: "ExperimentsTests",
dependencies: [
Expand Down Expand Up @@ -289,6 +302,12 @@ let package = Package(
.process("Resources"),
.process("../NetworkingTests/Responses")
]
),
.testTarget(
name: "PointOfSaleTests",
dependencies: [
"PointOfSale"
]
)
]
)
Expand Down Expand Up @@ -368,6 +387,7 @@ enum XcodeSupport {
"WordPressUI",
"WPMediaPicker",
"Yosemite",
"PointOfSale",
.product(name: "Alamofire", package: "Alamofire"),
.product(name: "Algorithms", package: "swift-algorithms"),
.product(name: "AutomatticAbout", package: "AutomatticAbout-swift"),
Expand Down Expand Up @@ -405,6 +425,7 @@ enum XcodeSupport {
"Fakes",
"TestKit",
"WordPressShared",
"PointOfSale", // TODO: Remove after POS modularization
.product(name: "Aztec", package: "AztecEditor-iOS"),
.product(name: "BuildkiteTestCollector", package: "test-collector-swift"),
.product(name: "ViewControllerPresentationSpy", package: "ViewControllerPresentationSpy"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import enum Yosemite.POSItemType
import enum Yosemite.POSItem
import struct Yosemite.POSSimpleProduct
import struct Yosemite.POSVariation
import enum WooFoundation.CountryCode
import enum Yosemite.PaymentMethod
import WooFoundation

extension WooAnalyticsEvent {
/// POS-specific analytics events
public extension WooAnalyticsEvent {
enum PointOfSale {
/// Event property Key.
private enum Key {
Expand Down Expand Up @@ -39,16 +40,16 @@ extension WooAnalyticsEvent {
static let scanValue = "scan_value"
}

static func paymentsOnboardingShown() -> WooAnalyticsEvent {
public static func paymentsOnboardingShown() -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSalePaymentsOnboardingShown, properties: [:])
}

static func paymentsOnboardingDismissed(onboardingState: CardPresentPaymentOnboardingState) -> WooAnalyticsEvent {
public static func paymentsOnboardingDismissed(onboardingState: CardPresentPaymentOnboardingState) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSalePaymentsOnboardingDismissed,
properties: [Key.paymentsOnboardingState: onboardingState.reasonForAnalytics])
}

static func addItemToCart(
public static func addItemToCart(
sourceView: WooAnalyticsEvent.PointOfSale.SourceView? = nil,
sourceViewType: WooAnalyticsEvent.PointOfSale.SourceViewType,
itemType: WooAnalyticsEvent.PointOfSale.ItemType,
Expand All @@ -75,7 +76,7 @@ extension WooAnalyticsEvent {
)
}

static func itemRemovedFromCart(
public static func itemRemovedFromCart(
sourceView: WooAnalyticsEvent.PointOfSale.SourceView,
itemType: WooAnalyticsEvent.PointOfSale.ItemType,
productType: WooAnalyticsEvent.PointOfSale.CartItemProductType? = nil
Expand All @@ -95,7 +96,7 @@ extension WooAnalyticsEvent {
)
}

static func checkoutTapped(purchasableItemsInCart: Int, couponsInCart: Int) -> WooAnalyticsEvent {
public static func checkoutTapped(purchasableItemsInCart: Int, couponsInCart: Int) -> WooAnalyticsEvent {
WooAnalyticsEvent(
statName: .pointOfSaleCheckoutTapped,
properties: [
Expand All @@ -108,11 +109,11 @@ extension WooAnalyticsEvent {
/// Tracks the time elapsed preparing reader for payment, after successful order creation
/// - Parameter waitingTime: Elapsed time from Order creation to card ready for payment
///
static func cardReaderReadyForCardPayment(waitingTime: Double) -> WooAnalyticsEvent {
public static func cardReaderReadyForCardPayment(waitingTime: Double) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleReaderReadyForCardPayment, properties: [Key.waitingTime: "\(waitingTime)"])
}

static func cardPresentCollectPaymentSuccess(forGatewayID: String?,
public static func cardPresentCollectPaymentSuccess(forGatewayID: String?,
countryCode: CountryCode,
paymentMethod: PaymentMethod,
cardReaderModel: String?,
Expand All @@ -134,34 +135,34 @@ extension WooAnalyticsEvent {
])
}

static func cashCollectPaymentSuccess(millisecondsSinceCustomerIteractionStarted: Double) -> WooAnalyticsEvent {
public static func cashCollectPaymentSuccess(millisecondsSinceCustomerIteractionStarted: Double) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleCashCollectPaymentSuccess, properties: [
Key.millisecondsSinceCustomerInteractionStarted: "\(millisecondsSinceCustomerIteractionStarted)",
])
}

static func searchButtonTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
public static func searchButtonTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
WooAnalyticsEvent(
statName: .pointOfSaleSearchButtonTapped,
properties: [Key.sourceView: SourceView(itemListType: itemListType).rawValue]
)
}

static func itemsHeaderTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
public static func itemsHeaderTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
WooAnalyticsEvent(
statName: .pointOfSaleItemsHeaderTapped,
properties: [Key.type: SourceView(itemListType: itemListType).rawValue]
)
}

static func preSearchRecentTermTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
public static func preSearchRecentTermTapped(itemListType: ItemListType) -> WooAnalyticsEvent {
WooAnalyticsEvent(
statName: .pointOfSalePreSearchRecentTermTapped,
properties: [Key.sourceView: SourceView(itemListType: itemListType).rawValue]
)
}

static func itemsPullToRefresh(
public static func itemsPullToRefresh(
sourceView: WooAnalyticsEvent.PointOfSale.SourceView,
sourceViewType: WooAnalyticsEvent.PointOfSale.SourceViewType
) -> WooAnalyticsEvent {
Expand All @@ -171,7 +172,7 @@ extension WooAnalyticsEvent {
)
}

static func itemsNextPageLoaded(
public static func itemsNextPageLoaded(
sourceView: WooAnalyticsEvent.PointOfSale.SourceView,
sourceViewType: WooAnalyticsEvent.PointOfSale.SourceViewType
) -> WooAnalyticsEvent {
Expand All @@ -181,7 +182,7 @@ extension WooAnalyticsEvent {
)
}

static func pointOfSaleSearchRemoteResultsFetched(itemType: POSItemType,
public static func pointOfSaleSearchRemoteResultsFetched(itemType: POSItemType,
resultsCount: Int,
millisecondsSinceRequestSent: Int) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleSearchRemoteResultsFetched,
Expand All @@ -192,7 +193,7 @@ extension WooAnalyticsEvent {
])
}

static func pointOfSaleItemsFetched(itemType: POSItemType,
public static func pointOfSaleItemsFetched(itemType: POSItemType,
totalItems: Int) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleItemsFetched,
properties: [
Expand All @@ -201,15 +202,15 @@ extension WooAnalyticsEvent {
])
}

static func barcodeScanningSuccess(scanDurationMs: Int, barcodeLength: Int) -> WooAnalyticsEvent {
public static func barcodeScanningSuccess(scanDurationMs: Int, barcodeLength: Int) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScanningSuccess,
properties: [
Key.scanDurationMs: "\(scanDurationMs)",
Key.barcodeLength: "\(barcodeLength)"
])
}

static func barcodeScanningFailed(scanDurationMs: Int, barcodeLength: Int, failReason: String) -> WooAnalyticsEvent {
public static func barcodeScanningFailed(scanDurationMs: Int, barcodeLength: Int, failReason: String) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScanningFailed,
properties: [
Key.scanDurationMs: "\(scanDurationMs)",
Expand All @@ -218,51 +219,51 @@ extension WooAnalyticsEvent {
])
}

static func barcodeScannerSetupScannerSelected(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
public static func barcodeScannerSetupScannerSelected(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupScannerSelected,
properties: [Key.scanner: scanner.analyticsName])
}

static func barcodeScannerSetupNextTapped(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
public static func barcodeScannerSetupNextTapped(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupNextTapped,
properties: [
Key.scanner: scanner.analyticsName,
Key.step: step
])
}

static func barcodeScannerSetupBackTapped(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
public static func barcodeScannerSetupBackTapped(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupBackTapped,
properties: [
Key.scanner: scanner.analyticsName,
Key.step: step
])
}

static func barcodeScannerSetupOpenSystemSettingsTapped(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
public static func barcodeScannerSetupOpenSystemSettingsTapped(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupOpenSystemSettingsTapped,
properties: [Key.scanner: scanner.analyticsName])
}

static func barcodeScannerSetupTestScanSuccess(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
public static func barcodeScannerSetupTestScanSuccess(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupTestScanSuccess,
properties: [Key.scanner: scanner.analyticsName])
}

static func barcodeScannerSetupTestScanFailed(scanner: PointOfSaleBarcodeScannerType, scanValue: String) -> WooAnalyticsEvent {
public static func barcodeScannerSetupTestScanFailed(scanner: PointOfSaleBarcodeScannerType, scanValue: String) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupTestScanFailed,
properties: [
Key.scanner: scanner.analyticsName,
Key.scanValue: scanValue
])
}

static func barcodeScannerSetupTestScanTimedOut(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
public static func barcodeScannerSetupTestScanTimedOut(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupTestScanTimedOut,
properties: [Key.scanner: scanner.analyticsName])
}

static func barcodeScannerSetupDismissed(scanner: PointOfSaleBarcodeScannerType? = nil, step: String? = nil) -> WooAnalyticsEvent {
public static func barcodeScannerSetupDismissed(scanner: PointOfSaleBarcodeScannerType? = nil, step: String? = nil) -> WooAnalyticsEvent {
var properties: [String: String] = [:]
if let scanner {
properties[Key.scanner] = scanner.analyticsName
Expand All @@ -274,12 +275,12 @@ extension WooAnalyticsEvent {
properties: properties)
}

static func barcodeScannerSetupRetryTapped(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
public static func barcodeScannerSetupRetryTapped(scanner: PointOfSaleBarcodeScannerType) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupRetryTapped,
properties: [Key.scanner: scanner.analyticsName])
}

static func barcodeScannerSetupScannerConnected(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
public static func barcodeScannerSetupScannerConnected(scanner: PointOfSaleBarcodeScannerType, step: String) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleBarcodeScannerSetupScannerConnected,
properties: [Key.scanner: scanner.analyticsName])
}
Expand All @@ -296,7 +297,7 @@ private extension WooAnalyticsEvent.PointOfSale {
}
}

extension WooAnalyticsEvent.PointOfSale {
public extension WooAnalyticsEvent.PointOfSale {
/// Source of the event where the event is triggered
/// Views: Product, Variation, and Coupon Lists. Cart view and Checkout error.
///
Expand All @@ -307,7 +308,7 @@ extension WooAnalyticsEvent.PointOfSale {
case cart
case error

init(itemType: POSItemType) {
public init(itemType: POSItemType) {
switch itemType {
case .product:
self = .product
Expand All @@ -318,7 +319,7 @@ extension WooAnalyticsEvent.PointOfSale {
}
}

init(itemListType: ItemListType) {
public init(itemListType: ItemListType) {
switch itemListType {
case .products:
self = .product
Expand All @@ -337,7 +338,7 @@ extension WooAnalyticsEvent.PointOfSale {
case preSearch = "pre_search"
case scanner

init(isSearching: Bool, searchTerm: String = "") {
public init(isSearching: Bool, searchTerm: String = "") {
switch (isSearching, searchTerm.isEmpty) {
case (false, _):
self = .list
Expand All @@ -357,7 +358,7 @@ extension WooAnalyticsEvent.PointOfSale {
case loading
case error

init(cartItem: Cart.PurchasableItem) {
public init(cartItem: Cart.PurchasableItem) {
switch cartItem.state {
case .loaded:
self = .product
Expand All @@ -375,7 +376,7 @@ extension WooAnalyticsEvent.PointOfSale {
case simple
case variation

init?(cartItem: Cart.PurchasableItem) {
public init?(cartItem: Cart.PurchasableItem) {
guard case let .loaded(item) = cartItem.state else {
return nil
}
Expand All @@ -390,3 +391,16 @@ extension WooAnalyticsEvent.PointOfSale {
}
}
}

public extension PaymentMethod {
var analyticsValue: String {
switch self {
case .card, .cardPresent:
return "card"
case .interacPresent:
return "card_interac"
case .unknown:
return "unknown"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
extension WooAnalyticsEvent {
import WooFoundation

/// POS Ineligible UI specific analytics events
public extension WooAnalyticsEvent {
enum PointOfSaleIneligibleUI {
/// Event property key.
private enum Key {
static let reason = "reason"
}

static func ineligibleUIShown(reason: POSIneligibleReason) -> WooAnalyticsEvent {
public static func ineligibleUIShown(reason: POSIneligibleReason) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleIneligibleUIShown, properties: [Key.reason: reason.analyticsValue])
}

static func ineligibleUIRetryTapped(reason: POSIneligibleReason) -> WooAnalyticsEvent {
public static func ineligibleUIRetryTapped(reason: POSIneligibleReason) -> WooAnalyticsEvent {
WooAnalyticsEvent(statName: .pointOfSaleIneligibleUIRetryTapped, properties: [Key.reason: reason.analyticsValue])
}
}
Expand Down
Loading