<commit_before>/*global define*/
/*jslint white:true*/
/**
 * Loads the required narrative configuration files.
 * This returns a Promise that will eventually hold the results.
 * This should mainly be invoked by the starting app, then
 * that result should be injected where necessary.
 *
 * @author Bill Riehl <wjriehl@lbl.gov>
 * @class narrativeConfig
 * @module Narrative
 * @static
 */
define([
    'jquery',
    'bluebird',
    'json!kbase/config/config.json',
    'json!kbase/config/icons.json'],
function($,
         Promise,
         configSet,
         iconsSet) {
    'use strict';

    // Get the workspace id from the URL
    var workspaceId = null;
    var m = window.location.href.match(/ws\.(\d+)\.obj\.(\d+)/);
    if (m && m.length > 1) {
        workspaceId = parseInt(m[1]);
    }

    // Build the config up from the configSet (from config.json)
    var config = {
        environment:       configSet.config,
        urls:              configSet[configSet.config],
        version:           configSet.version,
        name:              configSet.name,
        git_commit_hash:   configSet.git_commit_hash,
        git_commit_time:   configSet.git_commit_time,
        release_notes:     configSet.release_notes,
        mode:              configSet.mode,
        dev_mode:          configSet.dev_mode,
        tooltip:           configSet.tooltip,
        icons:             iconsSet,
        workspaceId:       workspaceId,
        loading_gif:       configSet.loading_gif,
        use_local_widgets: configSet.use_local_widgets
    };

    var debug = config.mode === "debug";
    config.debug = debug;

    // Add a remote UI-common to the Require.js config
    require.config({
        paths: {
            uiCommonPaths: config.urls.ui_common_root + 'widget-paths'
        }
    });
    window.kbconfig = config;

    /**
     * Updates the RequireJS config with additional locations from
     * a config given by the ui-common repo. This file is expected to be
     * called "widget-paths.js" and should be deployed in the configured
     * ui-common location.
     *
     * Note that this is optional. If we're expected to use local widgets,
     * as configured with the use_local_widgets flag, then skip this step
     * and just run the callback.
     */
    function updateConfig() {
        return Promise.try(function() {
            console.log('Config: checking remote widgets');
            if (!config.use_local_widgets) {
                // var uiCommonPaths = config.urls.ui_common_root + "widget-paths.json";
                require(['uiCommonPaths'], function(pathConfig) {
                    for (var name in pathConfig.paths) {
                        pathConfig.paths[name] = config.urls.ui_common_root + pathConfig.paths[name];
                    }
                    require.config(pathConfig);
                    config.new_paths = pathConfig;
                    if (callback) {
                        callback(config);
                    }
                }, function(error) {
                    console.log("Unable to get updated widget paths. Sticking with what we've got.");
                });
            }
            return config;
        })
        .then(function(config) {
            console.log('Config: fetching remote data configuration.');
            return Promise.resolve($.getJSON(config.urls.data_panel_sources));
        })
        .then(function(dataCategories) {
            console.log('Config: processing remote data configuration.');
            config.publicCategories = dataCategories[config.environment].publicData;
            config.exampleData = dataCategories[config.environment].exampleData;
            return Promise.try(function() { return config; });
        })
        .catch(function(error) {
            console.error('Config: unable to process remote data configuration options. Searching locally.');
            return Promise.resolve($.getJSON('static/kbase/config' + config.urls.data_panel_sources));
        })
        .then(function(dataCategories) {
            console.log('Config: processing local data configuration.');
            config.publicCategories = dataCategories[config.environment].publicData;
            config.exampleData = dataCategories[config.environment].exampleData;
            return Promise.try(function() { return config; });
        })
        .catch(function(error) {
            console.error('Config: unable to process local configuration options, too! Public and Example data unavailable!');
            return Promise.try(function() { return config; });
        });
    }

    /**
     * Simple wrapper to return a URL by its key. If not present, just returns undefined.
     */
    function url(key) {
        return config.urls[key];
    }

    /**
     * Simple wrapper to return some value by its key. If not present, just returns undefined.
     */
    function get(key) {
        return config[key];
    }

    return {
        updateConfig: updateConfig,
        config: config,
        url: url,
        get: get,
        debug: debug
    }
});<commit_msg>Fixed issue with Promises generated while looking up data source config were crossing badly.<commit_after>/*global define*/
/*jslint white:true*/
/**
 * Loads the required narrative configuration files.
 * This returns a Promise that will eventually hold the results.
 * This should mainly be invoked by the starting app, then
 * that result should be injected where necessary.
 *
 * @author Bill Riehl <wjriehl@lbl.gov>
 * @class narrativeConfig
 * @module Narrative
 * @static
 */
define([
    'jquery',
    'bluebird',
    'json!kbase/config/config.json',
    'json!kbase/config/icons.json'],
function($,
         Promise,
         configSet,
         iconsSet) {
    'use strict';

    // Get the workspace id from the URL
    var workspaceId = null;
    var m = window.location.href.match(/ws\.(\d+)\.obj\.(\d+)/);
    if (m && m.length > 1) {
        workspaceId = parseInt(m[1]);
    }

    // Build the config up from the configSet (from config.json)
    var config = {
        environment:       configSet.config,
        urls:              configSet[configSet.config],
        version:           configSet.version,
        name:              configSet.name,
        git_commit_hash:   configSet.git_commit_hash,
        git_commit_time:   configSet.git_commit_time,
        release_notes:     configSet.release_notes,
        mode:              configSet.mode,
        dev_mode:          configSet.dev_mode,
        tooltip:           configSet.tooltip,
        icons:             iconsSet,
        workspaceId:       workspaceId,
        loading_gif:       configSet.loading_gif,
        use_local_widgets: configSet.use_local_widgets
    };

    var debug = config.mode === "debug";
    config.debug = debug;

    // Add a remote UI-common to the Require.js config
    require.config({
        paths: {
            uiCommonPaths: config.urls.ui_common_root + 'widget-paths'
        }
    });
    window.kbconfig = config;

    /**
     * Updates the RequireJS config with additional locations from
     * a config given by the ui-common repo. This file is expected to be
     * called "widget-paths.js" and should be deployed in the configured
     * ui-common location.
     *
     * Note that this is optional. If we're expected to use local widgets,
     * as configured with the use_local_widgets flag, then skip this step
     * and just run the callback.
     */
    function updateConfig() {
        return Promise.try(function() {
            console.log('Config: checking remote widgets');
            if (!config.use_local_widgets) {
                // var uiCommonPaths = config.urls.ui_common_root + "widget-paths.json";
                require(['uiCommonPaths'], function(pathConfig) {
                    for (var name in pathConfig.paths) {
                        pathConfig.paths[name] = config.urls.ui_common_root + pathConfig.paths[name];
                    }
                    require.config(pathConfig);
                    config.new_paths = pathConfig;
                    if (callback) {
                        callback(config);
                    }
                }, function(error) {
                    console.log("Unable to get updated widget paths. Sticking with what we've got.");
                });
            }
            return config;
        })
        .then(function(config) {
            console.log('Config: fetching remote data configuration.');
            return Promise.resolve($.getJSON(config.urls.data_panel_sources));
        })
        .then(function(dataCategories) {
            console.log('Config: processing remote data configuration.');
            config.publicCategories = dataCategories[config.environment].publicData;
            config.exampleData = dataCategories[config.environment].exampleData;
            return Promise.try(function() { return config; });
        })
        .catch(function(error) {
            console.error('Config: unable to process remote data configuration options. Searching locally.');
            // hate embedding this stuff, but it seems the only good way.
            // the filename is the last step of that url path (after the last /)
            var path = config.urls.data_panel_sources.split('/');

            return Promise.resolve($.getJSON('static/kbase/config/' + path[path.length-1]))
            .then(function(dataCategories) {
                console.log('Config: processing local data configuration.');
                config.publicCategories = dataCategories[config.environment].publicData;
                config.exampleData = dataCategories[config.environment].exampleData;
                return Promise.try(function() { return config; });
            })
            .catch(function(error) {
                console.error('Config: unable to process local configuration options, too! Public and Example data unavailable!');
                return Promise.try(function() { return config; });
            });
        })
    }

    /**
     * Simple wrapper to return a URL by its key. If not present, just returns undefined.
     */
    function url(key) {
        return config.urls[key];
    }

    /**
     * Simple wrapper to return some value by its key. If not present, just returns undefined.
     */
    function get(key) {
        return config[key];
    }

    return {
        updateConfig: updateConfig,
        config: config,
        url: url,
        get: get,
        debug: debug
    }
});<|endoftext|>


