Source: Ecommerce/ecommerce.js

/**
 * @class
 * @classdesc Plugin used to manage ecommerce event sending.
 * @name Ecommerce
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param parent {object} Instance of the Tag used
 * @public
 */
window['ATInternet']['Tracker']['Plugins']['Ecommerce'] = function (parent) {
    "use strict";

    var _config = {};
    var _domain = '';

    // Plugin configuration.
    parent.configPlugin('Ecommerce', dfltPluginCfg || {}, function (newConf) {
        _config = newConf;
    });

    /* ---------------------------------- Utility methods ------------------------------------------------- */

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

    /**
     * Get parameter value.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param tagObject {object} Object from tag
     * @param hitKey {string} Name of the parameter in buffer
     * @param tagKey {string} Name of the property to get
     * @param hitObject {object} Hit object
     * @private
     */
    var _setValueFromKey = function (tagObject, hitKey, tagKey, hitObject) {
        if (tagObject.hasOwnProperty(tagKey)) {
            if (typeof tagObject[tagKey] !== 'undefined') {
                hitObject[hitKey] = tagObject[tagKey];
            }
        }
    };

    /* ---------------------------------- SalesTracker methods ------------------------------------------------- */

    /**
     * Process cart object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cartObject {object} Cart object
     * @private
     */
    var _processOrder = function (cartObject) {
        var cart = cartObject || {};
        var turnoverTaxIncluded = Number(cart['turnoverTaxIncluded']) || 0;
        var turnoverTaxFree = Number(cart['turnoverTaxFree']) || 0;
        var taxAmount = (turnoverTaxIncluded || turnoverTaxFree) - (turnoverTaxFree || turnoverTaxIncluded);
        parent.plugins.exec('SalesTracker', 'order.set', [{
            turnover: turnoverTaxIncluded,
            amount: {
                amountTaxIncluded: turnoverTaxIncluded,
                amountTaxFree: turnoverTaxFree,
                taxAmount: taxAmount.toFixed(2)
            }
        }]);
    };

    /**
     * Process cart object for SalesTracker cart
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cartObject {Object} Cart object
     * @param isBasketPage {Boolean}
     * @private
     */
    var _processCart = function (cartObject, isBasketPage) {
        var cart = cartObject || {};
        parent.plugins.exec('SalesTracker', 'cart.set', [{
            cartId: cart['id'],
            isBasketPage: isBasketPage
        }]);
    };

    /**
     * Process promotional code object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param promotionalCodeArray {Array} Promotional code array
     * @private
     */
    var _processPromotionalCode = function (promotionalCodeArray) {
        parent.plugins.exec('SalesTracker', 'order.set', [{
            discount: {
                promotionalCode: encodeURIComponent((promotionalCodeArray || []).join('|'))
            }
        }]);
    };

    /**
     * Process transaction object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param transactionObject {object} Transaction object
     * @private
     */
    var _processTransaction = function (transactionObject) {
        var transaction = transactionObject || {};
        parent.plugins.exec('SalesTracker', 'order.set', [{
            orderId: transaction['id'],
            status: 3,
            paymentMethod: '',
            confirmationRequired: false
        }]);
    };

    /**
     * Process shipping object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param shippingObject {object} Shipping object
     * @private
     */
    var _processShipping = function (shippingObject) {
        var shipping = shippingObject || {};
        parent.plugins.exec('SalesTracker', 'order.set', [{
            delivery: {
                shippingFeesTaxIncluded: shipping['costTaxIncluded'],
                shippingFeesTaxFree: shipping['costTaxFree'],
                deliveryMethod: encodeURIComponent(shipping['delivery'])
            }
        }]);
    };

    /**
     * Process customer object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param customerObject {object} Customer object
     * @private
     */
    var _processCustomer = function (customerObject) {
        var customer = customerObject || {};
        parent.plugins.exec('SalesTracker', 'order.set', [{
            newCustomer: !!customer['new']
        }]);
    };

    /**
     * Process product categories
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param salesTrackerProduct {Object} SalesTracker object
     * @param salesInsightsProduct {Object} SalesInsights object
     * @private
     */
    var _processProductCategories = function (salesTrackerProduct, salesInsightsProduct) {
        for (var x = 1; x <= 6; x++) {
            if (typeof salesInsightsProduct['category' + x] !== 'undefined') {
                salesTrackerProduct['category' + x] = salesInsightsProduct['category' + x] ? '[' + encodeURIComponent(salesInsightsProduct['category' + x]) + ']' : '';
            }
        }
    };

    /**
     * Process products array for SalesTracker cart
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _processCartProducts = function (productsArray) {
        var products = productsArray || [];
        var salesTrackerProduct;
        products.map(function (product) {
            salesTrackerProduct = {
                productId: product['id'] + (product['name'] ? '[' + encodeURIComponent(product['name']) + ']' : ''),
                quantity: product['quantity'],
                unitPriceTaxIncluded: product['priceTaxIncluded'],
                unitPriceTaxFree: product['priceTaxFree']
            };
            _processProductCategories(salesTrackerProduct, product);
            parent.plugins.exec('SalesTracker', 'cart.add', [{
                product: salesTrackerProduct
            }]);
        });
    };

    /**
     * Process products array for SalesTracker viewed products
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _processViewedProducts = function (productsArray) {
        var products = productsArray || [];
        var salesTrackerProduct;
        products.map(function (product) {
            salesTrackerProduct = {
                productId: product['id'] + (product['name'] ? '[' + encodeURIComponent(product['name']) + ']' : '')
            };
            _processProductCategories(salesTrackerProduct, product);
            parent.plugins.exec('SalesTracker', 'product.add', [salesTrackerProduct]);
        });
    };

    /* ---------------------------------- Ecommerce methods ------------------------------------------------- */

    /**
     * Get cart object from type
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param type {String} Type name
     * @return {Object}
     * @private
     */
    var _getCartFromType = function (type) {
        // Get cart if already defined
        var typeCart;
        var cart = {};
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            typeCart = contextEcommerceObject[i][type] || {};
            if (typeCart['j:cart']) {
                cart = typeCart['j:cart'];
                break;
            }
        }
        return cart;
    };

    /**
     * Get transaction ID from type
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param type {String} Type name
     * @return {String}
     * @private
     */
    var _getTransactionIdFromType = function (type) {
        // Get transaction ID if already defined
        var confirmation;
        var idTransaction = '';
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            confirmation = contextEcommerceObject[i][type] || {};
            if (confirmation['j:transaction']) {
                idTransaction = confirmation['j:transaction']['s:id'];
                break;
            }
        }
        return idTransaction;
    };

    /**
     * Generate 'product.display' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductDisplay = function (productsArray) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.display', product, 'j:product', 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.display', {'j:product': product}, 'ecommerce']);
            }
        });
    };

    /**
     * Generate 'product.click' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductClick = function (productsArray) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.click', product, 'j:product', 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.click', {'j:product': product}, 'ecommerce']);
            }
        });
    };

    /**
     * Generate 'product.page_display' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductPageDisplay = function (productsArray) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.page_display', product, 'j:product', 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.page_display', {'j:product': product}, 'ecommerce']);
            }
        });
    };

    /**
     * Generate 'product.add_to_cart' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @param idCart {String} cart ID
     * @private
     */
    var _setProductAddToCart = function (productsArray, idCart) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.add_to_cart', product, 'j:product', 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.add_to_cart', {
                    'j:cart': {
                        's:id': idCart
                    },
                    'j:product': product
                }, 'ecommerce']);
            }
        });
    };

    /**
     * Generate 'product.remove_from_cart' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @param idCart {String} cart ID
     * @private
     */
    var _setProductRemoveFromCart = function (productsArray, idCart) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.remove_from_cart', product, 'j:product', 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.remove_from_cart', {
                    'j:cart': {
                        's:id': idCart
                    },
                    'j:product': product
                }, 'ecommerce']);
            }
        });
    };

    /**
     * Generate 'cart.creation' event.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cart {Object} cart
     * @private
     */
    var _setCartCreation = function (cart) {
        var cartCreation = {
            'j:cart': {
                's:id': cart.idCart,
                's:currency': cart.currency,
                'f:turnoverTaxIncluded': cart.turnoverTaxIncluded,
                'f:turnoverTaxFree': cart.turnoverTaxFree,
                'n:quantity': cart.quantity,
                'n:nbDistinctProduct': cart.nbDistinctProduct
            }
        };
        parent.plugins.exec('Event', 'set', ['cart.creation', cartCreation, null, 'ecommerce']);
    };

    /**
     * Complete 'cart.creation' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idCart {String} cart ID
     * @private
     */
    var _updateCartCreation = function (idCart) {
        // Complete 'cart.creation' events if necessary
        var cartCreation;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            cartCreation = contextEcommerceObject[i]['cart.creation'] || {};
            if (cartCreation['j:cart']) {
                cartCreation['j:cart']['s:id'] = idCart;
            }
        }
    };

    /**
     * Generate 'cart.confirmation' event.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cart {Object} cart object
     * @private
     */
    var _setCartConfirmation = function (cart) {
        var cartConfirmation = {
            'j:cart': ATInternet.Utils.cloneSimpleObject(cart)
        };
        parent.plugins.exec('Event', 'set', ['cart.confirmation', cartConfirmation, null, 'ecommerce']);
    };

    /**
     * Complete 'cart.confirmation' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param cart {Object} cart object
     * @private
     */
    var _updateCartConfirmation = function (idTransaction, cart) {
        // Complete 'cart.confirmation' events if necessary
        var cartConfirmation;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            cartConfirmation = contextEcommerceObject[i]['cart.confirmation'] || {};
            if (cartConfirmation) {
                if (idTransaction) {
                    cartConfirmation['j:transaction'] = {
                        's:id': idTransaction
                    };
                }
                else if (cart && cartConfirmation['j:cart']) {
                    cartConfirmation['j:cart'] = ATInternet.Utils.completeFstLevelObj(cartConfirmation['j:cart'], cart, true);
                }
            }
        }
    };

    /**
     * Generate 'product.purchased' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param idCart {String} cart ID
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductPurchased = function (idTransaction, idCart, productsArray) {
        var products = productsArray || [];
        products.map(function (product, index) {
            if (index === 0) {
                parent.plugins.exec('Event', 'set', ['product.purchased', {
                    'j:transaction': {
                        's:id': idTransaction
                    },
                    'j:cart': {
                        's:id': idCart
                    },
                    'j:product': product
                }, null, 'ecommerce']);
            }
            else {
                parent.plugins.exec('Event', 'add', ['product.purchased', {
                    'j:transaction': {
                        's:id': idTransaction
                    },
                    'j:cart': {
                        's:id': idCart
                    },
                    'j:product': product
                }, 'ecommerce']);
            }
        });
    };

    /**
     * Complete 'product.purchased' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param idCart {String} cart ID
     * @private
     */
    var _updateProductPurchased = function (idTransaction, idCart) {
        // Complete 'product.purchased' events if necessary
        var productPurchased;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            productPurchased = contextEcommerceObject[i]['product.purchased'] || {};
            if (idTransaction && productPurchased['j:transaction']) {
                productPurchased['j:transaction']['s:id'] = idTransaction;
            }
            else if (idCart && productPurchased['j:cart']) {
                productPurchased['j:cart']['s:id'] = idCart;
            }
        }
    };

    /**
     * Get full page label
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param tagObject {Object} tag object
     * @returns string {String} Click name completed with chapters from tag object
     * @private
     */
    var _getFullName = function (tagObject) {
        var name = tagObject['name'];
        parent['exec']('Utils', 'manageChapters', [tagObject, 'chapter', 3], function (data) {
            name = data + (name ? name : '');
        });
        return name;
    };

    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tags to manage ecommerce sending.
     * @name ecommerce
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayPageProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.addProduct.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.addProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.removeProduct.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.removeProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayCart.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayCart.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.updateCart.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.deliveryCheckout.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.deliveryCheckout.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.paymentCheckout.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.paymentCheckout.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.discount.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.transaction.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.payment.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.customer.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.products.set}
     * @property {function} reset Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.reset}
     * @public
     */
    parent.ecommerce = {
        displayProduct: {},
        displayPageProduct: {},
        addProduct: {},
        removeProduct: {},
        displayCart: {},
        updateCart: {},
        deliveryCheckout: {},
        paymentCheckout: {},
        transactionConfirmation: {}
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Reset ecommerce context.
     * @alias ecommerce.reset
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @example
     * <pre><code class="javascript">tag.ecommerce.reset();
     * </code></pre>
     * @public
     */
    parent.ecommerce.reset = function () {
        parent.plugins.exec('Event', 'reset', ['ecommerce']);
    };

    /* ---------------------------------- Type product.display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product display (helper).
     * @alias ecommerce.displayProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * @example
     * <pre><code class="javascript">tag.ecommerce.displayProduct.products.set([{
                    "id": "7",
                    "variant": "1",
                    "name": "Robe en mousseline imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 1,
                    "priceTaxIncluded": 19.68,
                    "priceTaxFree": 16.4,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes d'été"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product = {};
                var products = [];
                tagObject.map(function (tagProduct) {
                    _setValueFromKey(tagProduct, 's:id', 'id', product);
                    _setValueFromKey(tagProduct, 's:variant', 'variant', product);
                    _setValueFromKey(tagProduct, 's:name', 'name', product);
                    _setValueFromKey(tagProduct, 's:brand', 'brand', product);
                    _setValueFromKey(tagProduct, 'b:discount', 'discount', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxIncluded', 'priceTaxIncluded', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxFree', 'priceTaxFree', product);
                    _setValueFromKey(tagProduct, 's:currency', 'currency', product);
                    _setValueFromKey(tagProduct, 'b:stock', 'stock', product);
                    _setValueFromKey(tagProduct, 's:category1', 'category1', product);
                    _setValueFromKey(tagProduct, 's:category2', 'category2', product);
                    _setValueFromKey(tagProduct, 's:category3', 'category3', product);
                    _setValueFromKey(tagProduct, 's:category4', 'category4', product);
                    _setValueFromKey(tagProduct, 's:category5', 'category5', product);
                    _setValueFromKey(tagProduct, 's:category6', 'category6', product);
                    products.push(product);
                    product = {};
                });
                _setProductDisplay(products);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'product.display',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.page_display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product page display (helper).
     * @alias ecommerce.displayPageProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayPageProduct.products.set([{
                    "id": "3",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 31.2,
                    "priceTaxFree": 26,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes décontractées"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayPageProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product = {};
                var products = [];
                tagObject.map(function (tagProduct) {
                    _setValueFromKey(tagProduct, 's:id', 'id', product);
                    _setValueFromKey(tagProduct, 's:variant', 'variant', product);
                    _setValueFromKey(tagProduct, 's:name', 'name', product);
                    _setValueFromKey(tagProduct, 's:brand', 'brand', product);
                    _setValueFromKey(tagProduct, 'b:discount', 'discount', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxIncluded', 'priceTaxIncluded', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxFree', 'priceTaxFree', product);
                    _setValueFromKey(tagProduct, 's:currency', 'currency', product);
                    _setValueFromKey(tagProduct, 'b:stock', 'stock', product);
                    _setValueFromKey(tagProduct, 's:category1', 'category1', product);
                    _setValueFromKey(tagProduct, 's:category2', 'category2', product);
                    _setValueFromKey(tagProduct, 's:category3', 'category3', product);
                    _setValueFromKey(tagProduct, 's:category4', 'category4', product);
                    _setValueFromKey(tagProduct, 's:category5', 'category5', product);
                    _setValueFromKey(tagProduct, 's:category6', 'category6', product);
                    products.push(product);
                    product = {};
                });
                _setProductPageDisplay(products);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processViewedProducts(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'product.page_display',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.add_to_cart ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product add (helper).
     * @alias ecommerce.addProduct.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.addProduct.cart.set({"id": "34"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.addProduct.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var addProduct = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', addProduct['j:cart']);
                parent.plugins.exec('Event', 'set', ['product.add_to_cart', addProduct['j:cart'], 'j:cart', 'ecommerce']);
                _updateCartCreation(addProduct['j:cart']['s:id']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'product.add_to_cart',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product add (helper).
     * @alias ecommerce.addProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.addProduct.products.set([{
                    "id": "3",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 31.2,
                    "priceTaxFree": 26,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes décontractées",
                    "quantity": 1,
                    "cartcreation": 1
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.addProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product = {};
                var products = [];
                var isCartCreation = false;
                var cart = {
                    idCart: _getCartFromType('product.add_to_cart')['s:id'],
                    currency: '',
                    turnoverTaxIncluded: 0,
                    turnoverTaxFree: 0,
                    quantity: 0,
                    nbDistinctProduct: 0
                };
                tagObject.map(function (tagProduct) {
                    _setValueFromKey(tagProduct, 's:id', 'id', product);
                    _setValueFromKey(tagProduct, 's:variant', 'variant', product);
                    _setValueFromKey(tagProduct, 's:name', 'name', product);
                    _setValueFromKey(tagProduct, 's:brand', 'brand', product);
                    _setValueFromKey(tagProduct, 'b:discount', 'discount', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxIncluded', 'priceTaxIncluded', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxFree', 'priceTaxFree', product);
                    _setValueFromKey(tagProduct, 's:currency', 'currency', product);
                    _setValueFromKey(tagProduct, 'b:stock', 'stock', product);
                    _setValueFromKey(tagProduct, 'n:quantity', 'quantity', product);
                    _setValueFromKey(tagProduct, 's:category1', 'category1', product);
                    _setValueFromKey(tagProduct, 's:category2', 'category2', product);
                    _setValueFromKey(tagProduct, 's:category3', 'category3', product);
                    _setValueFromKey(tagProduct, 's:category4', 'category4', product);
                    _setValueFromKey(tagProduct, 's:category5', 'category5', product);
                    _setValueFromKey(tagProduct, 's:category6', 'category6', product);
                    _setValueFromKey(tagProduct, 'b:cartcreation', 'cartcreation', product);
                    cart.currency = tagProduct['currency'];
                    cart.turnoverTaxIncluded += (Number(tagProduct['priceTaxIncluded']) || 0) * (Number(tagProduct['quantity']) || 0);
                    cart.turnoverTaxFree += (Number(tagProduct['priceTaxFree']) || 0) * (Number(tagProduct['quantity']) || 0);
                    cart.quantity += Number(tagProduct['quantity']) || 0;
                    cart.nbDistinctProduct += 1;
                    if (Boolean(Number(tagProduct['cartcreation']))) {
                        isCartCreation = true;
                    }
                    products.push(product);
                    product = {};
                });
                _setProductAddToCart(products, cart.idCart);
                isCartCreation && _setCartCreation(cart);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'product.add_to_cart',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.remove_from_cart ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product remove (helper).
     * @alias ecommerce.removeProduct.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.removeProduct.cart.set({"id": "34"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.removeProduct.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var removeProduct = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', removeProduct['j:cart']);
                parent.plugins.exec('Event', 'set', ['product.remove_from_cart', removeProduct['j:cart'], 'j:cart', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'product.remove_from_cart',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product remove (helper).
     * @alias ecommerce.removeProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.removeProduct.products.set([{
                    "id": "4",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 61.19,
                    "priceTaxFree": 50.99,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes de soirée",
                    "quantity": 1
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.removeProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product = {};
                var products = [];
                var idCart = _getCartFromType('product.remove_from_cart')['s:id'];
                tagObject.map(function (tagProduct) {
                    _setValueFromKey(tagProduct, 's:id', 'id', product);
                    _setValueFromKey(tagProduct, 's:variant', 'variant', product);
                    _setValueFromKey(tagProduct, 's:name', 'name', product);
                    _setValueFromKey(tagProduct, 's:brand', 'brand', product);
                    _setValueFromKey(tagProduct, 'b:discount', 'discount', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxIncluded', 'priceTaxIncluded', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxFree', 'priceTaxFree', product);
                    _setValueFromKey(tagProduct, 's:currency', 'currency', product);
                    _setValueFromKey(tagProduct, 'b:stock', 'stock', product);
                    _setValueFromKey(tagProduct, 'n:quantity', 'quantity', product);
                    _setValueFromKey(tagProduct, 's:category1', 'category1', product);
                    _setValueFromKey(tagProduct, 's:category2', 'category2', product);
                    _setValueFromKey(tagProduct, 's:category3', 'category3', product);
                    _setValueFromKey(tagProduct, 's:category4', 'category4', product);
                    _setValueFromKey(tagProduct, 's:category5', 'category5', product);
                    _setValueFromKey(tagProduct, 's:category6', 'category6', product);
                    products.push(product);
                    product = {};
                });
                _setProductRemoveFromCart(products, idCart);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'product.remove_from_cart',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart display (helper).
     * @alias ecommerce.displayCart.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayCart.cart.set({
                    "id": "53",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 10.81,
                    "turnoverTaxFree": 9.01,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayCart.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var displayCart = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', displayCart['j:cart']);
                _setValueFromKey(tagObject, 's:currency', 'currency', displayCart['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxIncluded', 'turnoverTaxIncluded', displayCart['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxFree', 'turnoverTaxFree', displayCart['j:cart']);
                _setValueFromKey(tagObject, 'n:quantity', 'quantity', displayCart['j:cart']);
                _setValueFromKey(tagObject, 'n:nbDistinctProduct', 'nbDistinctProduct', displayCart['j:cart']);
                parent.plugins.exec('Event', 'set', ['cart.display', displayCart['j:cart'], 'j:cart', 'ecommerce']);
                if (_config.autoSalesTracker) {
                    _processCart(tagObject, true);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.display',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart display (helper).
     * @alias ecommerce.displayCart.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayCart.products.set([{
                    "id": "1",
                    "name": "T-shirt délavé à manches courtes",
                    "priceTaxIncluded": 10.81,
                    "priceTaxFree": 9.01,
                    "quantity": 1,
                    "category1": "Femmes",
                    "category2": "Tops",
                    "category3": "T-shirts",
                    "category4": "Manches Courtes",
                    "category5": "Cols Ronds",
                    "category6": "Coton"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayCart.products = {
        set: function (tagObject) {
            // SalesTracker
            if (_config.autoSalesTracker) {
                if (tagObject instanceof Array) {
                    _processCartProducts(tagObject);
                }
                else if (tagObject) {
                    /* @if debug */
                    parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                        type: 'cart.display',
                        data: tagObject,
                        origin: 'ecommerce'
                    });
                    /* @endif */
                }
            }
        }
    };

    /* ---------------------------------- Type cart.update ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart update (helper).
     * @alias ecommerce.updateCart.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.updateCart.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 62.4,
                    "turnoverTaxFree": 52,
                    "quantity": 2
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.updateCart.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var updateCart = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', updateCart['j:cart']);
                _setValueFromKey(tagObject, 's:currency', 'currency', updateCart['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxIncluded', 'turnoverTaxIncluded', updateCart['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxFree', 'turnoverTaxFree', updateCart['j:cart']);
                _setValueFromKey(tagObject, 'n:quantity', 'quantity', updateCart['j:cart']);
                _setValueFromKey(tagObject, 'n:nbDistinctProduct', 'nbDistinctProduct', updateCart['j:cart']);
                parent.plugins.exec('Event', 'set', ['cart.update', updateCart['j:cart'], 'j:cart', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.update',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.delivery ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for delivery checkout (helper).
     * @alias ecommerce.deliveryCheckout.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.deliveryCheckout.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.deliveryCheckout.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var deliveryCheckout = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', deliveryCheckout['j:cart']);
                _setValueFromKey(tagObject, 's:currency', 'currency', deliveryCheckout['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxIncluded', 'turnoverTaxIncluded', deliveryCheckout['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxFree', 'turnoverTaxFree', deliveryCheckout['j:cart']);
                _setValueFromKey(tagObject, 'n:quantity', 'quantity', deliveryCheckout['j:cart']);
                _setValueFromKey(tagObject, 'n:nbDistinctProduct', 'nbDistinctProduct', deliveryCheckout['j:cart']);
                parent.plugins.exec('Event', 'set', ['cart.delivery', deliveryCheckout['j:cart'], 'j:cart', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.delivery',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for delivery checkout (helper).
     * @alias ecommerce.deliveryCheckout.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.deliveryCheckout.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.deliveryCheckout.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var deliveryCheckout = {
                    'j:shipping': {}
                };
                _setValueFromKey(tagObject, 's:delivery', 'delivery', deliveryCheckout['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxIncluded', 'costTaxIncluded', deliveryCheckout['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxFree', 'costTaxFree', deliveryCheckout['j:shipping']);
                parent.plugins.exec('Event', 'set', ['cart.delivery', deliveryCheckout['j:shipping'], 'j:shipping', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.delivery',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.payment ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for payment checkout (helper).
     * @alias ecommerce.paymentCheckout.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.paymentCheckout.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.paymentCheckout.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var paymentCheckout = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', paymentCheckout['j:cart']);
                _setValueFromKey(tagObject, 's:currency', 'currency', paymentCheckout['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxIncluded', 'turnoverTaxIncluded', paymentCheckout['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxFree', 'turnoverTaxFree', paymentCheckout['j:cart']);
                _setValueFromKey(tagObject, 'n:quantity', 'quantity', paymentCheckout['j:cart']);
                _setValueFromKey(tagObject, 'n:nbDistinctProduct', 'nbDistinctProduct', paymentCheckout['j:cart']);
                parent.plugins.exec('Event', 'set', ['cart.payment', paymentCheckout['j:cart'], 'j:cart', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.payment',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for payment checkout (helper).
     * @alias ecommerce.paymentCheckout.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.paymentCheckout.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.paymentCheckout.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var paymentCheckout = {
                    'j:shipping': {}
                };
                _setValueFromKey(tagObject, 's:delivery', 'delivery', paymentCheckout['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxIncluded', 'costTaxIncluded', paymentCheckout['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxFree', 'costTaxFree', paymentCheckout['j:shipping']);
                parent.plugins.exec('Event', 'set', ['cart.payment', paymentCheckout['j:shipping'], 'j:shipping', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'cart.payment',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type transaction.confirmation ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "creation_utc": 1514973161
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {
                    'j:cart': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 's:currency', 'currency', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxIncluded', 'turnoverTaxIncluded', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 'f:turnoverTaxFree', 'turnoverTaxFree', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 'd:creation_utc', 'creation_utc', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 'n:quantity', 'quantity', transactionConfirmation['j:cart']);
                _setValueFromKey(tagObject, 'n:nbDistinctProduct', 'nbDistinctProduct', transactionConfirmation['j:cart']);
                // Ecommerce
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['j:cart'], 'j:cart', 'ecommerce']);
                _setCartConfirmation(transactionConfirmation['j:cart']);
                _updateProductPurchased(null, transactionConfirmation['j:cart']['s:id']);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCart(tagObject, false);
                    _processOrder(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.discount.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.discount.set(["DQQYRZSJ", "UN1ENE27"]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.discount = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var transactionConfirmation = {
                    'a:s:promotionalCode': tagObject
                };
                // Ecommerce
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['a:s:promotionalCode'], 'a:s:promotionalCode', 'ecommerce']);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processPromotionalCode(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.transaction.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.transaction.set({"id": "27"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.transaction = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {
                    'j:transaction': {}
                };
                _setValueFromKey(tagObject, 's:id', 'id', transactionConfirmation['j:transaction']);
                // Ecommerce
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['j:transaction'], 'j:transaction', 'ecommerce']);
                _updateCartConfirmation(transactionConfirmation['j:transaction']['s:id'], null);
                _updateProductPurchased(transactionConfirmation['j:transaction']['s:id'], null);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processTransaction(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {
                    'j:shipping': {}
                };
                _setValueFromKey(tagObject, 's:delivery', 'delivery', transactionConfirmation['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxIncluded', 'costTaxIncluded', transactionConfirmation['j:shipping']);
                _setValueFromKey(tagObject, 'f:costTaxFree', 'costTaxFree', transactionConfirmation['j:shipping']);
                // Ecommerce
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['j:shipping'], 'j:shipping', 'ecommerce']);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processShipping(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.payment.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.payment.set({"mode": "Chèque"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.payment = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {
                    'j:payment': {}
                };
                _setValueFromKey(tagObject, 's:mode', 'mode', transactionConfirmation['j:payment']);
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['j:payment'], 'j:payment', 'ecommerce']);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.customer.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.customer.set({
                    "new": 0
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.customer = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {
                    'j:customer': {}
                };
                _setValueFromKey(tagObject, 'b:new', 'new', transactionConfirmation['j:customer']);
                // Ecommerce
                parent.plugins.exec('Event', 'set', ['transaction.confirmation', transactionConfirmation['j:customer'], 'j:customer', 'ecommerce']);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCustomer(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an object', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.products.set([{
                    "id": "2",
                    "variant": "2",
                    "name": "Chemisier",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 32.4,
                    "priceTaxFree": 27,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Tops",
                    "category4": "Chemisiers"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product = {};
                var products = [];
                var idCart = _getCartFromType('transaction.confirmation')['s:id'];
                var idTransaction = _getTransactionIdFromType('transaction.confirmation');
                tagObject.map(function (tagProduct) {
                    _setValueFromKey(tagProduct, 's:id', 'id', product);
                    _setValueFromKey(tagProduct, 's:variant', 'variant', product);
                    _setValueFromKey(tagProduct, 's:name', 'name', product);
                    _setValueFromKey(tagProduct, 's:brand', 'brand', product);
                    _setValueFromKey(tagProduct, 'b:discount', 'discount', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxIncluded', 'priceTaxIncluded', product);
                    _setValueFromKey(tagProduct, 'f:priceTaxFree', 'priceTaxFree', product);
                    _setValueFromKey(tagProduct, 's:currency', 'currency', product);
                    _setValueFromKey(tagProduct, 'b:stock', 'stock', product);
                    _setValueFromKey(tagProduct, 'n:quantity', 'quantity', product);
                    _setValueFromKey(tagProduct, 's:category1', 'category1', product);
                    _setValueFromKey(tagProduct, 's:category2', 'category2', product);
                    _setValueFromKey(tagProduct, 's:category3', 'category3', product);
                    _setValueFromKey(tagProduct, 's:category4', 'category4', product);
                    _setValueFromKey(tagProduct, 's:category5', 'category5', product);
                    _setValueFromKey(tagProduct, 's:category6', 'category6', product);
                    products.push(product);
                    product = {};
                });
                // Create 'product.purchased' events
                _setProductPurchased(idTransaction, idCart, products);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCartProducts(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug('Event:event:set:Error', 'ERROR', 'Not an array', {
                    type: 'transaction.confirmation',
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * Launch plugin when all dependencies are loaded.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @private
     */
    var _init = function () {
        _domain = _config.defaultCollectSubdomain + _config.defaultCollectDomains[0];
        if (_config.collectDomain) {
            _domain = String(_config.collectDomain);
        }
        else {
            var collectDomain = '';
            var log = parent.getConfig('logSSL') || parent.getConfig('log');
            var domain = parent.getConfig('domain');
            if (log && domain) {
                collectDomain = log + '.' + domain;
            }
            else {
                collectDomain = parent.getConfig('collectDomainSSL') || parent.getConfig('collectDomain');
            }
            for (var i = 0; i < _config.defaultCollectDomains.length; i++) {
                if (collectDomain.indexOf(_config.defaultCollectDomains[i]) > -1) {
                    _domain = _config.defaultCollectSubdomain + _config.defaultCollectDomains[i];
                    break;
                }
            }
        }
    };

    _init();

    /* ---------------------------------- onDispatch ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Will be called by tracker.dispatch if any event has been set.
     * @alias ecommerce.onDispatch
     * @memberof! ATInternet.Tracker.Tag#
     * @param callback {function} Callback to execute
     * @function
     * @private
     */
    parent.ecommerce.onDispatch = function (callback) {
        parent.plugins.exec('Event', 'onDispatch', [callback, 'ecommerce', _domain]);
    };

    // For unit tests on private elements !!!
    /* @if test */
    var _this = this;
    _this._isObject = _isObject;
    _this._setValueFromKey = _setValueFromKey;
    _this._processCart = _processCart;
    _this._processOrder = _processOrder;
    _this._processPromotionalCode = _processPromotionalCode;
    _this._processTransaction = _processTransaction;
    _this._processShipping = _processShipping;
    _this._processCustomer = _processCustomer;
    _this._processProductCategories = _processProductCategories;
    _this._processCartProducts = _processCartProducts;
    _this._processViewedProducts = _processViewedProducts;
    _this._getCartFromType = _getCartFromType;
    _this._getTransactionIdFromType = _getTransactionIdFromType;
    _this._setProductDisplay = _setProductDisplay;
    _this._setProductClick = _setProductClick;
    _this._setProductPageDisplay = _setProductPageDisplay;
    _this._setProductAddToCart = _setProductAddToCart;
    _this._setProductRemoveFromCart = _setProductRemoveFromCart;
    _this._setCartCreation = _setCartCreation;
    _this._updateCartCreation = _updateCartCreation;
    _this._setCartConfirmation = _setCartConfirmation;
    _this._updateCartConfirmation = _updateCartConfirmation;
    _this._setProductPurchased = _setProductPurchased;
    _this._updateProductPurchased = _updateProductPurchased;
    _this._getFullName = _getFullName;
    _this._init = _init;
    _this._domain = _domain;
    /* @endif */

};
window['ATInternet']['Tracker']['addPlugin']('Ecommerce');