Source: Ecommerce/ecommerce.js

/**
 * @class
 * @classdesc Plugin used to manage ecommerce event sending.
 * @name Ecommerce
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param tag {object} Instance of the Tag used
 * @public
 */
ATInternet.Tracker.Plugins.Ecommerce = function (tag) {

    'use strict';

    var _utility = null;
    var _salesInsights = null;

    /* ---------------------------------- Utility properties ------------------------------------------------- */

    // Types of SalesInsights events
    var Types = {
        product: {
            awaiting_payment: 'product.awaiting_payment',
            add_to_cart: 'product.add_to_cart',
            display: 'product.display',
            page_display: 'product.page_display',
            purchased: 'product.purchased',
            remove_from_cart: 'product.remove_from_cart'
        },
        cart: {
            awaiting_payment: 'cart.awaiting_payment',
            creation: 'cart.creation',
            delivery: 'cart.delivery',
            display: 'cart.display',
            payment: 'cart.payment',
            update: 'cart.update'
        },
        transaction: {
            confirmation: 'transaction.confirmation'
        }
    };

    //  Main keys of SalesInsights objects
    var Keys = {
        product: 'product',
        cart: 'cart',
        shipping: 'shipping',
        payment: 'payment',
        transaction: 'transaction'
    };

    //  Property keys of SalesInsights objects
    var Properties = {
        product: {
            id: 'id',
            variant: 'variant',
            $: '$',
            brand: 'brand',
            discount: 'discount',
            pricetaxincluded: 'pricetaxincluded',
            pricetaxfree: 'pricetaxfree',
            currency: 'currency',
            stock: 'stock',
            quantity: 'quantity',
            category1: 'category1',
            category2: 'category2',
            category3: 'category3',
            category4: 'category4',
            category5: 'category5',
            category6: 'category6',
            cartcreation: 'cartcreation'
        },
        cart: {
            id: 'id',
            version: 'version',
            currency: 'currency',
            turnovertaxincluded: 'turnovertaxincluded',
            turnovertaxfree: 'turnovertaxfree',
            quantity: 'quantity',
            nbdistinctproduct: 'nbdistinctproduct',
            creation_utc: 'creation_utc'
        },
        shipping: {
            delivery: 'delivery',
            costtaxincluded: 'costtaxincluded',
            costtaxfree: 'costtaxfree'
        },
        payment: {
            mode: 'mode'
        },
        customer: {
            'new': 'new'
        },
        transaction: {
            id: 'id',
            promocode: 'promocode',
            firstpurchase: 'firstpurchase'
        }
    };

    // Debug object error
    var _error = {
        level: 'ERROR',
        messageArray: 'Not an array',
        messageObject: 'Not an object'
    };

    var _debug = {
        level: 'DEBUG',
        messageEnd: 'method ended',
        messageCall: 'method called'
    };

    var _origin = 'ecommerce';

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

    /**
     * Object used to manage utility methods
     * @name Utility
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @inner
     * @type {function}
     * @property {function} objectKeysToLowercase Tag helper, see details here {@link ATInternet.Tracker.Tag#Utility.objectKeysToLowercase}
     * @property {function} arrayObjectKeysToLowercase Tag helper, see details here {@link ATInternet.Tracker.Tag#Utility.arrayObjectKeysToLowercase}
     * @private
     */
    var Utility = function () {

        /**
         * Change tag object properties to lowercase and 'name' keys to '$'
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param tagObject {object} Object from tag
         * @return {object}
         * @private
         */
        this.objectKeysFromLegacyToNewFormat = function (tagObject) {
            var tagObjectUtil = {};
            var newKey;
            for (var tagKey in tagObject) {
                if (tagObject.hasOwnProperty(tagKey)) {
                    newKey = tagKey.toLowerCase();
                    newKey = ((newKey === 'name') ? '$' : newKey);
                    tagObjectUtil[newKey] = tagObject[tagKey];
                }
            }
            return tagObjectUtil;
        };

        /**
         * Change array tag object properties to lowercase and 'name' keys to '$'
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param tagArray {Array} Array from tag
         * @return {Array}
         * @private
         */
        this.arrayObjectKeysFromLegacyToNewFormat = function (tagArray) {
            var tagArrayUtil = [];
            for (var i = 0; i < tagArray.length; i++) {
                tagArrayUtil.push(_utility.objectKeysFromLegacyToNewFormat(tagArray[i]));
            }
            return tagArrayUtil;
        };

    };

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

    /**
     * Object used to manage SalesInsights methods
     * @name SalesInsights
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @inner
     * @type {function}
     * @property {function} initCartWithId Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.initCartWithId}
     * @property {function} getObjectValueFromType Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.getObjectValueFromType}
     * @property {function} setEventFromProductsAndCart Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setEventFromProductsAndCart}
     * @property {function} setProductAwaitingPayment Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductAwaitingPayment}
     * @property {function} updateProductAwaitingPayment Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.updateProductAwaitingPayment}
     * @property {function} setProductDisplay Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductDisplay}
     * @property {function} setProductPageDisplay Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductPageDisplay}
     * @property {function} setProductAddToCart Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductAddToCart}
     * @property {function} setProductRemoveFromCart Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductRemoveFromCart}
     * @property {function} setCartCreation Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setCartCreation}
     * @property {function} updateCartCreation Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.updateCartCreation}
     * @property {function} setProductPurchased Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.setProductPurchased}
     * @property {function} updateProductPurchased Tag helper, see details here {@link ATInternet.Tracker.Tag#SalesInsights.updateProductPurchased}
     * @private
     */
    var SalesInsights = function () {

        /**
         * Init cart object with cart ID
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param id {String} cart ID
         * @return {object}
         * @private
         */
        this.initCartWithId = function (id) {
            var cart = {};
            cart[Properties.cart.id] = id;
            cart[Properties.cart.currency] = "";
            cart[Properties.cart.turnovertaxincluded] = 0;
            cart[Properties.cart.turnovertaxfree] = 0;
            cart[Properties.cart.quantity] = 0;
            cart[Properties.cart.nbdistinctproduct] = 0;
            return cart;
        };

        /**
         * Get object from type
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param type {String} Type name
         * @param key {String} Key name ('transaction', 'cart', etc.)
         * @return {object}
         * @private
         */
        this.getObjectValueFromType = function (type, key) {
            var typeObject;
            var transaction = {};
            var contextEcommerceObject = tag.getContext(_origin) || [];
            for (var i = 0; i < contextEcommerceObject.length; i++) {
                typeObject = contextEcommerceObject[i][type] || {};
                if (typeObject[key]) {
                    transaction = typeObject[key];
                    break;
                }
            }
            return transaction;
        };

        /**
         * Generate events from products array and cart object
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param type {string} Event type
         * @param productsArray {Array} Products array
         * @param cart {object} cart object
         * @private
         */
        this.setEventFromProductsAndCart = function (type, productsArray, cart) {
            var products = productsArray || [];
            var addObject = {};
            for (var i = 0; i < products.length; i++) {
                if (i === 0) {
                    tag.event.set(type, products[i], Keys.product, _origin);
                    if (cart && Object.keys(cart).length !== 0) {
                        tag.event.set(type, cart, Keys.cart, _origin);
                    }
                } else {
                    addObject[Keys.product] = products[i];
                    if (cart && Object.keys(cart).length !== 0) {
                        addObject[Keys.cart] = cart;
                    }
                    tag.event.add(type, addObject, _origin);
                }
                addObject = {};
            }
        };

        /**
         * Generate 'product.awaiting_payment' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @param cart {object} cart object
         * @private
         */
        this.setProductAwaitingPayment = function (productsArray, cart) {
            this.setEventFromProductsAndCart(Types.product.awaiting_payment, productsArray, cart);
        };

        /**
         * Set version to ProductAwaitingPayment from CartAwaitingPayment cart
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param cart {object} cart object
         * @private
         */
        this.updateProductAwaitingPayment = function (cart) {
            var idCart = cart ? cart[Properties.cart.id] : '';
            var versionCart = cart ? cart[Properties.cart.version] : '';
            if (idCart && versionCart) {
                // Complete 'product.awaiting' events
                var productAwaiting;
                var contextEcommerceObject = tag.getContext(_origin) || [];
                for (var i = 0; i < contextEcommerceObject.length; i++) {
                    productAwaiting = contextEcommerceObject[i][Types.product.awaiting_payment];
                    if (productAwaiting) {
                        productAwaiting[Keys.cart] = {};
                        productAwaiting[Keys.cart][Properties.cart.id] = idCart;
                        productAwaiting[Keys.cart][Properties.cart.version] = versionCart;
                        contextEcommerceObject[i][Types.product.awaiting_payment] = productAwaiting;
                    }
                }
            }
        };

        /**
         * Generate 'product.display' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @private
         */
        this.setProductDisplay = function (productsArray) {
            this.setEventFromProductsAndCart(Types.product.display, productsArray, null);
        };

        /**
         * Generate 'product.page_display' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @private
         */
        this.setProductPageDisplay = function (productsArray) {
            this.setEventFromProductsAndCart(Types.product.page_display, productsArray, null);
        };

        /**
         * Generate 'product.add_to_cart' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @param cart {object} cart object
         * @private
         */
        this.setProductAddToCart = function (productsArray, cart) {
            this.setEventFromProductsAndCart(Types.product.add_to_cart, productsArray, cart);
        };

        /**
         * Generate 'product.remove_from_cart' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @param cart {object} cart object
         * @private
         */
        this.setProductRemoveFromCart = function (productsArray, cart) {
            this.setEventFromProductsAndCart(Types.product.remove_from_cart, productsArray, cart);
        };

        /**
         * Generate 'cart.creation' event
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param cart {object} cart
         * @private
         */
        this.setCartCreation = function (cart) {
            var cartCreation = {};
            cartCreation[Keys.cart] = cart;
            tag.event.set(Types.cart.creation, cartCreation, null, _origin);
        };

        /**
         * Complete 'cart.creation' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param cart {object} cart object
         * @private
         */
        this.updateCartCreation = function (cart) {
            var idCart = cart ? cart[Properties.cart.id] : '';
            if (idCart) {
                // Complete 'cart.creation' events if necessary
                var cartCreation;
                var contextEcommerceObject = tag.getContext(_origin) || [];
                for (var i = 0; i < contextEcommerceObject.length; i++) {
                    cartCreation = contextEcommerceObject[i][Types.cart.creation];
                    if (cartCreation && cartCreation[Keys.cart]) {
                        cartCreation[Keys.cart][Properties.cart.id] = idCart;
                        contextEcommerceObject[i][Types.cart.creation] = cartCreation;
                    }
                }
            }
        };

        /**
         * Generate 'product.purchased' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param productsArray {Array} Products array
         * @param transaction {object} transaction object
         * @param cart {object} cart object
         * @private
         */
        this.setProductPurchased = function (productsArray, transaction, cart) {
            var products = productsArray || [];
            var idTransaction = transaction ? transaction[Properties.transaction.id] : '';
            var idCart = cart ? cart[Properties.cart.id] : '';
            var eventObject = {};
            for (var i = 0; i < products.length; i++) {
                eventObject[Keys.transaction] = {};
                eventObject[Keys.transaction][Properties.transaction.id] = idTransaction;
                eventObject[Keys.cart] = {};
                eventObject[Keys.cart][Properties.cart.id] = idCart;
                eventObject[Keys.product] = products[i];
                if (i === 0) {
                    tag.event.set(Types.product.purchased, eventObject, null, _origin);
                } else {
                    tag.event.add(Types.product.purchased, eventObject, _origin);
                }
                eventObject = {};
            }
        };

        /**
         * Complete 'product.purchased' events
         * @memberof ATInternet.Tracker.Plugins.Ecommerce#
         * @function
         * @param transaction {object} transaction object
         * @param cart {object} cart object
         * @private
         */
        this.updateProductPurchased = function (transaction, cart) {
            // Complete 'product.purchased' events if necessary
            var idTransaction = transaction ? transaction[Properties.transaction.id] : '';
            var idCart = cart ? cart[Properties.cart.id] : '';
            var productPurchased;
            var contextEcommerceObject = tag.getContext(_origin) || [];
            for (var i = 0; i < contextEcommerceObject.length; i++) {
                productPurchased = contextEcommerceObject[i][Types.product.purchased];
                if (productPurchased) {
                    if (idTransaction && productPurchased[Keys.transaction]) {
                        productPurchased[Keys.transaction][Properties.transaction.id] = idTransaction;
                    } else if (idCart && productPurchased[Keys.cart]) {
                        productPurchased[Keys.cart][Properties.cart.id] = idCart;
                    }
                    contextEcommerceObject[i][Types.product.purchased] = productPurchased;
                }
            }
        };

    };

    /* ---------------------------------- Ecommerce helpers ------------------------------------------------- */

    /**
     * [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.cartAwaitingPayment.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.cartAwaitingPayment.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.cartAwaitingPayment.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.cartAwaitingPayment.payment.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.cartAwaitingPayment.transaction.set}
     * @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}
     * @deprecated {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
     */
    tag.ecommerce = {
        cartAwaitingPayment: {},
        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
     */
    tag.ecommerce.reset = function () {
        tag.event.reset(_origin);
        /* @if debug */
        tag.debug('Ecommerce:ecommerce:reset', _debug.level, _debug.messageCall, {
            'origin': _origin
        });
        /* @endif */
    };

    /* ---------------------------------- Type cart.awaiting_payment ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart object on cart awaiting payment (helper).
     * @alias ecommerce.cartAwaitingPayment.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.cartAwaitingPayment.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnovertaxincluded": 40.8,
                    "turnovertaxfree": 34,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    tag.ecommerce.cartAwaitingPayment.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var cartAwaitingPayment = {};
                cartAwaitingPayment[Keys.cart] = tagObject;

                // Add a cart version
                var uuid = ATInternet.Utils.uuid();
                cartAwaitingPayment[Keys.cart][Properties.cart.version] = uuid.v4().split('-')[0];

                _salesInsights.updateProductAwaitingPayment(cartAwaitingPayment[Keys.cart]);

                // Ecommerce
                tag.event.set(Types.cart.awaiting_payment, cartAwaitingPayment[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for products object on cart awaiting payment (helper).
     * @alias ecommerce.cartAwaitingPayment.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.cartAwaitingPayment.products.set([{
                    "id": "2",
                    "variant": "2",
                    "$": "Chemisier",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "pricetaxincluded": 32.4,
                    "pricetaxfree": 27,
                    "currency": "EUR",
                    "stock": 1,
                    "quantity": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Tops",
                    "category4": "Chemisiers"
                }]);
     * </code></pre>
     * @public
     */
    tag.ecommerce.cartAwaitingPayment.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = tagObject;
                var fullCart = _salesInsights.getObjectValueFromType(Types.cart.awaiting_payment, Keys.cart);
                var productCart = {};
                if (fullCart[Properties.cart.id]) {
                    productCart[Properties.cart.id] = fullCart[Properties.cart.id];
                }
                if (fullCart[Properties.cart.version]) {
                    productCart[Properties.cart.version] = fullCart[Properties.cart.version];
                }
                _salesInsights.setProductAwaitingPayment(products, productCart);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */

            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for shipping object on cart awaiting payment (helper).
     * @alias ecommerce.cartAwaitingPayment.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.cartAwaitingPayment.shipping.set({
                    "delivery": "My carrier",
                    "costtaxincluded": 8.4,
                    "costtaxfree": 7
                });
     * </code></pre>
     * @public
     */
    tag.ecommerce.cartAwaitingPayment.shipping = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var cartAwaitingPayment = {};
                cartAwaitingPayment[Keys.shipping] = tagObject;

                // Ecommerce
                tag.event.set(Types.cart.awaiting_payment, cartAwaitingPayment[Keys.shipping], Keys.shipping, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:shipping:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:shipping:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for payment object on cart awaiting payment (helper).
     * @alias ecommerce.cartAwaitingPayment.payment.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.cartAwaitingPayment.payment.set({"mode": "Chèque"});
     * </code></pre>
     * @public
     */
    tag.ecommerce.cartAwaitingPayment.payment = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var cartAwaitingPayment = {};
                cartAwaitingPayment[Keys.payment] = tagObject;

                // Ecommerce
                tag.event.set(Types.cart.awaiting_payment, cartAwaitingPayment[Keys.payment], Keys.payment, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:payment:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */

            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:payment:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction on cart awaiting payment (helper).
     * @alias ecommerce.cartAwaitingPayment.transaction.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.cartAwaitingPayment.transaction.set({"promocode": ["BIU4YTCR", "1WUY4TWX"], "firstpurchase": 0});
     * </code></pre>
     * @public
     */
    tag.ecommerce.cartAwaitingPayment.transaction = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var cartAwaitingPayment = {};
                cartAwaitingPayment[Keys.transaction] = tagObject;

                // Ecommerce
                tag.event.set(Types.cart.awaiting_payment, cartAwaitingPayment[Keys.transaction], Keys.transaction, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:transaction:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:cartAwaitingPayment:transaction:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- 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",
                    "$": "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
     */
    tag.ecommerce.displayProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = tagObject;
                _salesInsights.setProductDisplay(products);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayProduct:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */

            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayProduct:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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",
                    "$": "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
     */
    tag.ecommerce.displayPageProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = tagObject;
                _salesInsights.setProductPageDisplay(products);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayPageProduct:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayPageProduct:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.addProduct.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var addProduct = {};
                addProduct[Keys.cart] = tagObject;

                tag.event.set(Types.product.add_to_cart, addProduct[Keys.cart], Keys.cart, _origin);

                _salesInsights.updateCartCreation(addProduct[Keys.cart]);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:addProduct:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */

            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:addProduct:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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",
                    "$": "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
     */
    tag.ecommerce.addProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = tagObject;
                var isCartCreation = false;
                var idCart = _salesInsights.getObjectValueFromType(Types.product.add_to_cart, Keys.cart)[Properties.cart.id];
                var fullCart = _salesInsights.initCartWithId(idCart);

                for (var i = 0; i < products.length; i++) {

                    fullCart[Properties.cart.currency] = products[i][Properties.product.currency];
                    fullCart[Properties.cart.turnovertaxincluded] += (Number(products[i][Properties.product.pricetaxincluded]) || 0) * (Number(products[i][Properties.product.quantity]) || 0);
                    fullCart[Properties.cart.turnovertaxfree] += (Number(products[i][Properties.product.pricetaxfree]) || 0) * (Number(products[i][Properties.product.quantity]) || 0);
                    fullCart[Properties.cart.quantity] += Number(products[i][Properties.product.quantity]) || 0;
                    fullCart[Properties.cart.nbdistinctproduct] += 1;

                    if (Boolean(Number(products[i][Properties.product.cartcreation]))) {
                        isCartCreation = true;
                    }
                }
                var productCart = {};
                if (fullCart[Properties.cart.id]) {
                    productCart[Properties.cart.id] = fullCart[Properties.cart.id];
                }
                _salesInsights.setProductAddToCart(products, productCart);
                isCartCreation && _salesInsights.setCartCreation(fullCart);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:addProduct:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:addProduct:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.removeProduct.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var removeProduct = {};
                removeProduct[Keys.cart] = tagObject;

                tag.event.set(Types.product.remove_from_cart, removeProduct[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:removeProduct:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:removeProduct:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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",
                    "$": "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
     */
    tag.ecommerce.removeProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = tagObject;
                var fullCart = {};
                fullCart[Properties.cart.id] = _salesInsights.getObjectValueFromType(Types.product.remove_from_cart, Keys.cart)[Properties.cart.id];

                var productCart = {};
                if (fullCart[Properties.cart.id]) {
                    productCart[Properties.cart.id] = fullCart[Properties.cart.id];
                }
                _salesInsights.setProductRemoveFromCart(products, productCart);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:removeProduct:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:removeProduct:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.displayCart.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var displayCart = {};
                displayCart[Keys.cart] = tagObject;

                tag.event.set(Types.cart.display, displayCart[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayCart:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:displayCart:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     * @deprecated
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayCart.products.set([{
                    "id": "1",
                    "$": "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
     */
    tag.ecommerce.displayCart.products = {
        set: function (tagObject) {
        }
    };

    /* ---------------------------------- 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
     */
    tag.ecommerce.updateCart.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var updateCart = {};
                updateCart[Keys.cart] = tagObject;

                tag.event.set(Types.cart.update, updateCart[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:updateCart:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:updateCart:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.deliveryCheckout.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var deliveryCheckout = {};
                deliveryCheckout[Keys.cart] = tagObject;

                tag.event.set(Types.cart.delivery, deliveryCheckout[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:deliveryCheckout:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:deliveryCheckout:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.deliveryCheckout.shipping = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var deliveryCheckout = {};
                deliveryCheckout[Keys.shipping] = tagObject;

                tag.event.set(Types.cart.delivery, deliveryCheckout[Keys.shipping], Keys.shipping, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:deliveryCheckout:shipping:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:deliveryCheckout:shipping:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.paymentCheckout.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var paymentCheckout = {};
                paymentCheckout[Keys.cart] = tagObject;

                tag.event.set(Types.cart.payment, paymentCheckout[Keys.cart], Keys.cart, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:paymentCheckout:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:paymentCheckout:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.paymentCheckout.shipping = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var paymentCheckout = {};
                paymentCheckout[Keys.shipping] = tagObject;

                tag.event.set(Types.cart.payment, paymentCheckout[Keys.shipping], Keys.shipping, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:paymentCheckout:shipping:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:paymentCheckout:shipping:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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,
                    "quantity": 1,
                    "nbdistinctproduct": 1,
                    "creation_utc": 1514973161
                });
     * </code></pre>
     * @public
     */
    tag.ecommerce.transactionConfirmation.cart = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var transactionConfirmation = {};
                transactionConfirmation[Keys.cart] = tagObject;

                // Ecommerce
                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.cart], Keys.cart, _origin);
                _salesInsights.updateProductPurchased(null, transactionConfirmation[Keys.cart]);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:cart:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:cart:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     * @deprecated
     */
    tag.ecommerce.transactionConfirmation.discount = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                var transactionConfirmation = {};
                transactionConfirmation[Keys.transaction] = {};
                transactionConfirmation[Keys.transaction][Properties.transaction.promocode] = tagObject;

                // Ecommerce
                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.transaction], Keys.transaction, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:discount:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:discount:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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", "promocode": ["BIU4YTCR", "1WUY4TWX"], "firstpurchase": 0});
     * </code></pre>
     * @public
     */
    tag.ecommerce.transactionConfirmation.transaction = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var transactionConfirmation = {};
                transactionConfirmation[Keys.transaction] = tagObject;

                // Ecommerce
                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.transaction], Keys.transaction, _origin);

                _salesInsights.updateProductPurchased(transactionConfirmation[Keys.transaction], null);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:transaction:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:transaction:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.transactionConfirmation.shipping = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var transactionConfirmation = {};
                transactionConfirmation[Keys.shipping] = tagObject;

                // Ecommerce
                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.shipping], Keys.shipping, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:shipping:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:shipping:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     */
    tag.ecommerce.transactionConfirmation.payment = {
        set: function (tagObject) {
            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var transactionConfirmation = {};
                transactionConfirmation[Keys.payment] = tagObject;

                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.payment], Keys.payment, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:payment:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:payment:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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
     * @deprecated
     */
    tag.ecommerce.transactionConfirmation.customer = {
        set: function (tagObject) {

            if (ATInternet.Utils.isObject(tagObject)) {

                tagObject = _utility.objectKeysFromLegacyToNewFormat(tagObject);

                var transactionConfirmation = {};
                transactionConfirmation[Keys.transaction] = {};
                transactionConfirmation[Keys.transaction][Properties.transaction.firstpurchase] = tagObject[Properties.customer['new']];

                // Ecommerce
                tag.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.transaction], Keys.transaction, _origin);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:customer:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:customer:set', _error.level, _error.messageObject, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @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",
                    "$": "Chemisier",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "pricetaxincluded": 32.4,
                    "pricetaxfree": 27,
                    "currency": "EUR",
                    "stock": 1,
                    "quantity": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Tops",
                    "category4": "Chemisiers"
                }]);
     * </code></pre>
     * @public
     */
    tag.ecommerce.transactionConfirmation.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {

                tagObject = _utility.arrayObjectKeysFromLegacyToNewFormat(tagObject);

                var products = [];
                var cart = _salesInsights.getObjectValueFromType(Types.transaction.confirmation, Keys.cart);
                var transaction = _salesInsights.getObjectValueFromType(Types.transaction.confirmation, Keys.transaction);

                for (var i = 0; i < tagObject.length; i++) {
                    products.push(tagObject[i]);
                }
                // Create 'product.purchased' events
                _salesInsights.setProductPurchased(products, transaction, cart);

                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:products:set', _debug.level, _debug.messageEnd, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            } else if (tagObject) {
                /* @if debug */
                tag.debug('Ecommerce:ecommerce:transactionConfirmation:products:set', _error.level, _error.messageArray, {
                    'data': tagObject,
                    'origin': _origin
                });
                /* @endif */
            }
        }
    };

    /**
     * Launch plugin when all dependencies are loaded.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @private
     */
    var _init = function () {
        _utility = new Utility();
        _salesInsights = new SalesInsights();
    };

    _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
     * @param elementType {string} Element type (mailto, form, redirection)
     * @function
     * @private
     */
    tag.ecommerce.onDispatch = function (callback, elementType) {
        tag.event.onDispatch(callback, elementType, _origin);
    };

// For unit tests on private elements !!!
    /* @if test */
    var _this = this;
    _this.Types = Types;
    _this.Keys = Keys;
    _this.Properties = Properties;
    _this._error = _error;
    _this._debug = _debug;
    _this.arrayObjectKeysFromLegacyToNewFormat = _utility.arrayObjectKeysFromLegacyToNewFormat;
    _this.objectKeysFromLegacyToNewFormat = _utility.objectKeysFromLegacyToNewFormat;
    _this.setValueFromKey = _utility.setValueFromKey;
    _this.getObjectValueFromType = _salesInsights.getObjectValueFromType;
    _this.setProductAwaitingPayment = _salesInsights.setProductAwaitingPayment;
    _this.updateProductAwaitingPayment = _salesInsights.updateProductAwaitingPayment;
    _this.setEventFromProductsAndCart = _salesInsights.setEventFromProductsAndCart;
    _this.setProductDisplay = _salesInsights.setProductDisplay;
    _this.setProductPageDisplay = _salesInsights.setProductPageDisplay;
    _this.setProductAddToCart = _salesInsights.setProductAddToCart;
    _this.setProductRemoveFromCart = _salesInsights.setProductRemoveFromCart;
    _this.setCartCreation = _salesInsights.setCartCreation;
    _this.updateCartCreation = _salesInsights.updateCartCreation;
    _this.setProductPurchased = _salesInsights.setProductPurchased;
    _this.updateProductPurchased = _salesInsights.updateProductPurchased;
    _this._init = _init;
    /* @endif */

};
ATInternet.Tracker.addPlugin('Ecommerce');