<commit_before>/*
 A collection of changes/additions to the behavior of c3js to account for bugs/hardcoded values/missing functionally.
 This is tested against c3 v0.4.11-rc1. Feature requests submitted upstream for "proper" implementation within c3.
 */
define([
    "jquery",
    "c3"
], function ($, c3) {
    "use strict";

    // Remove hardcoded transparency from scatter plot points
    c3.chart.internal.fn.opacityForCircleOriginal = c3.chart.internal.fn.opacityForCircle;
    c3.chart.internal.fn.opacityForCircle = function (d) {
        var $$ = this;
        return this.isScatterType(d) ? 1 : $$.opacityForCircleOriginal(d);
    };

    // Define a new histogram plot type, which is a subtype of bar chart, but with different min/max x bar values
    c3.chart.internal.fn.hasTypeOriginal = c3.chart.internal.fn.hasType;
    c3.chart.internal.fn.hasType = function (type, targets) {
        var $$ = this;
        return $$.hasTypeOriginal(type, targets) || (type === "bar" ? $$.hasTypeOriginal("histogram", targets) : false);
    };
    c3.chart.internal.fn.isHistogramType = function (d) {
        var id = this.isString(d) ? d : d.id;
        return this.config.data_types[id] === 'histogram';
    };
    c3.chart.internal.fn.isBarTypeOriginal = c3.chart.internal.fn.isBarType;
    c3.chart.internal.fn.isBarType = function (d) {
        var $$ = this;
        return $$.isBarTypeOriginal(d) || $$.isHistogramType(d);
    };

    c3.chart.internal.fn.generateGetBarPointsOriginal = c3.chart.internal.fn.generateGetBarPoints;
    c3.chart.internal.fn.generateGetBarPoints = function (barIndices, isSub) {
        var $$ = this;
        var coordFunction = $$.generateGetBarPointsOriginal(barIndices, isSub);
        return function (d, i) {
            if ($$.isHistogramType(d)) {
                var minX = $$.getXValue(d.id, i);
                var maxX = i + 1 < $$.data.xs[d.id].length ? $$.getXValue(d.id, i + 1) : minX;
                var minY = 0;
                var maxY = d.value;

                return [
                    [$$.x(minX) + 1, $$.y(minY)],
                    [$$.x(minX) + 1, $$.y(maxY)],
                    [$$.x(maxX) - 1, $$.y(maxY)],
                    [$$.x(maxX) - 1, $$.y(minY)]
                ];
            } else {
                return coordFunction(d, i);
            }
        };
    };

    // Force grid lines to align to x axis ticks
    c3.chart.internal.fn.generateGridDataOriginal = c3.chart.internal.fn.generateGridData;
    c3.chart.internal.fn.generateGridData = function (type, scale) {
        var $$ = this;
        return $$.xAxisTickValues || $$.generateGridDataOriginal(type, scale);
    };

    // Add a "save" function to export PNGs to c3 plots
    c3.chart.fn.save = function (filename) {
        var realSvg = this.internal.svg[0][0];
        var supportsToDataURL = function () {
            var c = document.createElement("canvas");
            var data = c.toDataURL("image/png");
            return (data.indexOf("data:image/png") == 0);
        };
        var supportsCanvas = function () {
            var c = document.createElement("canvas");
            var data = c.toDataURL("image/png");
            return (data.indexOf("data:image/png") == 0);
        };
        var isIE = function () {
            return navigator.userAgent.indexOf("MSIE ") > -1 ||
                navigator.userAgent.indexOf("Trident/") > -1 ||
                navigator.userAgent.indexOf("Edge/") > -1;
        };

        var getSvgAsText = function (realSvg) {
            // Create copy of the chart (but dont add it the DOM, let it get gc'ed at end of function)
            var svgClone = realSvg.cloneNode(true);

            // Recursively inline the computed style of all svg (sub-)elements
            var allValidSVGStyleProperties = ["alignment-baseline", "baseline-shift", "clip", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cursor", "direction", "display", "dominant-baseline", "enable-background", "fill", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "font", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", "glyph-orientation-vertical", "image-rendering", "kerning", "letter-spacing", "lighting-color", "marker", "marker-end", "marker-mid", "marker-start", "mask", "opacity", "overflow", "pointer-events", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-decoration", "text-rendering", "unicode-bidi", "visibility", "word-spacing", "writing-mode"];
            $(svgClone).css($(realSvg).css(allValidSVGStyleProperties));
            var realSvgElements = $(realSvg).find("*");
            var cloneSvgElements = $(svgClone).find("*");
            for (var i = 0; i < realSvgElements.size(); i = i + 1) {
                // JQUERY ick!
                $(cloneSvgElements[i]).css($(realSvgElements[i]).css(allValidSVGStyleProperties));
            }

            // Make sure the svg clone is full valid svg doc
            var xmlns = "http://www.w3.org/2000/xmlns/";
            svgClone.setAttribute("version", "1.1");
            svgClone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg");
            svgClone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
            svgClone.setAttribute("width", realSvg.getAttribute("width"));
            svgClone.setAttribute("height", realSvg.getAttribute("height"));
            svgClone.setAttribute("viewBox", "0 0 " + realSvg.getAttribute("width") + " " + realSvg.getAttribute("height"));

            // Get svg as text
            var div = document.createElement("div");
            div.appendChild(svgClone);
            var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
            return doctype + div.innerHTML;
        };

        function convertSvgTextToSvgDataUrl(svgText) {
            return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgText)));
        }

        if (isIE() || !(supportsCanvas() && supportsToDataURL())) {
            alert("This functionality is not available in your web browser");
        } else {
            var svgText = getSvgAsText(realSvg);
            // Create a canvas
            var canvas = document.createElement("canvas");
            canvas.setAttribute("width", realSvg.getAttribute("width"));
            canvas.setAttribute("height", realSvg.getAttribute("height"));
            var canvasContext = canvas.getContext("2d");

            // Draw svg into canvas
            var image = new Image();
            image.src = convertSvgTextToSvgDataUrl(svgText);
            $(image).on("load", function () {
                canvasContext.drawImage(
                    image, 0, 0, canvas.getAttribute("width"), canvas.getAttribute("height"));

                // Trigger download
                var filenameClean = filename.replace(/[^\w\d]+/gi, "-").toLowerCase() + ".png";
                var a = document.createElement("a");
                a.download = filenameClean;
                var canvasData = canvas.toDataURL("image/png");
                a.href = canvasData;
                document.body.appendChild(a);
                a.addEventListener("click", function () {
                    a.parentNode.removeChild(a);
                });
                a.click();
            });
        }
    };
});
<commit_msg>Add workaround for mac desktop safari chart download bug<commit_after>/*
 A collection of changes/additions to the behavior of c3js to account for bugs/hardcoded values/missing functionally.
 This is tested against c3 v0.4.11-rc1. Feature requests submitted upstream for "proper" implementation within c3.
 */
