/**
* @class
* @classdesc SalesTracker Plugin is used to track orders, aisle or products.
* @name SalesTracker
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param tag {object} Instance of the Tag used
* @public
*/
ATInternet.Tracker.Plugins.SalesTracker = function (tag) {
'use strict';
var _productsQuantity = 0;
// Debug object error
var _error = {
level: 'ERROR',
messageBoolean: 'Not a boolean',
messageObject: 'Not an object',
messageArray: 'Not an array'
};
var _debug = {
level: 'DEBUG',
messageEnd: 'method ended'
};
/**
* Convert value to string.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param value {object} Value to convert
* @return {string}
* @private
*/
var _value2strIfExist = function (value) {
if (value === undefined || value === null) return "";
return value + "";
};
/**
* Add parameter from tag to buffer.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @param param {string} Name of the parameter in buffer
* @param key {string} Name of the property to get
* @private
*/
var _setParamIfExist = function (tagObject, param, key) {
if (tagObject.hasOwnProperty(key)) {
var value = _value2strIfExist(tagObject[key]);
tag.setParam(param, value, {hitType: ['page']});
}
};
/**
* Check if tag object contains needed properties.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @param neededProperties {Array} List of needed properties
* @return {boolean}
* @private
*/
var _tagObjectInvalid = function (tagObject, neededProperties) {
for (var i = 0; i < neededProperties.length; i++) {
if (tagObject[neededProperties[i]] === undefined) {
return true;
}
}
return false;
};
/**
* Set new customer parameter.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @private
*/
var _setNewCustomer = function (tagObject) {
if (typeof tagObject.newCustomer === 'boolean') {
var newcus = tagObject.newCustomer ? '1' : '0';
tag.setParam('newcus', newcus, {hitType: ['page']});
} else if (tagObject.newCustomer) {
/* @if debug */
tag.debug('SalesTracker:order:set:newCustomer:Error', _error.level, _error.messageBoolean, tagObject);
/* @endif */
if (typeof tag.getParams('newcus') === 'undefined') {
tag.setParam('newcus', '0', {hitType: ['page']});
}
}
};
/**
* Set amount values.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param amount {object} Object from tag
* @private
*/
var _setAmount = function (amount) {
if (ATInternet.Utils.isObject(amount)) {
_setParamIfExist(amount, 'mtht', 'amountTaxFree');
_setParamIfExist(amount, 'mtttc', 'amountTaxIncluded');
_setParamIfExist(amount, 'tax', 'taxAmount');
} else if (amount) {
/* @if debug */
tag.debug('SalesTracker:order:set:amount:Error', _error.level, _error.messageObject, {value: amount});
/* @endif */
}
};
/**
* Set delivery values.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param delivery {object} Object from tag
* @private
*/
var _setDelivery = function (delivery) {
if (ATInternet.Utils.isObject(delivery)) {
_setParamIfExist(delivery, 'fp', 'shippingFeesTaxIncluded');
_setParamIfExist(delivery, 'fpht', 'shippingFeesTaxFree');
_setParamIfExist(delivery, 'dl', 'deliveryMethod');
} else if (delivery) {
/* @if debug */
tag.debug('SalesTracker:order:set:delivery:Error', _error.level, _error.messageObject, {value: delivery});
/* @endif */
}
};
/**
* Set discount values.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param discount {object} Object from tag
* @private
*/
var _setDiscount = function (discount) {
if (ATInternet.Utils.isObject(discount)) {
_setParamIfExist(discount, 'dsc', 'discountTaxIncluded');
_setParamIfExist(discount, 'dscht', 'discountTaxFree');
_setParamIfExist(discount, 'pcd', 'promotionalCode');
} else if (discount) {
/* @if debug */
tag.debug('SalesTracker:order:set:discount:Error', _error.level, _error.messageObject, {value: discount});
/* @endif */
}
};
/**
* Set 'tp' parameter to 'pre1' if current page order need further confirmation.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @private
*/
var _setConfirmationRequired = function (tagObject) {
if (typeof tagObject.confirmationRequired === 'boolean') {
var tp = tagObject.confirmationRequired ? 'pre1' : '';
tag.setParam('tp', tp, {hitType: ['page']});
} else if (tagObject.confirmationRequired) {
/* @if debug */
tag.debug('SalesTracker:order:set:confirmationRequired:Error', _error.level, _error.messageBoolean, tagObject);
/* @endif */
if (typeof tag.getParams('tp') === 'undefined') {
tag.setParam('tp', '', {hitType: ['page']});
}
}
};
/**
* Set custom variables for the order.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param orderCustomVariables {Array} List of custom variables to set
* @private
*/
var _setCustomVariables = function (orderCustomVariables) {
var ocv = orderCustomVariables;
if (ocv instanceof Array) {
for (var i = 0; i < ocv.length; i++) {
_setParamIfExist(ocv, "o" + (i + 1), i);
}
} else if (ocv) {
/* @if debug */
tag.debug('SalesTracker:order:set:orderCustomVariables:Error', _error.level, _error.messageArray, {value: ocv});
/* @endif */
}
};
/**
* Set 'tp' parameter to 'cart' if current page is basket.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @private
*/
var _setIsBasketPage = function (tagObject) {
if (typeof tagObject.isBasketPage === 'boolean') {
if (tag.getParams('tp') !== 'pre1') {
var tp = tagObject.isBasketPage ? 'cart' : '';
tag.setParam('tp', tp, {hitType: ['page']});
}
} else if (tagObject.isBasketPage) {
/* @if debug */
tag.debug('SalesTracker:cart:set:isBasketPage:Error', _error.level, _error.messageBoolean, tagObject);
/* @endif */
if (typeof tag.getParams('tp') === 'undefined') {
tag.setParam('tp', '', {hitType: ['page']});
}
}
};
/**
* Build full product name from categories and ID.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @private
*/
var _productIdMaker = function (tagObject) {
var _product = (tagObject['productId'] ? tagObject['productId'] : '');
var _category = (tagObject['category'] ? tagObject['category'] + '::' : '');
var data = tag.utils.manageChapters(tagObject, 'category', 6);
if (data) {
_category = data;
}
return _category + _product;
};
/**
* Set product values.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param product {object} Object from tag
* @private
*/
var _addProduct = function (product) {
if (ATInternet.Utils.isObject(product)) {
_productsQuantity++;
var _idx = _productsQuantity;
var productId = _productIdMaker(product);
tag.setParam('pdt' + _idx, productId, {hitType: ['page']});
_setParamIfExist(product, 'qte' + _idx, 'quantity');
_setParamIfExist(product, 'mt' + _idx, 'unitPriceTaxIncluded');
_setParamIfExist(product, 'mtht' + _idx, 'unitPriceTaxFree');
_setParamIfExist(product, 'dsc' + _idx, 'discountTaxIncluded');
_setParamIfExist(product, 'dscht' + _idx, 'discountTaxFree');
_setParamIfExist(product, 'pcode' + _idx, 'promotionalCode');
} else if (product) {
/* @if debug */
tag.debug('SalesTracker:cart:add:product:Error', _error.level, _error.messageObject, {value: product});
/* @endif */
}
};
/**
* Set viewed product values.
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} Object from tag
* @private
*/
var _addViewedProduct = function (tagObject) {
var _str = '';
var data = tag.utils.manageChapters(tagObject, 'category', 6);
if (data) {
_str = data;
}
_str += tagObject.productId;
var _context = tag.getContext('product') || {};
if (_context.viewedProducts) {
_context.viewedProducts.push(_str);
} else {
_context.viewedProducts = [_str];
}
tag.setContext('product', _context);
};
/**
* Get page label with chapters
* @name _getFullName
* @memberof ATInternet.Tracker.Plugins.SalesTracker#
* @function
* @param tagObject {object} tag object
* @returns string {string} Click name completed with chapters present in tag object
* @private
*/
var _getFullName = function (tagObject) {
return tag.utils.manageChapters(tagObject, 'chapter', 3) + (tagObject['name'] ? tagObject['name'] : '');
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Tags to track order values.
* @name order
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#order.set}
* @public
*/
tag.order = {};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Tags to track cart values.
* @name cart
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#cart.set}
* @property {function} add Tag helper, see details here {@link ATInternet.Tracker.Tag#cart.add}
* @public
*/
tag.cart = {};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Tags to track aisle values.
* @name aisle
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#aisle.set}
* @public
*/
tag.aisle = {};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Tags to manage salesTracker.
* @name salesTracker
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @private
*/
tag.salesTracker = {};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Tags to track viewed products.
* @name product
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} add Tag helper, see details here {@link ATInternet.Tracker.Tag#product.add}
* @public
*/
tag.product = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Set order properties.
* @alias order.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 10 properties : orderId, turnover, status, newCustomer, amount, delivery, paymentMethod, discount, confirmationRequired, orderCustomVariables
* @example
* <pre><code class="javascript">tag.order.set({
* orderId: 8235,
* turnover: 2049,
* status: 1,
* newCustomer: true,
* amount: {
* amountTaxIncluded: 2049,
* amountTaxFree: 1649.36,
* taxAmount: 339.64
* },
* delivery: {
* shippingFeesTaxIncluded: 19.9,
* shippingFeesTaxFree: 16,
* deliveryMethod: "1[Colissimo]"
* },
* paymentMethod: 1,
* discount: {
* discountTaxIncluded: 9.9,
* discountTaxFree: 7.96,
* promotionalCode: "CDPR15485Q"
* },
* confirmationRequired: false,
* orderCustomVariables: [5, 30 ,14, "[contact tel]", 1],
* });
* </code></pre>
* @public
*/
tag.order.set = function (tagObject) {
var valid = false;
if (ATInternet.Utils.isObject(tagObject) && !ATInternet.Utils.isEmptyObject(tagObject)) {
valid = true;
tag.dispatchSubscribe('page'); //Register helper to final call to send hit
tag.dispatchSubscribe('salesTracker'); //Register helper to final call
_setParamIfExist(tagObject, 'cmd', 'orderId');
_setParamIfExist(tagObject, 'roimt', 'turnover');
_setParamIfExist(tagObject, 'st', 'status');
_setNewCustomer(tagObject);
_setAmount(tagObject.amount);
_setDelivery(tagObject.delivery);
_setParamIfExist(tagObject, 'mp', 'paymentMethod');
_setDiscount(tagObject.discount);
_setConfirmationRequired(tagObject);
_setCustomVariables(tagObject.orderCustomVariables);
}
/* @if debug */
tag.debug('SalesTracker:order:set', _debug.level, _debug.messageEnd, tagObject);
/* @endif */
return valid;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Set cart properties.
* @alias cart.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 2 properties : cartId, isBasketPage
* @example
* <pre><code class="javascript">tag.cart.set({
* cartId: 8235,
* isBasketPage: true
* });</code></pre>
* @public
*/
tag.cart.set = function (tagObject) {
var valid = false;
if (ATInternet.Utils.isObject(tagObject) && !ATInternet.Utils.isEmptyObject(tagObject)) {
valid = true;
tag.dispatchSubscribe('page'); //Register helper to final call to send hit
tag.dispatchSubscribe('salesTracker'); //Register helper to final call
_setParamIfExist(tagObject, 'idcart', 'cartId');
_setIsBasketPage(tagObject);
}
/* @if debug */
tag.debug('SalesTracker:cart:set', _debug.level, _debug.messageEnd, tagObject);
/* @endif */
return valid;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Add product to cart.
* @alias cart.add
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 1 property : product
* @example
* <pre><code class="javascript">tag.cart.add({
* product: {
* category1: "1[Computers_and_Networking]",
* category2: "25[Computers]",
* category3: "56[Laptops]",
* ...
* category6: "300[Chromebook]",
* productId: "564[laptop_ACER_A56]",
* quantity: 1,
* unitPriceTaxIncluded: 549,
* unitPriceTaxFree: 456.2,
* discountTaxIncluded: 10,
* discountTaxFree: 8.04,
* promotionalCode: "Offre_New_Customer"
* }
* });
* </code></pre>
* @public
*/
tag.cart.add = function (tagObject) {
var valid = false;
if (ATInternet.Utils.isObject(tagObject) && !ATInternet.Utils.isEmptyObject(tagObject)) {
valid = true;
_addProduct(tagObject.product);
}
/* @if debug */
tag.debug('SalesTracker:cart:add', _debug.level, _debug.messageEnd, tagObject);
/* @endif */
return valid;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Set aisle properties.
* @alias aisle.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 6 properties : level1, level2, level3, level4, level5, level6
* @example
* <pre><code class="javascript">tag.aisle.set({
* level1: "10[high_tech]",
* level2: "20[Computers_network]",
* level3: "30[Computers]",
* level4: "40[Laptops]",
* level5: "50[Asus]",
* level6: "60[17]"
* });
* </code></pre>
* @public
*/
tag.aisle.set = function (tagObject) {
var valid = false;
if (ATInternet.Utils.isObject(tagObject) && !ATInternet.Utils.isEmptyObject(tagObject)) {
valid = true;
tag.dispatchSubscribe('page'); //Register helper to final call to send hit
var aisl = tag.utils.manageChapters(tagObject, 'level', 6);
aisl = aisl.replace(/::$/gi, '');
tag.setParam('aisl', aisl, {hitType: ['page']});
}
/* @if debug */
tag.debug('SalesTracker:aisle:set', _debug.level, _debug.messageEnd, tagObject);
/* @endif */
return valid;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Add viewed product.
* @alias product.add
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 4 properties : productId, category1, category2, category3
* @example
* <pre><code class="javascript">tag.product.add({
* productId: "564[laptop_ACER_A56]",
* category1: "1[Computers_and_Networking]",
* category2: "25[Computers]",
* category3: "56[Laptops]"
* });
* </code></pre>
* @public
*/
tag.product.add = function (tagObject) {
var valid = false;
if (ATInternet.Utils.isObject(tagObject) && !ATInternet.Utils.isEmptyObject(tagObject) && !_tagObjectInvalid(tagObject, ['productId'])) {
valid = true;
_addViewedProduct(tagObject);
tag.dispatchSubscribe('salesTracker');
} else {
/* @if debug */
tag.debug('SalesTracker:product:add:Error', _error.level, 'Product object content problem', tagObject);
/* @endif */
}
/* @if debug */
tag.debug('SalesTracker:product:add', _debug.level, _debug.messageEnd, tagObject);
/* @endif */
return valid;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.SalesTracker SalesTracker}] Will be called by tracker.dispatch if any SalesTracker has been set.
* @alias salesTracker.onDispatch
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param callback {function} Callback to execute
* @private
*/
tag.salesTracker.onDispatch = function (callback) {
var productContext = tag.getContext('product');
if (productContext && productContext.viewedProducts) {
var hitType = ['product'];
var pageContext = tag.getContext('page');
if (typeof pageContext !== 'undefined') {
tag.setParam('p', _getFullName(pageContext), {'hitType': hitType});
tag.setParam('s2', pageContext.level2 || '', {'hitType': hitType});
}
tag.setParam('pdtl', productContext.viewedProducts.join('|'), {'truncate': true, 'hitType': hitType});
tag.setParam('type', 'pdt', {'hitType': hitType});
tag.sendHit(null, [['hitType', hitType]], callback, null, null);
}
/* @if debug */
if (tag.getParams('cmd') === '') {
tag.debug('SalesTracker:order:onDispatch:Error', _error.level, 'Required "orderId" parameter is not defined');
}
if (!tag.getParams('idcart') && ((tag.getParams('tp') === 'cart') || (tag.getParams('tp') === 'pre1'))) {
tag.debug('SalesTracker:cart:onDispatch:Error', _error.level, 'Required "cartId" parameter is not defined');
}
/* @endif */
};
// For unit tests on private elements !!!
/* @if test */
var _this = this;
_this._value2strIfExist = _value2strIfExist;
_this._setParamIfExist = _setParamIfExist;
_this._tagObjectInvalid = _tagObjectInvalid;
_this._setNewCustomer = _setNewCustomer;
_this._setAmount = _setAmount;
_this._setDelivery = _setDelivery;
_this._setDiscount = _setDiscount;
_this._setConfirmationRequired = _setConfirmationRequired;
_this._setCustomVariables = _setCustomVariables;
_this._setIsBasketPage = _setIsBasketPage;
_this._productIdMaker = _productIdMaker;
_this._addProduct = _addProduct;
_this._addViewedProduct = _addViewedProduct;
_this._getFullName = _getFullName;
/* @endif */
};
ATInternet.Tracker.addPlugin('SalesTracker');