From 97a4015a551425007f02030945083e76cf4bcb5b Mon Sep 17 00:00:00 2001 From: ellingtonkirby Date: Mon, 18 Sep 2017 16:33:44 -0400 Subject: [PATCH] Feature - MPArticle Kotlin Integration --- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle | 2 +- simcoe-mparticle/.gitignore | 1 + simcoe-mparticle/build.gradle | 34 +++ simcoe-mparticle/proguard-rules.pro | 25 +++ simcoe-mparticle/src/main/AndroidManifest.xml | 15 ++ .../mparticle/MPCommerceEventSimcoe.kt | 61 ++++++ .../mparticle/MPEventSimcoe.kt | 64 ++++++ .../MPTransactionAttributesSimcoe.kt | 34 +++ .../mparticle/MpProduct.kt | 47 ++++ .../mparticle/MparticleProvider.kt | 200 ++++++++++++++++++ .../src/main/res/values/strings.xml | 3 + .../simcoe/SimcoeProduct.kt | 18 ++ .../simcoe/SimcoeProductConvertible.kt | 5 + .../simcoe/trackers/CartLogTracking.kt | 25 +++ .../simcoe/trackers/CheckoutTracking.kt | 17 ++ .../simcoe/trackers/LifetimeValueTracking.kt | 4 +- 18 files changed, 556 insertions(+), 7 deletions(-) create mode 100644 simcoe-mparticle/.gitignore create mode 100644 simcoe-mparticle/build.gradle create mode 100644 simcoe-mparticle/proguard-rules.pro create mode 100644 simcoe-mparticle/src/main/AndroidManifest.xml create mode 100644 simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPCommerceEventSimcoe.kt create mode 100644 simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPEventSimcoe.kt create mode 100644 simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPTransactionAttributesSimcoe.kt create mode 100644 simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MpProduct.kt create mode 100644 simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MparticleProvider.kt create mode 100644 simcoe-mparticle/src/main/res/values/strings.xml create mode 100644 simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProduct.kt create mode 100644 simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProductConvertible.kt create mode 100644 simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CartLogTracking.kt create mode 100644 simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CheckoutTracking.kt diff --git a/build.gradle b/build.gradle index 42f97c8..7d625bc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.1.2-2' + ext.kotlin_version = '1.1.4-3' repositories { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.4.0-alpha7' + classpath 'com.android.tools.build:gradle:3.0.0-alpha9' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1f3ff61..8964afb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue May 02 16:55:48 EDT 2017 +#Mon Sep 18 12:12:01 EDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip diff --git a/settings.gradle b/settings.gradle index cef831b..6eb4aad 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ -include ':simcoe' +include ':simcoe', ':simcoe-mparticle' include ':simcoe-mixpanel' include ':sample' diff --git a/simcoe-mparticle/.gitignore b/simcoe-mparticle/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/simcoe-mparticle/.gitignore @@ -0,0 +1 @@ +/build diff --git a/simcoe-mparticle/build.gradle b/simcoe-mparticle/build.gradle new file mode 100644 index 0000000..ea1e9c2 --- /dev/null +++ b/simcoe-mparticle/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + + versionCode Integer.parseInt(project.VERSION_CODE) + versionName project.VERSION_NAME + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + api 'com.mparticle:android-core:4.16.2' + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + compile project(path: ':simcoe') +} +repositories { + mavenCentral() +} diff --git a/simcoe-mparticle/proguard-rules.pro b/simcoe-mparticle/proguard-rules.pro new file mode 100644 index 0000000..8ab425a --- /dev/null +++ b/simcoe-mparticle/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/ellingtonkirby/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/simcoe-mparticle/src/main/AndroidManifest.xml b/simcoe-mparticle/src/main/AndroidManifest.xml new file mode 100644 index 0000000..955946d --- /dev/null +++ b/simcoe-mparticle/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPCommerceEventSimcoe.kt b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPCommerceEventSimcoe.kt new file mode 100644 index 0000000..998993e --- /dev/null +++ b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPCommerceEventSimcoe.kt @@ -0,0 +1,61 @@ +package com.prolificinteractive.mparticle + +import com.mparticle.commerce.CommerceEvent +import com.mparticle.commerce.Product +import com.prolificinteractive.simcoe.Properties + + +fun getCommerceEvent(action: String, products: Array, eventProperties: Properties?): CommerceEvent { + val product = products[0] + val productList: MutableList = products.copyOfRange(1, products.size).toMutableList() + val event = CommerceEvent.Builder(action, product) + event.products(productList) + + val checkoutOptions = eventProperties?.get(MPCommerceEventKeys.CHECKOUT_OPTIONS.key).toString() + val checkoutStep = eventProperties?.get(MPCommerceEventKeys.CHECKOUT_STEP.key) as Int + val currency = eventProperties.get(MPCommerceEventKeys.CURRENCY.key).toString() + val nonInteractive = eventProperties.get(MPCommerceEventKeys.NON_INTERACTIVE.key) as Boolean + //TODO what to do with promotionContainer? + val productListName = eventProperties.get(MPCommerceEventKeys.PRODUCT_LIST_NAME.key).toString() + val productListSource = eventProperties.get(MPCommerceEventKeys.PRODUCT_LIST_SOURCE.key).toString() + val screenName = eventProperties.get(MPCommerceEventKeys.SCREEN_NAME.key).toString() + val transaction = getTransactionAttributes(eventProperties) + + return event + .checkoutOptions(checkoutOptions) + .checkoutStep(checkoutStep) + .currency(currency) + .nonInteraction(nonInteractive) + .productListName(productListName) + .productListSource(productListSource) + .screen(screenName) + .transactionAttributes(transaction) + .build() +} + +// +// MPCommerceEventKeys.swift +// Simcoe +// +/// The MPCommerceEvent keys available to use with eventProperties. +/// +/// - checkoutOptions: The checkout options. +/// - checkoutStep: The checkout step. +/// - currency: The currency. +/// - nonInteractive: The non interactive flag. +/// - promotionContainer: The promotion container. +/// - productListName: The product list name. +/// - productListSource: The product list source. +/// - screenName: The screen name. +/// - transactionAttributes: The transactions attributes. +enum class MPCommerceEventKeys(val key: String) { + CHECKOUT_OPTIONS("checkoutOptions"), + CHECKOUT_STEP("checkoutStep"), + CURRENCY("currency"), + NON_INTERACTIVE("nonInteractive"), + PROMOTION_CONTAINER("promotionContainer"), + PRODUCT_LIST_NAME("productListName"), + PRODUCT_LIST_SOURCE("productListSource"), + SCREEN_NAME("screenName"), + TRANSACTION_ATTRIBUTES("transactionAttributes"); +} \ No newline at end of file diff --git a/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPEventSimcoe.kt b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPEventSimcoe.kt new file mode 100644 index 0000000..c91aff7 --- /dev/null +++ b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPEventSimcoe.kt @@ -0,0 +1,64 @@ +package com.prolificinteractive.mparticle + +import com.mparticle.MPEvent +import com.mparticle.MParticle +import com.mparticle.MParticle.EventType +import com.prolificinteractive.simcoe.Properties +import java.util.Date + +fun eventData(type: MParticle.EventType, + name: String, + category: String? = null, + duration: Float? = null, + startTime: Date? = null, + endTime: Date? = null, + customFlags: Map>? = null, + info: Properties? = null): Properties { + var properties: Properties = mutableMapOf(MPEventKeys.EVENT_TYPE.key to type, MPEventKeys.NAME.key to name) + + if (category != null) { + properties.plus(MPEventKeys.CATEGORY.key to category) + } + + if (duration != null) { + properties.plus(MPEventKeys.DURATION.key to duration) + } + + if (customFlags != null) { + properties.plus(MPEventKeys.CUSTOM_FLAGS.key to customFlags) + } + + if (info != null) { + for ((key, value) in info) { + properties.plus(key to value) + } + } + + return properties +} + +@Suppress("UNCHECKED_CAST") +fun toEvent(data: Properties): MPEvent { + if (data[MPEventKeys.EVENT_TYPE.key] == null || data[MPEventKeys.NAME.key] == null) { + throw MPEventGenerationError("Failed to initialize the MPEvent. Check that you have a valid event name and type and try again. Names must not be an empty string.") + } + val eventType: MParticle.EventType = data[MPEventKeys.EVENT_TYPE.key] as EventType + val eventName: String = data[MPEventKeys.NAME.key] as String + var event: MPEvent = MPEvent.Builder(eventName, eventType) + .category(data[MPEventKeys.CATEGORY.key] as String) + .duration(data[MPEventKeys.DURATION.key] as Double) + .build() + event.customFlags.putAll(data[MPEventKeys.CUSTOM_FLAGS.key] as Map>) + + return event +} + +class MPEventGenerationError(message: String?) : RuntimeException(message) {} + +enum class MPEventKeys(val key : String) { + EVENT_TYPE("SimcoeInternalMPEventType"), + CATEGORY("SimcoeInternalMPCategory"), + DURATION("SimcoeInternalMPDuration"), + NAME("SimcoeInternalName"), + CUSTOM_FLAGS("SimcoeInternalCustomFlags"); +} \ No newline at end of file diff --git a/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPTransactionAttributesSimcoe.kt b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPTransactionAttributesSimcoe.kt new file mode 100644 index 0000000..59ecdb9 --- /dev/null +++ b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MPTransactionAttributesSimcoe.kt @@ -0,0 +1,34 @@ +package com.prolificinteractive.mparticle + +import com.mparticle.commerce.TransactionAttributes +import com.prolificinteractive.simcoe.Properties + +fun getTransactionAttributes(properties: Properties?): TransactionAttributes { + val transaction = TransactionAttributes() + transaction.affiliation = properties?.get(MPTransactionAttributesKeys.AFFILIATION.key)?.toString() + transaction.couponCode = properties?.get(MPTransactionAttributesKeys.COUPON_CODE.key)?.toString() + transaction.revenue = properties?.get(MPTransactionAttributesKeys.REVENUE.key) as Double + transaction.shipping = properties?.get(MPTransactionAttributesKeys.SHIPPING.key) as Double + transaction.tax = properties?.get(MPTransactionAttributesKeys.TAX.key) as Double + transaction.id = properties?.get(MPTransactionAttributesKeys.TRANSACTION_ID.key)?.toString() + + return transaction +} + +/// The MPTransactionAttributes keys available. +/// +/// - affiliation: The affiliation. +/// - couponCode: The coupon code. +/// - revenue: The revenue amount. +/// - shipping: The shipping amount. +/// - tax: The tax amount. +/// - transactionId: The transaction Id. +enum class MPTransactionAttributesKeys(val key: String) { + + AFFILIATION("affiliation"), + COUPON_CODE("couponCode"), + REVENUE("revenue"), + SHIPPING("shipping"), + TAX("tax"), + TRANSACTION_ID("transactionId"); +} \ No newline at end of file diff --git a/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MpProduct.kt b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MpProduct.kt new file mode 100644 index 0000000..64e0605 --- /dev/null +++ b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MpProduct.kt @@ -0,0 +1,47 @@ +package com.prolificinteractive.mparticle + +import com.mparticle.commerce.Product +import com.prolificinteractive.simcoe.SimcoeProductConvertible + + +fun mpProduct(simcoeProductConvertible: SimcoeProductConvertible): Product { + val simcoeProduct = simcoeProductConvertible.toSimcoeProduct() + val product = Product. + Builder( + simcoeProduct.productName, + simcoeProduct.productId, + simcoeProduct.price ?: 0.toDouble() + ) + .quantity(simcoeProduct.quantity.toDouble()) + + + val properties = simcoeProduct.properties ?: return product.build() + + product.brand(properties[MPProductKeys.BRAND.key] as? String ?: "") + product.category(properties[MPProductKeys.CATEGORY.key] as? String ?: "") + product.couponCode(properties[MPProductKeys.COUPON_CODE.key] as? String ?: "") + product.sku(properties[MPProductKeys.SKU.key] as? String ?: "") + product.position(properties[MPProductKeys.POSITION.key] as? Int ?: 0) + + return product.build() +} + + +// +// Simcoe +// +/// The MPProduct keys available for use with additionalProperties. +/// +/// - brand: The product brand. +/// - category: A category to which the product belongs. +/// - couponCode: The coupon associated with the product. +/// - sku: The sku of the product. +/// - position: The position of the product on the screen or impression list. +/// - variant: The variant. +enum class MPProductKeys(val key: String) { + BRAND("brand"), + CATEGORY("category"), + COUPON_CODE("couponCode"), + SKU("sku"), + POSITION("position"); +} \ No newline at end of file diff --git a/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MparticleProvider.kt b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MparticleProvider.kt new file mode 100644 index 0000000..ecf8f2e --- /dev/null +++ b/simcoe-mparticle/src/main/java/com/prolificinteractive/mparticle/MparticleProvider.kt @@ -0,0 +1,200 @@ +package com.prolificinteractive.mparticle + +import android.content.Context +import com.mparticle.MPEvent +import com.mparticle.MParticle +import com.mparticle.commerce.Product +import com.prolificinteractive.simcoe.Failure +import com.prolificinteractive.simcoe.Properties +import com.prolificinteractive.simcoe.SimcoeProductConvertible +import com.prolificinteractive.simcoe.Success +import com.prolificinteractive.simcoe.TrackingResult +import com.prolificinteractive.simcoe.trackers.CartLogTracking +import com.prolificinteractive.simcoe.trackers.CheckoutTracking +import com.prolificinteractive.simcoe.trackers.EventTracking +import com.prolificinteractive.simcoe.trackers.LifetimeValueTracking +import com.prolificinteractive.simcoe.trackers.PageViewTracking +import com.prolificinteractive.simcoe.trackers.TimedEventTracking +import java.math.BigDecimal +import java.util.Arrays + +/** + * Creates a new mParticle analytics provider instance. + */ +class MparticleProvider(private val token: String, private val secret: String) : + EventTracking, + PageViewTracking, + LifetimeValueTracking, + TimedEventTracking, + CartLogTracking, + CheckoutTracking { + + companion object { + private val MPARTICLE_PROVIDER_NAME = "MParticle" + } + + /** Initializes and starts the SDK with the input key and secret. + * + * - Parameters: + * - key: The key. + * - secret: The secret. + **/ + override fun start(context: Context) { + MParticle.start(context, token, secret) + } + + override fun stop() {} + + override fun providerName(): String { + return MPARTICLE_PROVIDER_NAME + } + + /** Tracks a checkout event. + * + * - Parameters: + * - products: The products. + * - eventProperties: The event properties. + * - Returns: A tracking result. + **/ + override fun trackCheckoutEvent(products: Array, eventProperties: Properties?): TrackingResult { + val mpProducts = products.map { product -> mpProduct(product) }.toTypedArray() + + val event = getCommerceEvent(Product.CHECKOUT, mpProducts, eventProperties) + + MParticle.getInstance().logEvent(event) + return Success() + } + + /** Logs the addition of a product to the cart. + * + * - Parameters: + * - product: The SimcoeProductConvertible instance. + * - eventProperties: The event properties. + * - Returns: A tracking result. + **/ + override fun logAddToCart(product: T, eventProperties: Properties?): TrackingResult { + val mpProducts = Arrays.asList(mpProduct(product)).toTypedArray() + val event = getCommerceEvent(Product.ADD_TO_CART, mpProducts, eventProperties) + MParticle.getInstance().logEvent(event) + return Success() + } + + /** Logs the removal of a product from the cart. + * + * - Parameters: + * - product: The SimcoeProductConvertible instance. + * - eventProperties: The event properties. + * - Returns: A tracking result. + **/ + override fun logRemoveFromCart(product: T, eventProperties: Properties?): TrackingResult { + val mpProducts = Arrays.asList(mpProduct(product)).toTypedArray() + val event = getCommerceEvent(Product.REMOVE_FROM_CART, mpProducts, eventProperties) + MParticle.getInstance().logEvent(event) + return Success() + } + + /** Tracks the lifetime value. + * + * - Parameters: + * - key: The lifetime value's identifier. + * - value: The lifetime value. + * - properties: The optional additional properties. + * - Returns: A tracking result. + **/ + override fun trackLifetimeValue(key: String, value: Any, properties: Properties?): TrackingResult { + val valDecimal = value as? BigDecimal ?: return Failure("Value must map to a Double") + val newProps = properties?.mapValues { item -> item.toString() } + MParticle.getInstance().logLtvIncrease(valDecimal, key, newProps) + + return Success() + } + + + /** Track the lifetime values. + * + * - Parameter: + * - attributes: The lifetime attribute values. + * - properties: The optional additional properties. + * - Returns: A tracking result. + **/ + override fun trackLifetimeValues(attributes: Properties, values: Properties?): TrackingResult { + attributes.map { property -> trackLifetimeValue(property.key, property.value, values) } + + return Success() + } + + /** Starts the timed event. + * + * - Parameters: + * - event: The event name. + * - properties: The event properties. + * - Returns: A tracking result. + **/ + override fun startTimedEvent(eventName: String, properties: Properties?): TrackingResult { + if (properties == null) { + return Failure("Cannot track a timed event without valid properties.") + } + + properties.plus(MPEventKeys.NAME.key to eventName) + + val event: MPEvent + + try { + event = toEvent(properties) + } catch (error: MPEventGenerationError) { + return Failure(error.message ?: "Unable to generate event") + } catch (error: Error) { + return Failure("Unknown error") + } + + MParticle.getInstance().logEvent(event) + return Success() + } + + /** Stops the timed event. + * + * - Parameters: + * - event: The event name. + * - properties: The event properties. + * - Returns: A tracking result. + **/ + override fun stopTimedEvent(eventName: String, properties: Properties?): TrackingResult { + return startTimedEvent(eventName, properties) + } + + /** Tracks an mParticle event. + * + * Internally, this generates an MPEvent object based on the properties passed in . The event string + * passed as the first parameter is delineated as the .name of the MPEvent. As a caller, you are + * required to pass in non-nil properties where one of the properties is the MPEventType. Failure + * to do so will cause this function to fail. + * + * It is recommended that you use the `Simcoe.eventData()` function in order to generate the properties + * dictionary properly. + * + * - Parameters: + * - event: The event name to log. + * - properties: The properties of the event. + * - Returns: A tracking result. + **/ + override fun trackEvent(eventName: String, properties: Properties?): TrackingResult { + var mProperties: Properties = properties ?: return Failure("Cannot track an event without valid properties.") + mProperties.plus(properties[MPEventKeys.NAME.key] to eventName) + val event: MPEvent = toEvent(mProperties) + MParticle.getInstance().logEvent(event) + return Success() + } + + /** Tracks the page view. + * + * - Parameters: + * - pageView: The page view to track. + * - properties: The optional additional properties. + * - Returns: A tracking result. + **/ + override fun trackPageView(pageName: String, properties: Properties?): TrackingResult { + //TODO 9/19/17 Figure out what to do with the properties object here + MParticle.getInstance().logScreen(pageName) + return Success() + } +} diff --git a/simcoe-mparticle/src/main/res/values/strings.xml b/simcoe-mparticle/src/main/res/values/strings.xml new file mode 100644 index 0000000..88f0fa4 --- /dev/null +++ b/simcoe-mparticle/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + simcoe-mparticle + diff --git a/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProduct.kt b/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProduct.kt new file mode 100644 index 0000000..c5529bb --- /dev/null +++ b/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProduct.kt @@ -0,0 +1,18 @@ +package com.prolificinteractive.simcoe + +class SimcoeProduct( + val productName: String, + val productId: String, + val quantity: Int, + val price: Double?, + val properties: Properties? +) { + /// The default initializer. + /// + /// - Parameters: + /// - productName: The product name. + /// - productId: The product Id. + /// - quantity: The quantity. + /// - price: The price. + /// - properties: The properties. +} \ No newline at end of file diff --git a/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProductConvertible.kt b/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProductConvertible.kt new file mode 100644 index 0000000..25accce --- /dev/null +++ b/simcoe/src/main/java/com/prolificinteractive/simcoe/SimcoeProductConvertible.kt @@ -0,0 +1,5 @@ +package com.prolificinteractive.simcoe + +interface SimcoeProductConvertible { + fun toSimcoeProduct() : SimcoeProduct +} \ No newline at end of file diff --git a/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CartLogTracking.kt b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CartLogTracking.kt new file mode 100644 index 0000000..7f152b2 --- /dev/null +++ b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CartLogTracking.kt @@ -0,0 +1,25 @@ +package com.prolificinteractive.simcoe.trackers + +import com.prolificinteractive.simcoe.Properties +import com.prolificinteractive.simcoe.SimcoeProductConvertible +import com.prolificinteractive.simcoe.TrackingResult + +/// Defines functionality for logging cart actions. +interface CartLogTracking : AnalyticsTracking { + + /// Logs the addition of a product to the cart. + /// + /// - Parameters: + /// - product: The SimcoeProductConvertible instance. + /// - eventProperties: The event properties. + /// - Returns: A tracking result. + fun logAddToCart(product: T, eventProperties: Properties?): TrackingResult + + /// Logs the removal of a product from the cart. + /// + /// - Parameters: + /// - product: The SimcoeProductConvertible instance. + /// - eventProperties: The event properties. + /// - Returns: A tracking result. + fun logRemoveFromCart(product: T, eventProperties: Properties?): TrackingResult +} \ No newline at end of file diff --git a/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CheckoutTracking.kt b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CheckoutTracking.kt new file mode 100644 index 0000000..4e77e33 --- /dev/null +++ b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/CheckoutTracking.kt @@ -0,0 +1,17 @@ +package com.prolificinteractive.simcoe.trackers + +import com.prolificinteractive.simcoe.Properties +import com.prolificinteractive.simcoe.SimcoeProductConvertible +import com.prolificinteractive.simcoe.TrackingResult + +/// Defines functionality for tracking checkout actions. +interface CheckoutTracking { + + /// Tracks a checkout event. + /// + /// - Parameters: + /// - products: The products. + /// - eventProperties: The event properties. + /// - Returns: A tracking result. + fun trackCheckoutEvent(products: Array, eventProperties: Properties?): TrackingResult +} \ No newline at end of file diff --git a/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/LifetimeValueTracking.kt b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/LifetimeValueTracking.kt index 799047a..f08b03f 100644 --- a/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/LifetimeValueTracking.kt +++ b/simcoe/src/main/java/com/prolificinteractive/simcoe/trackers/LifetimeValueTracking.kt @@ -15,7 +15,7 @@ interface LifetimeValueTracking : AnalyticsTracking { * @param value The lifetime value. * @return A tracking result. */ - fun trackLifetimeValue(key: String, value: Any): TrackingResult + fun trackLifetimeValue(key: String, value: Any, properties: Properties?): TrackingResult /** * Tracks the lifetime values for a given JSON object. @@ -23,5 +23,5 @@ interface LifetimeValueTracking : AnalyticsTracking { * @param values The values. * @return A tracking result. */ - fun trackLifetimeValues(values: Properties?): TrackingResult + fun trackLifetimeValues(attributes : Properties, values: Properties?): TrackingResult }