define([
    "jquery",
    "c3"
], function ($, c3) {
    "use strict";

    // Remove hardcoded transparency from scatter plot points
    c3.chart.internal.fn.opacityForCircleOriginal = c3.chart.internal.fn.opacityForCircle;
    c3.chart.internal.fn.opacityForCircle = function (d) {
        var $$ = this;
        return this.isScatterType(d) ? 1 : $$.opacityForCircleOriginal(d);
    };

    // Define a new histogram plot type, which is a subtype of bar chart, but with different min/max x bar values
    c3.chart.internal.fn.hasTypeOriginal = c3.chart.internal.fn.hasType;
    c3.chart.internal.fn.hasType = function (type, targets) {
        var $$ = this;
        return $$.hasTypeOriginal(type, targets) || (type === "bar" ? $$.hasTypeOriginal("histogram", targets) : false);
    };
    c3.chart.internal.fn.isHistogramType = function (d) {
        var id = this.isString(d) ? d : d.id;
        return this.config.data_types[id] === 'histogram';
    };
    c3.chart.internal.fn.isBarTypeOriginal = c3.chart.internal.fn.isBarType;
    c3.chart.internal.fn.isBarType = function (d) {
        var $$ = this;
        return $$.isBarTypeOriginal(d) || $$.isHistogramType(d);
    };

    c3.chart.internal.fn.generateGetBarPointsOriginal = c3.chart.internal.fn.generateGetBarPoints;
    c3.chart.internal.fn.generateGetBarPoints = function (barIndices, isSub) {
        var $$ = this;
        var coordFunction = $$.generateGetBarPointsOriginal(barIndices, isSub);
        return function (d, i) {
            if ($$.isHistogramType(d)) {
                var minX = $$.getXValue(d.id, i);
                var maxX = i + 1 < $$.data.xs[d.id].length ? $$.getXValue(d.id, i + 1) : minX;
                var minY = 0;
                var maxY = d.value;

                return [
                    [$$.x(minX) + 1, $$.y(minY)],
                    [$$.x(minX) + 1, $$.y(maxY)],
                    [$$.x(maxX) - 1, $$.y(maxY)],
                    [$$.x(maxX) - 1, $$.y(minY)]
                ];
            } else {
                return coordFunction(d, i);
            }
        };
    };

    // Force grid lines to align to x axis ticks
    c3.chart.internal.fn.generateGridDataOriginal = c3.chart.internal.fn.generateGridData;
    c3.chart.internal.fn.generateGridData = function (type, scale) {
        var $$ = this;
        return $$.xAxisTickValues || $$.generateGridDataOriginal(type, scale);
    };

    // Add a "save" function to export PNGs to c3 plots
    c3.chart.fn.save = function (filename) {
        var realSvg = this.internal.svg[0][0];
        var supportsToDataURL = function () {
            var c = document.createElement("canvas");
            var data = c.toDataURL("image/png");
            return (data.indexOf("data:image/png") == 0);
        };
        var supportsCanvas = function () {
            var c = document.createElement("canvas");
            var data = c.toDataURL("image/png");
            return (data.indexOf("data:image/png") == 0);
        };
        var isIE = function () {
            return navigator.userAgent.indexOf("MSIE ") > -1 ||
                navigator.userAgent.indexOf("Trident/") > -1 ||
                navigator.userAgent.indexOf("Edge/") > -1;
        };

        var getSvgAsText = function (realSvg) {
            // Create copy of the chart (but dont add it the DOM, let it get gc'ed at end of function)
            var svgClone = realSvg.cloneNode(true);

            // Recursively inline the computed style of all svg (sub-)elements
            var allValidSVGStyleProperties = ["alignment-baseline", "baseline-shift", "clip", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cursor", "direction", "display", "dominant-baseline", "enable-background", "fill", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "font", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", "glyph-orientation-vertical", "image-rendering", "kerning", "letter-spacing", "lighting-color", "marker", "marker-end", "marker-mid", "marker-start", "mask", "opacity", "overflow", "pointer-events", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-decoration", "text-rendering", "unicode-bidi", "visibility", "word-spacing", "writing-mode"];
            $(svgClone).css($(realSvg).css(allValidSVGStyleProperties));
            var realSvgElements = $(realSvg).find("*");
            var cloneSvgElements = $(svgClone).find("*");
            for (var i = 0; i < realSvgElements.size(); i = i + 1) {
                // JQUERY ick!
                $(cloneSvgElements[i]).css($(realSvgElements[i]).css(allValidSVGStyleProperties));
            }

            // Make sure the svg clone is full valid svg doc
            var xmlns = "http://www.w3.org/2000/xmlns/";
            svgClone.setAttribute("version", "1.1");
            svgClone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg");
            svgClone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
            svgClone.setAttribute("width", realSvg.getAttribute("width"));
            svgClone.setAttribute("height", realSvg.getAttribute("height"));
            svgClone.setAttribute("viewBox", "0 0 " + realSvg.getAttribute("width") + " " + realSvg.getAttribute("height"));

            // Get svg as text
            var div = document.createElement("div");
            div.appendChild(svgClone);
            var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
            return doctype + div.innerHTML;
        };

        function convertSvgTextToSvgDataUrl(svgText) {
            return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgText)));
        }

        if (isIE() || !(supportsCanvas() && supportsToDataURL())) {
            alert("This functionality is not available in your web browser");
        } else {
            var svgText = getSvgAsText(realSvg);
            // Create a canvas
            var canvas = document.createElement("canvas");
            canvas.setAttribute("width", realSvg.getAttribute("width"));
            canvas.setAttribute("height", realSvg.getAttribute("height"));
            var canvasContext = canvas.getContext("2d");

            // Draw svg into canvas
            var image = new Image();
            image.src = convertSvgTextToSvgDataUrl(svgText);
            $(image).on("load", function () {
                canvasContext.drawImage(
                    image, 0, 0, canvas.getAttribute("width"), canvas.getAttribute("height"));

                // Trigger download
                var filenameClean = filename.replace(/[^\w\d]+/gi, "-").toLowerCase() + ".png";
                var a = document.createElement("a");
                a.download = filenameClean;
                var canvasData = canvas.toDataURL("image/png");
                a.href = canvasData;
                a.target = "_parent"; // workaround for safari's lack of "download" attribute
                document.body.appendChild(a);
                a.addEventListener("click", function () {
                    a.parentNode.removeChild(a);
                });
                a.click();
            });
        }
    };
});
<|endoftext|>


<commit_before>/* Copyright 2021 Binovo IT Human Project SL
   Copyright 2022 Landoo Sistemas de Informacion SL
   Copyright 2022 Advanced Programming Solu SL
   License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
*/

