Source: SalesTracker/salestracker.js

/**
 * @class
 * @classdesc SalesTracker Plugin is used to track orders, aisle or products.
 * @name SalesTracker
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param parent {object} Instance of the Tag used
 * @public
 */
window['ATInternet']['Tracker']['Plugins']['SalesTracker'] = function (parent) {
    "use strict";
    var self = this;

    /**
     * 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) return "";
        return value + "";
    };

    /**
     * Add parameter from tag to buffer.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param tagObject {object} Object from tag
     * @param param {object} Name of the parameter in buffer
     * @param key {object} Name of the property to get
     * @private
     */
    var _setParamIfExist = function (tagObject, param, key) {
        if (tagObject.hasOwnProperty(key)) {
            var value = _value2strIfExist(tagObject[key]);
            parent.setParam(param, value, {hitType: ['page']});
        }
    };

    /**
     * Check if tag object is empty.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param tagObject {object} Object from tag
     * @return {boolean}
     * @private
     */
    var _objectIsEmpty = function (tagObject) {
        for (var p in tagObject) {
            if (tagObject.hasOwnProperty(p)) {
                return false;
            }
        }
        return true;
    };

    /**
     * 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;
    };

    /**
     * Check if type of tag is object.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param tagObject {object} Object from tag
     * @return {boolean}
     * @private
     */
    var _isObject = function (tagObject) {
        return ((typeof tagObject === 'object') && !(tagObject instanceof Array));
    };

    /**
     * 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';
            parent.setParam('newcus', newcus, {hitType: ['page']});
        }
        else if (tagObject.newCustomer) {
            /* @if debug */
            parent.debug('SalesTracker:order:set:newCustomer:Error','ERROR','Not a boolean',tagObject);
            /* @endif */
            if (typeof parent.getParams('newcus') === 'undefined') {
                parent.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 (_isObject(amount)) {
            _setParamIfExist(amount, 'mtht', 'amountTaxFree');
            _setParamIfExist(amount, 'mtttc', 'amountTaxIncluded');
            _setParamIfExist(amount, 'tax', 'taxAmount');
        }
        else if (amount) {
            /* @if debug */
            parent.debug('SalesTracker:order:set:amount:Error','ERROR','Not an object',{value:amount});
            /* @endif */
        }
    };

    /**
     * Set delivery values.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param delivery {object} Object from tag
     * @private
     */
    var _setDelivery = function (delivery) {
        if (_isObject(delivery)) {
            _setParamIfExist(delivery, 'fp', 'shippingFeesTaxIncluded');
            _setParamIfExist(delivery, 'fpht', 'shippingFeesTaxFree');
            _setParamIfExist(delivery, 'dl', 'deliveryMethod');
        }
        else if (delivery) {
            /* @if debug */
            parent.debug('SalesTracker:order:set:delivery:Error','ERROR','Not an object',{value:delivery});
            /* @endif */
        }
    };

    /**
     * Set discount values.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param discount {object} Object from tag
     * @private
     */
    var _setDiscount = function (discount) {
        if (_isObject(discount)) {
            _setParamIfExist(discount, 'dsc', 'discountTaxIncluded');
            _setParamIfExist(discount, 'dscht', 'discountTaxFree');
            _setParamIfExist(discount, 'pcd', 'promotionalCode');
        }
        else if (discount) {
            /* @if debug */
            parent.debug('SalesTracker:order:set:discount:Error','ERROR','Not an object',{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' : '';
            parent.setParam('tp', tp, {hitType: ['page']});
        }
        else if (tagObject.confirmationRequired) {
            /* @if debug */
            parent.debug('SalesTracker:order:set:confirmationRequired:Error','ERROR','Not a boolean',tagObject);
            /* @endif */
            if (typeof parent.getParams('tp') === 'undefined') {
                parent.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 */
            parent.debug('SalesTracker:order:set:orderCustomVariables:Error','ERROR','Not an array',{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 (parent.getParams('tp') !== 'pre1') {
                var tp = tagObject.isBasketPage ? 'cart' : '';
                parent.setParam('tp', tp, {hitType: ['page']});
            }
        }
        else if (tagObject.isBasketPage) {
            /* @if debug */
            parent.debug('SalesTracker:cart:set:isBasketPage:Error','ERROR','Not a boolean',tagObject);
            /* @endif */
            if (typeof parent.getParams('tp') === 'undefined') {
                parent.setParam('tp', '', {hitType: ['page']});
            }
        }
    };

    /**
     * Set product values.
     * @memberof ATInternet.Tracker.Plugins.SalesTracker#
     * @function
     * @param product {object} Object from tag
     * @private
     */
    var _addProduct = function (product) {
        if (_isObject(product)) {
            _productsQuantity++;
            var _idx = _productsQuantity;
            var productId = _productIdMaker(product);
            parent.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 */
            parent.debug('SalesTracker:cart:add:product:Error','ERROR','Not an object',{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 = '';
        parent['exec']('Utils', 'manageChapters', [tagObject, 'category', 6], function(data) {
            if (data) {
                _str = data;
            }
        });
        _str += tagObject.productId;

        var _context = parent.getContext('product') || {};
        if (_context.viewedProducts) {
            _context.viewedProducts.push(_str);
        } else {
            _context.viewedProducts = [_str];
        }
        parent.setContext('product', _context);
    };

    var _productsQuantity = 0;

    /**
     * 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'] + '::' : '');

        parent['exec']('Utils', 'manageChapters', [tagObject, 'category', 6], function(data){
            if (data) {
                _category = data;
            }
        });

        return _category + _product;
    };

    /**
     * [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
     */
    parent['order'] = self['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
     */
    parent['cart'] = self['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
     */
    parent['aisle'] = self['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
     */
    parent['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
     */
    parent['product'] = self['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
     */
    parent['order']['set'] = self['order']['set'] = function (tagObject) {
        var valid = false;
        if (_isObject(tagObject) && !_objectIsEmpty(tagObject)) {
            valid = true;
            parent.dispatchSubscribe('page'); //Register helper to final call to send hit
            parent.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 */
        parent.debug('SalesTracker:order:set','DEBUG','method ended',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
     */
    parent['cart']['set'] = self['cart']['set'] = function (tagObject) {
        var valid = false;
        if (_isObject(tagObject) && !_objectIsEmpty(tagObject)) {
            valid = true;
            parent.dispatchSubscribe('page'); //Register helper to final call to send hit
            parent.dispatchSubscribe('salesTracker'); //Register helper to final call
            _setParamIfExist(tagObject, 'idcart', 'cartId');
            _setIsBasketPage(tagObject);
        }
        /* @if debug */
        parent.debug('SalesTracker:cart:set','DEBUG','method ended',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
     */
    parent['cart']['add'] =  self['cart']['add'] = function (tagObject) {
        var valid = false;
        if (_isObject(tagObject) && !_objectIsEmpty(tagObject)) {
            valid = true;
            _addProduct(tagObject.product);
        }
        /* @if debug */
        parent.debug('SalesTracker:cart:add','DEBUG','method ended',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
     */
    parent['aisle']['set'] =  self['aisle']['set'] = function (tagObject) {
        var valid = false;
        if (_isObject(tagObject) && !_objectIsEmpty(tagObject)) {
            valid = true;
            parent.dispatchSubscribe('page'); //Register helper to final call to send hit
            var aisl = '';
            parent['exec']('Utils', 'manageChapters', [tagObject, 'level', 6], function(data){
                aisl = data;
            });
            aisl = aisl.replace(/::$/gi, '');
            parent.setParam('aisl', aisl, {hitType: ['page']});
        }
        /* @if debug */
        parent.debug('SalesTracker:aisle:set','DEBUG','method ended',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
     */
    parent['product']['add'] =  self['product']['add'] = function (tagObject) {
        var valid = false;
        if (_isObject(tagObject) && !_objectIsEmpty(tagObject) && !_tagObjectInvalid(tagObject, ['productId'])) {
            valid = true;
            _addViewedProduct(tagObject);
            parent.dispatchSubscribe('salesTracker');
        } else {
            /* @if debug */
            parent.debug('SalesTracker:product:add:Error','ERROR','Product object content problem',tagObject);
            /* @endif */
        }
        /* @if debug */
        parent.debug('SalesTracker:product:add','DEBUG','method ended',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
     * @private
     */
    parent['salesTracker']['onDispatch'] = self['onDispatch'] = function () {
        if (parent.getParams("cmd") === '') {
            /* @if debug */
            parent.debug('SalesTracker:order:onDispatch:Error','ERROR','Required "orderId" parameter is not defined');
            /* @endif */
        }
        if (!parent.getParams("idcart") && ((parent.getParams("tp") === 'cart') || (parent.getParams("tp") === 'pre1'))) {
            /* @if debug */
            parent.debug('SalesTracker:cart:onDispatch:Error','ERROR','Required "cartId" parameter is not defined');
            /* @endif */
        }
        var _context = parent.getContext('product');
        if (_context && _context.viewedProducts && _context.viewedProducts.length > 0) {
            parent.setParam('pdtl', _context.viewedProducts.join('|'), {'hitType': ['product']});
            parent.setParam('type', "pdt", {'hitType': ['product']});
            parent.sendHit(null, [['hitType', ['product']]]);
        }
    };
};
window['ATInternet']['Tracker']['addPlugin']('SalesTracker');