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
}