odoo.define("l10n_es_ticketbai_pos.tbai_models", function (require) {
    "use strict";

    var core = require("web.core");
    var _t = core._t;
    var field_utils = require("web.field_utils");

    var Backbone = window.Backbone;
    var tbai = window.tbai;
    var QRCode = window.QRCode;

    /* A TicketBAI Simplified Invoice represents a customer's order
    to be exported to the Tax Agency.
    */
    var TicketBAISimplifiedInvoice = Backbone.Model.extend({
        initialize: function (attributes, options) {
            Backbone.Model.prototype.initialize.apply(this, arguments);
            var opts = options || {};
            this.pos = opts.pos;
            this.previous_tbai_invoice = null;
            this.order = opts.order || null;
            this.number = opts.number || null;
            this.number_prefix = opts.number_prefix || null;
            this.expedition_date = opts.expedition_date || null;
            this.signature_value = opts.signature_value || null;
            this.tbai_identifier = opts.tbai_identifier || null;
            this.tbai_qr_src = opts.tbai_qr_src || null;
            this.tbai_qr_url = null;
            this.vat_regime_key = "01";
            this.vat_regime_key2 = null;
            this.vat_regime_key3 = null;
            this.unsigned_datas = null;
            this.datas = null;
        },

        // Tested on Epson TM-20II
        // 164 (default pixels with margin '0') * 35 (required QR image width in mm) / 22 (default width in mm) = 260
        // Pixels. 255 is the maximum.
        qr_options: {
            margin: 0,
            width: 255,
        },

        build_invoice: function () {
            var self = this;
            var built = new $.Deferred();
            var options = {};
            var deviceId = this.pos.config.tbai_device_serial_number || null;
            // Addon l10n_es_pos -> Order.export_as_JSON()
            var simplified_invoice = null;
            var tbai_json = null;

            this.previous_tbai_invoice = this.pos.get_tbai_last_invoice_data();
            this.expedition_date = new Date();
            simplified_invoice =
                this.order.simplified_invoice ||
                this.pos.config.l10n_es_simplified_invoice_prefix +
                    this.pos.get_padding_simple_inv(
                        this.pos.config.l10n_es_simplified_invoice_number
                    );
            this.number_prefix = this.pos.config.l10n_es_simplified_invoice_prefix;
            this.number = simplified_invoice.slice(this.number_prefix.length);

            if (this.order.fiscal_position) {
                var tbai_vat_regime_key = this.order.fiscal_position
                    .tbai_vat_regime_key;
                if (tbai_vat_regime_key) {
                    this.vat_regime_key = tbai_vat_regime_key[0];
                }
                var tbai_vat_regime_key2 = this.order.fiscal_position
                    .tbai_vat_regime_key2;
                if (tbai_vat_regime_key2) {
                    this.vat_regime_key2 = tbai_vat_regime_key2[0];
                }
                var tbai_vat_regime_key3 = this.order.fiscal_position
                    .tbai_vat_regime_key3;
                if (tbai_vat_regime_key3) {
                    this.vat_regime_key3 = tbai_vat_regime_key3[0];
                }
            }

            tbai_json = this.export_as_JSON();
            if (!_.isEmpty(tbai_json) && this.pos.tbai_signer !== null) {
                if (typeof deviceId === "string" || deviceId instanceof String) {
                    options.deviceId = deviceId;
                }
                try {
                    this.unsigned_datas = tbai.toXml(
                        tbai_json.Invoice,
                        tbai_json.PreviousInvoiceId || null,
                        tbai_json.Software,
                        options
                    );
                    this.pos.tbai_signer.sign(this.unsigned_datas).then(
                        function (datas) {
                            self.datas = datas;
                            self.signature_value = tbai.getTbaiChainInfo(datas).hash;
                            self.tbai_identifier = tbai.getTbaiId(datas);
                            self.tbai_qr_url = tbai.getTbaiUrlFromBaseURL(
                                datas,
                                self.pos.tbai_qr_base_url
                            );
                            QRCode.toDataURL(self.tbai_qr_url, self.qr_options).then(
                                function (src) {
                                    self.tbai_qr_src = src;
                                    built.resolve();
                                },
                                function (err) {
                                    throw new Error(err);
                                }
                            );
                        },
                        function (err) {
                            throw new Error(err);
                        }
                    );
                } catch (e) {
                    console.error(e);
                    this.showPopup("ErrorPopup", {
                        title: _t("TicketBAI"),
                        body: e.message,
                    });
                    built.reject();
                }
            } else {
                built.reject();
            }
            return built;
        },
        get_vat_without_country_code: function (vat, country_code) {
            var vat_without_country_code = null;
            var vat_upper = vat.toUpperCase();
            var country_code_upper = country_code ? country_code.toUpperCase() : null;
            if (
                country_code_upper &&
                vat_upper.slice(0, country_code_upper.length) === country_code_upper
            ) {
                vat_without_country_code = vat_upper.slice(country_code_upper.length);
            } else {
                vat_without_country_code = vat_upper;
            }
            return vat_without_country_code;
        },
        get_tbai_company_vat: function () {
            var company = this.pos.company;
            return this.get_vat_without_country_code(company.vat, company.country.code);
        },
        get_tbai_partner_vat: function (partner_id) {
            var partner = this.pos.db.get_partner_by_id(partner_id);
            var country_code = this.pos.get_country_code_by_id(partner.country_id[0]);
            if (country_code === "ES" || partner.tbai_partner_idtype === "02") {
                return this.get_vat_without_country_code(partner.vat, country_code);
            }
            return partner.tbai_partner_identification_number;
        },
        export_as_JSON: function () {
            var order_json =
                (this.order !== null && this.order.export_as_JSON()) || null;
            var tbai_json = {};
            var company = this.pos.company;
            var vat_keys = [this.vat_regime_key];
            var self = this;

            if (
                order_json !== null &&
                this.number !== null &&
                this.expedition_date !== null
            ) {
                if (this.vat_regime_key2 !== null) {
                    vat_keys.push(this.vat_regime_key2);
                }
                if (this.vat_regime_key3 !== null) {
                    vat_keys.push(this.vat_regime_key3);
                }
                tbai_json.Invoice = {
                    simple: true,
                    issuer: {
                        irsId: this.get_tbai_company_vat(),
                        name: company.name,
                    },
                    id: {
                        number: this.number,
                        serie: this.number_prefix,
                        issuedTime: this.expedition_date,
                    },
                    description: {
                        text: order_json.name,
                        operationDate: this.expedition_date,
                    },
                    lines: this.get_tbai_lines_from_json(order_json.lines),
                    total: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(order_json.amount_total)
                    ),
                    vatKeys: vat_keys,
                };
                tbai_json.Invoice.vatLines = this.get_tbai_vat_lines_from_json(
                    order_json
                );
                if (order_json.partner_id) {
                    var partner = this.pos.db.get_partner_by_id(order_json.partner_id);
                    var zip = partner.zip;
                    var address =
                        (partner.street || "") +
                        ", " +
                        (partner.zip || "") +
                        " " +
                        (partner.city || "") +
                        ", " +
                        (partner.country_id[1] || "");
                    tbai_json.Invoice.recipient = {
                        irsId: this.get_tbai_partner_vat(order_json.partner_id),
                        name: partner.name,
                        postal: zip,
                        address: address,
                    };
                }
                if (this.previous_tbai_invoice !== null) {
                    tbai_json.PreviousInvoiceId = {
                        number: this.previous_tbai_invoice.number,
                        serie: this.previous_tbai_invoice.number_prefix,
                        issuedTime: new Date(
                            JSON.parse(
                                JSON.stringify(
                                    this.previous_tbai_invoice.expedition_date
                                )
                            )
                        ),
                        hash: this.previous_tbai_invoice.signature_value.substring(
                            0,
                            100
                        ),
                    };
                }
                tbai_json.Software = {
                    license: company.tbai_license_key,
                    developerIrsId: this.get_tbai_partner_vat(
                        company.tbai_developer_id[0]
                    ),
                    name: company.tbai_software_name,
                    version: this.pos.tbai_version,
                };
            }
            return tbai_json;
        },
        get_tbai_lines_from_json: function (lines_json) {
            var lines = [];
            var line = null;
            var company = this.pos.company;
            var description_line = null;
            var self = this;
            lines_json.forEach(function (item) {
                line = item[2];
                description_line = line.tbai_description.substring(0, 250);
                if (company.tbai_protected_data && company.tbai_protected_data_txt) {
                    description_line = company.tbai_protected_data_txt.substring(
                        0,
                        250
                    );
                }
                lines.push({
                    description: description_line,
                    quantity: line.qty,
                    price: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_unit)
                    ),
                    discount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.discount)
                    ),
                    discountAmount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(
                            (line.qty * line.tbai_price_unit * line.discount) / 100.0
                        )
                    ),
                    vat: line.tbai_vat_amount,
                    amount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_without_tax)
                    ),
                    amountWithVat: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_with_tax)
                    ),
                });
            });
            return lines;
        },
        get_tbai_vat_lines_from_json: function (order_json) {
            var vatLines = [];
            var vatLinesJson = order_json.taxLines;
            var self = this;
            if (vatLinesJson && vatLinesJson.length > 0) {
                vatLinesJson.forEach(function (vatLineJson) {
                    var vatLine = vatLineJson[2];
                    vatLines.push({
                        base: field_utils.parse.float(
                            self.pos.format_currency_no_symbol(vatLine.baseAmount)
                        ),
                        rate: vatLine.tax.amount,
                        amount: field_utils.parse.float(
                            self.pos.format_currency_no_symbol(vatLine.amount)
                        ),
                    });
                });
            } else {
                var fline = order_json.lines[0][2];
                vatLines.push({
                    base: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(order_json.amount_total)
                    ),
                    rate: fline.tbai_vat_amount,
                    amount: 0,
                });
            }
            return vatLines;
        },
    });

    return {
        TicketBAISimplifiedInvoice: TicketBAISimplifiedInvoice,
    };
});
<commit_msg>[FIX]vat regime key now takes code (str 2 digits) instead of id(int)<commit_after>/* Copyright 2021 Binovo IT Human Project SL
   Copyright 2022 Landoo Sistemas de Informacion SL
   Copyright 2022 Advanced Programming Solu SL
   License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
*/

