Skip to content

Commit

Permalink
Commerce event processing and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SbDove committed Jun 26, 2024
1 parent 524e187 commit 0ffc365
Show file tree
Hide file tree
Showing 2 changed files with 436 additions and 1 deletion.
231 changes: 231 additions & 0 deletions src/commerce-handler.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
var ProductActionTypes = {
AddToCart: 10,
Click: 14,
Checkout: 12,
CheckoutOption: 13,
Impression: 22,
Purchase: 16,
Refund: 17,
RemoveFromCart: 11,
ViewDetail: 15,
}

var ProductActionNames = {
0: "Unknown",
1: "Add To Cart",
2: "Remove From Cart",
3: "Checkout",
4: "Checkout Option",
5: "Click",
6: "View Detail",
7: "Purchase",
8: "Refund",
9: "Add To Wishlist",
10: "Remove From Wishlist",
}

var PromotionType = {
PromotionClick: 19,
PromotionView: 18,
}

var PromotionTypeNames = {
19: "Click",
18: "View",
}
var HeapConstants = {
EventNameItem: "Item",
EventNameProductAction: "Product Action Event",
EventNameProductActionPart: "Product Action: ",
EventNamePromotionPart: "Promotion: ",
EventNameImpression: "Impression Event",
MaxPropertyLength: 1023,
KeyProductName: "product_name",
KeyProductPrice: "product_price",
KeyProductQuantity: "product_quantity",
KeyProductTotalProductAmount: "total_product_amount",
KeyProductSku: "product_id",
KeyProductBrand: "product_brand",
KeyProductCategory: "product_category",
KeyProductSkus: "skus",
KeyPromotionCreative: "creative",
KeyPromotionId: "id",
KeyPromotionPosition: "position",
}

function CommerceHandler(common) {
this.common = common || {};
}
Expand Down Expand Up @@ -61,6 +116,182 @@ CommerceHandler.prototype.logCommerceEvent = function(event) {
21: ProductRemoveFromWishlist,
22: ProductImpression
*/
let events = [];

switch (event.EventCategory) {
case ProductActionTypes.Impression:
events = buildImpressionEvents(event);
break;
case PromotionType.PromotionClick:
case PromotionType.PromotionView:
events = buildPromotionEvents(event);
break;
default:
events = buildProductActionEvents(event);
};

events.forEach((event) => {
window.heap.track(event.Name, event.Properties);
});
};

function buildImpressionEvents(event) {
let events = [];

if (event.ProductImpressions.length > 0) {
event.ProductImpressions.forEach((impression) => {
let productSkus = [];
if (impression.ProductList.length > 0) {
impression.ProductList.forEach((product) => {
let [productEvent, productSku] = buildProductEvent(product);
events.push(productEvent);
if(productSku) {
productSkus.push(productSku);
}
})
}

events.push(buildActionEvent(event, HeapConstants.EventNameImpression, productSkus))
})
}


return events;
};

function buildPromotionEvents(event) {
let events = [];
let promotionIds = [];
if (event.PromotionAction.PromotionList.length > 0) {
event.PromotionAction.PromotionList.forEach((promotion) => {
let [promotionEvent, promotionId] = buildPromotionEvent(promotion);
events.push(promotionEvent);

if(promotionId) {
promotionIds.push(promotionId);
}
})
}
let promotionActionEventName = HeapConstants.EventNamePromotionPart + PromotionTypeNames[event.EventCategory];
events.push(buildActionEvent(event, promotionActionEventName, promotionIds));
return events;
}

function buildProductActionEvents(event) {
let events = [];
let productSkus = [];

if (event.ProductAction.ProductList.length > 0) {
event.ProductAction.ProductList.forEach((product) => {
let [productEvent, productSku] = buildProductEvent(product);

events.push(productEvent);

if (productSku) {
productSkus.push(productSku);
}
});
}
let actionEventName = event.ProductAction == null ? HeapConstants.EventNameProductAction : HeapConstants.EventNameProductActionPart + ProductActionNames[event.ProductAction.ProductActionType]
events.push(buildActionEvent(event, actionEventName, productSkus));

return events;
}

function buildActionEvent(event, eventName, productSkus) {
let properties = event.EventAttributes == null ? {} : event.EventAttributes;
properties[HeapConstants.KeyProductSkus] = productSkus;
return {Name: eventName, Properties: properties};
}

function buildProductEvent(product) {
let event = {};
let properties = product.Attributes;
if (!properties) {
properties = {};
}

let validatedName = validateHeapPropertyValue(product.Name);
if (validatedName) {
properties[HeapConstants.KeyProductName] = validatedName;
}

let validatedPrice = validateHeapPropertyValue(product.Price);
if (validatedPrice) {
properties[HeapConstants.KeyProductPrice] = validatedPrice;
}

let validatedQuantity = validateHeapPropertyValue(product.Quantity);
if (validatedQuantity) {
properties[HeapConstants.KeyProductQuantity] = validatedQuantity;
}

let validatedTotalProductAmount = validateHeapPropertyValue(product.TotalProductAmount);
if (validatedTotalProductAmount) {
properties[HeapConstants.KeyProductTotalProductAmount] = validatedTotalProductAmount;
}

let validatedSku = validateHeapPropertyValue(product.Sku);
if (validatedSku) {
properties[HeapConstants.KeyProductSku] = validatedSku;
}

let validatedBrand = validateHeapPropertyValue(product.Brand);
if (validatedBrand) {
properties[HeapConstants.KeyProductBrand] = validatedBrand;
}

let validatedCategory = validateHeapPropertyValue(product.Category);
if (validatedCategory) {
properties[HeapConstants.KeyProductCategory] = validatedCategory;
}

event.Name = HeapConstants.EventNameItem;
event.Properties = properties;

let productSku = validatedSku;
return [event, productSku];
}

function buildPromotionEvent(promotion) {
let event = {};
let properties = promotion.Attributes ? promotion.Attributes : {};

let validatedPromotionValues = {
KeyPromotionCreative: validateHeapPropertyValue(promotion.Creative),
KeyPromotionId: validateHeapPropertyValue(promotion.Id),
KeyPromotionPosition: validateHeapPropertyValue(promotion.Position),
}

Object.keys(validatedPromotionValues).forEach((key) => {
let value = validatedPromotionValues[key];

if (value === undefined || key === undefined) {
return;
}

let constKey = HeapConstants[key];
properties[constKey] = value;
})
event.Name = HeapConstants.EventNameItem;
event.Properties = properties;
let promotionId = validatedPromotionValues.KeyPromotionId;

return [event, promotionId];
}

function validateHeapPropertyValue(value){
if (typeof value === "boolean" || typeof value === "number") {
return value;
}

if (value === undefined || value === null) {
return value;
} else if (value.length > HeapConstants.MaxPropertyLength){
return value.substring(0, HeapConstants.MaxPropertyLength);
} else {
return value;
}
}

module.exports = CommerceHandler;
Loading

0 comments on commit 0ffc365

Please sign in to comment.