odoo.define("l10n_es_ticketbai_pos.tbai_models", function (require) {
    "use strict";

    var core = require("web.core");
    var _t = core._t;
    var field_utils = require("web.field_utils");

    var Backbone = window.Backbone;
    var tbai = window.tbai;
    var QRCode = window.QRCode;

    /* A TicketBAI Simplified Invoice represents a customer's order
    to be exported to the Tax Agency.
    */
    var TicketBAISimplifiedInvoice = Backbone.Model.extend({
        initialize: function (attributes, options) {
            Backbone.Model.prototype.initialize.apply(this, arguments);
            var opts = options || {};
            this.pos = opts.pos;
            this.previous_tbai_invoice = null;
            this.order = opts.order || null;
            this.number = opts.number || null;
            this.number_prefix = opts.number_prefix || null;
            this.expedition_date = opts.expedition_date || null;
            this.signature_value = opts.signature_value || null;
            this.tbai_identifier = opts.tbai_identifier || null;
            this.tbai_qr_src = opts.tbai_qr_src || null;
            this.tbai_qr_url = null;
            this.vat_regime_key = "01";
            this.vat_regime_key2 = null;
            this.vat_regime_key3 = null;
            this.unsigned_datas = null;
            this.datas = null;
        },

        // Tested on Epson TM-20II
        // 164 (default pixels with margin '0') * 35 (required QR image width in mm) / 22 (default width in mm) = 260
        // Pixels. 255 is the maximum.
        qr_options: {
            margin: 0,
            width: 255,
        },

        build_invoice: function () {
            var self = this;
            var built = new $.Deferred();
            var options = {};
            var deviceId = this.pos.config.tbai_device_serial_number || null;
            // Addon l10n_es_pos -> Order.export_as_JSON()
            var simplified_invoice = null;
            var tbai_json = null;

            this.previous_tbai_invoice = this.pos.get_tbai_last_invoice_data();
            this.expedition_date = new Date();
            simplified_invoice =
                this.order.simplified_invoice ||
                this.pos.config.l10n_es_simplified_invoice_prefix +
                    this.pos.get_padding_simple_inv(
                        this.pos.config.l10n_es_simplified_invoice_number
                    );
            this.number_prefix = this.pos.config.l10n_es_simplified_invoice_prefix;
            this.number = simplified_invoice.slice(this.number_prefix.length);

            if (this.order.fiscal_position) {
                var tbai_vat_regime_key = this.order.fiscal_position
                    .tbai_vat_regime_key;
                if (tbai_vat_regime_key) {
                    var id_vat_regime_key = this.order.fiscal_position
                        .tbai_vat_regime_key[0];
                    var object_vat_regime_key = self.pos.tbai_vat_regime_keys.find(
                        (x) => x.id === id_vat_regime_key
                    );
                    this.vat_regime_key = object_vat_regime_key.code;
                }
                var tbai_vat_regime_key2 = this.order.fiscal_position
                    .tbai_vat_regime_key2;
                if (tbai_vat_regime_key2) {
                    var id_vat_regime_key = this.order.fiscal_position
                        .tbai_vat_regime_key2[0];
                    var object_vat_regime_key = self.pos.tbai_vat_regime_keys.find(
                        (x) => x.id === id_vat_regime_key
                    );
                    this.vat_regime_key2 = object_vat_regime_key.code;
                }
                var tbai_vat_regime_key3 = this.order.fiscal_position
                    .tbai_vat_regime_key3;
                if (tbai_vat_regime_key3) {
                    var id_vat_regime_key = this.order.fiscal_position
                        .tbai_vat_regime_key3[0];
                    var object_vat_regime_key = self.pos.tbai_vat_regime_keys.find(
                        (x) => x.id === id_vat_regime_key
                    );
                    this.vat_regime_key3 = object_vat_regime_key.code;
                }
            }

            tbai_json = this.export_as_JSON();
            if (!_.isEmpty(tbai_json) && this.pos.tbai_signer !== null) {
                if (typeof deviceId === "string" || deviceId instanceof String) {
                    options.deviceId = deviceId;
                }
                try {
                    this.unsigned_datas = tbai.toXml(
                        tbai_json.Invoice,
                        tbai_json.PreviousInvoiceId || null,
                        tbai_json.Software,
                        options
                    );
                    this.pos.tbai_signer.sign(this.unsigned_datas).then(
                        function (datas) {
                            self.datas = datas;
                            self.signature_value = tbai.getTbaiChainInfo(datas).hash;
                            self.tbai_identifier = tbai.getTbaiId(datas);
                            self.tbai_qr_url = tbai.getTbaiUrlFromBaseURL(
                                datas,
                                self.pos.tbai_qr_base_url
                            );
                            QRCode.toDataURL(self.tbai_qr_url, self.qr_options).then(
                                function (src) {
                                    self.tbai_qr_src = src;
                                    built.resolve();
                                },
                                function (err) {
                                    throw new Error(err);
                                }
                            );
                        },
                        function (err) {
                            throw new Error(err);
                        }
                    );
                } catch (e) {
                    console.error(e);
                    this.showPopup("ErrorPopup", {
                        title: _t("TicketBAI"),
                        body: e.message,
                    });
                    built.reject();
                }
            } else {
                built.reject();
            }
            return built;
        },
        get_vat_without_country_code: function (vat, country_code) {
            var vat_without_country_code = null;
            var vat_upper = vat.toUpperCase();
            var country_code_upper = country_code ? country_code.toUpperCase() : null;
            if (
                country_code_upper &&
                vat_upper.slice(0, country_code_upper.length) === country_code_upper
            ) {
                vat_without_country_code = vat_upper.slice(country_code_upper.length);
            } else {
                vat_without_country_code = vat_upper;
            }
            return vat_without_country_code;
        },
        get_tbai_company_vat: function () {
            var company = this.pos.company;
            return this.get_vat_without_country_code(company.vat, company.country.code);
        },
        get_tbai_partner_vat: function (partner_id) {
            var partner = this.pos.db.get_partner_by_id(partner_id);
            var country_code = this.pos.get_country_code_by_id(partner.country_id[0]);
            if (country_code === "ES" || partner.tbai_partner_idtype === "02") {
                return this.get_vat_without_country_code(partner.vat, country_code);
            }
            return partner.tbai_partner_identification_number;
        },
        export_as_JSON: function () {
            var order_json =
                (this.order !== null && this.order.export_as_JSON()) || null;
            var tbai_json = {};
            var company = this.pos.company;
            var vat_keys = [this.vat_regime_key];
            var self = this;

            if (
                order_json !== null &&
                this.number !== null &&
                this.expedition_date !== null
            ) {
                if (this.vat_regime_key2 !== null) {
                    vat_keys.push(this.vat_regime_key2);
                }
                if (this.vat_regime_key3 !== null) {
                    vat_keys.push(this.vat_regime_key3);
                }
                tbai_json.Invoice = {
                    simple: true,
                    issuer: {
                        irsId: this.get_tbai_company_vat(),
                        name: company.name,
                    },
                    id: {
                        number: this.number,
                        serie: this.number_prefix,
                        issuedTime: this.expedition_date,
                    },
                    description: {
                        text: order_json.name,
                        operationDate: this.expedition_date,
                    },
                    lines: this.get_tbai_lines_from_json(order_json.lines),
                    total: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(order_json.amount_total)
                    ),
                    vatKeys: vat_keys,
                };
                tbai_json.Invoice.vatLines = this.get_tbai_vat_lines_from_json(
                    order_json
                );
                if (order_json.partner_id) {
                    var partner = this.pos.db.get_partner_by_id(order_json.partner_id);
                    var zip = partner.zip;
                    var address =
                        (partner.street || "") +
                        ", " +
                        (partner.zip || "") +
                        " " +
                        (partner.city || "") +
                        ", " +
                        (partner.country_id[1] || "");
                    tbai_json.Invoice.recipient = {
                        irsId: this.get_tbai_partner_vat(order_json.partner_id),
                        name: partner.name,
                        postal: zip,
                        address: address,
                    };
                }
                if (this.previous_tbai_invoice !== null) {
                    tbai_json.PreviousInvoiceId = {
                        number: this.previous_tbai_invoice.number,
                        serie: this.previous_tbai_invoice.number_prefix,
                        issuedTime: new Date(
                            JSON.parse(
                                JSON.stringify(
                                    this.previous_tbai_invoice.expedition_date
                                )
                            )
                        ),
                        hash: this.previous_tbai_invoice.signature_value.substring(
                            0,
                            100
                        ),
                    };
                }
                tbai_json.Software = {
                    license: company.tbai_license_key,
                    developerIrsId: this.get_tbai_partner_vat(
                        company.tbai_developer_id[0]
                    ),
                    name: company.tbai_software_name,
                    version: this.pos.tbai_version,
                };
            }
            return tbai_json;
        },
        get_tbai_lines_from_json: function (lines_json) {
            var lines = [];
            var line = null;
            var company = this.pos.company;
            var description_line = null;
            var self = this;
            lines_json.forEach(function (item) {
                line = item[2];
                description_line = line.tbai_description.substring(0, 250);
                if (company.tbai_protected_data && company.tbai_protected_data_txt) {
                    description_line = company.tbai_protected_data_txt.substring(
                        0,
                        250
                    );
                }
                lines.push({
                    description: description_line,
                    quantity: line.qty,
                    price: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_unit)
                    ),
                    discount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.discount)
                    ),
                    discountAmount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(
                            (line.qty * line.tbai_price_unit * line.discount) / 100.0
                        )
                    ),
                    vat: line.tbai_vat_amount,
                    amount: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_without_tax)
                    ),
                    amountWithVat: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(line.tbai_price_with_tax)
                    ),
                });
            });
            return lines;
        },
        get_tbai_vat_lines_from_json: function (order_json) {
            var vatLines = [];
            var vatLinesJson = order_json.taxLines;
            var self = this;
            if (vatLinesJson && vatLinesJson.length > 0) {
                vatLinesJson.forEach(function (vatLineJson) {
                    var vatLine = vatLineJson[2];
                    vatLines.push({
                        base: field_utils.parse.float(
                            self.pos.format_currency_no_symbol(vatLine.baseAmount)
                        ),
                        rate: vatLine.tax.amount,
                        amount: field_utils.parse.float(
                            self.pos.format_currency_no_symbol(vatLine.amount)
                        ),
                    });
                });
            } else {
                var fline = order_json.lines[0][2];
                vatLines.push({
                    base: field_utils.parse.float(
                        self.pos.format_currency_no_symbol(order_json.amount_total)
                    ),
                    rate: fline.tbai_vat_amount,
                    amount: 0,
                });
            }
            return vatLines;
        },
    });

    return {
        TicketBAISimplifiedInvoice: TicketBAISimplifiedInvoice,
    };
});
<|endoftext|>


<commit_before>const config = {
  env: process.env.NODE_ENV || 'development',
  port: process.env.PORT || 3000,
  host: process.env.HOST || 'localhost'
}

config.globals = {
  'process.env': {
    'NODE_ENV': JSON.stringify(config.env)
  },
  NODE_ENV: config.env,
  __DEV__: config.env === 'development',
  __PROD__: config.env === 'production',
  __TEST__: config.env === 'test'
}

module.exports = config
<commit_msg>config: Set ENV<commit_after>const ENV = process.env.NODE_ENV || 'development'

module.exports = {
  env: ENV,
  port: process.env.PORT || 3000,
  host: process.env.HOST || 'localhost',
  globals: {
    'process.env': {
      'NODE_ENV': JSON.stringify(ENV)
    },
    NODE_ENV: ENV,
    __DEV__: ENV === 'development',
    __PROD__: ENV === 'production',
    __TEST__: ENV === 'test'
  }
}
<|endoftext|>


<commit_before>/**
* Check keys that exist in the current list which will be used in composing
* object. This method checks against accidentally removing data keys due to
* instability from the metadata layer. The check returns true if there was no
* match and false if at least one key from the previous list exists in the
* current list
* @param {array|string} prev - list of keys from the object being overwritten
* @param {array} curr - list of keys to be used in composing current object
* @returns {array} list of keys that can be deleted
*/
function locationKeysSanityCheck(prev, curr) {
    if (!prev || prev.length === 0) {
        return true;
    }
    // backwards compatibility check if object is of model version 2
    if (typeof prev === 'string') {
        return curr.every(v => v.key !== prev);
    }
    const keysMap = {};
    prev.forEach(v => { keysMap[v.key] = true; });
    return curr.every(v => !keysMap[v.key]);
}

module.exports = locationKeysSanityCheck;
<commit_msg>bugfix: ZENKO-3243: sanity check on complete upload<commit_after>/**
* Check keys that exist in the current list which will be used in composing
* object. This method checks against accidentally removing data keys due to
* instability from the metadata layer. The check returns true if there was no
* match and false if at least one key from the previous list exists in the
* current list
* @param {array|string} prev - list of keys from the object being overwritten
* @param {array} curr - list of keys to be used in composing current object
* @returns {array} list of keys that can be deleted
*/
function locationKeysSanityCheck(prev, curr) {
    if (!prev || prev.length === 0) {
        return true;
    }
    // backwards compatibility check if object is of model version 2
    if (typeof prev === 'string') {
        return curr.every(v => v.key !== prev);
    }
    const keysMap = {};
    prev.forEach(v => {
        if (!keysMap[v.dataStoreType]) {
            keysMap[v.dataStoreType] = {};
        }
        keysMap[v.dataStoreType][v.key] = true;
    });
    return curr.every(v => !(keysMap[v.dataStoreType] && keysMap[v.dataStoreType][v.key]));
}

module.exports = locationKeysSanityCheck;
<|endoftext|>


<commit_before>var $ = require('jquery');
var cdb = require('cartodb.js');
var UserSettingsView = require('../public_common/user_settings_view');
var PublicMapWindow = require('./public_map_window');
var MapCardPreview = require('../new_common/views/mapcard_preview');
var LikeView = require('../new_common/views/likes/view');

$(function() {

  // No attributions and no links in this map (at least from cartodb)
  cartodb.config.set({
    cartodb_attributions: "",
    cartodb_logo_link: ""
  });

  $.extend( $.easing, {
    easeInQuad: function (x, t, b, c, d) {
      return c*(t/=d)*t + b;
    }
  });

  cdb.init(function() {
    cdb.templates.namespace = 'cartodb/';

    $(document.body).bind('click', function() {
      cdb.god.trigger('closeDialogs');
    });

    var authenticatedUser = new cdb.open.AuthenticatedUser();
    authenticatedUser.bind('change', function() {
      if (authenticatedUser.get('username')) {
        var user = new cdb.admin.User(authenticatedUser.attributes);
        var userSettingsView = new UserSettingsView({
          el: $('.js-user-settings'),
          model: user
        });
        userSettingsView.render();

        var userDashboardUrl = user.viewUrl().dashboard();
        $('.UserAvatar-img').wrap($('<a>',{
           href: userDashboardUrl
        }));

        $('.js-login').hide();
        $('.js-learn').hide();
      }
    });

    $('.js-likes').each(function() {
      var likeModel = cdb.admin.Like.newByVisData({
        likeable: false,
        vis_id: $(this).data('vis-id'),
        likes: $(this).data('likes-count')
      });
      authenticatedUser.bind('change', function() {
        if (authenticatedUser.get('username')) {
          likeModel.bind('loadModelCompleted', function() {
            likeModel.set('likeable', true);
          });
          likeModel.fetch();
        }
      });
      var likeView = new LikeView({
        el: this,
        model: likeModel
      });
      likeView.render();
    });

    $('.MapCard').each(function() {

      var vizjson = $(this).data('vizjson-url');
      var zoom    = $(this).data('zoom');

      if (vizjson) {
        var mapCardPreview = new MapCardPreview({
          el: $(this).find('.js-header'),
          zoom: zoom,
          vizjson: vizjson
        });
        mapCardPreview.load();
      }
    });

    // Check if device is a mobile
    var mobileDevice = /Android|webOS|iPad|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

    // Window view
    var public_window = new PublicMapWindow({
      el:                   window,
      user_name:            user_name,
      owner_username:       owner_username,
      vis_id:               vis_id,
      vis_name:             vis_name,
      vizdata:              vizdata,
      config:               config,
      map_options:          map_options,
      isMobileDevice:       mobileDevice,
      belong_organization:  belong_organization
    });

    authenticatedUser.fetch();
  });
});
<commit_msg>Finally added some comments for new public map entry.js<commit_after>var $ = require('jquery');
var cdb = require('cartodb.js');
var UserSettingsView = require('../public_common/user_settings_view');
var PublicMapWindow = require('./public_map_window');
var MapCardPreview = require('../new_common/views/mapcard_preview');
var LikeView = require('../new_common/views/likes/view');

$(function() {

  // No attributions and no links in this map (at least from cartodb)
  cartodb.config.set({
    cartodb_attributions: "",
    cartodb_logo_link: ""
  });

  $.extend( $.easing, {
    easeInQuad: function (x, t, b, c, d) {
      return c*(t/=d)*t + b;
    }
  });

  cdb.init(function() {
    cdb.templates.namespace = 'cartodb/';

    $(document.body).bind('click', function() {
      cdb.god.trigger('closeDialogs');
    });

    var authenticatedUser = new cdb.open.AuthenticatedUser();
    authenticatedUser.bind('change', function() {
      if (authenticatedUser.get('username')) {
        var user = new cdb.admin.User(authenticatedUser.attributes);
        var userSettingsView = new UserSettingsView({
          el: $('.js-user-settings'),
          model: user
        });
        userSettingsView.render();

        var userDashboardUrl = user.viewUrl().dashboard();
        $('.UserAvatar-img').wrap($('<a>',{
           href: userDashboardUrl
        }));

        $('.js-login').hide();
        $('.js-learn').hide();
      }
    });

    // Vis likes
    $('.js-likes').each(function() {
      var likeModel = cdb.admin.Like.newByVisData({
        likeable: false,
        vis_id: $(this).data('vis-id'),
        likes: $(this).data('likes-count')
      });
      authenticatedUser.bind('change', function() {
        if (authenticatedUser.get('username')) {
          likeModel.bind('loadModelCompleted', function() {
            likeModel.set('likeable', true);
          });
          likeModel.fetch();
        }
      });
      var likeView = new LikeView({
        el: this,
        model: likeModel
      });
      likeView.render();
    });

    // More user vis cards
    $('.MapCard').each(function() {

      var vizjson = $(this).data('vizjson-url');
      var zoom    = $(this).data('zoom');

      if (vizjson) {
        var mapCardPreview = new MapCardPreview({
          el: $(this).find('.js-header'),
          zoom: zoom,
          vizjson: vizjson
        });
        mapCardPreview.load();
      }
    });

    // Check if device is a mobile
    var mobileDevice = /Android|webOS|iPad|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

    // Window view
    var public_window = new PublicMapWindow({
      el:                   window,
      user_name:            user_name,
      owner_username:       owner_username,
      vis_id:               vis_id,
      vis_name:             vis_name,
      vizdata:              vizdata,
      config:               config,
      map_options:          map_options,
      isMobileDevice:       mobileDevice,
      belong_organization:  belong_organization
    });

    authenticatedUser.fetch();
  });
});
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

// Public node modules.
const _ = require('lodash');

// Local Strapi dependencies.
const utils = require('../utils/utils');

/**
 * JSON API helper
 */

module.exports = {

  default: {},

  /**
   * Parse request
   */

  parse: function * (ctx) {
    // Assign used method
    this.default.method = ctx.method.toUpperCase();

    // Detect X-HTTP-Method-Override for some clients
    // which don't support PATCH method
    if (ctx.header.hasOwnProperty('x-http-method-override') && ctx.header['x-http-method-override'] === 'PATCH') {
      this.default.method = 'POST';
    }

    // HTTP methods allowed
    switch (this.default.method) {
      case 'GET':
        // Nothing to do
        break;
      case 'PATCH':
      case 'POST':
        try {
          yield this.fetchSchema(ctx);
          yield this.formatBody(ctx);
        } catch (err) {
          throw err;
        }
        break;
      case 'DELETE':
        // Nothing to do
        break;
      default:
        throw {
          status: 403,
          body: {
            message: 'Invalid HTTP method'
          }
        };
    }
  },

  /**
   * Format attributes for more simple API
   */

  formatBody: function * (ctx) {
    const body = ctx.request.body;
    const values = _.assign({}, body.data.attributes, _.mapValues(body.data.relationships, function (relation) {
      return _.isArray(relation.data) ? _.map(relation.data, 'id') : relation.data.id;
    }));

    ctx.request.body = values;
  },

  /**
   * Fetch attributes schema
   */

  fetchSchema: function * (ctx) {
    const body = ctx.request.body;

    if (!body.hasOwnProperty('data')) {
      throw {
        status: 403,
        body: {
          message: 'Missing `data` member'
        }
      };
    } else if (!utils.isRessourceObject(body.data) && this.default.method !== 'POST') {
      throw {
        status: 403,
        body: {
          message: 'Invalid ressource object'
        }
      };
    } else if (!body.data.hasOwnProperty('type') && this.default.method === 'POST') {
      throw {
        status: 403,
        body: {
          message: 'Invalid ressource object'
        }
      };
    } else if (!strapi.models.hasOwnProperty(body.data.type)) {
      throw {
        status: 403,
        body: {
          message: 'Unknow `type` ' + body.data.type
        }
      };
    }

    // Extract required attributes
    const requiredAttributes = _.omit(_.mapValues(strapi.models[body.data.type].attributes, function (attr) {
      return (attr.required && attr.type) ? attr : undefined;
    }), _.isUndefined);
    // Identify missing attributes
    const missingAttributes = body.data.hasOwnProperty('attributes') ? _.difference(_.keys(requiredAttributes), _.keys(body.data.attributes)) : null;

    if (!_.isEmpty(missingAttributes)) {
      throw {
        status: 403,
        body: {
          message: 'Missing required attributes (' + missingAttributes.toString() + ')'
        }
      };
    }

    // Extract required relationships
    const requiredRelationships = _.omit(_.mapValues(strapi.models[body.data.type].attributes, function (attr) {
      return (attr.required && (attr.model || attr.collection)) ? attr : undefined;
    }), _.isUndefined);
    // Identify missing relationships
    const missingRelationships = body.data.hasOwnProperty('relationships') ? _.difference(_.keys(requiredRelationships), _.keys(body.data.relationships)) : null;

    if (!_.isEmpty(missingRelationships)) {
      throw {
        status: 403,
        body: {
          message: 'Missing required relationships (' + missingRelationships.toString() + ')'
        }
      };
    }

    // Build array of errors
    if (_.size(requiredRelationships)) {
      const errors = _.remove(_.flattenDeep(_.map(body.data.relationships, function (relation, key) {
        if (!relation.hasOwnProperty('data')) {
          return {
            message: 'Missing `data` member for relationships ' + relation
          };
        } else if (_.isArray(relation.data)) {
          return _.map(relation.data, function (ressource, position) {
            if (!utils.isRessourceObject(ressource)) {
              return {
                position: position,
                message: 'Invalid ressource object in relationships ' + key
              };
            }
          });
        } else if (!utils.isRessourceObject(relation.data)) {
          return {
            message: 'Invalid ressource object for relationships ' + key
          };
        }
      })), function (n) {
        return !_.isUndefined(n);
      });

      if (!_.isEmpty(errors)) {
        throw {
          status: 403,
          body: errors
        };
      }
    }
  }
};
<commit_msg>Fire error when query parameter is not supported<commit_after>'use strict';

/**
 * Module dependencies
 */

// Public node modules.
const _ = require('lodash');

// Local Strapi dependencies.
const utils = require('../utils/utils');

/**
 * JSON API helper
 */

module.exports = {

  default: {},

  /**
   * Parse request
   */

  parse: function * (ctx) {
    // Assign used method
    this.default.method = ctx.method.toUpperCase();

    // Detect X-HTTP-Method-Override for some clients
    // which don't support PATCH method
    if (ctx.header.hasOwnProperty('x-http-method-override') && ctx.header['x-http-method-override'] === 'PATCH') {
      this.default.method = 'POST';
    }

    // HTTP methods allowed
    switch (this.default.method) {
      case 'GET':
        // Nothing to do
        try {
          yield this.fetchQuery(ctx);
        } catch (err) {
          throw err;
        }
        break;
      case 'PATCH':
      case 'POST':
        try {
          yield this.fetchSchema(ctx);
          yield this.formatBody(ctx);
        } catch (err) {
          throw err;
        }
        break;
      case 'DELETE':
        // Nothing to do
        break;
      default:
        throw {
          status: 403,
          body: {
            message: 'Invalid HTTP method'
          }
        };
    }
  },

  /**
   * Format attributes for more simple API
   */

  formatBody: function * (ctx) {
    const body = ctx.request.body;
    const values = _.assign({}, body.data.attributes, _.mapValues(body.data.relationships, function (relation) {
      return _.isArray(relation.data) ? _.map(relation.data, 'id') : relation.data.id;
    }));

    ctx.request.body = values;
  },

  /**
   * Fetch query parameters
   */

  fetchQuery: function * (ctx) {
    _.forEach(_.keys(ctx.query), function (key) {
       if (_.includes(['include', 'fields', 'sort'], key)) {
         throw {
           status: 400,
           body: {
             message: 'Parameter `' + key + '` is not supported yet'
           }
         };
       }
    });
  },

  /**
   * Fetch attributes schema
   */

  fetchSchema: function * (ctx) {
    const body = ctx.request.body;

    if (!body.hasOwnProperty('data')) {
      throw {
        status: 403,
        body: {
          message: 'Missing `data` member'
        }
      };
    } else if (!utils.isRessourceObject(body.data) && this.default.method !== 'POST') {
      throw {
        status: 403,
        body: {
          message: 'Invalid ressource object'
        }
      };
    } else if (!body.data.hasOwnProperty('type') && this.default.method === 'POST') {
      throw {
        status: 403,
        body: {
          message: 'Invalid ressource object'
        }
      };
    } else if (!strapi.models.hasOwnProperty(body.data.type)) {
      throw {
        status: 403,
        body: {
          message: 'Unknow `type` ' + body.data.type
        }
      };
    }

    // Extract required attributes
    const requiredAttributes = _.omit(_.mapValues(strapi.models[body.data.type].attributes, function (attr) {
      return (attr.required && attr.type) ? attr : undefined;
    }), _.isUndefined);
    // Identify missing attributes
    const missingAttributes = body.data.hasOwnProperty('attributes') ? _.difference(_.keys(requiredAttributes), _.keys(body.data.attributes)) : null;

    if (!_.isEmpty(missingAttributes)) {
      throw {
        status: 403,
        body: {
          message: 'Missing required attributes (' + missingAttributes.toString() + ')'
        }
      };
    }

    // Extract required relationships
    const requiredRelationships = _.omit(_.mapValues(strapi.models[body.data.type].attributes, function (attr) {
      return (attr.required && (attr.model || attr.collection)) ? attr : undefined;
    }), _.isUndefined);
    // Identify missing relationships
    const missingRelationships = body.data.hasOwnProperty('relationships') ? _.difference(_.keys(requiredRelationships), _.keys(body.data.relationships)) : null;

    if (!_.isEmpty(missingRelationships)) {
      throw {
        status: 403,
        body: {
          message: 'Missing required relationships (' + missingRelationships.toString() + ')'
        }
      };
    }

    // Build array of errors
    if (_.size(requiredRelationships)) {
      const errors = _.remove(_.flattenDeep(_.map(body.data.relationships, function (relation, key) {
        if (!relation.hasOwnProperty('data')) {
          return {
            message: 'Missing `data` member for relationships ' + relation
          };
        } else if (_.isArray(relation.data)) {
          return _.map(relation.data, function (ressource, position) {
            if (!utils.isRessourceObject(ressource)) {
              return {
                position: position,
                message: 'Invalid ressource object in relationships ' + key
              };
            }
          });
        } else if (!utils.isRessourceObject(relation.data)) {
          return {
            message: 'Invalid ressource object for relationships ' + key
          };
        }
      })), function (n) {
        return !_.isUndefined(n);
      });

      if (!_.isEmpty(errors)) {
        throw {
          status: 403,
          body: errors
        };
      }
    }
  }
};
<|endoftext|>