kendo.culture("pt-BR");

// para testes
var vok = "";
var verror = "";
var vsuccess = "";
var vcomplete = "";
var vt1 = "naoini"; vt2 = "naoini"; vt3 = "naoini"; vt4 = "naoini";
var ve1 = "naoini"; ve2 = "naoini"; ve3 = "naoini"; ve4 = "naoini";
var vtl = [];
var vtd = {};

var s_data, s_textStatus, s_jqXHR,
    e_jqXHR, e_textStatus, e_errorThrown;

var $export = $export || {};

// controle de sessao por aba
var GuidProxy = "";

// componenete User

function User(login, base) {
    this.login = login || "";
    this.base = base || "";
}

User.prototype.update = function (user) {
    "use strict";
    this.login = user.Nome;
    this.base = user.NomeBase;
};

User.prototype.getCustomData = function (key) {
    "use strict";
    var self = this;
    if (localStorage) {
        return localStorage.getItem(self.login + "_" + key + "_" + self.base);
    }
    return null;
};

User.prototype.setCustomData = function (key, value) {
    "use strict";
    var self = this;
    if (localStorage) {
        localStorage.setItem(self.login + '_' + key + '_' + self.base, value);
    }
};

User.prototype.getSessionData = function (key) {
    "use strict";
    var self = this;
    if (window.sessionStorage) {
        return window.sessionStorage.getItem(self.login + "_" + key + "_" + self.base);
    }
    return null;
};

User.prototype.setSessionData = function (key, value) {
    "use strict";
    var self = this;
    if (window.sessionStorage) {
        window.sessionStorage.setItem(self.login + '_' + key + '_' + self.base, value);
    }
};

var currentUser = new User();

// extend string

if (typeof String.prototype.format !== 'function') {
    String.prototype.format = function () {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function (match, number) {
            return typeof args[number] != 'undefined'
              ? args[number]
              : match
            ;
        });
    };
}

if (typeof String.prototype.toDate !== 'function') {
    String.prototype.toDate = function () {
        var mes = this.substr(3, 3);
        var dia = this.substr(0, 3);
        var ano = this.substr(6, 4);
        return new Date(mes + dia + ano);
    };
}

if (typeof String.prototype.toFloat !== 'function') {
    String.prototype.toFloat = function () {
        return parseFloat(this.replace('.', '').replace(',', '.'));
    };
}

if (typeof String.prototype.toInt !== 'function') {
    String.prototype.toInt = function () {
        return parseInt(this.replace('.', '').replace(',', '.'));
    };
}

if (typeof String.prototype.asFloat !== 'function') {
    String.prototype.asFloat = function () {
        return parseFloat(this);
    };
}

if (typeof String.prototype.asInt !== 'function') {
    String.prototype.asInt = function () {
        return parseInt(this);
    };
}

if (typeof String.prototype.toCasasDecimais !== 'function') {
    String.prototype.toCasasDecimais = function (casasDecimais) {
        var value = this.replace(',', '');
        value = value.replace('.', '');
        var arr = value.split('');
        arr.reverse();
        arr.splice(casasDecimais, 0, ',');
        arr.reverse();
        value = arr.join('');
        return value;
    };
}

if (typeof String.prototype.startsWith !== 'function') {
    String.prototype.startsWith = function (str) {
        return this.indexOf(str) == 0;
    };
}

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function (str) {
        return this.slice(-str.length) == str;
    };
}

if (typeof String.prototype.isValidDate !== 'function') {
    String.prototype.isValidDate = function () {
        var dateRegExp = /^(?:(?:31(\/|-|\.))(?:0?[13578]|1[02])\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/;
        var matched = this.match(dateRegExp);
        return matched != null;
    };
}

if (typeof String.prototype.leftPad !== 'function') {
    String.prototype.leftPad = function (length, padString) {
        var str = this;
        if (str.length >= length) {
            return str.toString();
        }
        else {
            if (padString === undefined)
                padString = " ";
            while (str.length < length)
                str = padString + str;
            return str;
        }
    };
}

if (typeof String.prototype.empty !== 'function') {
    String.prototype.empty = function () {
        return this.trim() === '';
    };
}

if (typeof String.prototype.removeOccurrencesOf !== 'function') {
    String.prototype.removeOccurrencesOf = function (regExp) {
        return this.replace(regExp, '');
    };
}

if (typeof String.prototype.formatMoney !== 'function') {
    Number.prototype.formatMoney = function (c, d, t) {
        var n = this,
            c = isNaN(c = Math.abs(c)) ? 2 : c,
            d = d == undefined ? "," : d,
            t = t == undefined ? "." : t,
            s = n < 0 ? "-" : "",
            i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
            j = (j = i.length) > 3 ? j % 3 : 0;
        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };
}

// extend date

if (typeof Date.prototype.compare !== 'function') {
    Date.prototype.compare = function () {
        if (arguments.length == 0 || typeof arguments[0] !== 'object') {
            throw new Error('Invalid Argument!');
        } else {
            if (this > arguments[0]) {
                return "greater";
            } else if (this < arguments[0]) {
                return "less";
            } else {
                return "equal";
            }
        }
    };
}

// extend document

if (typeof document.getElementsByClassName !== 'function') {
    document.getElementsByClassName = function () {
        var elms = document.getElementsByTagName('*');
        var ei = new Array();
        var ecl;
        for (var i = 0; i < elms.length; i++) {
            if (elms[i].getAttribute('class')) {
                ecl = elms[i].getAttribute('class').split(' ');
                for (j = 0; j < ecl.length; j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            } else if (elms[i].className) {
                ecl = elms[i].className.split(' ');
                for (var j = 0; j < ecl.length; j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            }
        }
        return ei;
    };
}

// extend number

if (typeof Number.prototype.compare !== 'function') {
    Number.prototype.compare = function () {
        if (arguments.length == 0 || typeof arguments[0] !== 'number') {
            throw new Error('Invalid Argument!');
        }
        if (this > arguments[0]) {
            return "greater";
        } else if (this < arguments[0]) {
            return "less";
        } else {
            return "equal";
        }
    };
}

// extend jquery

(function ($) {
    $.fn.viewModel = function (viewModelName) {
        var viewModel = this[0], selector = this.selector;

        if (viewModelName !== undefined && viewModel !== undefined) {
            set(viewModelName, viewModel);
        } else if (selector !== undefined) {
            return get(selector);
        }
        return this;
    };

    var InputType = {
        CHECKBOX: 'checkbox'
    };

    function set(viewModelName, viewModel) {
        var $bindedViewModel = $('[vm-model=' + viewModelName + ']');
        for (var prop in viewModel) {
            if (viewModel.hasOwnProperty(prop)) {
                var $field = $bindedViewModel.filter('[vm-field=' + prop + ']')
				   , type = $field.attr('type');
                setDataForType($field, type, viewModel[prop]);
            }
        }
    }

    function setDataForType($el, type, data) {
        switch (type) {
            case InputType.CHECKBOX:
                $el[0].checked = data;
                break;
            default:
                $el.val(data);
                break;
        }
    }

    function get(viewModelName) {
        var model = {}, $bindedViewModel = $('[vm-model=' + viewModelName + '][vm-field]');

        $bindedViewModel.each(function (i, el) {
            var $el = $(el)
			   , field = $el.attr('vm-field')
			   , type = $el.attr('type')
			   , data = getValueForType($el, type);

            model[field] = getValueForType($el, type);
        });
        return model;
    }

    function getValueForType($el, type) {
        switch (type) {
            case InputType.CHECKBOX:
                return $el[0].checked;
                break;
            default:
                return $el.val();
                break;
        }
    }
})(jQuery);

(function ($) {
    $.fn.template = function () {
        var model = this.selector;
        if (model)
            return $('.template[data-template=' + model + ']').html();
        return null;
    };
})(jQuery);

// versao do browser

log_versao = (function () {
    obj_log_versao = {
        log: ""
    };
    function log_versao_ok(dados) {
        obj_log_versao.log += dados + "\r\n";
    }

    log_versao_ok("versao_ok");
    log_versao_ok("");
    log_versao_ok("navigator.userAgent=" + navigator.userAgent);
    log_versao_ok("");
    // o SeaMonkey fica igual ao Firefox por isso o if abaixo
    if (navigator.userAgent.toLowerCase().indexOf("seamonkey") > -1
        || navigator.userAgent.toLowerCase().indexOf("opera") > -1) {
        log_versao_ok("return eh opera");
        return false;
    }
    if (navigator.userAgent.toLowerCase().indexOf("chrome") !== -1
        && navigator.userAgent.toLowerCase().indexOf("msie") !== -1
        && navigator.userAgent.toLowerCase().indexOf("firefox") !== -1
        && navigator.userAgent.toLowerCase().indexOf("safari") !== -1) {
        log_versao_ok("return nao eh chrome/msie/firefox/safari");
        return false;
    }

    var ua = navigator.userAgent, tem,
    M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i) || [];
    if (/trident/i.test(M[1])) {
        tem = /\brv[ :]+(\d+(\.\d+)?)/g.exec(ua) || [];
        var result = 'IE ' + (tem[1] || '');
        log_versao_ok("return RE1");
        return result;
    }
    M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
    if ((tem = ua.match(/version\/([\.\d]+)/i)) != null) M[2] = tem[1];
    var nome_versao = M.join(' ');

    // - exemplos
    // Chrome 29.0.1547.76
    // Firefox 20.0
    // MSIE 7.0
    // modo padrao compativel do ie8 aparece como ie7
    // MSIE 8.0
    // MSIE 10.0
    // Opera 9.80 11.61
    // Safari 534.57.2 5.1.7

    var lst_nome_versao = nome_versao.split(" ");
    obj_log_versao.nome_versao = lst_nome_versao[0].toLowerCase();
    log_versao_ok("nome_versao=" + nome_versao);
    log_versao_ok("lst_nome_versao=" + lst_nome_versao);

    // exemplo: se tiver somente "MSIE" ao inves de "MSIE 10.0"
    if (lst_nome_versao.length < 2) {
        log_versao_ok("return lst_nome_versao.length < 2");
        return false;
    }

    var lst_versao = lst_nome_versao[1].split(".");
    var nro_versao_maior = 0;
    try {
        log_versao_ok("try lst_versao=" + lst_versao);
        var nro = parseInt(lst_versao[0]);
        if (typeof nro == "number")
            nro_versao_maior = nro;
    }
    catch (e) {
        log_versao_ok("catch lst_versao");
    }
    obj_log_versao.nro_versao_maior = nro_versao_maior;
    log_versao_ok("nro_versao_maior=" + nro_versao_maior);

    if (lst_nome_versao[0].toLowerCase() != "chrome" && lst_nome_versao[0].toLowerCase() != "firefox" && lst_nome_versao[0].toLowerCase() != "msie" && lst_nome_versao[0].toLowerCase() != "safari") {
        log_versao_ok("return lst_nome_versao not chrome/firefox/msi/safari");
        return false;
    }

    if (lst_nome_versao[0].toLowerCase() == "chrome" && nro_versao_maior < 25) {
        log_versao_ok("return chrome < 25");
        return false;
    }
    if (lst_nome_versao[0].toLowerCase() == "safari" && nro_versao_maior < 500) {
        log_versao_ok("return safari < 9");
        return false;
    }
    if (lst_nome_versao[0].toLowerCase() == "firefox" && nro_versao_maior < 20) {
        log_versao_ok("return firefox < 20");
        return false;
    }
    if (lst_nome_versao[0].toLowerCase() == "msie" && nro_versao_maior < 9) {
        log_versao_ok("return msie < 9");
        return false;
    }

    log_versao_ok("ok");
    return obj_log_versao;
})();

// diversos

if (!Date.now) {
    Date.now = function () {
        return new Date();
    };
}

function getQueryParam(name) {
    if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
        return decodeURIComponent(name[1]);
}

function getCurrentDateHour() {
    var dateHour = new Date();
    var yyyy = dateHour.getFullYear();
    var mm = dateHour.getMonth() + 1;
    var dd = dateHour.getDate();
    var hh = dateHour.getHours();
    var min = dateHour.getMinutes();

    if (mm < 10)
        mm = "0" + mm;
    if (dd < 10)
        dd = "0" + dd;
    if (hh < 10)
        hh = "0" + hh;
    if (min < 10)
        min = "0" + min;

    return dd + "/" + mm + "/" + yyyy + " - " + hh + ":" + min;
}

function getDateNowDDMMYYYY() {
    var today = new Date();

    var yyyy = today.getFullYear();

    var mm = today.getMonth() + 1;
    if (mm < 10) {
        mm = "0" + mm;
    }

    var dd = today.getDate();
    if (dd < 10) {
        dd = "0" + dd;
    }

    today = dd + "/" + mm + "/" + yyyy;
    return today;
}

function getDateNowMMYYYY() {
    var today = new Date();

    var yyyy = today.getFullYear();

    var mm = today.getMonth() + 1;
    if (mm < 10) {
        mm = "0" + mm;
    }

    today = mm + "/" + yyyy;
    return today;
}

function getDateJsonMS(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}

function getDateJsonMSDay(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)).getDate();
}

function getDateJsonMSMonth(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)).getMonth() + 1;
}

function getDateJsonMSYear(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)).getFullYear();
}

function getDateJsonMSYearYY(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)).getFullYear().toString().substr(2, 2);
}

function getDateJsonMSYearYYYY(value) {
    return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10)).getFullYear();
}

function getDateJsonMSStringDDMMYY(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: getDateJsonMSStringDDMMYY'");
    else if (typeof value !== "string")
        throw new Error("O tipo do parametro 'value' eh invalido. Rotina: 'getDateJsonMSStringDDMMYY', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        return "00/00/0000";
    else {
        var year = getDateJsonMSYearYY(value).toString();
        if (year.length < 2) year = "0" + year;

        var month = getDateJsonMSMonth(value).toString();
        if (month.length < 2) month = "0" + month;

        var day = getDateJsonMSDay(value).toString();
        if (day.length < 2) day = "0" + day;

        var data = day + "/" + month + "/" + year;
        if (data === "01/01/01") data = "00/00/00";

        return data;
    }
}

function getDateJsonMSStringDDMMYYYY(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: getDateJsonMSStringDDMMYYYY'");
    else if (typeof value !== "string")
        throw new Error("O tipo do parametro 'value' eh diferente 'string'. Rotina: 'getDateJsonMSStringDDMMYYYY', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        return "00/00/0000";
    else {
        var year = getDateJsonMSYearYYYY(value).toString();
        if (year.length < 2) year = "0" + year;
        if (year.length < 3) year = "0" + year;
        if (year.length < 4) year = "0" + year;

        var month = getDateJsonMSMonth(value).toString();
        if (month.length < 2) month = "0" + month;

        var day = getDateJsonMSDay(value).toString();
        if (day.length < 2) day = "0" + day;

        var data = day + "/" + month + "/" + year;
        if (data === "01/01/0001") data = "00/00/0000";

        return data;
    }
}

function convertDateToStringDDMMYYYY(value) {
    if (value === undefined || value === null || value === "")
        throw new Error("O parametro 'value' nao foi informado. Rotina: convertDateToStringDDMMYYYY'");
    else if (typeof value !== "object")
        throw new Error("O tipo do parametro 'value' eh diferente 'object'. Rotina: 'convertDateToStringDDMMYYYY', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else {
        var year = value.getFullYear();

        var month = (value.getMonth() + 1).toString();
        if (month.length < 2) month = "0" + month;

        var day = value.getDate().toString();
        if (day.length < 2) day = "0" + day;

        var data = day + "/" + month + "/" + year;
        return data;
    }
}

// TODO: renomear para mapper? colocar no objeto Date? objs, functions auxiliares?
function convertStringDecimalPtBrToFloat(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: convertStringDecimalPtBrToFloat'");
    else if (typeof value !== "string")
        throw new Error("O tipo do parametro 'value' eh diferente 'string'. Rotina: 'convertStringDecimalPtBrToFloat', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        return 0;
    else 
        return parseFloat(value.replace(".", "").replace(",", "."));
}

function convertDateStringDDMMYYYYToDate(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: convertDateStringDDMMYYYYToDate'");
    else if (typeof value !== "string")
        throw new Error("O tipo do parametro 'value' eh diferente 'string'. Rotina: 'convertDateStringDDMMYYYYToDate', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        return "00/00/0000";
    else {
        var dataSplit = value.split("/");
        return new Date(dataSplit[2], (parseInt(dataSplit[1]) - 1).toString(), dataSplit[0]);
    }
}

function convertDateStringMMYYYYToDate(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: convertDateStringMMYYYYToDate'");
    else if (typeof value !== "string")
        throw new Error("O tipo do parametro 'value' eh diferente 'string'. Rotina: 'convertDateStringMMYYYYToDate', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        return "00/0000";
    else {
        var dataSplit = value.split("/");
        return new Date(dataSplit[1], (parseInt(dataSplit[0]) - 1).toString(), 1);
    }
}

function formatDecimalPtBr(value) {
    if (value === undefined)
        throw new Error("O parametro 'value' nao foi informado. Rotina: formatDecimalPtBr'");
    else if (typeof value !== "number")
        throw new Error("O tipo do parametro 'value' eh diferente 'number'. Rotina: 'formatDecimalPtBr', value=\"{0}\", tipo=\"{1}\"".format(value, typeof value));
    else if (value === null || value === "")
        value = 0;
    return value.formatMoney().leftPad(15).replace(" ", "&nbsp");
}

function setVal(id, value) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    $(obj).val(value);
}

function isChecked(id) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    return $(obj).is(":checked");
}

function getVal(id) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    return $(obj).val();
}

function getDate(id) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    return $(obj).val() === "" ? "" : $(obj).val().substr(3, 3) + $(obj).val().substr(0, 3) + $(obj).val().substr(6, 4);
}

function setHtml(id, value) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    $(obj).html(value);
}

function getHtml(id) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    return $(obj).html();
}

function setChecked(id, op) {
    var obj = document.getElementById(id);
    if (obj === null)
        throw new Error("Objeto \"{0}\" nao encontrado.".format(id));
    obj.checked = op;
}

function requestLeg(onComplete) {
    "use strict";
    $.ajax({
        type: "GET",
        url: window.baseUrl + "Leg",
        async: true,
        cache: true,
        complete: function () {
            if (onComplete) {
                onComplete();
            }
        }
    });
}

function sleep(milliseconds) {
    if (milliseconds === undefined || milliseconds === null || typeof milliseconds !== "number")
        milliseconds = 1000;

    $.ajaxSetup({
        async: false
    });

    $.getJSON(window.baseUrl + "util/sleep?milliseconds=" + milliseconds.toString(), null, function (data) {
    });

    $.ajaxSetup({
        async: true
    });
}

var log = (function (msg) {
    if (window.console && window.console.log)
        console.log(msg);
});

var ping = {
    when: "ping",
    time: 10000,
    showConsole: false,
    stop: false,
    start: (function () {
        // fixar manualmente o "timeout" no ajax para evitar usar um valor padão pequeno
        // usar cache=false no ajax para ter certeza que vai cair no aplicativo
        window.setTimeout(function () {
            $.ajax({
                type: "POST",
                url: window.baseUrl + ping.when,
                cache: false,
                timeout: 50000,
                beforeSend: function () {
                    if (ping.showConsole) log("send ping url={0}".format(window.baseUrl + ping.when));
                },
                error: function (jqxhr, textStatus, errorThrown) {
                    if (ping.showConsole) log("    error ping, textStatus=\"{6}\", errorThrown=\"{7}\", readyState=\"{0}\", status=\"{1}\", statusText=\"{2}\", responseText=\"{3}\", isResolved=\"{4}\", isRejected=\"{5}\", "
                        .format(jqxhr.readyState, jqxhr.status, jqxhr.statusText, jqxhr.responseText, jqxhr.isResolved(), jqxhr.isRejected(), textStatus, errorThrown));
                    if (jqxhr.status === 0) {
                        // melhorar
                        //alert("Error, sem conexão.");
                        // se ocorrer erro de rede, nao fazer o ping novamente, pq pode ocorrer erros de rede seguido,
                        // e essa rotina executar 100mil veses direto, colocar algum tipo de sleep
                    } else if (jqxhr.status == 503) {
                        //alert("Error, limite de conexões do servidor excedido.");
                        if (!ping.stop) window.setTimeout(ping.start, ping.time);
                    } else {
                        //alert("Error: " + jqxhr.status + "-" + jqxhr.responseText);
                        if (!ping.stop) window.setTimeout(ping.start, ping.time);
                    }
                },
                complete: function (jqxhr) {
                    // não usar setInteval, pois pode sobrecarregar o servidor ou o client, só agendar o próximo ping,
                    // quando o anterior terminou
                    if (!ping.stop) window.setTimeout(ping.start, ping.time);
                    if (ping.showConsole) log("    complete ping, readyState=\"{0}\", status=\"{1}\", statusText=\"{2}\", responseText=\"{3}\", isResolved=\"{4}\", isRejected=\"{5}\", "
                        .format(jqxhr.readyState, jqxhr.status, jqxhr.statusText, jqxhr.responseText, jqxhr.isResolved(), jqxhr.isRejected()));
                }
            });
        }, ping.time);
    })
};
ping.start();

var selectDisable = (function (id) {
    $(id).css({
        "-webkit-user-select": "none",
        "-khtml-user-select": "none",
        "-moz-user-select": "none",
        "-ms-user-select": "none",
        "-o-user-select": "none",
        "user-select": "none",
        "-webkit-touch-callout": "none"
    });
    // TODO: no IE9 estava apresentando problemas, resolvi desabilitar no momento
    //$(id).attr("onselectstart", "return false;");
    //$(id).attr("unselectable", "on;");
});

var generateId = (function (pre) {
    try {
        var dt = (new Date()).getTime();
        var ram = Math.random().toString().replace(".", "");
        var id = pre + "-" + dt + "-" + ram;
        var count = $("#" + id).length;
        if (count > 0)
            throw new Error("generateId Exception: Id duplicado.");
        return id;
    }
    catch (err) {
        throw new Error("generateId Exception: {0}".format(err.message));
    }
});

var msgWait = ({
    show: (function (msg, showImage) {
        if (!msg) msg = "Aguarde, processando...";
        if (showImage === undefined || showImage === null) showImage = true;
        if ($("body > #msgWait_loading_overlay").length > 0)
            msgWait.hide();
        var msgWait_loading_overlay = $("<div id='msgWait_loading_overlay'>");
        msgWait_loading_overlay.css({
            "position": "absolute",
            "top": "0",
            "left": "0",
            "right": "0",
            "bottom": "0",
            "background-color": "#000",
            "opacity": "0.7",
            "filter": "alpha(opacity=70)"
        });
        msgWait_loading_overlay.appendTo("body");

        var msgWait_loading_message = $("<div id='msgWait_loading_message'>");
        msgWait_loading_message.css({
            "position": "absolute",
            "width": "400px",
            "height": "100px",
            "left": "50%",
            "top": "50%",
            "margin-left": "-200px",
            "margin-top": "-50px",
            "line-height": "100px",
            "text-align": "center",
            "font-size": "1.2em",
            "background-color": "#fff",
            "border": "1px solid #cccccc",
            "-webkit-border-radius": "9px",
            "-moz-border-radius": "9px",
            "-o-border-radius": "9px",
            "-khtml-border-radius": "9px",
            "border-radius": "9px"
        });
        msgWait_loading_message.html("{0} {1}".format(msg, showImage ? "<img src='" + window.baseUrl + "Libs/Kendo-2013.2.716/styles/Uniform/loading-image.gif' />" : ""));
        msgWait_loading_message.appendTo("body");

        selectDisable("body");
        selectDisable("#msgWait_loading_overlay");
        selectDisable("#msgWait_loading_message");

        msgWait_loading_overlay.css("cursor", "wait");
        msgWait_loading_message.css("cursor", "wait");

        msgWait.isShow = true;
    }),

    hide: (function () {
        $("#msgWait_loading_message").remove();
        $("#msgWait_loading_overlay").remove();

        $("#msgWait_loading_message").css("cursor", "");
        $("#msgWait_loading_overlay").css("cursor", "");

        msgWait.isShow = false;
    })
});
msgWait.isShow = false;

function request(route, params, function_success, function_error, showWait, paramsTransfer, timeout) {
    if (showWait === undefined)
        showWait = true;
    if (showWait) msgWait.show();
    // TODO: melhorar os nomes e logica
    //  colocar num try catch com mensage de der erro, para chamar de novo

    //var span = $("span");
    //for (var tag in span) {
    //    if (span[tag].getAttribute && span[tag].getAttribute("id") !== null) {
    //        //log(span[tag].getAttribute("id"));
    //        $("#" + span[tag].getAttribute("id")).html("ok-span-" + tag);
    //    }
    //}

    //var input = $("input");
    //for (var tag in input) {
    //    if (input[tag].getAttribute && input[tag].getAttribute("id") !== null) {
    //        //log(input[tag].getAttribute("id"));
    //        $("#" + input[tag].getAttribute("id")).val("ok-input-" + tag);
    //    }
    //}

    if (route === undefined || typeof route !== "string" || route === "")
        throw new Error("request: Campo \"route\" nao informado.");

    if (params === null)
        params = undefined;
    if (params !== undefined && (typeof params !== "object"))
        throw new Error("request: Tipo (\"{0}\") do campo \"params\" invalido.".format(typeof params));

    if (function_success === null)
        function_success = undefined;
    if (function_success !== undefined && (typeof function_success !== "function"))
        throw new Error("request: Tipo (\"{0}\") do campo \"function_success\" invalido.".format(typeof function_success));

    if (function_error === null)
        function_error = undefined;
    if (function_error !== undefined && (typeof function_error !== "function"))
        throw new Error("request: Tipo (\"{0}\") do campo \"function_error\" invalido.".format(typeof function_error));

    $.ajax({
        url: window.baseUrl + route,
        type: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json",
            "GuidProxy": GuidProxy
        },
        dataType: "json",
        data: params !== undefined ? JSON.stringify(params) : "",
        cache: false,
        async: true, // se colocar false nao funciona
        timeout: timeout ? timeout : 90000,
        beforeSend: function () {
            //log("***request beforeSend");
        },
        error: function (jqxhr, textStatus, errorThrown) {
            //log("***request verror");
            //log("\terror, textStatus=\"{6}\", errorThrown=\"{7}\", readyState=\"{0}\", status=\"{1}\", statusText=\"{2}\", responseText=\"{3}\", isResolved=\"{4}\", isRejected=\"{5}\", "
            //    .format(jqxhr.readyState, jqxhr.status, jqxhr.statusText, jqxhr.responseText, jqxhr.isResolved(), jqxhr.isRejected(), textStatus, errorThrown));
            if (showWait) msgWait.hide();
            verror = { jqxhr: jqxhr, textStatus: textStatus, errorThrown: errorThrown };
            if (function_error !== undefined)
                function_error(verror);
        },
        success: function (result, textStatus, jqxhr) {
            //log("***request vsuccess: " + result);
            //log("\tcomplete, readyState=\"{0}\", status=\"{1}\", statusText=\"{2}\", responseText=\"{3}\", isResolved=\"{4}\", isRejected=\"{5}\", "
            //    .format(jqxhr.readyState, jqxhr.status, jqxhr.statusText, jqxhr.responseText, jqxhr.isResolved(), jqxhr.isRejected()));
            if (showWait) msgWait.hide();
            vsuccess = { result: result, textStatus: textStatus, jqxhr: jqxhr };
            if (function_success !== undefined)
                function_success(result, paramsTransfer);
        },
        complete: function (jqxhr) {
            //log("***request complete vcomplete:");
            vcomplete = jqxhr;
            if (showWait) msgWait.hide();
        }
    });

    //msgWait.hide();
}

function carregaLogoClienteCompras(CodigoGuid) {
    var src = window.baseUrl + "Compras/Movimentos/GetLogoCliente?guid=" + CodigoGuid;
    $("#logoCliente").attr("src", src);

    $("#logoCliente").on('load', function () {
        var logoCiente = document.getElementById("logoCliente");
        var maxWidth = logoCliente.style.maxWidth.asInt();
        var maxHeight = logoCliente.style.maxHeight.asInt();
        var width = $("#logoCliente").width();
        var height = $("#logoCliente").height();

        if (height < width) {
            var diff = maxHeight - height;
            if (diff > 0)
                logoCliente.style.marginTop = Math.round(diff / 2) + "px";
        }
    });

    $("#linkLogoCliente").on("click", (function () {
        window.location = window.baseUrl;
    }));

    $("#linkLogoRadarWeb").on("dblclick", (function () {
        window.open(window.location);
    }));
}

//
// namespace principal
//

var Radar = {};

Radar.Web = (function () {
    "use strict";
    var Home = {},
        Empresarial = {},
        Contabil = {},
        Comercial = {},
        Gerenciador = {},
        Ged = {},
        Executivo = {},
        Financeiro = {},
        Estoque = {},
        Assistec = {},
        Compras = {},
        Test = {},

        controlGroupBehavior = {
            normal: "control-group",
            error: "control-group error",
            warning: "control-group warning",
            success: "control-group success"
        },
        alertLevel = {
            normal: 0,
            success: 1,
            warning: 2,
            error: 3,
            question: 4
        },
        alertBehavior = {
            success: "success",
            warning: "warning",
            error: "error"
        };

    var IcmsType = {
        CONTRIBUINTE: 83,
        ISENTO: 78,
        NAO_CONTRIBUINTE: 0
    };

    var PessoaType = {
        JURIDICA: 74,
        FISICA: 70
    };
    
    // helper

    function byId(id) {
        return document.getElementById(id);
    }

    // TODO: "succes:", o correto na documentacao do jquery eh success mas estranhamente esta funcionando
    function getJsonFromRoute(route, data, onSuccess, onError) {
        "use strict";
        var url = window.baseUrl + route;
        return $.ajax({
            url: url,
            type: "GET",
            headers: {
                "GuidProxy": GuidProxy
            },
            dataType: "json",
            contentType: 'application/json; charset=utf-8',
            async: true,
            data: data,
            cache: false,
            succes: function (resp) {
                if (onSuccess) {
                    onSuccess(resp);
                }
            },
            error: function (resp) {
                if (onError) {
                    onError(resp);
                }
            }
        });
    }

    // TODO: "succes:", o correto na documentacao do jquery eh success mas estranhamente esta funcionando
    // no momento eh usado apenas no "MovimentosPedido" e "MovimentosAtendimentoTecnico"
    // de preferencia usar request2 que ja tem varios tratamentos padrao
    function postJsonToRoute(route, data, onSuccess, onError) {
        "use strict";
        var url = window.baseUrl + route;
        return $.ajax({
            url: url,
            type: "POST",
            headers: {
                "GuidProxy": GuidProxy
            },
            dataType: "json",
            contentType: 'application/json; charset=utf-8',
            data: data,
            cache: false,
            succes: function (resp) {
                if (onSuccess) {
                    onSuccess(resp);
                }
            },
            error: function (resp) {
                if (onError) {
                    onError(resp);
                }
            }
        });
    }

    // TODO: melhorar
    function requestNoAsync(route, params, onSuccess, onError, catchError) {
        if (route === undefined || typeof route !== "string" || route === "")
            throw new Error("request: Campo \"route\" nao informado.");

        if (params === null)
            params = undefined;
        if (params !== undefined && (typeof params !== "object"))
            throw new Error("request: Tipo (\"{0}\") do campo \"params\" invalido.".format(typeof params));

        if (onSuccess === null)
            onSuccess = undefined;
        if (onSuccess !== undefined && (typeof onSuccess !== "function"))
            throw new Error("request: Tipo (\"{0}\") do campo \"onSuccess\" invalido.".format(typeof onSuccess));

        if (onError === null)
            onError = undefined;
        if (onError !== undefined && (typeof onError !== "function"))
            throw new Error("request: Tipo (\"{0}\") do campo \"onError\" invalido.".format(typeof onError));

        // TODO: colocar em um try catch tb
        $.ajax({
            url: route,
            type: "POST",
            data: params !== undefined ? JSON.stringify(params) : "",
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json",
                "GuidProxy": GuidProxy
            },
            dataType: "json",
            cache: false,
            async: false,
            timeout: 90000,
            error: function (jqxhr, textStatus, errorThrown) {
                if (catchError) {
                    log("Error: textStatus=\"{6}\", errorThrown=\"{7}\", readyState=\"{0}\", status=\"{1}\", statusText=\"{2}\", responseText=\"{3}\", isResolved=\"{4}\", isRejected=\"{5}\", ".format(jqxhr.readyState, jqxhr.status, jqxhr.statusText, jqxhr.responseText, jqxhr.isResolved(), jqxhr.isRejected(), textStatus, errorThrown));
                    var u = new Util();
                    u.alert("Erro: " + jqxhr.status + "-" + jqxhr.statusText, getAlertBehavior(alertLevel.warning));
                }
                verror = { jqxhr: jqxhr, textStatus: textStatus, errorThrown: errorThrown };
                if (onError !== undefined)
                    onError(verror);
            },
            success: function (result, textStatus, jqxhr) {
                vsuccess = { result: result, textStatus: textStatus, jqxhr: jqxhr };
                if (onSuccess !== undefined)
                    onSuccess(result);
            }
        });
    }

    // TODO: melhorar fazer:
    //      tratamento de timeout
    //      opção de retry quando ocorrer erro interno ou timeout
    //      tratamento erro quando servidor está off, ou recusando muitos pedidos
    //      opção de enviar email do erro gerado
    //      verificar integridade do retorno
    // já trata por padrão vários erros de chamadas ajax:
    //      tela de wait automáticamente, sem cache
    //      tratamento padrão para erro de código interno JS
    //      tratamento padrão para erro alert do servidor
    //      redirect para sessão expirada
    //      tratamento padrão para erro interno (> 500) no servidor
    //
    // o erro abaixo ocorre quando fazer request com um route errado,
    // o endereco do route tem que ter um retorno no formato json, e nao html
    // jqxhr.status 200
    // jqxhr.statusText "OK"
    // textStatus "parsererror"
    // errorThrown.message "Unexpected token <"
    function request2(route, params, onSuccess, onError, onIsAlert, timeout, onAfterShowAlertError, onAfterShowAlert, onAfterShowError) {
        var u = new Util();

        function localOnAfterShowAlert() {
            if (onAfterShowAlertError) onAfterShowAlertError();
            if (onAfterShowAlert) onAfterShowAlert();
        }

        function localOnAfterShowError() {
            if (onAfterShowAlertError) onAfterShowAlertError();
            if (onAfterShowError) onAfterShowError();
        }

        request(route, params,
            function (model) {
                try {
                    ve2 = model; // seta variáveis globais de erro, para debug em produção

                    if (model.IsAlert && model.CodeError > 0 && onIsAlert) {
                        onIsAlert(model);
                    }
                    else if (model.IsAlert) {
                        // tratamento padrão para erro alert do servidor
                        u.dialogOk(model.Message, null, true, localOnAfterShowAlert, alertBehavior.warning);
                        if (onError) onError();
                    } else {
                        if (onSuccess) {
                            ve3 = onSuccess;
                            onSuccess(model);
                        }
                    }
                }
                catch (err) {
                    ve1 = err; // seta variáveis globais de erro, para debug em produção

                    // tratamento padrão para erro de código interno JS
                    u.dialogOk(err.message, null, true, localOnAfterShowError, alertBehavior.warning);
                    log("number: " + err.number);
                    log("name: " + err.name);
                    log("message: " + err.message);
                    log("description: " + err.description);
                    log("stack: " + err.stack);
                    if (onError) onError();
                }
            },
            function (err) {
                // obs: usado em outras rotinas, se alterar aqui, tem que alterar em outros lugares tambem
                // redirect para sessão expirada
                if (err.jqxhr.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                    window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.location;
                }
                else {
                    ve1 = err; // seta variáveis globais de erro, para debug em produção

                    // tratamento padrão para erro interno (> 500) no servidor
                    u.dialogOk(err.jqxhr.status + "-" + err.jqxhr.statusText + "-" + err.textStatus, null, true, localOnAfterShowError, alertBehavior.warning);
                    if (onError) onError();
                }
            },
            true,
            null,
            timeout
        );
    }

    function redirect(url, params) {
        setTimeout(function () { $('#waiting').show(); }, 200);
        var data = "";
        for (var index in params) {
            data += (data === "" ? "?" : "&") + index + "=" + params[index];
        }
        window.location.href = window.baseUrl + url + (data !== "" ? data : "");
    }
    function getAlertBehavior(level) {
        if (level == alertLevel.success)
            return "success";
        if (level == alertLevel.warning)
            return "warning";
        if (level == alertLevel.error)
            return "error";
        return "warning";
    }

    function alterControlGroupBehavior(fieldId, behavior) {
        "use strict";
        byId(fieldId).parentNode.parentNode.className = behavior;
    }

    function isFieldControlGroupInBehavior(fieldId, behavior) {
        return byId(fieldId).parentNode.parentNode.className == behavior;
    }

    // TODO: refatorar Util.prototype.alterTab = function (tabToAlterIndex) {
    function alterTab(tabToAlterIndex) {
        var tabsLi = $("#myTab li");
        var tabPane = $(".tab-pane");
        for (var i = 0; i < tabsLi.length; i = i + 1) {
            tabsLi[i].className = "";
            tabPane[i].className = "tab-pane";
        }
        tabsLi[tabToAlterIndex].className = "active";
        tabPane[tabToAlterIndex].className = "tab-pane active in";
    }

    function isFieldEnabled(id) {
        return !$("#" + id).attr("disabled");
    }

    function disableNegativePermissionsFields() {
        var inputs = $('input'),
            l = inputs.length;
        for (var i = 0; i < l; i = i + 1) {
            var input = inputs[i];
            if (input.hasAttribute('datapermission')) {
                var permission = input.getAttribute('datapermission');
                if (permission == "False") {
                    input.disabled = true;
                }
            }
        }
    }

    function disableAllInputs() {
        var inputs = $('input'),
           l = inputs.length;
        for (var i = 0; i < l; i = i + 1) {
            var input = inputs[i];
            input.disabled = true;
        }

        var textAreas = $('textarea'),
        g = textAreas.length;
        for (var j = 0; j < g; j = j + 1) {
            var textArea = textAreas[j];
            textArea.disabled = true;
        }
    }

    function makeDatePicker(idDatePicker) {
        $(function () {
            $(idDatePicker).datepicker($.extend({
                closeText: 'Fechar',
                prevText: '&#x3c;Anterior',
                nextText: 'Proximo&#x3e;',
                currentText: 'Atual',
                monthNames: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
                monthNamesShort: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
                dayNames: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
                dayNamesShort: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'],
                dayNamesMin: ['D', 'S', 'T', 'Q', 'Q', 'S', 'S'],
                weekHeader: 'Semanas',
                dateFormat: 'dd/mm/yy',
                firstDay: 1,
                isRTL: false,
                showMonthAfterYear: false,
                yearSuffix: ''
            }, $.datepicker.regional['pt'])).setMask("99/99/9999");
        });
    }

    function makeDatePickerMMAAAA(idDatePicker) {
        $(idDatePicker).datepicker({
            monthNames: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
            monthNamesShort: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'mm/yy',
            firstDay: 1,
            isRTL: false
        });

        $(idDatePicker).focus(function () {
            var thisCalendar = $(this);
            $('.ui-datepicker-calendar').detach();
            $('.ui-datepicker-close').click(function () {
                var month = parseInt($("#ui-datepicker-div .ui-datepicker-month :selected").val());
                month++;
                if (month.toString().length === 1) month = "0" + month;
                var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                $(idDatePicker).val(month + "/" + year);
                $(idDatePicker).trigger("change");
            });
            $("#ui-datepicker-div > .ui-datepicker-calendar").css("display", "none");
            $("#ui-datepicker-div .ui-datepicker-current").css("display", "none");
            $("#ui-datepicker-div .ui-datepicker-close").html("OK");
        });

        $(idDatePicker).setMask("99/9999");
    }

    function setMaxPagersSize(size) {
        var pagers = $('.k-pager-numbers');
        pagers.each(function (index, pager) {
            setPagerSize(pager, size);
        });
    }

    function setPagerSize(pager, size) {
        var lis = pager.children;
        var l = lis.length;
        for (var i = size + 1; i < l; i = i + 1) {
            lis.item(size).remove();
        }
    }

    function setMask() {
        $(".masked").each(function (index, input) {
            var mask = input.attributes.radarmask.value;
            var params = mask.split('valor');

            if (params.length == 1) {
                $(input).setMask();
            } else {

                var integer = params[1].split('-')[1];
                var decimal = params[1].split('-')[2];

                $(input).autoNumeric('destroy');
                $(input).autoNumeric('init', getAutoNumericOptions(integer, decimal));
            }
        });
    }

    function getAutoNumericOptions(integer, decimal) {
        return {
            aSep: '.',
            aDec: ',',
            altDec: '.',
            vMin: toVMaskAutoNumeric(integer, decimal, '0'),
            vMax: toVMaskAutoNumeric(integer, decimal, '9')
        };
    }

    function toVMaskAutoNumeric(integer, decimal, value) {
        return "{0}.{1}".format(toVNumAutoNumeric(integer, value), toVNumAutoNumeric(decimal, value));
    }

    function toVNumAutoNumeric(qnt, value) {
        var result = "";
        for (var i = 0; i < qnt; i = i + 1) {
            result = result.concat(value);
        }
        return result;
    }

    function listenToggleProdutoGradesF4() {
        "use stric";

        // se alterar aqui, verificar se tem que alterar em:
        // listenToggleProdutoGradesF4
        // ModalGrupoContas.prototype.listenToggleProdutoGradesF4
        // ValidatorLookupProduto.prototype.listenToggleProdutoGradesF4

        $('#inputCodigoProduto').on('focus', function () {
            "use strict";
            $('#linkButtonModalProdutos').show();
            $('#linkButtonModalGrade1').hide();
            $('#linkButtonModalGrade2').hide();
            $('#linkButtonModalGrade3').hide();
        });
        $('#inputCodigoGrade1').on('focus', function () {
            "use strict";
            $('#linkButtonModalProdutos').hide();
            $('#linkButtonModalGrade1').show();
            $('#linkButtonModalGrade2').hide();
            $('#linkButtonModalGrade3').hide();
        });
        $('#inputCodigoGrade2').on('focus', function () {
            "use strict";
            $('#linkButtonModalProdutos').hide();
            $('#linkButtonModalGrade1').hide();
            $('#linkButtonModalGrade2').show();
            $('#linkButtonModalGrade3').hide();
        });
        $('#inputCodigoGrade3').on('focus', function () {
            "use strict";
            $('#linkButtonModalProdutos').hide();
            $('#linkButtonModalGrade1').hide();
            $('#linkButtonModalGrade2').hide();
            $('#linkButtonModalGrade3').show();
        });
    }

    function dateValidatorOnValid(validator) {
        var input = $(validator.input);
        input.prev().removeClass('radar-error');
        input.removeClass('radar-error');
    }

    // TODO: remover futuramente
    function dateValidatorOnInvalid(validator) {
        var u = new Util();
        var input = $(validator.input);
        input.prev().addClass('radar-error');
        input.addClass('radar-error');
        if (!validator.v2)
            input.focus();

        if (validator.isMMAAAA) {
            if (!validator.input.value.match(/^\d{2}\/\d{4}$/)) {
                u.alert('Informe uma data com o formato MM/AAAA.', alertBehavior.warning);
            } else {
                u.alert('A data: "{0}" não é uma data válida'.format(input.val()), alertBehavior.warning);
            }
        }
        else {
            if (validator.input.value.match(/^\d{2}\/\d{2}\/\d{2}$/)) {
                u.alert('Informe uma data com o formato DD/MM/AAAA.', alertBehavior.warning);
            } else {
                u.alert('A data: "{0}" não é uma data válida'.format(input.val()), alertBehavior.warning);
            }
        }
    }

    // TODO: duplicado, se alterar aqui, alterar no ValidatorDate
    function dateValidatorOnInvalidDialog(validator, onAfterShow) {
        var u = new Util();

        if (validator.isMMAAAA) {
            if (!validator.input.value.match(/^\d{2}\/\d{4}$/))
                u.dialogOk('Informe uma data com o formato MM/AAAA.', null, true, onAfterShow, alertBehavior.warning);
            else
                u.dialogOk('A data: "{0}" não é uma data válida'.format(validator.input.value), null, true, onAfterShow, alertBehavior.warning);
        }
        else {
            if (validator.input.value.match(/^\d{2}\/\d{2}\/\d{2}$/))
                u.dialogOk('Informe uma data com o formato DD/MM/AAAA.', null, true, onAfterShow, alertBehavior.warning);
            else
                u.dialogOk('A data: "{0}" não é uma data válida'.format(validator.input.value), null, true, onAfterShow, alertBehavior.warning);
        }
    }

    // TODO:
    function setFilialDefault(validator, setTodas, NoAsync) {
        var u = new Util();
        if (NoAsync) {
            $.ajax({
                type: "GET",
                url: window.baseUrl + "Empresarial/F4Filial/GetFilialPadrao_E_QuantidadeFiliaisAtivas",
                async: false,
                data: "",
                dataType: "json",
                contentType: 'application/json; charset=utf-8',
                cache: false,
                success: function (data) {
                    if (data.IsAlert)
                        u.alert(data.Message, alertBehavior.warning);
                    // quando tem mas de uma Filial ativa, retorna "0 - Todas Filiais"
                    if (data.QuantidadeFiliaisAtivas > 1) {
                        if (setTodas)
                            validator.setValues(data.Codigo, data.Nome);
                        validator.enable();
                    }
                    else {
                        validator.setValues(data.Codigo, data.Nome);
                        validator.disable();
                    }
                },
                error: function (result) {
                    u.alert(result.status + "-" + result.statusText, alertBehavior.warning);
                }
            });
        }
        else {
            getJsonFromRoute("Empresarial/F4Filial/GetFilialPadrao_E_QuantidadeFiliaisAtivas").done(
                function (data) {
                    if (data.IsAlert)
                        throw new Error(data.Message);
                    // quando tem mas de uma Filial ativa, retorna "0 - Todas Filiais"
                    if (data.QuantidadeFiliaisAtivas > 1) {
                        if (setTodas)
                            validator.setValues(data.Codigo, data.Nome);
                        validator.enable();
                    }
                    else {
                        validator.setValues(data.Codigo, data.Nome);
                        validator.disable();
                    }
                }
            );
        }
    }

    function msgWarning(msg) {
        Alert(msg, getAlertBehavior(alertLevel.warning));
    }

    var Alert = function (message, behavior) {
        var modal = "";
        modal += '<div class="alert alert-' + behavior + ' data-dismiss="alert" ">';
        modal += '<button type="button" class="close" data-dismiss="alert">&times;</button>';
        modal += '<strong>' + message + '</strong></i>';
        modal += '</div>';
        $("#divErrors").append(modal);
    };

    // utils

    var Util = function () {
    };

    Util.prototype.addButtonHelpBreadcrumb = function (help, title, cotacaoWeb) {
        if ($(".breadcrumb").length > 0 && $(".breadcrumb > .radar-help").length === 0) {
            var html = '<a class="radar-help" style="float: right; padding: 0; margin: 0; margin-top: -10px " href="#" role="button" data-toggle="modal" data-help="' + help + '" data-title="' + title + '"><i class="sprite-help-gray"></i></a>';
            $(".breadcrumb").append(html);

            // listen
            $('.radar-help').on('click', function (e) {
                if (cotacaoWeb) {
                    window.open(window.baseUrl + 'helps/CotacaoWeb/CotacaoWeb.htm', "Help");
                }
                else {
                    var basHelp = window.baseUrl + 'helps/';
                    var inp = e.currentTarget;
                    if (inp.hasAttribute('data-help')) {
                        var help = inp.getAttribute('data-help');
                        // se for IE9 ocorre erro de "SCRIPT87: Argumento inválido" quando no 2 parametro do window.open, 
                        // contiver um texto "Help.hml", o problema no texto é o ".htm", pois sem o mesmo funciona
                        if (inp.hasAttribute('data-title') && !(log_versao.nome_versao === "msie" && log_versao.nro_versao_maior === 9)) {
                            var title = inp.getAttribute('data-title');
                            window.open(basHelp + help, title);
                        } else {
                            window.open(basHelp + help, "Help");
                        };
                    }
                }
            });
        }
    };

    Util.prototype.alert = function (message, behavior, untilClick, pAlertId) {
        var modal = "";

        // controle para remover mensagens duplicadas
        var msgs = $(".alert > strong");
        var mensagemDuplicada = false;
        for (var i = 0; i < msgs.length; i++) {
            if ($(msgs[i]).html() === message) {
                mensagemDuplicada = true;
            }
        }
        if (mensagemDuplicada)
            return;
        // TODO: como evitar mesma mensagem aparecer mais de uma vez
        var alertId = "alert" + Date.now();
        //if (pAlertId !== undefined && pAlertId !== "")
        //    alertId = pAlertId;

        modal += '<div id="' + alertId + '" class="alert alert-' + behavior + ' " data-dismiss="alert" >';
        modal += '<a class="close" data-dismiss="alert" href="#">&times;</a>';
        modal += '<strong>' + message + '</strong></i>';
        modal += '</div>';

        if (untilClick !== true) {
            setTimeout(function () {
                $("#" + alertId).click();
            }, 5000);
        }

        //if ($("#alertMessage > #" + alertId).length === 0)
        $("#alertMessage").append(modal);
    };

    Util.prototype.dialog = function (title, message, onOk, onCancel, lastFieldFocus, v2) {
        "use strict";
        var modal = "" +
        '<div id="dialogModal" class="modal hide" style="top:20%"  tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">' +
        '<div class="modal-header">' +
        '<h4 id="myModalLabel" style="color: white">' + (title != undefined && title != null && title != "" ? title : 'Confirmação') + '</h4>' +
        '</div>' +
        '<div class="modal-body">' +
        '<p>' + message + '</p>' +
        '</div>' +
        '<div class="modal-footer">' +
        '<button id="buttonConfirm" class="btn btn-inverse btn-small " data-dismiss="modal">Sim</button>' +
        '<button id="buttonCancel" class="btn btn-inverse btn-small" data-dismiss="modal" aria-hidden="true">Não</button>' +
        '</div>' +
        '</div>';
        document.getElementById('modalDiv').innerHTML = modal;

        $("#buttonConfirm").on('click', function (ev) {
            onOk(ev);
            if (v2) $('#dialogModal').modal('hide');
        });

        if (onCancel !== undefined && onCancel !== null) {
            $('#buttonCancel').on('click', function (ev) {
                onCancel(ev);
                if (v2) $('#dialogModal').modal('hide');
            });
        }

        if (lastFieldFocus !== undefined && lastFieldFocus !== null) {
            $('#cancelModal').on('hidden', function () {
                $("#" + lastFieldFocus).focus();
            });
        }

        if (v2)
            $('#dialogModal').modal('show');
    };

    Util.prototype.dialogOk = function (message, callback, v2, onAfterShow, behavior, onBeforeShow, noButtons) {
        "use strict";

        // atualmente a busca do datasource do grid é executado 2x, e se ocorrer algum erro, a rotina dialogOk
        // é executada 2x, deixando o fundo da tela preta e não esmaecida
        $(".modal-backdrop.in").remove();

        var id = generateId();

        if (onBeforeShow) {
            onBeforeShow();
        }

        var htmlMessage = message;
        if (v2 && behavior) {
            if (behavior === alertBehavior.success) {
                htmlMessage = '<i class="sprite-warning-green"></i>&nbsp&nbsp&nbsp' + message;
            }
            else {
                htmlMessage = '<i class="sprite-warning-orange"></i>&nbsp&nbsp&nbsp' + message;
            }
        }

        // usado na cotação quando ocorrer error, porque na cotação não tem menus e nem botões de navegação (ex: voltar)
        if (noButtons) {
            var modal = "" +
            '<div id="dialogModalOk' + id + '" class="modal hide" style="top:20%" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">' +
            '<div class="modal-header">' +
            '<h4 id="myModalLabel' + id + '" style="color: white">Mensagem</h4>' +
            '</div>' +
            '<div class="modal-body">' +
            '<p>' + htmlMessage + '</p>' +
            '</div>' +
            '<div class="modal-footer" style="height: 26px">' +
            '</div>' +
            '</div>';
            document.getElementById('modalDiv').innerHTML = modal;
            $('#dialogModalOk' + id).modal('show');
        }
        else {
            var modal = "" +
            '<div id="dialogModalOk' + id + '" class="modal hide" style="top:20%" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">' +
            '<div class="modal-header">' +
            '<h4 id="myModalLabel' + id + '" style="color: white">Mensagem</h4>' +
            '</div>' +
            '<div class="modal-body">' +
            '<p>' + htmlMessage + '</p>' +
            '</div>' +
            '<div class="modal-footer">' +
            '<button id="buttonOk' + id + '" class="btn btn-inverse btn-small" data-dismiss="modal" aria-hidden="true">OK</button>' +
            '</div>' +
            '</div>';
            document.getElementById('modalDiv').innerHTML = modal;

            if (callback) {
                $('#buttonOk' + id).on('click', function () {
                    callback();
                });
            }

            if (v2) {
                $('#buttonOk' + id).on('click', function () {
                    $('#dialogModalOk' + id).modal('hide');
                });
                $('#dialogModalOk' + id).modal('show');
                $('#buttonOk' + id).focus();
            }

            if (onAfterShow) {
                $("#dialogModalOk" + id).on("hidden", function () {
                    onAfterShow();
                })
            }
        }
    };

    Util.prototype.getAlertBehavior = function (level) {
        "use strict";
        switch (level) {
            case 'success':
                return alertBehavior.success;
            case 'warning':
                return alertBehavior.warning;
            case 'error':
                return alertBehavior.warning;
            default:
                return alertBehavior.warning;
        }
    };

    Util.prototype.getAlertBehaviorNumber = function (level) {
        "use strict";
        switch (level) {
            case '1':
                return alertBehavior.success;
            case '2':
                return alertBehavior.warning;
            case '3':
                return alertBehavior.warning;
            default:
                return alertBehavior.warning;
        }
    };

    Util.prototype.getControlGroupBehavior = function (controlGroupLevel) {
        "use strict";
        switch (controlGroupLevel) {
            case 'normal':
                return "control-group";
            case 'success':
                return "control-group success";
            case 'error':
                return "control-group error";
            default:
                return "control-group warning";
        }
    };

    Util.prototype.required = function (inputId, descriptionId, message) {
        "use strict";
        var self = this,
            input = document.getElementById(inputId),
            value = input.value,
            description = document.getElementById(descriptionId);

        if (value === "" || parseInt(value) === 0) {
            self.alterControlGroupBehavior(inputId, self.getControlGroupBehavior(alertLevel.warning));
            self.alert(message, self.getAlertBehavior(alertLevel.warning));
            description.innerHTML = message;
            input.focus();
            throw new Error(message);
        } else {
            self.alterControlGroupBehavior(inputId, self.getControlGroupBehavior(alertLevel.normal));
            description.innerHTML = "";
            return value;
        }
    };

    Util.prototype.alterControlGroupBehavior = function (inputId, behavior) {
        "use strict";
        document.getElementById(inputId).parentNode.parentNode.className = behavior;
    };

    Util.prototype.alterTab = function (tabToAlterIndex) {
        var tabsLi = $("#myTab li"),
            j = tabsLi.length,
            tabPane = $(".tab-pane");
        for (var i = 0; i < j; i = i + 1) {
            tabsLi[i].className = "";
            tabPane[i].className = "tab-pane fade";
        }
        tabsLi[tabToAlterIndex].className = "active";
        tabPane[tabToAlterIndex].className = "tab-pane fade active in";
    };

    Util.prototype.changeTab = function (tabToAlterIndex) {
        var tabs = $("#tabs > li");
        var tabPanes = $(".tab-pane");
        tabs.removeClass("active");
        tabPanes.removeClass("active in");
        $(tabs[tabToAlterIndex]).addClass("active");
        $(tabPanes[tabToAlterIndex]).addClass("active in");
    };

    Util.prototype.enable = function (inputId) {
        "use strict";
        var input = document.getElementById(inputId);
        input.disabled = false;
        // para buttons criados com a tag A
        if (input.tagName === "A")
            $("#" + inputId).removeAttr("disabled");
    };

    Util.prototype.disable = function (inputId) {
        "use strict";
        var input = document.getElementById(inputId);
        input.disabled = true;
        // para buttons criados com a tag A
        if (input.tagName === "A")
            $("#" + inputId).attr("disabled");
    };

    var u = new Util();

    // componente Table

    function Table(options) {
        this.id = options.id;
        this.route = options.route;
        this.toolbar = options.toolbar;
        this.pageable = options.pageable;
        this.showFilter = options.showFilter;
        this.columns = options.columns;
        this.columnsLegend = options.columnsLegend;
        this.scrollable = options.scrollable;

        // dependencias
        this.params = options.params;
        // criado inicialmente para setar como visivel a aba do campo obrigatorio
        this.onParams = options.onParams;
        this.msgDialog = options.msgDialog;
        this.idModalHideShow = options.idModalHideShow;

        this.onChange = options.onChange;
        this.onDataBound = options.onDataBound;
        this.onDataBinding = options.onDataBinding;
        this.dataSourceType = options.dataSourceType;
        this.dataSource = options.dataSource;
        this.columnMenu = options.columnMenu;
        this.sortable = options.sortable;
        this.fieldDepende = options.fieldDepende;
        this.mixedFields = options.mixedFields;
        this.ModalGrupoContas = options.ModalGrupoContas;
        this.classePai = "";
        this.onAfterReadFilteredDataSource = null;
        this.v2 = options.v2;
        this.paramsRequired = options.paramsRequired;
        this.paramsDefault = options.paramsDefault;
        this.height = options.height;

        // não carrega automaticamente o data source quando criar a grid, usado nas telas principais de movimentos,
        // exemplo: assistência técnica, atendimento técnico, agendamentos de visitas
        this.initNotLoad = options.initNotLoad;

        this.GuidProxy = options.GuidProxy;
    }

    Table.prototype.make = function () {
        "use strict";
        var self = this;
        self.grid = $("#" + self.id).kendoGrid({
            dataSource: self.getChoosedDataSource(),

            change: function (ev) {
                var grid = this;

                var ids = grid.select().map(function () {
                    return grid.dataItem($(this)).Id;
                }).toArray();

                localStorage.setItem('settings_' + self.id + '_rows', JSON.stringify(ids));

                if (self.onChange) {
                    self.onChange(ev);
                }
            },
            dataBound: function (ev) {
                var grid = this;
                var dataSource = grid.dataSource;

                var state = kendo.stringify({
                    page: dataSource.page(),
                    pageSize: dataSource.pageSize(),
                    sort: dataSource.sort(),
                    group: dataSource.group(),
                    filter: dataSource.filter()
                });

                currentUser.setCustomData("settings_" + self.id + "_state", state);
                if (self.onDataBound) {
                    self.onDataBound(ev);
                }

                var toutId = setTimeout(function () {
                    //setMaxPagersSize(5);
                });
            },
            dataBinding: function (ev) {
                if (self.onDataBinding) {
                    self.onDataBinding(ev);
                }
            },
            columnReorder: function () {
                self.saveState(this);
                self.saveColumns(this);
            },

            toolbar: self.toolbar ? self.toolbar : self.showFilter ? self.filterCode() : "",
            reorderable: true,
            resizable: true,
            selectable: true,
            columnMenu: self.columnMenu !== undefined ? self.columnMenu : true,
            sortable: self.sortable !== undefined ? self.sortable : {
                allowUnsort: true
            },
            pageable: self.pageable !== undefined ? self.pageable : {
                refresh: true,
                numeric: true,
                pageSizes: [5, 10, 15],
                buttonCount: 5
            },
            columns: self.loadColumns()
        });

        self.grid = self.getGrid();
        self.loadSettings();
        self.listen();

        if (self.height)
            $("#" + self.id + " .k-grid-content").height(self.height);

        $("#" + self.id).addClass("k-state-selected-radar");
    };

    Table.prototype.listen = function () {
        "use strict";
        var self = this;
        function makeFilter() {
            var filter = {};
            filter['Term'] = document.getElementById("input-filter-term-" + self.id).value;
            filter['Field'] = document.getElementById("select-filter-" + self.id).value;
            filter['Operator'] = "contains";

            if (self.dataSourceType == "Normal" || self.dataSourceType == "Parameter" || self.dataSourceType == "Mixed") {
                self.filter(filter['Field'], filter['Operator'], filter['Term']);
            } else {
                var dataSourceOptions = self.getFilteredDataSource(filter);
                var dataSource = new kendo.data.DataSource(dataSourceOptions);
                dataSource.read();

                if (self.grid != null) {
                    self.grid.setDataSource(dataSource);
                }
            }
        }

        if (self.showFilter) {
            $("#inputF4DoFilter" + self.id).on('click', function () {
                makeFilter();
            });
            $("#input-filter-term-" + self.id).on('keypress', function (ev) {
                var key = ev.keyCode || ev.which;
                if (key == 13) {
                    makeFilter();
                }
            });
        }

        $("#" + self.id).on('mousemove', function () {
            self.saveColumns();
        });

        self.loadSettings();
    };

    Table.prototype.length = function () {
        "use strict";
        var self = this;

        return self.getDataSource().data().length;
    };

    Table.prototype.getGrid = function () {
        "use strict";
        var self = this;
        return $("#" + self.id).data("kendoGrid");
    };

    Table.prototype.getSelectedData = function () {
        "use strict";
        var self = this;
        var grid = $("#" + self.id).data("kendoGrid");
        var row = grid.select();
        return grid.dataItem(row);
    };

    Table.prototype.getColumns = function () {
        "use strict";
        var self = this;
        if (localStorage) {
            var stringyColumns = currentUser.getCustomData("settings_" + self.id + "_columns");
            var columns = JSON.parse(stringyColumns);
            return columns;
        }
        return null;
    };

    Table.prototype.saveColumns = function (grid) {
        "use strict";
        var self = this;
        setTimeout(function () {
            if (!grid) {
                grid = self.grid;
            }
            var columns = grid.columns;
            var stringyColumns = JSON.stringify(columns);
            if (localStorage) {
                currentUser.setCustomData("settings_" + self.id + "_columns", stringyColumns);
            }
        }, 100);
    };

    Table.prototype.loadColumns = function () {
        "use strict";
        var self = this;
        var result;
        var columns = self.getColumns();
        result = columns ? columns : self.columns;
        return result;
    };

    Table.prototype.getState = function () {
        "use strict";
        var self = this;
        if (localStorage) {
            return JSON.parse(currentUser.getCustomData("settings_" + self.id + "_state"));
        }
        return null;
    };

    Table.prototype.saveState = function (grid) {
        "use strict";
        if (localStorage) {
            var self = this;
            var dataSource = grid.dataSource;
            var state = kendo.stringify({
                page: dataSource.page(),
                pageSize: dataSource.pageSize(),
                sort: dataSource.sort(),
                group: dataSource.group(),
                filter: dataSource.filter()
            });
            currentUser.setCustomData("settings_" + self.id + "_state", state);
        }
    };

    Table.prototype.loadState = function () {
        "use strict";
        var self = this;
        var dataSource = self.getDataSource();
        var state = self.getState();
        if (state) {
            if (state.filter) {
                parseFilterDates(state.filter, dataSource.options.schema.model.fields);
            }
            dataSource.query(state);
        } else {
            dataSource.read();
        }

        function parseFilterDates(filter, fields) {
            if (filter.filters) {
                for (var i = 0; i < filter.filters.length; i++) {
                    parseFilterDates(filter.filters[i], fields);
                }
            } else {
                if (fields[filter.field].type == "date") {
                    filter.value = kendo.parseDate(filter.value);
                }
            }
        }
    };

    Table.prototype.loadSettings = function () {
        "use strict";
        var self = this;
        self.loadState();
    };

    Table.prototype.getChoosedDataSource = function () {
        "use strict";
        var self = this;

        if (self.initNotLoad) {
            self.initNotLoad = false;
            return;
        }

        switch (self.dataSourceType) {
            case "Filtered":
                return self.getFilteredDataSource();
            case "Normal":
                return self.getNormalDataSource();
            case "Parameter":
                return self.getParameterDataSource();
            case "Object":
                return self.getObjectDataSource();
            case "Mixed":
                return self.getMixedDataSource();
            default:
                return self.getNormalDataSource();
        }
    };

    Table.prototype.getSortingOptions = function () {
        "use strict";
        var self = this;
        var data = {};
        if (self.grid) {
            if (self.grid.dataSource["_sort"]) {
                var sortingOptions = self.grid.dataSource['_sort'][0];
                if (sortingOptions) {
                    data['Field'] = sortingOptions.field;
                    data['Sort'] = sortingOptions.dir;
                }
            }
        }
        return data;
    };

    Table.prototype.getPagingOptions = function (options) {
        "use strict";
        var data = {};
        data['Page'] = options.data.page;
        data['PageSize'] = options.data.pageSize;
        data['Skip'] = options.data.skip;
        data['Take'] = options.data.take;
        return data;
    };

    Table.prototype.getFilteredDataSource = function (filter) {
        "use strict";
        var self = this;
        var u = new Util();
        var state = self.getState();
        var defaultPageSize = self.pageable ? self.pageable.pageSizes[0] : 10;
        var pageSize = state ? (state.pageSize ? state.pageSize : defaultPageSize) : defaultPageSize;
        var dataSource = {
            type: "JSON",
            transport: {
                read: function (options) {
                    var data = {};
                    data["Sorting"] = self.getSortingOptions(options);
                    data["Filter"] = filter;
                    data['Paging'] = self.getPagingOptions(options);
                    data["classePai"] = self.classePai;
                    if (self.GuidProxy) data["GuidProxy"] = self.GuidProxy;
                    var params = self.getParams();
                    if (params != undefined) {
                        data['Params'] = params;
                    }
                    $.ajax({
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json'
                        },
                        url: self.route,
                        dataType: "json",
                        type: "POST",
                        data: JSON.stringify(data),
                        success: function (result) {
                            if (result.IsAlert) {
                                $(".k-loading-mask").remove();
                                var mensage = result.Message;
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, getAlertBehavior(result.Level));
                                }

                                options.success({ data: new Array(), total: 0 });
                                if (self.onAfterReadFilteredDataSource) {
                                    self.onAfterReadFilteredDataSource(self, false);
                                }
                            } else {
                                options.success(result);
                                if (self.onAfterReadFilteredDataSource) {
                                    self.onAfterReadFilteredDataSource(self, true);
                                }
                            }
                        },
                        error: function (result) {
                            $(".k-loading-mask").remove();
                            var mensage = result.status + "-" + result.statusText;

                            // obs: usado em outras rotinas, se alterar aqui, tem que alterar em outros lugares tambem
                            // redirect para sessão expirada
                            if (result.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.location;
                            }
                            else {
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, alertBehavior.warning);
                                }
                            }

                            if (self.onAfterReadFilteredDataSource) {
                                self.onAfterReadFilteredDataSource(self, false);
                            }
                        }
                    });
                }
            },
            schema: {
                data: 'data',
                total: 'total'
            },
            serverPaging: true,
            serverSorting: true,
            pageSize: pageSize
        };
        return dataSource;
    };

    Table.prototype.getParameterDataSource = function () {
        "use strict";
        var self = this;
        var u = new Util();
        var dataSource = {
            type: "JSON",
            transport: {
                read: function (options) {
                    var data = {};
                    if (self.GuidProxy) data["GuidProxy"] = self.GuidProxy;
                    data['Params'] = self.getParams();
                    $.ajax({
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json'
                        },
                        url: self.route,
                        dataType: "json",
                        type: "POST",
                        data: JSON.stringify(data),
                        success: function (result) {
                            if (result.IsAlert) {
                                $(".k-loading-mask").remove();
                                var mensage = result.Message;
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, getAlertBehavior(result.Level));
                                }

                                options.success({ data: new Array(), total: 0 });
                            } else {
                                options.success(result);
                            }
                        },
                        error: function (result) {
                            $(".k-loading-mask").remove();
                            var mensage = result.status + "-" + result.statusText;

                            // obs: usado em outras rotinas, se alterar aqui, tem que alterar em outros lugares tambem
                            // redirect para sessão expirada
                            if (result.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.location;
                            }
                            else {
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, alertBehavior.warning);
                                }
                            }
                        }
                    });
                }
            },
            schema: {
                data: 'data',
                total: 'total'
            },
            // TODO: usar valor de parametro e nao fixo
            pageSize: 10
        };
        return dataSource;
    };

    Table.prototype.getNormalDataSource = function () {
        "use strict";
        var self = this;
        var u = new Util();
        var dataSource = {
            type: "JSON",
            transport: {
                read: function (options) {
                    $.ajax({
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json'
                        },
                        url: self.route,
                        dataType: "json",
                        type: "GET",
                        success: function (result) {
                            if (result.IsAlert) {
                                $(".k-loading-mask").remove();
                                var mensage = result.Message;
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, getAlertBehavior(result.Level));
                                }
                                
                                options.success({ data: new Array(), total: 0 });
                            } else {
                                options.success(result);
                            }
                        },
                        error: function (result) {
                            $(".k-loading-mask").remove();
                            var mensage = result.status + "-" + result.statusText;

                            // obs: usado em outras rotinas, se alterar aqui, tem que alterar em outros lugares tambem
                            // redirect para sessão expirada
                            if (result.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.location;
                            }
                            else {
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, alertBehavior.warning);
                                }
                            }
                        }
                    });
                }
            },
            // TODO: usar valor de parametro e nao fixo
            pageSize: 10
        };
        return dataSource;
    };

    Table.prototype.getMixedDataSource = function (filter) {
        "use strict";
        var self = this;
        var u = new Util();
        var dataSource = {
            type: "JSON",
            transport: {
                read: function (options) {
                    var data = {};
                    if (self.GuidProxy) data["GuidProxy"] = self.GuidProxy;

                    var opt = {};
                    opt["Sorting"] = self.getSortingOptions(options);
                    opt["Filter"] = filter;
                    opt["Paging"] = self.getPagingOptions(options);
                    data["Options"] = opt;

                    var mixedFields = self.mixedFields;

                    if (mixedFields != undefined) {
                        var len = mixedFields.length;

                        for (var i = 0; i < len; i = i + 1) {
                            var codInput = mixedFields[i].id.replace("input", "");
                            data[codInput] = mixedFields[i].value;
                        }
                    }

                    $.ajax({
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json'
                        },
                        url: self.route,
                        dataType: "json",
                        type: "POST",
                        data: JSON.stringify(data),
                        success: function (result) {
                            if (result.IsAlert) {
                                $(".k-loading-mask").remove();
                                var mensage = result.Message;
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, getAlertBehavior(result.Level));
                                }

                                options.success({ data: new Array(), total: 0 });
                            } else {
                                options.success(result);
                            }
                        },
                        error: function (result) {
                            $(".k-loading-mask").remove();
                            var mensage = result.status + "-" + result.statusText;

                            // obs: usado em outras rotinas, se alterar aqui, tem que alterar em outros lugares tambem
                            // redirect para sessão expirada
                            if (result.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.location;
                            }
                            else {
                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }
                                    u.dialogOk(mensage, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }
                                    }, alertBehavior.warning);
                                } else {
                                    u.alert(mensage, alertBehavior.warning);
                                }
                            }
                        }
                    });
                }
            },
            schema: {
                data: 'data',
                total: 'total'
            },
            serverPaging: true,
            serverSorting: true,
            // TODO: usar valor de parametro e nao fixo
            pageSize: 10
        };
        return dataSource;
    };

    Table.prototype.getObjectDataSource = function () {
        "use strict";
        var self = this;
        return self.dataSource;
    };

    Table.prototype.getDataSource = function () {
        "use strict";
        var self = this;
        return self.grid.dataSource;
    };

    Table.prototype.setDataSource = function (dataSource) {
        "use strict";
        var self = this;
        $("#" + self.id).data("kendoGrid").setDataSource(dataSource);
    };

    Table.prototype.filter = function (field, operator, term) {
        "use strict";
        var self = this;
        var filter = [
            { field: field, operator: operator, value: term }
        ];

        var dataSource = self.getDataSource();
        dataSource.filter(filter);
    };

    Table.prototype.filters = function (filters) {
        "use strict";
        var self = this;
        var dataSource = self.getDataSource();
        dataSource.filter(filters);
    };

    Table.prototype.clearFilter = function () {
        "use strict";
        var self = this;
        var dataSource = self.getDataSource();
        dataSource.filter(null);
    };

    Table.prototype.filterCode = function () {
        "use strict";
        var self = this;
        var columns = self.columns;
        var j = columns.length;
        var filterCode = "";
        filterCode += "<select id='select-filter-" + self.id + "'>";

        for (var i = 0; i < j; i = i + 1)
            if (!$(columns[i]).attr("hidden")) // if (!columns[i].hidden) //no IE9 XXX.hidden retorna "undefined" ao inves de "hidden"
                filterCode += "<option value='" + columns[i].field + "'>" + columns[i].title + "</option>";

        filterCode += "</select'>";
        filterCode += "<input type='text' id='input-filter-term-" + self.id + "' style='margin-bottom: 0px'/>";
        filterCode += "<a id='inputF4DoFilter" + self.id + "' role='button' style='cursor: pointer; margin-left: 5px'><i class='icon-filter'></i></a>";
        filterCode += "<span id='inputFilterLegend' class='radar-filter-legend'></span>";

        return filterCode;
    };

    Table.prototype.selectFilterLegend = function (value) {
        "use strict";
        var self = this;
        if (self.columnsLegend) {
            var legend = self.columnsLegend[value];
            var legendSpan = document.getElementById('inputFilterLegend');
            if (legend) {
                legendSpan.innerHTML = legend;
            } else {
                legendSpan.innerHTML = "";
            }
        }
    };

    Table.prototype.makeFilter = function () {
        "use strict";
        var self = this;
        $('#select-filter-' + self.id).kendoDropDownList({
            dataTextField: "title",
            dataValueField: "value",
            select: function (e) {
                var dataItem = this.dataItem(e.item.index());
                self.selectFilterLegend(dataItem.value);
            }
        });

        var value = document.getElementById('select-filter-' + self.id).value;
        self.selectFilterLegend(value);
    };

    Table.prototype.getParams = function () {
        "use strict";
        var self = this,
            search = self.params,
            result = {};
        if (search == undefined) {
            return search;
        }

        var j = search.length,
            validator;
        for (var i = 0; i < j; i = i + 1) {
            validator = search[i];
            result[validator.field] = validator.value;
            if (self.v2 && (validator.invalid || validator.isEmpty()) && self.paramsDefault[i]) {
                result[validator.field] = self.paramsDefault[i];
            }

        }

        return result;
    };

    Table.prototype.validate = function () {
        "use strict";
        var self = this,
            params = self.params,
            j = params ? params.length : 0,
            validator;

        for (var i = 0; i < j; i = i + 1) {
            validator = params[i];
            if (self.v2) {
                // somente critica se o params for obrigatorio,
                // usado na Assistencia Tecnica, F4 do campo servico, onde eh passado o parametro
                // tabela precos dos servicos, que nao eh obrigatorio, mas tem que passar por default
                // a tabela padao
                if (validator.invalid && self.paramsRequired[i]) {

                    if (self.msgDialog) {
                        if (self.onParams) self.onParams(validator);
                        u.dialogOk(validator.onPendencyMessage, null, true, function () {
                            validator.focus(controlGroupBehavior.warning);
                        }, alertBehavior.warning);
                    }
                    else {
                        validator.focus(controlGroupBehavior.warning);
                        validator.showValidateMessage();
                    }

                    return true;
                }
            }
            else {
                if (validator.invalid) {

                    if (self.msgDialog) {
                        if (self.onParams) self.onParams(validator);
                        u.dialogOk(validator.onPendencyMessage, null, true, function () {
                            validator.focus(controlGroupBehavior.warning);
                        }, alertBehavior.warning);
                    }
                    else {
                        validator.focus(controlGroupBehavior.warning);
                        validator.showValidateMessage();
                    }

                    return true;
                }
            }
        }
        return false;
    };

    Table.prototype.refresh = function () {
        "use strict";
        var self = this;

        if (self.grid !== undefined)
            self.grid.dataSource.read();
    };

    Table.prototype.clearSelectedData = function () {
        "use strict";
        var self = this;
        self.grid.clearSelection();
    };

    Table.prototype.haveDependency = function () {
        "use strict";
        var self = this;
        return self.validate();
    };

    // componente Grid, TODO: ver diferenca do grid e table e Modal

    function Grid(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];

        if (!self.height) self.height = 150;
        if (!self.dados) self.dados = [];

        var gridX = new Table({
            id: self.id,
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            pageable: false,
            columns: self.columns,
            dataSourceType: "Object",
            onChange: function (dados) {
                if (self.onChange) {
                    var data = gridX.getSelectedData();
                    self.onChange(data);
                }
            }
        });
        gridX.make();

        self.setValue(self.dados);
    }

    Grid.prototype.setValue = function (dados, onMapper) {
        "use strict";
        var self = this;

        // seta a altura do grid
        $("#" + self.id + " .k-grid-content").height(self.height);

        // carrega os dados
        var data = new kendo.data.DataSource({ data: [] });

        if (dados) {
            $.each(dados, function (i, el) {
                if (onMapper) {
                    data.options.data.push(onMapper(el));
                }
                else {
                    data.options.data.push(el);
                }
            });
        }

        $("#" + self.id).data("kendoGrid").setDataSource(data);
    }

    Grid.prototype.clear = function () {
        "use strict";
        var self = this;

        // seta a altura do grid
        $("#" + self.id + " .k-grid-content").height(self.height);

        // carrega os dados
        var data = new kendo.data.DataSource({ data: [] });
        $("#" + self.id).data("kendoGrid").setDataSource(data);
    }

    // TODO:
    // atualiza o campo na grid e no datasource, mas funciona apenas para campos que estão na grid,
    // para outros campos do datasource, ocorre erro
    Grid.prototype.setValueColumnSelect = function (column, value) {
        "use strict";
        var self = this;

        var grid = $("#" + self.id).data("kendoGrid");
        var row = grid.select();
        var uid = row.data().uid;
        var data = grid.dataItem(row);
        data.set(column, value);
        grid.table.find('tr[data-uid="' + uid + '"]').addClass('k-state-selected');
    }

    // TODO:
    // atualiza o campo no datasource, mais indicado para campos que nao estao na grid,
    // pois atualiza apenas o datasource, nao atualiza na grid
    Grid.prototype.setValueColumnSelectInDatasource = function (column, value) {
        "use strict";
        var self = this;

        var grid = $("#" + self.id).data("kendoGrid");
        var registroSelecionado = self.getSelectedData();
        if (registroSelecionado !== null) {
            var registros = $("#" + self.id).data("kendoGrid").dataSource.data();
            $.each(registros, function (atual) {
                if (registros[atual].uid === registroSelecionado.uid) {
                    registros[atual][column] = value;
                    return false;
                }
            });
        }
    };

    Grid.prototype.getSelectedData = function () {
        "use strict";
        var self = this;

        var grid = $("#" + self.id).data("kendoGrid");
        var row = grid.select();
        return grid.dataItem(row);
    };

    Grid.prototype.getSelectedDataIndex = function () {
        "use strict";
        var self = this;

        var grid = $("#" + self.id).data("kendoGrid");
        var row = grid.select();
        return row.index();
    };

    Grid.prototype.getDataSource = function () {
        "use strict";
        var self = this;

        var registros = $("#" + self.id).data("kendoGrid").dataSource.data();
        return registros;
    }

    Grid.prototype.getLength = function () {
        "use strict";
        var self = this;
        var registros = $("#" + self.id).data("kendoGrid").dataSource.data();
        return registros.length;
    }
    Grid.prototype.getDadosVM = function () {
        "use strict";
        var self = this;

        var list = [];
        var dataSource = self.getDataSource();

        $.each(dataSource, function (atual) {
            list.push(dataSource[atual].DadosVM);
        });

        return list;
    }

    Grid.prototype.deleteSelectedData = function () {
        "use strict";
        var self = this;

        var grid = $("#" + self.id).data("kendoGrid");
        var registroSelecionado = self.getSelectedData();
        if (registroSelecionado !== null) {
            var registros = $("#" + self.id).data("kendoGrid").dataSource.data();
            $.each(registros, function (atual) {
                if (registros[atual].uid === registroSelecionado.uid) {
                    registros.splice(atual, 1);
                    return false;
                }
            });
        }
    };

    Grid.prototype.add = function (val) {
        "use strict";
        var self = this;

        $("#" + self.id).data("kendoGrid").dataSource.add(val);
    };

    Grid.prototype.updateSelectedData = function (alt) {
        "use strict";
        var self = this;

        var registroSelecionado = self.getSelectedData();
        var registros = $("#" + self.id).data("kendoGrid").dataSource.data();
        $.each(registros, function (atual) {
            if (registros[atual].uid === registroSelecionado.uid) {
                alt(registros[atual]);
            }
        });
        $("#" + self.id).data("kendoGrid").refresh();
    }

    // componenete Modal

    function Modal(name, button, input, table, onShow, options) {
        this.name = name;
        this.id = button.href.split('#')[1];
        this.button = button;
        this.input = input;
        this.onShow = onShow;
        if (table instanceof Table) {
            this.table = table;
        } else {
            throw new Error("Deve ser passada uma Table como parametro no construtor.");
        }

        this.useClassePai = null;
        if (options) {
            this.ModalGrupoContas = options.ModalGrupoContas;

            this.onHidden = options.onHidden;

            this.validatorInput = options.validatorInput;
            if (this.validatorInput)
                this.validatorInput.setModal(this);

            // hierarquia
            this.showOpcaoExibir = options.showOpcaoExibir;
            this.exibirHierarquiaLista = options.exibirHierarquiaLista ? options.exibirHierarquiaLista : "H";
            this.exibirHierarquiaReload = true;
            this.urlBuscaHierarquia = window.baseUrl + options.urlBuscaHierarquia;
            this.allowContaTitulo = options.allowContaTitulo;

            if (options.exibirHierarquiaParams === undefined || options.exibirHierarquiaParams === null || options.exibirHierarquiaParams === "")
                options.exibirHierarquiaParams = {};
            this.exibirHierarquiaParams = options.exibirHierarquiaParams;

            this.onDblClickGetItem = options.onDblClickGetItem;

            // classe pai
            this.useClassePai = options.useClassePai;
            this.ClassePaiURL = options.ClassePaiURL;
        } else {
            this.ModalGrupoContas = false;
            this.validatorInput = null;

            // hierarquia
            this.showOpcaoExibir = false;
            this.exibirHierarquiaLista = "L";
            this.exibirHierarquiaParams = {};
        }

        this.changeOpcaoExibir = false;
        this.TreeviewAjaxNodeHierarquia = null;
        // salva o link do modal para pode desabilitar/habilitar novamente, usado pelo GrupoContas
        $(this.button).data("href", $(this.button).attr("href"));

        if (options) {
            this.disableConsultation = options.disableConsultation;
            this.idDescription = options.idDescription;
        }

        // caso o table usar msgDialog, se ocorrer algum erro na table, antes de motras a msgDialog,
        // eh ocultado o modal do F4 para ocorrer erro de tela preta/recursivo
        table.idModalHideShow = this.id;
    }

    Modal.prototype.exibirHierarquia_SetParams = function (param, value) {
        "use strict";
        var self = this;

        self.exibirHierarquiaReload = true;
        self.exibirHierarquiaParams[param] = value;
        if (self.TreeviewAjaxNodeHierarquia)
            self.TreeviewAjaxNodeHierarquia.exibirHierarquiaParams[param] = value;
    };

    Modal.prototype.saveSettings = function (data) {
        "use strict";
        var self = this;
        var stringData = JSON.stringify(data);
        currentUser.setCustomData("modal_settings_" + self.input.id, stringData);
    };

    Modal.prototype.loadSettings = function () {
        "use strict";
        var self = this;
        var stringData = currentUser.getCustomData("modal_settings_" + self.input.id);
        if (stringData !== undefined && stringData !== null && stringData !== "") {
            var data = JSON.parse(stringData);
            return data;
        }
        else {
            return null;
        }
    };

    Modal.prototype.make = function () {
        "use strict";
        var self = this,
            modalCode = "";

        if (self.showOpcaoExibir) {
            var fields = self.loadSettings();
            if (fields !== null) {
                if (fields.radiosHierarquia) {
                    self.exibirHierarquiaLista = "H";
                }
                else {
                    self.exibirHierarquiaLista = "L";
                }
            }
        }

        modalCode += "<div id='" + self.id + "' class='modal hide' tabindex='-2' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true' style='z-index: 1450'>";

        modalCode += "<div class='modal-header'>";
        modalCode += "  <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>";
        modalCode += "  <h4 style='color: white'>" + self.name + "</h4>";
        modalCode += "</div>";

        modalCode += "<div class='modal-body' style='padding: 0px;'>";

        if (self.showOpcaoExibir) {
            modalCode += "  <div id='" + self.id + "divF4ModalExibir' style='padding: 2px;margin: 2px;'>";
            modalCode += "    <label class='inline' style='display: inline-block;'>Exibir:&nbsp&nbsp&nbsp</label>";
            modalCode += "    <label class='radio inline'>";
            modalCode += "      <input type='radio' name='" + self.id + "optionsRadios' id='" + self.id + "radiosHierarquia' value='option1' " + (self.exibirHierarquiaLista === "H" ? "checked" : "") + " ><span>Hierarquia&nbsp&nbsp&nbsp</span>";
            modalCode += "    </label>";
            modalCode += "    <label class='radio inline'>";
            modalCode += "      <input type='radio' name='" + self.id + "optionsRadios' id='" + self.id + "radiosLista' value='option2' " + (self.exibirHierarquiaLista === "L" ? "checked" : "") + " ><span>Lista</span>";
            modalCode += "    </label>";
            modalCode += "  </div>";
        }

        if (self.useClassePai) {
            modalCode += "<div id='ladoEsquerdo" + self.id + "' style='float: left; margin: 0; margin-top: 33px; padding: 0; width: 30px;'>";
            modalCode += "    <div id='divModalUseClassePai" + self.id + "'style='width: 24px; margin-rigth: 2px; margin-left: 2px; border: 1px solid #ccc; display: block; white-space: normal; text-align: center;'>";
            modalCode += "    </div>";
            modalCode += "</div>";

            modalCode += "<div id='ladoDireito" + self.id + "' style='float: right; margin: 0; padding: 0; width: 530px;'>";
        }

        if (self.exibirHierarquiaLista === "L") {
            modalCode += "  <div id='" + self.id + "divModalContentLista' style='display: block;'>";
            modalCode += "    <div id='" + self.table.id + "'></div>";
            modalCode += "  </div>";
            modalCode += "  <div id='" + self.id + "divModalContentHierarquia' style='display: none; border-top: 1px solid #ccc;'>";
            modalCode += "  </div>";
        }
        else {
            modalCode += "  <div id='" + self.id + "divModalContentLista' style='display: none;'>";
            modalCode += "    <div id='" + self.table.id + "'></div>";
            modalCode += "  </div>";
            modalCode += "  <div id='" + self.id + "divModalContentHierarquia' style='display: block; border-top: 1px solid #ccc;'>";
            modalCode += "  </div>";
        }

        if (self.useClassePai) {
            modalCode += "</div>";
        }

        modalCode += "</div>";

        modalCode += "<div class='modal-footer'>";
        modalCode += "  <input type='button' id='inputF4ModalOk" + self.table.id + "' value='OK' class='btn btn-inverse btn-small' data-dismiss='modal' aria-hidden='true' style='width: 75px'/>";
        if (self.ModalGrupoContas) {
            modalCode += "  <input type='button' id='inputF4ModalCancelar'" + self.table.id + " value='Cancelar' class='btn btn-inverse btn-small' data-dismiss='modal' aria-hidden='true' style='width: 75px'/>";
        }
        else {
            modalCode += "  <input type='button' id='inputF4ModalCancelar'  value='Cancelar' class='btn btn-inverse btn-small' data-dismiss='modal' aria-hidden='true' style='width: 75px'/>";
        }
        modalCode += "</div>";

        modalCode += "</div>";

        $("#modalDiv").append(modalCode);
    };

    Modal.prototype.listenUseClassePai = function () {
        "use strict";
        var self = this;

        var style = document.createElement("style");
        style.type = "text/css";
        style.innerHTML = "\
            /* seleciona item */\
            .useclassepai-select {\
                color: white;\
                background: #314A63;\
            }\
            ";
        document.getElementsByTagName("head")[0].appendChild(style);

        // carrega classes pai
        requestNoAsync(window.baseUrl + self.ClassePaiURL, {},
            function (model) {
                for (var classePai in model) {
                    var div = $("<div />");
                    div.html(model[classePai].toString());
                    div.appendTo("#divModalUseClassePai" + self.id);
                }
            }
        );

        // bind
        $("#divModalUseClassePai" + self.id + " > div").unbind("click");
        $("#divModalUseClassePai" + self.id + " > div").bind("click", function (event) {
            $("#divModalUseClassePai" + self.id + " > div").removeClass("useclassepai-select");
            $(event.target).addClass("useclassepai-select");

            // seta nova classe pai e recarrega
            self.table.classePai = $(event.target).html();
            $("#" + self.table.id).data("kendoGrid").dataSource.read();
        });

        // somente é possível saber o height exato do grid, depois que todos os dados forrem carregados
        self.table.onAfterReadFilteredDataSource = function (table, sucess) {
            self.ajustModalHeight();
        }

        var selectFirstItem = $("#divModalUseClassePai" + self.id).children()[0];
        $(selectFirstItem).addClass("useclassepai-select");

        self.table.classePai = selectFirstItem.innerHTML;
    }

    // TODO: quando a janela do navegador for muito pequena, forçar o modal com um tamanho mínimo e ativar um scrool único na tela,
    // hoje o tamanho mínimo já é aplicado, inclusive possui um scrool, mas o scrool funciona somente para tela abaixo do modal,
    // futuramente corrigir isso
    //
    // TODO: ajusta altura do modal conforme a quandidade de linhas da paginação
    //
    // ajusta a altura do modal conforme o tamanho da janela do navegador
    Modal.prototype.ajustModalHeight = function () {
        "use strict";
        var self = this;

        // pega altura da janela do navegador
        var heightWindow = $(window).outerHeight();
        // calcula altura do modal junto com os pixels do "top", o 25 no final é 25px do margin-bottom
        $("#" + self.id).css("top", "20px")
        var heightModal = parseInt($("#" + self.id).css("top")) + $("#" + self.id).outerHeight() + 20;

        // calcula a diferenca altura a mais para subtrair da altura da grid-content do modal,
        var diffHeight = heightModal - heightWindow;

        // ajusta altura do modal para menos (diffHeight > 0), quando o mesmo for mais alto que a janela do navegador
        // ajusta altura do modal para mais (diffHeight < 0), quando a janela do navegador for maior que o modal
        if (diffHeight !== 0) {
            // tanto o Site.css como o bootstrap.css tem definido um valor para max-height na classe ".modal-body", 
            // tem que alterar esse valor também, senão será colocar um scroll na div com a classe ".modal-body"
            if (diffHeight < 0)
                $("#" + self.id + " .modal-body").css("max-height", heightModal - diffHeight); // como o valor de diffHeight é negativo, - com - irá somar

            // 3 linhas * 27px (~27px altura de cada linha), ou seja, mostra pelo menos 3 linhas de resultados
            var heightMin = 81;

            if (self.showOpcaoExibir && self.exibirHierarquiaLista === "H") {
                var heightTreeviewAjaxNodeHierarquia = $("#" + self.id + "divModalContentHierarquia").outerHeight();

                var newHeightTreeviewAjaxNodeHierarquia = heightTreeviewAjaxNodeHierarquia - diffHeight;

                if (newHeightTreeviewAjaxNodeHierarquia < heightMin) {
                    $("#" + self.id + "divModalContentHierarquia").height(heightMin);
                }
                else {
                    $("#" + self.id + "divModalContentHierarquia").height(newHeightTreeviewAjaxNodeHierarquia);
                }
            }
            else {
                var heightGridContent = $("#" + self.id + " .k-grid-content").outerHeight();

                var newHeightGridContent = heightGridContent - diffHeight;

                if (newHeightGridContent < heightMin) {
                    $("#" + self.id + " .k-grid-content").height(heightMin);
                }
                else {
                    $("#" + self.id + " .k-grid-content").height(newHeightGridContent);
                }
            }
        }

        // o bootstrap tem vários tipos de @media para vários tipos de resoluções de telas,
        // onde é trocado algumas regras de posicionamento do modal na tela, por exemplo,
        // o @media (max-width: 767px), seta left/right com 20px, o que acabava quebrando a lógica de
        // dimencionamento dos F4 com consulta classePai, deixava um espaço em branco muito grande entre o
        // div da lista de classePai e a div do grid
        var newWidthModal = 0;
        if (self.useClassePai) {
            newWidthModal = parseInt($("#ladoEsquerdo" + self.id).outerWidth()) + parseInt($("#ladoDireito" + self.id).outerWidth());
        }
        else if (self.exibirHierarquiaLista === "H") {
            // tem que buscar a largura do .modal-body, pois é o mesmo que tem o scrool, se burcar a lagura do
            // divModalContentHierarquia não vai funciona, por o mesmo não tem a lagurar do scroll, 
            // e vai fazer o cálculo errado a cada novo request
            newWidthModal = parseInt($("#" + self.id + " .modal-body").outerWidth());
        }
        else {
            newWidthModal = parseInt($("#" + self.id + "divModalContentLista").outerWidth());
        }

        // define uma largura fixa no modal, porque senão o bootstrap define uma largura conforme o @media,
        // o que vai acabar bagunçando o componentes internos que não está preparados
        $("#" + self.id + " > .modal-body").width(newWidthModal);

        // tem que alterar os valores de left/right/margin-left por causa do css do bootstrap que já define valores para esses atributos
        var leftRightModal = ($(window).outerWidth() - newWidthModal) / 2;
        $("#" + self.id).css("left", leftRightModal + "px");
        $("#" + self.id).css("right", (leftRightModal - 1) + "px");
        $("#" + self.id).css("margin-left", "0");

        // ajusta a altura da div ladoEsquerdo (lista da classePai da tabela) de acordo com a altura div ladoDireito
        if (self.useClassePai) {
            // a div divModalUseClassePai está dentro da div ladoEsquerdo que tem um valor de margin-top
            var marginTopLadoEsquerdo = parseInt($("#ladoEsquerdo" + self.id).css("margin-top"));
            var heightLadoDireito = parseInt($("#ladoDireito" + self.id).css("height"));
            $("#divModalUseClassePai" + self.id).css("height", (heightLadoDireito - marginTopLadoEsquerdo - 3) + "px");
        }
    }

    Modal.prototype.show = function () {
        "use strict";
        var self = this;

        if (self.onShow)
            self.onShow(self);

        if (!self.isDisabled()) {
            if (!self.table.haveDependency()) {
                var el = document.getElementById(self.id);
                // somente cria o modal/grid caso o mesmo nao tenha sido criado ainda
                if (!el) {
                    self.make();
                    if (self.useClassePai)
                        self.listenUseClassePai();
                    else {
                        // somente é possível saber o height exato do grid, depois que todos os dados forrem carregados
                        self.table.onAfterReadFilteredDataSource = function (table, sucess) {
                            self.ajustModalHeight();
                        }
                    }

                    if (self.showOpcaoExibir) {
                        self.listenFieldsModal();
                    }
                    if (self.showOpcaoExibir && self.exibirHierarquiaLista === "H") {
                        if (!self.TreeviewAjaxNodeHierarquia || self.exibirHierarquiaReload) {
                            self.exibirHierarquiaReload = false; // se alterou o CodigoTabelaPrecos, tem que recarregar
                            setHtml(self.id + "divModalContentHierarquia", "");
                            // hierarquia
                            self.TreeviewAjaxNodeHierarquia = new TreeviewAjaxNode({
                                id: self.id + "TreeviewAjaxNodeHierarquia",
                                name: self.name,
                                idContainer: self.id + "divModalContentHierarquia",
                                idButtonOK: "inputF4ModalOk" + self.table.id,
                                validatorInput: self.validatorInput,

                                urlDataSource: self.urlBuscaHierarquia,
                                allowContaTitulo: self.allowContaTitulo,
                                exibirHierarquiaParams: self.exibirHierarquiaParams,

                                onDblClickGetItem: self.onDblClickGetItem
                            });

                            // somente é possível saber o height exato do grid, depois que todos os dados forrem carregados
                            self.TreeviewAjaxNodeHierarquia.onAfterReadFilteredDataSource = function (table, sucess) {
                                self.ajustModalHeight();
                            }
                        }
                        else {
                            self.TreeviewAjaxNodeHierarquia.CollapseAll();
                        }
                        $("#" + self.id + "divModalContentHierarquia").css("display", "block");
                        $("#" + self.id + "divModalContentLista").css("display", "none");
                    }
                    else {
                        self.table.make();
                        self.table.makeFilter();
                        self.table.listen();
                        $("#" + self.id + "divModalContentLista").css("display", "block");
                        $("#" + self.id + "divModalContentHierarquia").css("display", "none");
                    }

                    $(window).resize(function () {
                        self.ajustModalHeight();
                    });
                }
                else if ((self.table.fieldDepende && self.table.fieldDepende.haveChange()) || self.changeOpcaoExibir || self.exibirHierarquiaReload) {
                    // - apenas recarrega a grid de dados do modal
                    // usado para campos grade, pois o produto (fieldDepende) pode ter sido alterado,
                    // e a grade pode ser diferente, por isso tem que carregar novamente a grid de consulta,
                    // outra situacao eh quando alterar de opcao Exibir hierarquia/lista
                    if (self.showOpcaoExibir) {
                        self.listenFieldsModal();
                    }
                    if (self.showOpcaoExibir && self.exibirHierarquiaLista === "H") {
                        if (!self.TreeviewAjaxNodeHierarquia || self.exibirHierarquiaReload) {
                            self.exibirHierarquiaReload = false; // se alterou o CodigoTabelaPrecos, tem que recarregar
                            setHtml(self.id + "divModalContentHierarquia", "");
                            // hierarquia
                            self.TreeviewAjaxNodeHierarquia = new TreeviewAjaxNode({
                                id: self.id + "TreeviewAjaxNodeHierarquia",
                                name: self.name,
                                idContainer: self.id + "divModalContentHierarquia",
                                idButtonOK: "inputF4ModalOk" + self.table.id,
                                validatorInput: self.validatorInput,

                                urlDataSource: self.urlBuscaHierarquia,
                                allowContaTitulo: self.allowContaTitulo,
                                exibirHierarquiaParams: self.exibirHierarquiaParams,

                                onDblClickGetItem: self.onDblClickGetItem
                            });

                            // somente é possível saber o height exato do grid, depois que todos os dados forrem carregados
                            self.TreeviewAjaxNodeHierarquia.onAfterReadFilteredDataSource = function (table, sucess) {
                                self.ajustModalHeight();
                            }
                        }
                        else {
                            self.TreeviewAjaxNodeHierarquia.CollapseAll();
                        }
                        $("#" + self.id + "divModalContentHierarquia").css("display", "block");
                        $("#" + self.id + "divModalContentLista").css("display", "none");
                    }
                    else {
                        var divTable = $("<div id='" + self.table.id + "'></div>");
                        divTable.appendTo("#divModalContent");

                        self.table.make();
                        self.table.makeFilter();
                        self.table.listen();
                        if (self.table.fieldDepende)
                            self.table.fieldDepende.setChange(false);

                        $("#" + self.id + "divModalContentHierarquia").css("display", "none");
                        $("#" + self.id + "divModalContentLista").css("display", "block");

                        // somente é possível saber o height exato do grid, depois que todos os dados forrem carregados
                        self.table.onAfterReadFilteredDataSource = function (table, sucess) {
                            self.ajustModalHeight();
                        }
                    }
                    self.changeOpcaoExibir = false;
                }
                else if (self.showOpcaoExibir && self.exibirHierarquiaLista === "H") {
                    self.TreeviewAjaxNodeHierarquia.CollapseAll();
                }
            }
        }
    };

    Modal.prototype.isDisabled = function () {
        "use strict";
        var self = this;
        return self.input.hasAttribute('disabled');
    };

    Modal.prototype.listenFieldsModal = function () {
        "use strict";
        var self = this;

        byId(self.id + "radiosHierarquia").onchange = function () {
            var fields = {
                radiosHierarquia: $("#" + self.id + "radiosHierarquia").attr("checked") !== undefined ? true : false,
                radiosLista: $("#" + self.id + "radiosLista").attr("checked") !== undefined ? true : false,
            }
            self.saveSettings(fields);
            self.exibirHierarquiaLista = "H";
            self.changeOpcaoExibir = true;
            self.show();
        };

        byId(self.id + "radiosLista").onchange = function () {
            var fields = {
                radiosHierarquia: $("#" + self.id + "radiosHierarquia").attr("checked") !== undefined ? true : false,
                radiosLista: $("#" + self.id + "radiosLista").attr("checked") !== undefined ? true : false,
            }
            self.saveSettings(fields);
            self.exibirHierarquiaLista = "L";
            self.changeOpcaoExibir = true;
            self.show();

            // a opção hierarquia desabilita o botão, só habilita quando seleciona um item
            byId("inputF4ModalOk" + self.table.id).disabled = false;
        };

        var fields = self.loadSettings();
        if (fields !== null) {
            if (fields.radiosHierarquia) {
                $("#" + self.id + "radiosLista").removeAttr("checked");
                $("#" + self.id + "radiosHierarquia")[0].checked = true;
            }
            else {
                $("#" + self.id + "radiosHierarquia").removeAttr("checked");
                $("#" + self.id + "radiosLista")[0].checked = true;
            }
        }
    }

    Modal.prototype.listen = function () {
        "use strict";
        var self = this;

        if (self.disableConsultation) {
            $(self.button).css("display", "none");
            $("#" + self.idDescription).css("display", "none");
        }
        else {
            // botao de consulta
            $(self.button).attr("href", $(self.button).data("href"));
            $(self.button).on('click', function () {
                self.show();
                // tem que ser aqui, porque o bind soh funciona quando o codigo html foi adicionado
                // entao tem que ser depois de ter mostrado
                if (self.onHidden) {
                    $("#" + self.id).on("hidden", function () {
                        self.onHidden(self);
                    });
                }
            });

            // dois clicks no campo
            $(self.input).on('dblclick', function () {
                self.button.click();
            });

            $(self.input).on('keydown', function (ev) {
                var evCodeKey = (ev.keyCode || ev.which);
                // F4 consulta
                if (evCodeKey == '115') {
                    ev.preventDefault();
                    ev.preventBubble = true;
                    self.button.click();
                }
            });
        }
    };

    Modal.prototype.unlisten = function () {
        "use strict";
        var self = this;

        $(self.button).removeAttr("href");
        $(self.button).off('click');
        $(self.input).off('dblclick');
        $(self.input).off('keydown');
    };

    // componenete ModalGrupoContas
    // TODO: remover "alert" do grupo de contas

    function ModalGrupoContas(options) {
        "use strict";
        var self = this;

        self.u = new Util();
        self.tipo = options.tipo;
        self.id = options.id;
        self.executeOnShowAndOnHidden = true;
        self.onShow = options.onShow;
        self.onHidden = options.onHidden;        
        self.grid = null;
        self.configValidatorConta = options.validatorConta;
        self.modalHierarquia = options.modalHierarquia;

        if (self.configValidatorConta && !self.configValidatorConta.fieldNome)
            self.configValidatorConta.fieldNome = "Nome";

        self.tableConta = options.tableConta;
        self.configModalConta = options.modalConta;

        self.makeModal();

        // carrega o grid apenas quando for visualizar, no bind-click do self.button
        // self.makeGrid();
        if (self.tipo === "Produto") {
            self.validatorInput = options.validatorInput;
            self.button = self.validatorInput[0].linkButtonModalGrupoContas;
            self.makeInputConta_Produto();
            self.listen_Produto();
        } else if (self.tipo === "ComboBox") {
            self.validatorInput = options.validatorInput;
            self.columns = options.columns;
            self.route = options.route;
            self.button = self.validatorInput[0].idLinkButtonModalGrupoContas;
            self.makeInputConta_ComboBox();
            self.listen_ComboBox();
        } else {
            self.validatorInput = options.validatorInput;
            self.button = self.validatorInput.linkButtonModalGrupoContas;
            self.makeInputConta();
            self.listen();
        }
    }

    ModalGrupoContas.prototype.makeModal = function () {
        "use strict";
        var self = this;

        var htmlModal = "";
        htmlModal += "<div id='ModalGrupoContas_" + self.id + "' class='modal hide' tabindex='-2' role='dialog' aria-hidden='true' style='z-index: 1450'>";

        htmlModal += "    <div class='modal-header'>";
        htmlModal += "        <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>";
        htmlModal += "        <h4 style='color: white'>Contas</h4>";
        htmlModal += "    </div>";

        htmlModal += "    <div class='modal-body'>";
        htmlModal += "        <fieldset class='radar-fieldset'>";
        htmlModal += "            <legend>Grupo de Contas</legend>";

        htmlModal += "            <div class='radar-row' style='margin-bottom: 15px;'>";
        htmlModal += "                <div class='control-group'>";
        htmlModal += "                    <div class='controls'>";
        htmlModal += "                        <div id='ModalGrupoContas_GridGrupoContas" + self.id + "'></div>";
        htmlModal += "                    </div>";
        htmlModal += "                </div>";
        htmlModal += "            </div>";

        htmlModal += "            <div class='radar-row'>";
        htmlModal += "                <div class='radar-control'>";

        if (self.tipo === "Produto") {
            htmlModal += "                <div class='control-group' style='width: 330px;'>";
            htmlModal += '                    <label for="ModalGrupoContas_inputCodigoProduto' + self.id + '" class="control-label radar-inline" style="width: 65px; text-align: left; float: left;">Produto: </label>';
            htmlModal += '                    <div class="controls" style="float: left">';
            htmlModal += '                        <input type="text" id="ModalGrupoContas_inputCodigoProduto' + self.id + '" maxlength="60" style="width: 100px; margin: 0">';
            htmlModal += '                        <input type="text" id="ModalGrupoContas_inputCodigoGrade1' + self.id + '" maxlength="5" style="width: 30px; margin: 0" disabled>';
            htmlModal += '                        <input type="text" id="ModalGrupoContas_inputCodigoGrade2' + self.id + '" maxlength="5" style="width: 30px; margin: 0" disabled>';
            htmlModal += '                        <input type="text" id="ModalGrupoContas_inputCodigoGrade3' + self.id + '" maxlength="5" style="width: 30px; margin: 0" disabled>';
            htmlModal += '                        <a id="ModalGrupoContas_linkButtonModalProdutos' + self.id + '" href="#ModalGrupoContas_modalProdutos' + self.id + '" role="button" data-toggle="modal"><i class="icon-search"></i></a>';
            htmlModal += '                        <a id="ModalGrupoContas_linkButtonModalGrade1' + self.id + '" href="#ModalGrupoContas_modalGrade1' + self.id + '" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>';
            htmlModal += '                        <a id="ModalGrupoContas_linkButtonModalGrade2' + self.id + '" href="#ModalGrupoContas_modalGrade2' + self.id + '" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>';
            htmlModal += '                        <a id="ModalGrupoContas_linkButtonModalGrade3' + self.id + '" href="#ModalGrupoContas_modalGrade3' + self.id + '" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>';
            htmlModal += '                        <span id="ModalGrupoContas_descriptionCodigoProduto' + self.id + '" class="help-inline" style="display: none"></span>';
            htmlModal += '                        <span id="ModalGrupoContas_descriptionCodigoGrade1' + self.id + '" class="help-inline" style="display: none"></span>';
            htmlModal += '                        <span id="ModalGrupoContas_descriptionCodigoGrade2' + self.id + '" class="help-inline" style="display: none"></span>';
            htmlModal += '                        <span id="ModalGrupoContas_descriptionCodigoGrade3' + self.id + '" class="help-inline" style="display: none"></span>';
        } else if (self.tipo === "ComboBox") {
            htmlModal += '                <div class="control-group"  style="width: 330px;">';
            htmlModal += '                    <label class="control-label" for="ModalGrupoContas_inputComboBox' + self.id + '" style="width: 120px; text-align: left; float: left;">Tipo de Operação:</label>';
            htmlModal += '                    <div class="controls" style="float: left">';
            htmlModal += '                        <input type="text" id="ModalGrupoContas_inputComboBox' + self.id + '" value="" style="width: 200px; padding-left: 4px;" />';
        } else {
            htmlModal += "                <div class='control-group'>";
            htmlModal += "                    <label for='ModalGrupoContas_InputCodigoConta" + self.id + "' class='control-label' style='display: inline-block;'>Conta: </label>";
            htmlModal += "                    <div class='controls' style='display: inline-block;'>";
            htmlModal += "                        <input type='text' id='ModalGrupoContas_InputCodigoConta" + self.id + "' maxlength='14' style='width: 115px;' />";
            htmlModal += "                        <a id='ModalGrupoContas_LinkButtonModalConta" + self.id + "' href='#ModalGrupoContas_ModalConta" + self.id + "' role='button' data-toggle='modal'><i class='icon-search'></i></a>";
            htmlModal += "                        <span id='ModalGrupoContas_DescriptionCodigoConta" + self.id + "' class='help-inline radar-inline' style='display: none'></span>";
        }

        htmlModal += "                        </div>";
        htmlModal += "                    </div>";
        htmlModal += "                </div>";
        htmlModal += "                <div class='radar-control' style='float: right;'>";
        htmlModal += "                    <div class='control-group'>";
        htmlModal += "                        <div class='controls'>";
        htmlModal += "                            <input type='button' id='ModalGrupoContas_ButtonAdicionar" + self.id + "' value='Adicionar' class='btn btn-inverse btn-small' style='width: 75px'/>";
        htmlModal += "                            <input type='button' id='ModalGrupoContas_ButtonRemover" + self.id + "' value='Remover' class='btn btn-inverse btn-small' style='width: 75px'/>";
        htmlModal += "                        </div>";
        htmlModal += "                    </div>";
        htmlModal += "                </div>";
        htmlModal += "            </div>";
        htmlModal += "        </fieldset>";
        htmlModal += "    </div>";

        htmlModal += "    <div class='modal-footer'>";
        htmlModal += "        <input type='button' id='ModalGrupoContas_ButtonOk" + self.id + "' value='OK' class='btn btn-inverse btn-small' data-dismiss='modal' aria-hidden='true' style='width: 75px'/>";
        htmlModal += "        <input type='button' id='ModalGrupoContas_ButtonCancel" + self.id + "'  value='Cancelar' class='btn btn-inverse btn-small' data-dismiss='modal' aria-hidden='true' style='width: 75px'/>";
        htmlModal += "    </div>";

        htmlModal += "</div>";

        $("#modalDiv").append(htmlModal);
    };

    ModalGrupoContas.prototype.makeGrid = function () {
        "use strict";
        var self = this;

        var ModalGrupoContas_GridGrupoContas = new Table({
            "id": "ModalGrupoContas_GridGrupoContas" + self.id,
            "pageable": false,
            "columns": [
                { field: "Codigo", title: "Código", width: 20, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Nome", title: "Nome", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }
            ],
            "dataSourceType": "Object"
        });
        ModalGrupoContas_GridGrupoContas.make();
        self.grid = ModalGrupoContas_GridGrupoContas;

        // seta a altura do grid
        $("#ModalGrupoContas_GridGrupoContas" + self.id + " .k-grid-content").height(150);

        // carrega os dados
        var data = new kendo.data.DataSource({ data: [] });
        if (self.validatorInput.getVarios()) {
            // se jah tem varias contas selecionadas, apenas carrega o datasource
            var registros = self.validatorInput.getGrupoContas();
            for (var atual in registros) {
                data.options.data.push(registros[atual]);
            }
        }
        else {
            // se tem apenas uma conta selecionada, cria um datasource com apenas um item
            if (!self.validatorInput.invalid) {
                data.options.data.push({
                    Codigo: $("#" + self.validatorInput.inputId).val(),
                    Nome: $("#" + self.validatorInput.descriptionId).html()
                });
            }
        }

        $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").setDataSource(data);
    };

    ModalGrupoContas.prototype.makeInputConta = function () {
        "use strict";
        var self = this;

        var validatorConta = new Validator({
            field: "ModalGrupoContas_InputCodigoConta" + self.id,
//            msgDialog: true, // TODO: continuar
            idModalHideShow: "ModalGrupoContas_" + self.id,
            fieldDescriptionId: "ModalGrupoContas_DescriptionCodigoConta" + self.id,
            fieldSearch: self.configValidatorConta.fieldSearch,
            onPendencyMessage: self.configValidatorConta.onPendencyMessage,
            route: self.configValidatorConta.route,
            v2: self.configValidatorConta.v2,
            ModalGrupoContas: true,
            grupoContasFieldNome: self.configValidatorConta.fieldNome,
            onValid: function (data) {
                $("#ModalGrupoContas_InputCodigoConta" + self.id).val(data.Codigo);
                $("#ModalGrupoContas_DescriptionCodigoConta" + self.id).html(data[self.configValidatorConta.fieldNome]);
                if (self.configValidatorConta.onValid)
                    self.configValidatorConta.onValid(data, validatorConta);
            },
            onInvalid: function (data) {
                validatorConta.clear({ error: true });
                validatorConta.focus();
                if (self.configValidatorConta.onInvalid)
                    self.configValidatorConta.onInvalid(data, validatorConta);
            },
            onEmpty: function () {
                validatorConta.clear();
                if (self.configValidatorConta.onEmpty)
                    self.configValidatorConta.onEmpty();
            }
        });
        validatorConta.listen();
        self.validatorConta = validatorConta;

        var modalGrupoContas_TableConta = new Table({
            id: "ModalGrupoContas_TableConta" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            route: self.tableConta.route,
            showFilter: self.tableConta.showFilter,
            ModalGrupoContas: true,
            columns: self.tableConta.columns,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = modalGrupoContas_TableConta.getSelectedData();
                    validatorConta.onValid(data);
                    validatorConta.update();
                    $("#ModalGrupoContas_ModalConta" + self.id).modal("hide");
                });
                $("#inputF4ModalCancelar" + this.id).on("click", function () {
                    $("#ModalGrupoContas_ModalConta" + self.id).modal("hide");
                });
            },
            onDataBound: function () {
                $("#ModalGrupoContas_TableConta" + self.id + " table tr").on("dblclick", function () {
                    var data = modalGrupoContas_TableConta.getSelectedData();
                    validatorConta.onValid(data);
                    validatorConta.update();
                    $("#ModalGrupoContas_ModalConta" + self.id).modal("hide");
                });
                $("#inputF4ModalCancelar" + this.id).on("click", function () {
                    $("#ModalGrupoContas_ModalConta" + self.id).modal("hide");
                });
            },
            dataSourceType: "Filtered"
        });

        if (self.modalHierarquia) {
            var modalConta = new Modal(
                self.modalHierarquia.name,
                byId("ModalGrupoContas_LinkButtonModalConta" + self.id),
                byId("ModalGrupoContas_InputCodigoConta" + self.id),
                modalGrupoContas_TableConta,
                function () {
                    self.executeOnShowAndOnHidden = false;
                    $("#ModalGrupoContas_" + self.id).modal("hide");
                },
                {
                    validatorInput: self.modalHierarquia.validatorInput,

                    // classe pai
                    useClassePai: self.configModalConta ? self.configModalConta.useClassePai : null,
                    ClassePaiURL: self.configModalConta ? self.configModalConta.ClassePaiURL : null,

                    // hierarquia
                    showOpcaoExibir: self.modalHierarquia.showOpcaoExibir,
                    urlBuscaHierarquia: self.modalHierarquia.urlBuscaHierarquia.replace(window.baseUrl, ""),
                    allowContaTitulo: self.modalHierarquia.allowContaTitulo,
                    exibirHierarquiaParams: self.modalHierarquia.exibirHierarquiaParams,
                    onDblClickGetItem: function (event, dados) {
                        validatorConta.setChange(true);

                        getJsonFromRoute(validatorConta.route.replace(window.baseUrl, ""), { CodigoLocal: dados['Codigo'] }).done(function (local) {
                            if (local.IsAlert)
                                throw new Error(local.Message);

                            validatorConta.onValid(local);
                            validatorConta.update();
                            validatorConta.PropertiesSpecifyField = local;
                            $("#ModalGrupoContas_ModalConta" + self.id).modal("hide");                            
                        });
                    },

                    onHidden: function () {
                        $("#ModalGrupoContas_" + self.id).modal("show");
                        self.executeOnShowAndOnHidden = true;
                    }
                }
            ).listen();
        } else {
            var modalConta = new Modal(
                "Conta",
                byId("ModalGrupoContas_LinkButtonModalConta" + self.id),
                byId("ModalGrupoContas_InputCodigoConta" + self.id),
                modalGrupoContas_TableConta,
                function () {
                    self.executeOnShowAndOnHidden = false;
                    $("#ModalGrupoContas_" + self.id).modal("hide");
                },
                {
                    validatorInput: self.configModalConta ? (self.configModalConta.useClassePai ? validatorConta : null) : null,

                    // classe pai
                    useClassePai: self.configModalConta ? self.configModalConta.useClassePai : null,
                    ClassePaiURL: self.configModalConta ? self.configModalConta.ClassePaiURL : null,

                    onHidden: function () {
                        $("#ModalGrupoContas_" + self.id).modal("show");
                        self.executeOnShowAndOnHidden = true;
                    }
                }
            ).listen();
        }
    };

    ModalGrupoContas.prototype.listen = function () {
        "use strict";
        var self = this;

        $("#ModalGrupoContas_ButtonAdicionar" + self.id).bind("click", function () {
            if (getVal("ModalGrupoContas_InputCodigoConta" + self.id) === "") {
                alert("Conta deve ser informada.");
            }
            else {
                var novoCodigo = getVal("ModalGrupoContas_InputCodigoConta" + self.id);
                var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
                var adicionado = false;
                $.each(registros, function (atual) {
                    if (registros[atual].Codigo === novoCodigo) {
                        adicionado = true;
                    }
                });
                if (!adicionado) {
                    $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.add({
                        Codigo: getVal("ModalGrupoContas_InputCodigoConta" + self.id),
                        Nome: getHtml("ModalGrupoContas_DescriptionCodigoConta" + self.id)
                    });
                }
            }
        });

        $("#ModalGrupoContas_ButtonRemover" + self.id).bind("click", function () {
            var registroSelecionado = self.grid.getSelectedData();
            if (registroSelecionado !== null) {
                var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
                $.each(registros, function (atual) {
                    if (registros[atual].Codigo === registroSelecionado.Codigo) {
                        registros.splice(atual, 1);
                        return false;
                    }
                });
            }
        });

        $("#ModalGrupoContas_ButtonOk" + self.id).bind("click", function () {
            var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
            var lista = [];
            $.each(registros, function (atual) {
                lista.push(registros[atual]);
            });
            self.validatorInput.setGrupoContas(lista);
            if (registros.length > 1) {
                self.validatorInput.setVarios(true);
            }
            else {
                self.validatorInput.setVarios(false);
            }
        });

        // quando clicar no botao modal do grupo contas do validator, limpa o campo conta e monta a grid com as contas
        $("#" + self.button).bind("click", function () {
            if (self.executeOnShowAndOnHidden && self.onShow) {
                self.onShow();
            }

            self.validatorConta.setValues("", "");
            self.makeGrid();

            // tem que ser aqui, porque o bind soh funciona quando o codigo html foi adicionado
            // entao tem que ser depois de ter mostrado
            if (self.onHidden) {
                $("#ModalGrupoContas_" + self.id).on("hidden", function () {
                    if (self.executeOnShowAndOnHidden) {
                        self.onHidden();
                    }
                });
            }
        });
    };

    ModalGrupoContas.prototype.makeGrid_Produto = function () {
        "use strict";
        var self = this;

        var ModalGrupoContas_GridGrupoContas = new Table({
            "id": "ModalGrupoContas_GridGrupoContas" + self.id,
            "pageable": false,
            "columns": [
                { field: "Classificacao", title: "Classificação", width: 58, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Codigo", title: "Código", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Nome", title: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Grade1", title: "Grade 1", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Grade2", title: "Grade 2", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                { field: "Grade3", title: "Grade 3", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }
            ],
            "dataSourceType": "Object"
        });
        ModalGrupoContas_GridGrupoContas.make();
        self.grid = ModalGrupoContas_GridGrupoContas;

        // seta a altura do grid
        $("#ModalGrupoContas_GridGrupoContas" + self.id + " .k-grid-content").height(150);

        // carrega os dados
        var data = new kendo.data.DataSource({ data: [] });
        if (self.validatorInput[0].getVarios()) {
            // se jah tem varias contas selecionadas, apenas carrega o datasource
            var registros = self.validatorInput[0].getGrupoContas();
            for (var atual in registros) {
                data.options.data.push(registros[atual]);
            }
        }
        else {
            // se tem apenas uma conta selecionada, cria um datasource com apenas um item
            if (!self.validatorInput[0].invalid) {
                data.options.data.push({
                    id: self.validatorInput[0].getValue() + self.validatorInput[1].getValue() + self.validatorInput[2].getValue() + self.validatorInput[3].getValue(),
                    Classificacao: self.validatorInput[0].PropertiesSpecifyField.Classificacao,
                    Codigo: self.validatorInput[0].getValue(),
                    Nome: self.validatorInput[0].getDescription(),
                    HaveGrade1: self.validatorInput[0].PropertiesSpecifyField.HaveGrade1,
                    HaveGrade2: self.validatorInput[0].PropertiesSpecifyField.HaveGrade2,
                    HaveGrade3: self.validatorInput[0].PropertiesSpecifyField.HaveGrade3,
                    CodigoGrade1: self.validatorInput[1].getValue(),
                    CodigoGrade2: self.validatorInput[2].getValue(),
                    CodigoGrade3: self.validatorInput[3].getValue(),
                    // TODO: temporario, mas tem que melhorar o replace
                    Grade1: self.validatorInput[1].getDescription().replace(" - ", ""),
                    Grade2: self.validatorInput[2].getDescription().replace(" - ", ""),
                    Grade3: self.validatorInput[3].getDescription().replace(" - ", "")
                });
            }
        }

        $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").setDataSource(data);
    };

    ModalGrupoContas.prototype.listen_Produto = function () {
        "use strict";
        var self = this;

        $("#ModalGrupoContas_ButtonAdicionar" + self.id).bind("click", function () {
            if (self.validatorProdutos.getValue() === "") {
                alert("Informe o código do Produto");
            }
            else {
                var novoId = self.validatorProdutos.getValue() + self.validatorGrade1.getValue() + self.validatorGrade2.getValue() + self.validatorGrade3.getValue();
                var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
                var adicionado = false;
                $.each(registros, function (atual) {
                    if (registros[atual].id === novoId) {
                        adicionado = true;
                    }
                });
                if (adicionado) {
                    if (self.validatorGrade1.getValue() === "")
                        alert("Produto já informado");
                    else
                        alert("Produto/Grade já informado");
                }
                else {
                    $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.add({
                        id: self.validatorProdutos.getValue() + self.validatorGrade1.getValue() + self.validatorGrade2.getValue() + self.validatorGrade3.getValue(),
                        Classificacao: self.validatorProdutos.PropertiesSpecifyField.Classificacao,
                        Codigo: self.validatorProdutos.getValue(),
                        Nome: self.validatorProdutos.getDescription(),
                        HaveGrade1: self.validatorProdutos.PropertiesSpecifyField.HaveGrade1,
                        HaveGrade2: self.validatorProdutos.PropertiesSpecifyField.HaveGrade2,
                        HaveGrade3: self.validatorProdutos.PropertiesSpecifyField.HaveGrade3,
                        CodigoGrade1: self.validatorGrade1.getValue(),
                        CodigoGrade2: self.validatorGrade2.getValue(),
                        CodigoGrade3: self.validatorGrade3.getValue(),
                        Grade1: self.validatorGrade1.getDescription().replace(" - ", ""),
                        Grade2: self.validatorGrade2.getDescription().replace(" - ", ""),
                        Grade3: self.validatorGrade3.getDescription().replace(" - ", "")
                    });
                }
            }
        });

        $("#ModalGrupoContas_ButtonRemover" + self.id).bind("click", function () {
            var registroSelecionado = self.grid.getSelectedData();
            if (registroSelecionado !== null) {
                var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
                $.each(registros, function (atual) {
                    if (registros[atual].id === registroSelecionado.id) {
                        registros.splice(atual, 1);
                        return false;
                    }
                });
            }
        });

        $("#ModalGrupoContas_ButtonOk" + self.id).bind("click", function () {
            var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
            var lista = [];
            $.each(registros, function (atual) {
                lista.push(registros[atual]);
            });
            self.validatorInput[0].setGrupoContas(lista);
            if (registros.length > 1) {
                self.validatorInput[0].setVarios(true, "Produto");
            }
            else {
                self.validatorInput[0].setVarios(false, "Produto", [self.validatorInput[1], self.validatorInput[2], self.validatorInput[3]]);
            }
        });

        // quando clicar no botao GrupoContas do validator, limpa o campo conta e monta a grid com as contas
        $("#" + self.button).bind("click", function () {
            if (self.executeOnShowAndOnHidden && self.onShow) {
                self.onShow();
            }

            self.validatorProdutos.setValues("", "");
            self.validatorGrade1.setValues("", "");
            self.validatorGrade2.setValues("", "");
            self.validatorGrade3.setValues("", "");

            self.makeGrid_Produto();

            // tem que ser aqui, porque o bind soh funciona quando o codigo html foi adicionado
            // entao tem que ser depois de ter adicionado
            if (self.onHidden) {
                $("#ModalGrupoContas_" + self.id).on("hidden", function () {
                    if (self.executeOnShowAndOnHidden) {
                        self.onHidden();
                    }
                });
            }
        });
    };

    ModalGrupoContas.prototype.makeInputConta_Produto = function () {
        "use strict";
        var self = this;

        // produto
        var validatorProdutos = new Validator({
            field: "ModalGrupoContas_inputCodigoProduto" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            fieldDescriptionId: "ModalGrupoContas_descriptionCodigoProduto" + self.id,
            fieldSearch: "CodigoProduto",
            v2: "v3",
            onPendencyMessage: "Deve ser informado o código do produto.",
            route: "Empresarial/F4Produto/GetProduto",
            onValid: function (data) {
                validatorProdutos.setChange(true);
                validatorProdutos.setValues(data["Codigo"], data["Nome"]);
                validatorProdutos.PropertiesSpecifyField = {
                    Classificacao: data.Classificacao,
                    HaveGrade1: data.HaveGrade1,
                    HaveGrade2: data.HaveGrade2,
                    HaveGrade3: data.HaveGrade3
                };

                validatorGrade1.clear({ disable: true });
                validatorGrade2.clear({ disable: true });
                validatorGrade3.clear({ disable: true });

                if (validatorProdutos.PropertiesSpecifyField.HaveGrade1) {
                    validatorGrade1.enable();
                    validatorGrade1.focus();
                } else {
                    $("#ModalGrupoContas_linkButtonModalProdutos" + self.id).focus();
                }

                if (validatorProdutos.PropertiesSpecifyField.HaveGrade2)
                    validatorGrade2.enable();

                if (validatorProdutos.PropertiesSpecifyField.HaveGrade3)
                    validatorGrade3.enable();
            },
            onInvalid: function (data) {
                validatorProdutos.setChange(true);
                validatorProdutos.clear({ error: true });
                validatorProdutos.focus();
                validatorGrade1.clear({ error: true, disable: true });
                validatorGrade2.clear({ error: true, disable: true });
                validatorGrade3.clear({ error: true, disable: true });
                validatorProdutos.PropertiesSpecifyField = {};
            },
            onEmpty: function () {
                validatorProdutos.setChange(true);
                validatorProdutos.clear();
                validatorGrade1.clear({ disable: true });
                validatorGrade2.clear({ disable: true });
                validatorGrade3.clear({ disable: true });
                validatorProdutos.PropertiesSpecifyField = {};
                $("#ModalGrupoContas_linkButtonModalProdutos" + self.id).focus();
            }
        });
        self.validatorProdutos = validatorProdutos;
        validatorProdutos.listen();

        var tableProdutos = new Table({
            id: "ModalGrupoContas_tableProdutos" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            route: window.baseUrl + "Empresarial/F4Produto/GetProdutos",
            showFilter: true,
            ModalGrupoContas: true,
            columns: [
                { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Unidade", field: "Unidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Preço", field: "ValorUnitario", width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                { title: "Classificação", field: "Classificacao", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
            ],
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = tableProdutos.getSelectedData(),
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProdutos.onValid(data);
                        validatorProdutos.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = tableProdutos.getSelectedData(),
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProdutos.onValid(data);
                        validatorProdutos.update();
                    });
                    $("#ModalGrupoContas_modalProdutos" + self.id).modal("hide");
                });
            },
            dataSourceType: "Filtered"
        });

        var modalProdutos = new Modal(
            "Produtos",
            byId("ModalGrupoContas_linkButtonModalProdutos" + self.id),
            byId("ModalGrupoContas_inputCodigoProduto" + self.id),
            tableProdutos,
            function () {
                $("#ModalGrupoContas_" + self.id).modal("hide");
            },
            {
                // hierarquia
                showOpcaoExibir: true,
                urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                onDblClickGetItem: function (event, dados) {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = dados,
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProdutos.onValid(data);
                        validatorProdutos.update();
                    });
                    $("#ModalGrupoContas_modalProdutos" + self.id).modal("hide");
                },

                onHidden: function () {
                    $("#ModalGrupoContas_" + self.id).modal("show");
                }
            }
        ).listen();

        // grades
        var columnsGrade = [
            { title: "Código", field: "Codigo", width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
            { title: "Descrição", field: "Descricao", width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
        ];

        // grade1
        var validatorGrade1 = new Validator({
            field: "ModalGrupoContas_inputCodigoGrade1" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            fieldDescriptionId: "ModalGrupoContas_descriptionCodigoGrade1" + self.id,
            fieldSearch: "CodigoGrade1",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 1.",
            route: "Empresarial/F4Produto/GetItemGrade1",
            pendency: [validatorProdutos],
            onValid: function (data) {
                validatorGrade1.setChange(true);
                validatorGrade1.setValues(data["Codigo"], " - " + data["Descricao"]);

                if (validatorProdutos.PropertiesSpecifyField.HaveGrade2) {
                    validatorGrade2.focus();
                }
            },
            onInvalid: function (data) {
                validatorGrade1.setChange(true);
                validatorGrade1.clear({ error: true });
                validatorGrade1.focus();
            },
            onEmpty: function () {
                validatorGrade1.setChange(true);
                validatorGrade1.clear();
                validatorGrade2.clear();
                validatorGrade3.clear();
            }
        });
        self.validatorGrade1 = validatorGrade1;
        validatorGrade1.listen();

        var tableGrade1 = new Table({
            id: "ModalGrupoContas_tableGrade1" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            route: window.baseUrl + "Empresarial/F4Produto/List1",
            showFilter: true,
            columns: columnsGrade,
            params: [validatorProdutos],
            fieldDepende: validatorProdutos,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade1.getSelectedData();
                    requestLeg(function () {
                        validatorGrade1.onValid(data);
                        validatorGrade1.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade1.getSelectedData();
                    requestLeg(function () {
                        validatorGrade1.onValid(data);
                        validatorGrade1.update();
                    });
                    $("#ModalGrupoContas_modalGrade1" + self.id).modal("hide");
                });
            },
            dataSourceType: "Parameter"
        });

        var modalGrade1 = new Modal("Grade",
            byId("ModalGrupoContas_linkButtonModalGrade1" + self.id),
            byId("ModalGrupoContas_inputCodigoGrade1" + self.id),
            tableGrade1,
            function () {
                $("#ModalGrupoContas_" + self.id).modal("hide");
            },
            {
                onHidden: function () {
                    $("#ModalGrupoContas_" + self.id).modal("show");
                },
            }
        ).listen();

        // grade2
        var validatorGrade2 = new Validator({
            field: "ModalGrupoContas_inputCodigoGrade2" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            fieldDescriptionId: "ModalGrupoContas_descriptionCodigoGrade2" + self.id,
            fieldSearch: "CodigoGrade2",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 2.",
            route: "Empresarial/F4Produto/GetItemGrade2",
            pendency: [validatorGrade1, validatorProdutos],
            onValid: function (data) {
                validatorGrade2.setChange(true);
                validatorGrade2.setValues(data["Codigo"], " - " + data["Descricao"]);

                if (validatorProdutos.PropertiesSpecifyField.HaveGrade3) {
                    validatorGrade3.focus();
                }
            },
            onInvalid: function (data) {
                validatorGrade2.setChange(true);
                validatorGrade2.clear({ error: true });
                validatorGrade2.focus();
            },
            onEmpty: function () {
                validatorGrade2.setChange(true);
                validatorGrade2.clear();
                validatorGrade3.clear();
            }
        });
        self.validatorGrade2 = validatorGrade2;
        validatorGrade2.listen();

        var tableGrade2 = new Table({
            id: "ModalGrupoContas_tableGrade2" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            route: window.baseUrl + "Empresarial/F4Produto/List2",
            showFilter: true,
            columns: columnsGrade,
            params: [validatorGrade1, validatorProdutos],
            fieldDepende: validatorGrade1,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade2.getSelectedData();
                    requestLeg(function () {
                        validatorGrade2.onValid(data);
                        validatorGrade2.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade2.getSelectedData();
                    requestLeg(function () {
                        validatorGrade2.onValid(data);
                        validatorGrade2.update();
                    });
                    $("#ModalGrupoContas_modalGrade2" + self.id).modal("hide");
                });
            },
            dataSourceType: "Parameter"
        });

        var modalGrade2 = new Modal("Grade",
            byId("ModalGrupoContas_linkButtonModalGrade2" + self.id),
            byId("ModalGrupoContas_inputCodigoGrade2" + self.id),
            tableGrade2,
            function () {
                $("#ModalGrupoContas_" + self.id).modal("hide");
            },
            {
                onHidden: function () {
                    $("#ModalGrupoContas_" + self.id).modal("show");
                },
            }
        ).listen();

        // grade3
        var validatorGrade3 = new Validator({
            field: "ModalGrupoContas_inputCodigoGrade3" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            fieldDescriptionId: "ModalGrupoContas_descriptionCodigoGrade3" + self.id,
            fieldSearch: "CodigoGrade3",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 3.",
            route: "Empresarial/F4Produto/GetItemGrade3",
            pendency: [validatorGrade2, validatorGrade1, validatorProdutos],
            onValid: function (data) {
                validatorGrade3.setChange(true);
                validatorGrade3.setValues(data["Codigo"], " - " + data["Descricao"]);
            },
            onInvalid: function (data) {
                validatorGrade3.setChange(true);
                validatorGrade3.clear({ error: true });
                validatorGrade3.focus();
            },
            onEmpty: function () {
                validatorGrade3.setChange(true);
                validatorGrade3.clear();
            }
        });
        self.validatorGrade3 = validatorGrade3;
        validatorGrade3.listen();

        var tableGrade3 = new Table({
            id: "ModalGrupoContas_tableGrade3" + self.id,
            //msgDialog: true, // TODO: continuar
            //idModalHideShow: "ModalGrupoContas_" + self.id,
            route: window.baseUrl + "Empresarial/F4Produto/List3",
            showFilter: true,
            columns: columnsGrade,
            params: [validatorGrade2, validatorGrade1, validatorProdutos],
            fieldDepende: validatorGrade2,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade3.getSelectedData();
                    validatorGrade3.onValid(data);
                    validatorGrade3.update();
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade3.getSelectedData();
                    validatorGrade3.onValid(data);
                    validatorGrade3.update();
                    $("#ModalGrupoContas_modalGrade3" + self.id).modal("hide");
                });
            },
            dataSourceType: "Parameter"
        });

        var modalGrade3 = new Modal("Grade",
            byId("ModalGrupoContas_linkButtonModalGrade3" + self.id),
            byId("ModalGrupoContas_inputCodigoGrade3" + self.id),
            tableGrade3,
            function () {
                $("#ModalGrupoContas_" + self.id).modal("hide");
            },
            {
                onHidden: function () {
                    $("#ModalGrupoContas_" + self.id).modal("show");
                },
            }
        ).listen();

        self.listenToggleProdutoGradesF4(self.id);
    };

    ModalGrupoContas.prototype.listenToggleProdutoGradesF4 = function (id) {
        "use strict";
        var self = this;

        // se alterar aqui, verificar se tem que alterar em:
        // listenToggleProdutoGradesF4
        // ModalGrupoContas.prototype.listenToggleProdutoGradesF4
        // ValidatorLookupProduto.prototype.listenToggleProdutoGradesF4

        $("#ModalGrupoContas_inputCodigoProduto" + id).on("focus", function () {
            "use strict";
            $("#ModalGrupoContas_linkButtonModalProdutos" + id).show();
            $("#ModalGrupoContas_linkButtonModalGrade1" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade2" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade3" + id).hide();
        });
        $("#ModalGrupoContas_inputCodigoGrade1" + id).on("focus", function () {
            "use strict";
            $("#ModalGrupoContas_linkButtonModalProdutos" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade1" + id).show();
            $("#ModalGrupoContas_linkButtonModalGrade2" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade3" + id).hide();
        });
        $("#ModalGrupoContas_inputCodigoGrade2" + id).on("focus", function () {
            "use strict";
            $("#ModalGrupoContas_linkButtonModalProdutos" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade1" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade2" + id).show();
            $("#ModalGrupoContas_linkButtonModalGrade3" + id).hide();
        });
        $("#ModalGrupoContas_inputCodigoGrade3" + id).on("focus", function () {
            "use strict";
            $("#ModalGrupoContas_linkButtonModalProdutos" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade1" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade2" + id).hide();
            $("#ModalGrupoContas_linkButtonModalGrade3" + id).show();
        });
    }

    ModalGrupoContas.prototype.makeGrid_ComboBox = function () {
        "use strict";
        var self = this;

        var ModalGrupoContas_GridGrupoContas = new Table({
            "id": "ModalGrupoContas_GridGrupoContas" + self.id,
            "pageable": false,
            "columns": self.columns,
            "dataSourceType": "Object"
        });
        ModalGrupoContas_GridGrupoContas.make();
        self.grid = ModalGrupoContas_GridGrupoContas;

        // seta a altura do grid
        $("#ModalGrupoContas_GridGrupoContas" + self.id + " .k-grid-content").height(150);

        // carrega os dados
        var data = new kendo.data.DataSource({ data: [] });
        if (self.validatorInput[0].getVarios()) {
            // se jah tem varias contas selecionadas, apenas carrega o datasource
            var registros = self.validatorInput[0].getGrupoContas();
            for (var atual in registros) {
                data.options.data.push(registros[atual]);
            }
        }
        else {
            // se tem apenas uma conta selecionada, cria um datasource com apenas um item
            var obj = {
                id: self.validatorInput[0].getValue()
            }
            obj[self.validatorInput[0].nameFieldDescription] = self.validatorInput[0].getDescription();
            data.options.data.push(obj);
        }

        $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").setDataSource(data);
    };

    ModalGrupoContas.prototype.listen_ComboBox = function () {
        "use strict";
        var self = this;

        $("#ModalGrupoContas_ButtonAdicionar" + self.id).bind("click", function () {
            var novoId = self.validatorComboBox.getValue();
            var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
            var adicionado = false;
            $.each(registros, function (atual) {
                if (registros[atual].id === novoId) {
                    adicionado = true;
                }
            });
            if (adicionado) {
                alert("Tipo de Operação já informada");
            }
            else {
                var obj = {
                    id: self.validatorComboBox.getValue()
                }
                obj[self.validatorInput[0].nameFieldDescription] = self.validatorComboBox.getDescription();
                $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.add(obj);
            }
        });

        $("#ModalGrupoContas_ButtonRemover" + self.id).bind("click", function () {
            var registroSelecionado = self.grid.getSelectedData();
            if (registroSelecionado !== null) {
                var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
                $.each(registros, function (atual) {
                    if (registros[atual].id === registroSelecionado.id) {
                        registros.splice(atual, 1);
                        return false;
                    }
                });
            }
        });

        $("#ModalGrupoContas_ButtonOk" + self.id).bind("click", function () {
            var registros = $("#ModalGrupoContas_GridGrupoContas" + self.id).data("kendoGrid").dataSource.data();
            var lista = [];
            $.each(registros, function (atual) {
                lista.push(registros[atual]);
            });
            self.validatorInput[0].setGrupoContas(lista);
            if (registros.length > 1) {
                self.validatorInput[0].setVarios(true);
            }
            else {
                self.validatorInput[0].setVarios(false);
            }
        });

        // quando clicar no botao GrupoContas do validator
        $("#" + self.button).bind("click", function () {
            self.makeGrid_ComboBox();
        });
    };

    ModalGrupoContas.prototype.makeInputConta_ComboBox = function () {
        "use strict";
        var self = this;

        var validatorComboBox = new ValidatorDropDown({
            idInputCodigo: "ModalGrupoContas_inputComboBox" + self.id,
            route: self.route
        });
        self.validatorComboBox = validatorComboBox;
    };

    // componente TreeviewAjaxNode
    // hierarquia

    var TreeviewAjaxNode = function (options) {
        var self = this;

        if ($("#" + options.id).length > 0)
            throw new Error("TreeviewAjaxNode: Já existe um componente com o Id=" + options.id);

        self.id = options.id;
        self.name = options.name;
        self.idContainer = options.idContainer;
        self.validatorInput = options.validatorInput;
        self.idButtonOK = options.idButtonOK;

        self.urlDataSource = options.urlDataSource;
        self.allowContaTitulo = options.allowContaTitulo;
        self.exibirHierarquiaParams = options.exibirHierarquiaParams;

        self.onDblClickGetItem = options.onDblClickGetItem;
        self.make();
    };

    TreeviewAjaxNode.prototype.make = (function () {
        var self = this;

        var cssHtml = "";

        // formata item, ajusta o indent dos itens da lista
        cssHtml += "\
        .treeviewajaxnode-item {\
            margin-top: 0px;\
            margin-bottom: 0px;\
            margin-left: 0px;\
            padding-top: 0px;\
            padding-bottom: 0px;\
            padding-left: 14px;\
        }";

        // formata item, remove numeracao dos itens da lista
        cssHtml += "\
        .treeviewajaxnode-list {\
            list-style-type: none;\
            margin-left: 0;\
            padding-left: 14px;\
        }";

        // formata item, marca item como selecionado
        cssHtml += "\
        .treeviewajaxnode-select {\
            color: white;\
            background: #314A63;\
            display: inline-block;\
        }";

        // imagem plus/minus para buscar childs do item
        cssHtml += "\
        .treeviewajaxnode-get-childs {\
            padding: 6px;\
            margin: 0;\
            top: 0;\
            botton: 0;\
            line-height: 21px;\
        }";

        // item título
        cssHtml += "\
        .treeviewajaxnode-is-conta-titulo {\
            display: inline-block;\
            padding: 0;\
            margin: 0;\
            line-height: 21px;\
        }";

        // item analítico
        cssHtml += "\
        .treeviewajaxnode-is-conta-analitica {\
            color: #808240;\
            display: inline-block;\
            padding: 0;\
            margin: 0;\
            line-height: 21px;\
        }";

        // item recolhido
        cssHtml += "\
        .treeviewajaxnode-collapse {\
        }";

        // item expandido
        cssHtml += "\
        .treeviewajaxnode-expand {\
        }";

        // css para formatar as tags html da lista
        var style = document.createElement("style");
        style.type = "text/css";
        style.innerHTML = cssHtml;
        document.getElementsByTagName("head")[0].appendChild(style);

        // criar nó root
        var htmlTreeviewAjaxNode = document.createElement("div");
        htmlTreeviewAjaxNode.id = self.id;
        htmlTreeviewAjaxNode.innerHTML = '\
            <ol class="treeviewajaxnode-list">\
                <li class="treeviewajaxnode-item" id="itens' + self.name + '" style="display: list-item" data-haschilds="true" data-loadchilds="false" >\
                    <img class="treeviewajaxnode-get-childs" src="' + window.baseUrl + 'Content/TreeviewAjaxNode/Images/minus.gif" />\
                    <label class="treeviewajaxnode-is-conta-titulo">' + self.name + '</label>\
                    <ol class="treeviewajaxnode-list" >\
                    </ol>\
                </li>\
            </ol>\
            ';
        document.getElementById(self.idContainer).appendChild(htmlTreeviewAjaxNode);

        // carregar itens do nó root
        self.getChilds("itens" + self.name, self.exibirHierarquiaParams);

        // disable button ok, pois não tem nenhum item selecionado ainda
        byId(self.idButtonOK).disabled = true;

        // remover a seleção de texto
        selectDisable("#" + self.id);

        // bind dos eventos
        self.listen();
    });

    TreeviewAjaxNode.prototype.getChilds = (function (idParent, params) {
        var self = this;
        var postParamObj = {};
        postParamObj['ClassificacaoNoPai'] = params.ClassificacaoNoPai;

        //até uma refatoração completa, os parâmetros serão preenchidos conforme o MVC mesmo
        if (self.name === "Produtos" || self.name === "Produto") {
            if (self.exibirHierarquiaParams.CodigoTabelaPrecos === undefined || self.exibirHierarquiaParams.CodigoTabelaPrecos === null || self.exibirHierarquiaParams.CodigoTabelaPrecos === "")
                self.exibirHierarquiaParams.CodigoTabelaPrecos = "1";

            postParamObj['CodigoTabelaPrecos'] = self.exibirHierarquiaParams.CodigoTabelaPrecos;
        } else if (self.name === "Locais") {
            if (self.exibirHierarquiaParams.BuscaPorHierarquia === undefined || self.exibirHierarquiaParams.BuscaPorHierarquia === null || self.exibirHierarquiaParams.BuscaPorHierarquia === "")
                self.exibirHierarquiaParams.BuscaPorHierarquia = true;

            if (self.exibirHierarquiaParams.CodFilial === undefined || self.exibirHierarquiaParams.CodFilial === null || self.exibirHierarquiaParams.CodFilial === "")
                self.exibirHierarquiaParams.CodFilial = "1";

            postParamObj['BuscaPorHierarquia'] = self.exibirHierarquiaParams.BuscaPorHierarquia;
        } else {
            throw new Error("Tipo desconhecido de busca por hierarquia.");
        }

        $.ajax({
            url: self.urlDataSource,
            type: "POST",
            data: JSON.stringify(postParamObj),
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json"
            },
            dataType: "json",
            cache: false,
            async: true,
            timeout: 90000,
            beforeSend: function () {
                var htmlLoad = '\
                    <li class="treeviewajaxnode-item">\
                        <img src="' + window.baseUrl + 'Content/TreeviewAjaxNode/Images/loading.gif" />\
                        <label>Carregando...</label>\
                    </li>\
                    ';
                $("#" + idParent + " > ol").html(htmlLoad);
            },
            error: function (jqxhr, textStatus, errorThrown) {
                var htmlError = '\
                    <li class="treeviewajaxnode-item">\
                        <img src="' + window.baseUrl + 'Content/TreeviewAjaxNode/Images/error.gif" />\
                        <label style="color: red">' + 'Error: ' + jqxhr.status + "-" + jqxhr.statusText + '</label>\
                    </li>\
                    ';
                $("#" + idParent + " > ol").html(htmlError);

                if (self.onAfterReadFilteredDataSource) {
                    self.onAfterReadFilteredDataSource(self, false);
                }
            },
            success: function (result, textStatus, jqxhr) {
                if (result.length === 0) {
                    var htmlNone = '\
                        <li class="treeviewajaxnode-item" data-haschilds="false" >\
                            <img src="' + window.baseUrl + 'Content/TreeviewAjaxNode/Images/info.gif" />\
                            <label>Nenhum item encontrado.</label>\
                        </li>\
                        ';
                    $("#" + idParent + " > ol").html(htmlNone);
                }
                else {
                    var htmlItens = "";

                    // monta lista com os itens encontrados
                    for (var item in result.data) {
                        if (result.data[item].TemFilho) {
                            // item com filhos, conta título
                            var lparams = {
                                ClassificacaoNoPai: result.data[item].Classificacao,
                            };
                            htmlItens += "\
                                <li class='treeviewajaxnode-item treeviewajaxnode-getitem' id='" + generateId('item') + "' params='" + JSON.stringify(lparams) + "' data-haschilds='true' data-loadchilds='false'>\
                                    <img class='treeviewajaxnode-get-childs' src='" + window.baseUrl + "Content/TreeviewAjaxNode/Images/plus.gif' />\
                                    <label class='treeviewajaxnode-is-conta-titulo'><span id='codigo' style='padding-left: 4px; padding-right: 14px'>" + result.data[item].Codigo + "</span> <span id='classificacao' style='padding-right: 14px'>" + result.data[item].Classificacao + "</span> <span id='nome' style='padding-right: 4px'>" + result.data[item].Nome + "</span> </label>\
                                    <ol class='treeviewajaxnode-list treeviewajaxnode-collapse' style='display: none'></ol>\
                                </li>\
                                ";
                        }
                        else {
                            // item sem filhos, conta analítica
                            htmlItens += "\
                                <li class='treeviewajaxnode-item treeviewajaxnode-getitem' data-haschilds='false'>\
                                    <img src='" + window.baseUrl + "Content/TreeviewAjaxNode/Images/none.gif' />\
                                    <label class='treeviewajaxnode-is-conta-analitica'><span id='codigo' style='padding-left: 4px; padding-right: 14px'>" + result.data[item].Codigo + "</span> <span id='classificacao' style='padding-right: 14px'>" + result.data[item].Classificacao + "</span> <span id='nome' style='padding-right: 4px'>" + result.data[item].Nome + "</span> </label>\
                                </li>\
                                ";
                        }
                    }
                    $("#" + idParent + " > ol").html(htmlItens);

                    // seta flag "loadchilds" somente quando nao ocorreu nenhum erro, e tiver registros, senao deixa desmarcado para tentar carregar novamente
                    $("#" + idParent).data("loadchilds", true);
                }

                if (self.onAfterReadFilteredDataSource) {
                    self.onAfterReadFilteredDataSource(self, true);
                }
            },
            complete: function (jqxhr) {
            }
        });
    });

    TreeviewAjaxNode.prototype.listen = (function () {
        var self = this;

        if (self.allowContaTitulo) {
            // listen nos itens, para selecionar visualmente, marcar como selecionado, conta título
            $("#" + self.id).on("click", ".treeviewajaxnode-is-conta-titulo", function (event) {
                self.removeSelect();
                self.select(event);
            });

            // listen nos itens, para buscar o item com 2 clicks, conta título
            $("#" + self.id).on("dblclick", ".treeviewajaxnode-is-conta-titulo", function (event) {
                self.getItem(false, event);
            });
        }

        // listen nos itens, para selecionar visualmente, marcar como selecionado
        $("#" + self.id).on("click", ".treeviewajaxnode-is-conta-analitica", function (event) {
            self.removeSelect();
            self.select(event);
        });

        // listen nos itens, para buscar o item com 2 clicks
        $("#" + self.id).on("dblclick", ".treeviewajaxnode-is-conta-analitica", function (event) {
            self.getItem(false, event);
        });

        // listen do botão "ok", para buscar o item selecionado
        $("#" + self.idButtonOK).on("click", function (event) {
            self.getItem(true);
        });

        // listen nas imagens plus/minus, para buscar os childs
        $("#" + self.id).on("click", ".treeviewajaxnode-get-childs", function (event) {
            var id = event.target.parentNode.id;
            if ($("#" + id).data("haschilds")) {
                if (!$("#" + id).data("loadchilds")) {
                    self.getChilds(id, JSON.parse($("#" + id).attr("params")));
                }
                // se ja carregou os childs, apenas mostra
                self.showHideChilds(id);
            }
        });
    });

    TreeviewAjaxNode.prototype.showHideChilds = (function (id) {
        if ($("#" + id + " > ol").css("display") === "none") {
            $("#" + id + " > ol").css("display", "list-item");
            $("#" + id + " > .treeviewajaxnode-get-childs").attr("src", window.baseUrl + "Content/TreeviewAjaxNode/Images/minus.gif");
            $("#" + id + " > ol").removeClass("treeviewajaxnode-collapse");
            $("#" + id + " > ol").addClass("treeviewajaxnode-expand");
        }
        else {
            $("#" + id + " > ol").css("display", "none");
            $("#" + id + " > .treeviewajaxnode-get-childs").attr("src", window.baseUrl + "Content/TreeviewAjaxNode/Images/plus.gif");
            $("#" + id + " > ol").addClass("treeviewajaxnode-collapse");
            $("#" + id + " > ol").removeClass("treeviewajaxnode-expand");
        }
    });

    TreeviewAjaxNode.prototype.removeSelect = function () {
        "use strict";
        var self = this;

        $("#" + self.id + " .treeviewajaxnode-select").css("color", ""); // gambi! ver Obs1-TreeviewAjaxNode
        $("#" + self.id + " .treeviewajaxnode-select").removeClass("treeviewajaxnode-select");
    }

    TreeviewAjaxNode.prototype.select = function (event) {
        "use strict";
        var self = this;

        // - o evento click/dblclick pode ser gerado na tag label, span ou outra em um nível mais baixo,
        // mas a seleção deve ser feita na tag label, por isso verifica onde foi gerado o evento,
        // para procurar em qual nível está a tag label,
        // - no momento existe apenas um nível abaixo do label, mas caso precisar de mais nível, 
        // basta adicionar mais linhas de verificação
        var objSelect = event.target;
        if (event.target.tagName.toLowerCase() !== "label") {
            objSelect = event.target.parentNode;
        }

        // seleciona o item
        $(objSelect).addClass("treeviewajaxnode-select");

        // Obs1-TreeviewAjaxNode
        // gambi! o ordem de procedencia para class e style em uma tag, eh alfabetica, entao mesmo
        // tento a class de style .treeviewajaxnode-select com color=while, o css usa o color=#808240 da
        // class de style .treeviewajaxnode-is-conta-analitica, por isso tenho que forcar o color via atributo
        $(objSelect).css("color", "white");

        // habilita button ok, pois agora selecionou um item
        byId(self.idButtonOK).disabled = false;
    }

    TreeviewAjaxNode.prototype.getItem = function (select, event) {
        "use strict";
        var self = this;

        var objSelect = null;
        if (select) {
            // busca item selecionado, usado pelo button
            objSelect = document.querySelectorAll("#" + self.id + " .treeviewajaxnode-select")[0];
        }
        else {
            // busca item clicado 2x, usado pelo mouse
            // - o evento click/dblclick pode ser gerado na tag label, span ou outra em um nível mais baixo,
            // mas a seleção deve ser feita na tag label, por isso verifica onde foi gerado o evento,
            // para procurar em qual nível está a tag label,
            // - no momento existe apenas um nível abaixo do label, mas caso precisar de mais nível, 
            // basta adicionar mais linhas de verificação
            objSelect = event.target;
            if (event.target.tagName.toLowerCase() !== "label") {
                objSelect = event.target.parentNode;
            }
        }

        if (self.onDblClickGetItem) {
            // para ficar padrão como na consulta por tabela
            var data = {
                Codigo: $(objSelect).children("#codigo").text(),
                Nome: $(objSelect).children("#nome").text()
            }
            self.onDblClickGetItem(event, data);
        }
    }

    TreeviewAjaxNode.prototype.CollapseAll = function () {
        "use strict";
        var self = this;

        // remove selecao de todos os itens

        // tem que setar a cor amarela no texto, porque a cor do texto que esta selecionado eh branca, 
        // mas isso apenas para produtos, para classes de produtos a cor e preta
        if ($("#" + self.id + " .treeviewajaxnode-select").parent().data("haschilds")) {
            $("#" + self.id + " .treeviewajaxnode-select").css("color", "");
        } else {
            $("#" + self.id + " .treeviewajaxnode-select").css("color", "#808240"); // gambi! explicacao logo abaixo
        }
        $("#" + self.id + " .treeviewajaxnode-select").removeClass("treeviewajaxnode-select");

        $("#" + self.id + " .treeviewajaxnode-expand").each(function () {
            $(this).css("display", "none");
            $($(this.parentElement).children()[0]).attr("src", window.baseUrl + "Content/TreeviewAjaxNode/Images/plus.gif");
            $(this).addClass("treeviewajaxnode-collapse");
            $(this).removeClass("treeviewajaxnode-expand");
        });

        // disable button ok, pois não tem nenhum item selecionado ainda
        byId(self.idButtonOK).disabled = true;
    };

    // componente PromptDialog

    var PromptDialog = function (options) {
        this.id = options.id;
        this.title = options.title;
        this.template = options.template;
        this.onOk = options.onOk;
        this.onCancel = options.onCancel;
    };

    PromptDialog.prototype.make = function () {
        "use strict";
        var self = this, finalTemplate, baseTemplate =
            "<div id='prompt-{0}' class='modal hide' tabindex='10' style='top: 15%; width: 455px; z-index: 1400' role='dialog'>\
			<div class='modal-header'>\
				<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>\
				<h4 style='color: white'>{1}</h4>\
			</div>\
		<div class='modal-body'>\
		{2}\
		</div>\
		<div class='modal-footer'>\
        <div>\
            <input type='button' id='prompt-{0}-ok' class='btn btn-inverse btn-small' value='OK' data-dismiss='modal' style='width: 75px'/>"
        if (self.onCancel) {
            baseTemplate += "<input type='button' id='prompt-{0}-cancel' class='btn btn-inverse btn-small' value='Cancelar' data-dismiss='modal' style='width: 75px'/>";
        }
        baseTemplate += "</div></div>";

        finalTemplate = baseTemplate.format(self.id, self.title, self.template);
        var same = $('#prompt-' + self.id);
        if (same.length > 0) {
            same.remove();
        }

        $('#modalDiv').append(finalTemplate);
    };

    PromptDialog.prototype.listen = function () {
        "use strict";
        var self = this;
        $('#prompt-' + self.id + '-ok').on('click', function () {
            if (self.onOk)
                self.onOk($('prompt-viewmodel').viewModel());
            self.show(false);
        });

        $('#prompt-' + self.id + '-cancel').on('click', function () {
            if (self.onOk)
                self.onCancel();
            self.show(false);
        });
    };

    PromptDialog.prototype.show = function (option) {
        "use strict";
        var self = this;
        if (option)
            $('#prompt-' + self.id).modal('show');
        else
            $('#prompt-' + self.id).modal('hide');
    };

    PromptDialog.prototype.dispose = function () {
        "use strict";
        var self = this;
        $('#prompt-' + self.id).remove();
        $('.modal-backdrop').remove();
    };

    var PromptDialogYesNo = function (options) {
        this.id = options.id;
        this.title = options.title;
        this.template = options.template;
        this.onYes = options.onYes;
        this.onNo = options.onNo;
    };

    PromptDialogYesNo.prototype.make = function () {
        "use strict";
        var self = this, finalTemplate, baseTemplate =
            "<div id='prompt-{0}' class='modal hide' tabindex='10' style='top: 15%; width: 455px; z-index: 1400' role='dialog'>\
			<div class='modal-header'>\
				<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>\
				<h4 style='color: white'>{1}</h4>\
			</div>\
		<div class='modal-body'>\
		{2}\
		</div>\
		<div class='modal-footer'>\
        <div>\
            <input type='button' id='prompt-{0}-yes' class='btn btn-inverse btn-small' value='Sim' data-dismiss='modal' style='width: 75px'/>\
            <input type='button' id='prompt-{0}-no' class='btn btn-inverse btn-small' value='Não' data-dismiss='modal' style='width: 75px'/>\
		</div>\
		</div>";

        var same = $('#prompt-' + self.id);
        if (same.length > 0) {
            same.remove();
        }

        finalTemplate = baseTemplate.format(self.id, self.title, self.template);
        $('#modalDiv').append(finalTemplate);
    };

    PromptDialogYesNo.prototype.listen = function () {
        "use strict";
        var self = this;
        $('#prompt-' + self.id + '-yes').on('click', function () {
            if (self.onYes)
                self.onYes($('prompt-viewmodel').viewModel());
            self.show(false);
        });

        $('#prompt-' + self.id + '-no').on('click', function () {
            if (self.onNo)
                self.onNo();
            self.show(false);
        });
    };

    PromptDialogYesNo.prototype.show = function (option) {
        "use strict";
        var self = this;
        if (option)
            $('#prompt-' + self.id).modal('show');
        else
            $('#prompt-' + self.id).modal('hide');
    };

    PromptDialogYesNo.prototype.dispose = function () {
        "use strict";
        var self = this;
        $('#prompt-' + self.id).remove();
        $('.modal-backdrop').remove();
    };

    // validators

    function Validator(options) {
        this.field = options.field;

        this.isGrupoContas = options.ModalGrupoContas;
        if (options.ModalGrupoContas || options.v2 === "v3") {
            this.field = options.fieldSearch;
            this.inputId = options.field;
            this.descriptionId = options.fieldDescriptionId;
            this.defaultValue = options.defaultValue;
            this.oldValue = {};
        }
        else {
            this.inputId = 'input' + options.field;
            this.descriptionId = 'description' + options.field;
        }
        this.PropertiesSpecifyField = {};

        this.input = null;
        this.description = null;
        this.route = window.baseUrl + options.route;
        this.value = "";
        this.lastValue = "";
        this.onPendencyMessage = options.onPendencyMessage;
        this.pendency = options.pendency;
        this.onValid = options.onValid;
        this.invalid = true;
        this.onInvalid = options.onInvalid;
        this.onEmpty = options.onEmpty;
        this.alertId = "alert" + Date.now();
        this.onUpdate = options.onUpdate;
        // foi necessário fazer alterações no Validator, e para não correr o risco da alteração atual influenciar no funcionamento das rotinas atuais,
        // foi criado a flag v2, para sinalizar o Validator a usar as novas alterações
        this.v2 = options.v2;
        this.existChange = false;
        // usado em conjunto com ModalGrupoContas
        this.Varios = false;
        this.linkButton = options.linkButton;
        this.linkButtonModalGrupoContas = options.linkButtonModalGrupoContas;
        this.grupoContas = null; // objeto lista com os registros
        this.grupoContasFieldNome = options.grupoContasFieldNome ? options.grupoContasFieldNome : "Nome";
        // objeto modal do validator, é atribuído a instancia do modal, pelo proprio
        // modal quando o mesmo eh criado
        this.modal = null;
        this.u = new Util();

        this.changeEmptyToAll = options.changeEmptyToAll;
        this.all = false;

        // flag para determinar como a mensagem será exibida, foi criada para fazer as alterações em etapas, para não quebrar o que está funcionando no momento
        this.msgDialog = options.msgDialog;
        this.idModalHideShow = options.idModalHideShow;

        this.GuidProxy = options.GuidProxy;
    }

    Validator.prototype.setVarios = function (op, tipo, grades) {
        'use strict';
        var self = this;

        if (op) {
            self.Varios = true;
            //self.modal.unlisten();

            // para limpar/desabilitar os campos grades
            if (tipo === "Produto" && self.onEmpty)
                self.onEmpty();

            self.setValues("", "Vários");
            $("#" + self.input.id).attr("readonly", true);
            $("#" + self.linkButton).css("cursor", "not-allowed");
        }
        else {
            self.Varios = false;
            self.modal.listen();
            if (self.grupoContas.length === 0) {
                self.setValues("", "");
                self.invalid = true;
            }
            else {
                var dados = self.grupoContas[0];
                if (tipo === "Produto") {
                    self.setValues(dados.Codigo, dados.Nome);
                    self.PropertiesSpecifyField.Classificacao = dados.Classificacao;
                    self.PropertiesSpecifyField.HaveGrade1 = dados.HaveGrade1;
                    self.PropertiesSpecifyField.HaveGrade2 = dados.HaveGrade2;
                    self.PropertiesSpecifyField.HaveGrade3 = dados.HaveGrade3;
                    if (dados.HaveGrade1) {
                        grades[0].enable();
                        grades[0].setValues(dados.CodigoGrade1, " - " + dados.Grade1);
                    }
                    if (dados.HaveGrade2) {
                        grades[1].enable();
                        grades[1].setValues(dados.CodigoGrade2, " - " + dados.Grade2);
                    }
                    if (dados.HaveGrade3) {
                        grades[2].enable();
                        grades[2].setValues(dados.CodigoGrade3, " - " + dados.Grade3);
                    }
                }
                else {
                    self.setValues(dados.Codigo, dados.Nome);
                }
            }
            $("#" + self.input.id).removeAttr("readonly");
            $("#" + self.linkButton).css("cursor", "auto");
        }
    }

    Validator.prototype.getVarios = function () {
        'use strict';
        var self = this;

        return self.Varios;
    }

    Validator.prototype.setModal = function (instance) {
        'use strict';
        var self = this;

        return self.modal = instance;
    }

    Validator.prototype.setGrupoContas = function (grupoContas) {
        'use strict';
        var self = this;

        return self.grupoContas = grupoContas;
    }

    Validator.prototype.setGrupoContasLista = function (lista) {
        'use strict';
        var self = this;

        var listaObjetos = [];
        for (var atual in lista) {
            var nomeConta = "Erro: Não carregado";

            var params = {};
            params[self.field] = lista[atual];

            requestNoAsync(self.route, params,
                function (model) {
                    if (model.IsAlert) {
                        nomeConta = "Erro: " + model.Message;
                    }
                    else {
                        nomeConta = model[self.grupoContasFieldNome];
                    }
                },
                function (perro) {
                    nomeConta = "Erro: " + perro.errorThrown;
                }
            );
            listaObjetos.push({
                Codigo: lista[atual],
                Nome: nomeConta
            });
        }
        self.grupoContas = listaObjetos;
    }

    Validator.prototype.getGrupoContas = function () {
        'use strict';
        var self = this;

        return self.grupoContas;
    }

    Validator.prototype.getGrupoContasString = function () {
        'use strict';
        var self = this;

        var lista = "";
        for (var conta in self.grupoContas)
            lista += self.grupoContas[conta].Codigo + ",";

        return lista;
    }

    Validator.prototype.getGrupoContasLista = function () {
        'use strict';
        var self = this;

        var lista = [];
        for (var atual in self.grupoContas) {
            lista.push(self.grupoContas[atual].Codigo);
        }
        return lista;
    }

    Validator.prototype.setGrupoContasOuConta = function (obj) {
        'use strict';
        var self = this;

        // filtro unico
        if (typeof obj === 'string') {
            if (obj !== "")
                self.setValue(obj);
        }
        else {
            // filtro GrupoContas
            self.setGrupoContasLista(obj);
            self.setVarios(true);
        }
    }

    Validator.prototype.getGrupoContasOuConta = function () {
        "use strict";
        var self = this;

        return self.getVarios() ? self.getGrupoContasLista() : self.getValue();
    }

    Validator.prototype.getGrupoContasStringOuConta = function () {
        "use strict";
        var self = this;

        return self.getVarios() ? self.getGrupoContasString() : self.getValue();
    }

    Validator.prototype.setValue = function (val) {
        'use strict';
        var self = this;

        self.input.value = val;
        self.update();
        self.validate();
    }

    Validator.prototype.getValue = function () {
        'use strict';
        var self = this;

        return self.input.value;
    }

    Validator.prototype.getDescription = function () {
        'use strict';
        var self = this;

        return self.description.innerHTML;
    }

    Validator.prototype.listen = function () {
        "use strict";
        var self = this;

        self.input = document.getElementById(self.inputId);
        self.description = document.getElementById(self.descriptionId);
        if (self.v2) {
            $(self.input).on("input", function () {
                self.value = self.input.value;
            });
            $(self.input).on("focus", function () {
                $(self.input).attr("bkp", $(self.input).val());
            });
            $(self.input).on("blur", function () {
                if (self.isGrupoContas && self.getVarios()) {
                    // seh eh um validator com grupo de contas, e selecionou mais de uma conta, nao limpa o campo
                    // e nem faz validacoes, pois o mesmo esta com o codigo "" e a descricao com "Varios",
                    // por causa do grupo de contas
                }
                else {
                    if ($(self.input).attr("bkp") !== $(self.input).val()) {
                        self.setChange(true);
                        self.validate();
                    }
                    else if (self.isEmpty()) {
                        self.clear();
                        // soh executa o "onEmpty" do "Validator", quando executa o "validate",
                        // se digitar um codigo invalido, limpa o campo, e volta o foco para o mesmo,
                        // se sair do campo sem digitar nada, nao executa o "validate" e consequentemente nao
                        // executa o "onEmpty", e consequentemente nao executa o "changeEmptyToAll",
                        // a linha abaixo previne que isso aconteca
                        if (self.changeEmptyToAll) {
                            self.onEmpty();
                        }
                    }
                }
            });
        }
        else {
            $(self.input).on('keyup', function () {
                self.value = self.input.value;
            });

            $(self.input).on('change', function () {
                self.value = self.input.value;
            });

            $(self.input).on('blur', function () {
                self.validate();
            });

            $(self.input).on('focus', function () {
                self.lastValue = self.value;
            });
        }
    };

    Validator.prototype.changed = function () {
        "use strict";
        return this.lastValue !== this.value;
    };

    Validator.prototype.setChange = function (Change) {
        var self = this;
        // primeiro eh setado como true no Validator.prototype.listen quando o campo sofre alteracao,
        // depois no Modal.prototype.show eh setado como false,
        // usado pelo modal para detectar quando houve uma mudanca no campo
        self.existChange = Change;
    }

    Validator.prototype.haveChange = function () {
        var self = this;
        return self.existChange;
    }

    Validator.prototype.validate = function () {
        "use strict";
        var self = this;

        if (self.isEmpty()) {
            self.alterBehavior(controlGroupBehavior.normal);
            self.description.innerHTML = "";
            self.invalid = true;
            if (self.onEmpty) {
                self.onEmpty();
            }
        } else {
            if (self.v2) {
                var search = self.pendencyResult();
                if (self.GuidProxy) search["GuidProxy"] = self.GuidProxy;

                if (!self.input.disabled) {
                    $.ajax({
                        url: self.route,
                        dataType: "json",
                        type: "GET",
                        data: search,
                        cache: false,
                        success: function (result) {
                            if (result.IsAlert) {
                                self.alterBehavior(controlGroupBehavior.warning);
                                self.invalid = true;

                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }

                                    self.u.dialogOk(result.Message, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }

                                        if (self.onInvalid) {
                                            self.onInvalid(result);
                                        }
                                    }, alertBehavior.warning);
                                }
                                else {
                                    self.u.alert(result.Message, self.u.getAlertBehaviorNumber(result.Level));
                                    if (self.onInvalid) {
                                        self.onInvalid(result);
                                    }
                                }
                            } else {
                                self.alterBehavior(controlGroupBehavior.normal);
                                self.invalid = false;
                                if (self.onValid) {
                                    self.onValid(result);
                                }
                            }
                        },
                        error: function (jqxhr, textStatus, errorThrown) {
                            self.alterBehavior(controlGroupBehavior.warning);
                            self.invalid = true;

                            if (self.msgDialog) {
                                if (self.idModalHideShow) {
                                    $("#" + self.idModalHideShow).modal("hide");
                                }

                                self.u.dialogOk(result.Message, null, true, function () {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("show");
                                    }

                                    if (self.onInvalid) {
                                        self.onInvalid(jqxhr);
                                    }
                                }, alertBehavior.warning);
                            }
                            else {
                                self.u.alert("Erro: " + jqxhr.status + "-" + jqxhr.statusText, u.getAlertBehaviorNumber(alertLevel.warning));
                                if (self.onInvalid) {
                                    self.onInvalid(jqxhr);
                                }
                            }
                        }
                    });
                }
            }
            else {
                var search = self.pendencyResult();
                if (self.GuidProxy) search["GuidProxy"] = self.GuidProxy;

                if (!self.input.disabled) {
                    $.ajax({
                        url: self.route,
                        dataType: 'json',
                        type: 'GET',
                        data: search,
                        cache: false,
                        success: function (result) {
                            if (result.IsAlert) {
                                self.alterBehavior(controlGroupBehavior.warning);
                                self.invalid = true;

                                if (self.msgDialog) {
                                    if (self.idModalHideShow) {
                                        $("#" + self.idModalHideShow).modal("hide");
                                    }

                                    self.u.dialogOk(result.Message, null, true, function () {
                                        if (self.idModalHideShow) {
                                            $("#" + self.idModalHideShow).modal("show");
                                        }

                                        if (self.onInvalid) {
                                            self.onInvalid(result);
                                        }
                                    }, alertBehavior.warning);
                                }
                                else {
                                    self.u.alert(result.Message, self.u.getAlertBehavior(result.Level));
                                    if (self.onInvalid) {
                                        self.onInvalid(result);
                                    }
                                }
                            } else {
                                self.alterBehavior(controlGroupBehavior.normal);
                                self.invalid = false;
                                if (self.onValid) {
                                    self.onValid(result);
                                }
                                disableNegativePermissionsFields();
                            }
                        },
                        error: function (err) {
                            self.alterBehavior(controlGroupBehavior.warning);
                            self.invalid = true;
                            if (self.onInvalid) {
                                self.onInvalid(err);
                            }
                        }
                    });
                }
            }
        }
    };

    Validator.prototype.forceValid = function () {
        "use strict";
        var self = this;
        self.alterBehavior(controlGroupBehavior.normal);
        self.invalid = false;
        self.value = self.input.value;
    };

    Validator.prototype.isEmpty = function () {
        "use strict";
        var self = this;
        return self.value.length === 0;
    };

    Validator.prototype.pendencyResult = function () {
        "use strict";

        var self = this,
            result = {},
            pend;

        if (self.pendency) {
            document.getElementById(self.inputId).value = "";

            var pendencies = self.pendency,
                j = pendencies.length;

            for (var i = 0; i < j; i++) {
                pend = pendencies[i];

                if (pend.isEmpty() || pend.invalid) {
                    var mensagem = "Pendências a serem resolvidas";

                    if (self.msgDialog) {
                        if (self.idModalHideShow) {
                            $("#" + self.idModalHideShow).modal("hide");
                        }

                        self.u.dialogOk(mensagem, null, true, function () {
                            if (self.idModalHideShow) {
                                $("#" + self.idModalHideShow).modal("show");
                            }

                            pend.focus(controlGroupBehavior.warning);
                            if (pend.onInvalid) pend.onInvalid();
                        }, alertBehavior.warning);
                    }
                    else {
                        pend.focus(controlGroupBehavior.warning);
                        pend.showValidateMessage();
                        pend.onInvalid();
                        self.u.alert(mensagem, alertLevel.warning);
                    }

                    throw new Error(mensagem);// exception mantida para nao preencher o campo
                } else {
                    result[pend.field] = pend.value;
                }
            }
        }
        result[self.field] = self.value;
        return result;
    };

    Validator.prototype.focus = function (behavior) {
        "use strict";
        var self = this;
        if (behavior) {
            self.input.focus();
            self.alterBehavior(behavior);
        } else {
            self.input.focus();
        }
        $(self.input).select();
    };

    Validator.prototype.alterBehavior = function (behavior) {
        "use strict";
        var self = this;
        self.input.parentNode.parentNode.className = behavior;
    };

    Validator.prototype.focusError = function () {
        "use strict";
        var self = this;

        self.focus();
        self.isValid = false;
        self.alterBehavior(controlGroupBehavior.warning);
    };

    Validator.prototype.showValidateMessage = function () {
        "use strict";
        var self = this;
        self.description.innerHTML = self.onPendencyMessage;
    };

    Validator.prototype.disable = function () {
        "use strict";
        var self = this;
        self.input.disabled = true;
    };

    Validator.prototype.enable = function () {
        "use strict";
        var self = this;
        self.input.disabled = false;
    };

    // TODO: refatorar e unificar
    Validator.prototype.enable2 = function (op) {
        "use strict";
        var self = this;
        self.input.disabled = !op;
    };

    Validator.prototype.clear = function (options) {
        "use strict";
        var self = this;
        self.value = "";
        self.input.value = "";
        self.description.innerHTML = "";
        self.invalid = true;
        self.PropertiesSpecifyField = {};

        if (options === undefined) {
            options = {};
        }

        if (options.error) {
            self.alterBehavior(controlGroupBehavior.warning);
        }
        else {
            self.alterBehavior(controlGroupBehavior.normal);
            if (options.disable)
                self.disable();
        }

        if (options.warning) {
            self.alterBehavior(controlGroupBehavior.warning);
        }
        if (options.focus) {
            self.input.focus();
        }
    };

    Validator.prototype.update = function () {
        "use strict";
        var self = this;

        self.lastValue = self.value;
        self.value = self.input.value;
        if (self.isEmpty()) {
            self.invalid = true;
        } else {
            self.invalid = false;
        }
        self.alterBehavior(controlGroupBehavior.normal);
        if (self.onUpdate)
            self.onUpdate();
    };

    Validator.prototype.setValues = function (id, description) {
        "use strict";
        var self = this;

        self.value = id;
        self.input.value = id;
        self.description.innerHTML = description;
        self.invalid = false;
        self.alterBehavior(controlGroupBehavior.normal);
    };

    Validator.prototype.setValue = function (value) {
        "use strict";
        var self = this;

        self.value = value;
        self.input.value = value;
        self.invalid = false;
        self.alterBehavior(controlGroupBehavior.normal);
    };

    Validator.prototype.setValueValidate = function (val) {
        'use strict';
        var self = this;

        if (val) {
            self.input.value = val;
            self.update();
            self.validate();
        }
    }

    var baseValidatorPrototypes = function () { };
    baseValidatorPrototypes.prototype = Validator.prototype;

    function ValidatorEx(options) {
        Validator.call(this, options);
        this.inputId = options.inputId;
        this.descriptionId = options.descriptionId;
    }

    ValidatorEx.prototype = new baseValidatorPrototypes();
    ValidatorEx.prototype.constructor = ValidatorEx;

    function DateValidator(options) {
        this.id = options.id;
        this.input = null;
        this.isValid = false;
        this.isEmptyValid = options.isEmptyValid;
        this.isEmpty = true;

        this.onValid = options.onValid;
        this.onInvalid = options.onInvalid;
        this.forceToStayFieldWhereErro = options.forceToStayFieldWhereErro;
        this.onChange = options.onChange;
        this.onBlur = options.onBlur;

        // foi necessário fazer alterações no Validator, e para não correr o risco da alteração atual influenciar no funcionamento das rotinas atuais,
        // foi criado a flag v2, para sinalizar o Validator a usar as novas alterações
        this.v2 = options.v2;
        this.isMMAAAA = options.isMMAAAA;

        this.constructInjection = options.constructInjection;
        this.construct();

        this.defaultValue = options.defaultValue;
        if (this.defaultValue) this.input.value = this.defaultValue;
    }

    DateValidator.prototype.isMinorDateNow = function () {
        "use strict";
        var self = this;

        var now = new Date();
        var nowWithoutHours = new Date(now.getFullYear(), now.getMonth(), now.getDate());

        return self.getValueDate() < nowWithoutHours;
    }

    DateValidator.prototype.construct = function () {
        "use strict";
        var self = this;

        if (self.constructInjection) {
            if (typeof self.constructInjection !== 'function') {
                console.warn('Invalid contruct injection!');
            } else {
                self.constructInjection();
            }
        }

        self.listen();
        self.validate();
    };

    DateValidator.prototype.enable = function (value) {
        'use strict';
        var self = this;

        if (value)
            $("#" + self.id).removeAttr("disabled");
        else
            $("#" + self.id).attr("disabled", "disabled");
    }

    DateValidator.prototype.focus = function (behavior) {
        "use strict";
        var self = this;

        if (behavior) self.alterBehavior(behavior);
        self.input.focus();
    };

    DateValidator.prototype.alterBehavior = function (behavior) {
        "use strict";
        var self = this;

        self.input.parentNode.parentNode.className = behavior;
    };

    DateValidator.prototype.focusError = function () {
        "use strict";
        var self = this;

        self.input.focus();
        self.isValid = false;
        self.alterBehavior(controlGroupBehavior.warning);
    };

    DateValidator.prototype.setValue = function (val) {
        'use strict';
        var self = this;
        self.input.value = val;
        self.validate();
        self.execute();
    }

    DateValidator.prototype.setValueBkp = function (val) {
        "use strict";
        var self = this;

        self.setValue(val);
        $("#" + self.id).attr("bkp", val);
    }

    DateValidator.prototype.clear = function () {
        "use strict";
        var self = this;

        self.input.value = "";
        self.validate();
        $("#" + self.id).attr("bkp", "");
    }

    DateValidator.prototype.setValueNoValidate = function (val) {
        'use strict';
        var self = this;
        self.input.value = val;
    }

    DateValidator.prototype.getValue = function () {
        'use strict';
        var self = this;
        return self.input.value;
    }

    DateValidator.prototype.getValueDate = function () {
        'use strict';
        var self = this;
        return convertDateStringDDMMYYYYToDate(self.input.value);
    }

    DateValidator.prototype.getValueDateDDMMYYYY = function () {
        'use strict';
        var self = this;
        if (self.isMMAAAA) {
            return convertDateStringMMYYYYToDate(self.input.value);
        }
        else {
            return convertDateStringDDMMYYYYToDate(self.input.value);
        }
    }

    DateValidator.prototype.forceExecuteValidate = function () {
        "use strict";
        var self = this;

        self.validate();
        self.execute();
        if (self.onChange) self.onChange();
    }

    DateValidator.prototype.listen = function () {
        'use strict';
        var self = this;
        var input = $('#' + self.id);
        self.input = input[0];
        if (self.v2) {
            $(self.input).on("input", function () {
                self.value = self.input.value;
            });

            $(self.input).on("focus", function () {
                $(self.input).attr("bkp", $(self.input).val());
                self.erroType = "";
            });

            $(self.input).on("blur", function () {
                if ($(self.input).attr("bkp") !== $(self.input).val()) {
                    self.validate();
                    self.execute();
                    if (self.onChange) self.onChange();
                }
                else if (self.onBlur) {
                    self.onBlur(self);
                }
                $(self.input).attr("bkp", $(self.input).val());

                if (self.v2 && self.forceToStayFieldWhereErro && !self.isValid) {
                    self.focus();
                }
            });

            $(self.input).on("change", function () {
                if ($(self.input).attr("bkp") !== $(self.input).val()) {
                    self.validate();
                    self.execute();
                    if (self.onChange) self.onChange();
                }
                $(self.input).attr("bkp", $(self.input).val());
            });
        }
        else {
            input.on('blur', function () {
                self.validate();
                self.execute();
            });
        }
    };

    DateValidator.prototype.validate = function () {
        "use strict";
        var self = this;

        if (self.isMMAAAA) {
            var val = self.input.value;
            if (val.match(/00\/0000/) || val == "") {
                if (self.isEmptyValid) {
                    self.isValid = true;
                } else {
                    self.isValid = false;
                }

                if (self.defaultValue) self.input.value = self.defaultValue;

            } else {
                if (!val.match(/^\d{2}\/\d{4}$/)) {
                    self.isValid = false;
                } else {
                    var mes = parseInt(val.split("/")[0])
                    self.isValid = mes > 0 && mes < 13;
                }
            }
        }
        else {
            var val = self.input.value;
            if (val.match(/00\/00\/0000/) || val == "") {
                if (self.isEmptyValid) {
                    self.isValid = true;
                } else {
                    self.isValid = false;
                }

                if (self.defaultValue) self.input.value = self.defaultValue;

            } else {
                if (val.match(/^\d{2}\/\d{2}\/\d{2}$/)) {
                    self.isValid = false;
                } else {
                    self.isValid = self.input.value.isValidDate();
                }
            }
        }

        if (self.v2) {
            if (self.getValue() !== "" && self.getValue() !== "00/00/0000") {
                self.isEmpty = false;

                if (self.isValid && self.defaultValue) self.input.value = self.defaultValue;
            }
            else {
                self.isEmpty = true;
            }
            if (self.isEmpty && self.isEmptyValid)
                self.alterBehavior(controlGroupBehavior.normal);
        }
    };

    DateValidator.prototype.execute = function () {
        "use strict";
        var self = this;
        if (self.isValid) {
            if (self.onValid) {
                self.onValid(self);
            }
        } else {
            if (self.onInvalid) {
                self.onInvalid(self);
            }
        }
    };

    // TODO: diferenca entre SimpleDateComparer e DateComparer
    function DateComparer(options) {
        this.idA = options.idA;
        this.idB = options.idB;
        this.inputA = null;
        this.inputB = null;
        this.verb = options.verb;
        this.isValid = options.valid;
        this.isListening = false;
        this.isMMAAAA = options.isMMAAAA;

        this.onValid = options.onValid;
        this.onInvalid = options.onInvalid;

        // na aba fatura do pedido, esta ficando com a tela preta, porque é apresentado várias vezes uma mensagem de erro no formato dialog,
        // mas o problema é que a função this.copare é chamada nos eventos change e no blur, para não causar problemas em outras telas,
        // foi criado a flag v2 para contornar esse problema
        this.v2 = options.v2;

        this.listen();
        this.compare();
    };

    DateComparer.prototype.listen = function () {
        "use strict";
        var self = this;
        self.inputA = $('#' + self.idA);
        self.inputB = $('#' + self.idB);

        if (self.v2) {
            self.inputA.on('change', function () {
                self.compare();
            });
            self.inputB.on('change', function () {
                self.compare();
            });
        }
        else {
            self.inputA.on('change', function () {
                self.compare();
            });
            self.inputA.on('blur', function () {
                self.compare();
            });
            self.inputB.on('change', function () {
                self.compare();
            });
            self.inputB.on('blur', function () {
                self.compare();
            });
        }

        self.isListening = true;
    };

    DateComparer.prototype.compare = function () {
        "use strict";
        var self = this;

        var valA = self.inputA.val();
        var valB = self.inputB.val();
        if (valA === "" || valB === "") {
            self.isValid = true;
        } else {
            if (self.isMMAAAA) {
                var result = ("01/" + valA).toDate().compare(("01/" + valB).toDate());
            }
            else {
                var result = valA.toDate().compare(valB.toDate());
            }
            self.isValid = (result == self.verb || result == 'equal');
        }
        self.execute();
        return self.isValid;
    };

    DateComparer.prototype.execute = function () {
        "use strict";
        var self = this;
        if (self.isValid) {
            if (self.onValid) {
                self.onValid(self);
            }
        } else {
            if (self.onInvalid) {
                self.onInvalid(self);
            }
        }
    };

    function CurrencyCompararer(options) {
        this.idA = options.idA;
        this.idB = options.idB;
        this.inputA = null;
        this.inputB = null;
        this.verb = options.verb;
        this.isValid = options.valid;
        this.isListening = false;

        this.onValid = options.onValid;
        this.onInvalid = options.onInvalid;

        this.construct();
    }

    CurrencyCompararer.prototype.construct = function () {
        "use strict";
        var self = this;
        self.listen();
        self.compare();
    };

    CurrencyCompararer.prototype.listen = function () {
        "use strict";
        var self = this;
        self.inputA = $('#' + self.idA);
        self.inputB = $('#' + self.idB);
        self.inputA.on('change', function () {
            self.compare();
        });
        self.inputA.on('blur', function () {
            self.compare();
        });
        self.inputB.on('change', function () {
            self.compare();
        });
        self.inputB.on('blur', function () {
            self.compare();
        });
        self.isListening = true;
    };

    CurrencyCompararer.prototype.compare = function () {
        "use strict";
        var self = this;

        var valA = self.inputA.val();
        var valB = self.inputB.val();
        if (valA === "" || valB === "") {
            self.isValid = true;
        } else {
            var result = valA.toFloat().compare(valB.toFloat());
            self.isValid = (result == self.verb || result == 'equal');
        }
        self.execute();
    };

    CurrencyCompararer.prototype.execute = function () {
        "use strict";
        var self = this;
        if (self.isValid) {
            if (self.onValid) {
                self.onValid(self);
            }
        } else {
            if (self.onInvalid) {
                self.onInvalid(self);
            }
        }
    };

    // TODO: trocar todos por apenas um componente, padronizar
    // var inputLayoutRelatorio = new DropDown({
    // var inputLayoutAtendimento = $("#inputLayoutRelatorio").kendoDropDownList({
    // var inputOpcao = new ValidatorDropDown({
    // DropDown
    function DropDown(options) {
        this.dropDown = null;
        this.id = options['id'];
        this.route = options['route'];
        this.data = options.data;
        this.defaultValue = options['defaultValue'] || null;
        this.defaultValueRoute = window.baseUrl + options['defaultValueRoute'] || null;
        this.onOpen = options['onOpen'];
        this.onClose = options['onClose'];
        this.onChange = options['onChange'];
        this.onSelect = options['onSelect'];
        this.onDataBound = options['onDataBound'];
    }

    DropDown.prototype.make = function () {
        "use strict";
        var self = this;

        if (self.data) {
            self.read = function (options) {
                $.ajax({
                    headers: {
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    },
                    url: window.baseUrl + self.route,
                    dataType: "json",
                    type: "POST",
                    data: JSON.stringify(self.data),
                    success: function (result) {
                    },
                    error: function (result) {
                    }
                });
            };
        }
        else {
            self.read = window.baseUrl + self.route;
        }

        self.dropDown = $("#" + self.id).kendoDropDownList({
            dataTextField: "Text",
            dataValueField: "Value",
            dataSource: {
                type: "json",
                transport: {
                    read: self.read
                }
            },
            value: self.defaultValue,
            open: self.onOpen,
            close: self.onClose,
            change: self.onChange,
            select: self.onSelect,
            dataBound: function () {
                if (self.onDataBound) {
                    self.onDataBound();
                }
            }
        }).data("kendoDropDownList");
    };

    DropDown.prototype.disable = function () {
        "use strict";
        var self = this;
        self.dropDown.enable(false);
    };

    DropDown.prototype.enable = function () {
        "use strict";
        var self = this;
        self.dropDown.enable();
    };

    DropDown.prototype.set = function (value) {
        "use strict";
        var self = this;
        if (self.dropDown != null) {
            self.dropDown.value(value);
        }
    };

    DropDown.prototype.get = function () {
        "use strict";
        var self = this;
        return self.dropDown.value();
    };

    DropDown.prototype.setIndex = function (index) {
        "use strict";
        var self = this;
        self.dropDown.select(index);
    };

    DropDown.prototype.getIndex = function () {
        "use strict";
        var self = this;
        self.dropDown.select();
    };

    DropDown.prototype.setDefault = function () {
        "use strict";
        var self = this;
        if (self.defaultValue != null) {
            self.set(self.defaultValue['Value']);
        } else if (self.defaultValueRoute) {
            getJsonFromRoute(self.defaultValueRoute, '').done(function (data) {
                if (data.IsAlert) {
                    throw new Error(data.Message);
                } else {
                    self.set(data['Value']);
                }
            });
        } else {
            throw new Error('Não a registro default para este campo');
        }
    };

    DropDown.prototype.select = function (callback) {
        "use strict";
        var self = this;
        self.dropDown.select(callback);
    };

    DropDown.prototype.change = function () {
        "use strict";
        var self = this;
        self.dropDown.trigger('change');
    };

    function RadioSwitcher(options) {
        this.groupSelector = options.groupSelector;
        this.onChange = options.onChange;
        this.construct();
    }

    RadioSwitcher.prototype.construct = function () {
        "use strict";
        this.listen();
    };

    RadioSwitcher.prototype.listen = function () {
        "use strict";
        var self = this;
        $(self.groupSelector).on('click', function () {
            if (self.onChange) {
                self.onChange(this);
            }
        });
    };

    RadioSwitcher.prototype.value = function (callback) {
        "use strict";
        var self = this
           , firstValue = $(self.groupSelector + ':checked').val()
           , callType = typeof callback;

        switch (callType) {
            case 'function':
                callback(firstValue);
                break;
            case 'string':
            case 'number':
                $(self.groupSelector + '[value=' + callback + ']').click();
                break;
        }

        return firstValue;
    };

    RadioSwitcher.prototype.change = function () {
        "use strict";
        var self = this;
        if (self.onChange) {
            self.onChange(this);
        }
    };

    function ValidatorDropDown(options) {
        "use strict";
        var self = this;

        self.abrev = options.abrev;
        self.idInputCodigo = options.idInputCodigo;
        self.idLinkButtonModal = options.idLinkButtonModal;
        self.idInputDescription = options.idInputDescription;
        self.idLinkButtonModalGrupoContas = options.idLinkButtonModalGrupoContas;

        self.ModalGrupoContas = options.ModalGrupoContas;
        self.columnsModalGrupoContas = options.columnsModalGrupoContas;
        self.nameFieldDescription = options.nameFieldDescription;
        self.route = options.route;
        self.width = options.width;

        if (self.abrev && !self.idInputCodigo) self.idInputCodigo = "input" + self.abrev;
        if (self.abrev && !self.idLinkButtonModal) self.idLinkButtonModal = "linkButtonModal" + self.abrev;
        if (self.abrev && !self.idInputDescription) self.idInputDescription = "description" + self.abrev;
        if (self.abrev && !self.idLinkButtonModalGrupoContas) self.idLinkButtonModalGrupoContas = "linkButtonModalGrupoContas" + self.abrev;

        self.onChange = options.onChange;

        if (options.dataSource) {
            // local
            self.dataSource = options.dataSource;
            self.dataTextField = options.dataTextField ? options.dataTextField : "Text";
            self.dataValueField = options.dataValueField ? options.dataValueField : "Value";
            self.valueFieldDefault = options.valueFieldDefault ? options.valueFieldDefault : "0";
            self.makeDropDownLocal();
        }
        else {
            // route
            self.makeDropDown();
            self.dropDown.make();

            // ajusta campo para ficar alinhado com os demais
            $($("#" + self.idInputCodigo).parent()).css("margin-bottom", "3px");
            $($("#" + self.idInputCodigo).parent()).css("margin-left", "4px");

            if (self.width) {
                $("span[aria-owns=" + self.idInputCodigo + "_listbox]").css("width", self.width + "px");
            }
        }

        self.enable = options.enable;
        if (self.enable !== undefined) {
            self.setEnable(self.enable)
        }

        self.Varios = false;
        self.grupoContas = [];

        if (self.ModalGrupoContas) {
            var modalGrupoContasX = new ModalGrupoContas({
                id: self.abrev ? self.abrev : self.idInputCodigo,
                tipo: "ComboBox",
                validatorInput: [this],
                columns: self.columnsModalGrupoContas,
                route: self.route
            });
        }
    }

    ValidatorDropDown.prototype.focus = function (val) {
        "use strict";
        var self = this;

        $("#" + self.idInputCodigo).parent().parent().focus();
    }

    ValidatorDropDown.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        if (self.dataSource) {
            return self.dropDown.data().kendoDropDownList.select(typeof val === "number" ? val : val.toInt());
        }
        else {
            return self.dropDown.set(val);
        }
    }

    ValidatorDropDown.prototype.setVarios = function (op) {
        "use strict";
        var self = this;

        if (op) {
            self.Varios = true;
            $($("#" + self.idInputCodigo + "Disable").parent()).css("display", "inline-block");
            $($("#" + self.idInputCodigo).parent()).css("display", "none");
            self.dropDownDisable.enable(false);
            setHtml(self.idInputDescription, "Vários")
        }
        else {
            self.Varios = false;
            $($("#" + self.idInputCodigo + "Disable").parent()).css("display", "none");
            $($("#" + self.idInputCodigo).parent()).css("display", "inline-block");
            setHtml(self.idInputDescription, "");
            if (self.grupoContas.length > 0) {
                var dados = self.grupoContas[0];
                self.setValue(dados.id);
            }
        }
    }

    ValidatorDropDown.prototype.makeDropDownLocal = function () {
        "use strict";
        var self = this;

        self.dropDown = $("#" + self.idInputCodigo).kendoDropDownList({
            id: self.idInputCodigo,
            dataSource: self.dataSource,
            dataTextField: self.dataTextField,
            dataValueField: self.dataValueField,
            value: self.valueFieldDefault,
            change: self.onChange
        });

        // ajusta campo para ficar alinhado com os demais
        $($("#" + self.idInputCodigo).parent()).css("margin-bottom", "3px");
        $($("#" + self.idInputCodigo).parent()).css("margin-left", "4px");

        // TODO: melhorar
        if (self.width) {
            $("span[aria-owns=" + self.idInputCodigo + "_listbox]").css("width", self.width + "px");
        }
        else {
            // seta automaticamente a largura do combobox, com o maior texto,
            // procura no combobox, o item que tem o texto com a maior quantidade de letras,
            // calculo de 13px por letra (considerando a maior letra sendo o "W")
            var obj = $("#" + self.idInputCodigo + "_listbox li");
            var totalPixelsGeral = 0;
            $.each(obj, function (i, el) {
                var totalPixelAtual = $(el).html().length * 14;
                if (totalPixelAtual > totalPixelsGeral)
                    totalPixelsGeral = totalPixelAtual;
            });
            $("span[aria-owns=" + self.idInputCodigo + "_listbox]").css("width", totalPixelsGeral + "px");
        }
    }

    ValidatorDropDown.prototype.setDataSource = function (dataSource) {
        "use strict";
        var self = this;

        self.dataSource = dataSource;
        self.makeDropDownLocal();
    }

    // TODO: remover onde usa setEnable
    ValidatorDropDown.prototype.setEnable = function (op) {
        "use strict";
        var self = this;

        $("#" + self.idInputCodigo).data("kendoDropDownList").enable(op);
    }

    // TODO: refatorar compoenentes para usar o mesmo nome
    ValidatorDropDown.prototype.enable2 = function (op) {
        "use strict";
        var self = this;

        $("#" + self.idInputCodigo).data("kendoDropDownList").enable(op);
    }

    ValidatorDropDown.prototype.getValue = function () {
        "use strict";
        var self = this;

        if (self.dataSource)
            return self.dropDown.val();
        else
            return self.dropDown.dropDown.dataItem().Value;
    }

    ValidatorDropDown.prototype.getDescription = function () {
        "use strict";
        var self = this;

        if (self.dataSource)
            return getHtml(self.idInputCodigo + "_option_selected");
        else
            return self.dropDown.dropDown.dataItem().Text;
    }

    ValidatorDropDown.prototype.makeDropDown = function () {
        "use strict";
        var self = this;

        self.dropDown = new DropDown({
            id: self.idInputCodigo,
            route: self.route,
            onChange: self.onChange
        });

        self.dropDownDisable = $("#" + self.idInputCodigo + "Disable").kendoDropDownList({}).data("kendoDropDownList");
        $($("#" + self.idInputCodigo + "Disable").parent()).css("display", "none");
    }

    ValidatorDropDown.prototype.getVarios = function () {
        "use strict";
        var self = this;

        return self.Varios;
    }

    ValidatorDropDown.prototype.setGrupoContas = function (grupoContas) {
        "use strict";
        var self = this;

        if (grupoContas.length > 1) {
            self.setVarios(true);
        }
        else {
            self.setVarios(false);
        }

        return self.grupoContas = grupoContas;
    }

    ValidatorDropDown.prototype.getGrupoContasString = function () {
        'use strict';
        var self = this;

        var grupoContasEnvia = "";
        if (self.getVarios()) {
            var lista = "";
            for (var conta in self.grupoContas)
                lista += self.grupoContas[conta].id + ",";
            grupoContasEnvia = lista;
        }
        else {
            grupoContasEnvia = self.getValue();
        }

        return grupoContasEnvia;
    }

    ValidatorDropDown.prototype.getGrupoContas = function () {
        "use strict";
        var self = this;

        var grupoContasSalva = [];
        if (self.getVarios()) {
            grupoContasSalva = self.grupoContas;
        }
        else {
            grupoContasSalva.push({
                id: self.getValue(),
            });
        }

        return self.grupoContas;
    }

    function ValidatorDate(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];

        var validatorX = new DateValidator({
            id: self.idInput,
            v2: true,
            isEmptyValid: self.isEmptyValid,
            defaultValue: self.defaultValue,
            constructInjection: function () {
                makeDatePicker("#" + this.id);
            },
            onBlur: function (validator) {
                if (validator.erroType !== "DataInvalida" && !validator.erroShowMesage && !validator.isEmptyValid && (validator.getValue() === "" || validator.getValue() === "00/00/0000")) {
                    validator.erroShowMesage = true;
                    u.dialogOk("Data inválida.", null, true, function () {
                        validator.alterBehavior(controlGroupBehavior.warning);
                        // nao forcar o focus no campo, pois agora usa msgDialog, se usar focus no campo, vai prender o usuario no campo, inclusive para sair da tela
                        //validator.focus();
                    }, alertBehavior.warning);
                }
                else
                    validator.alterBehavior(controlGroupBehavior.normal);
            },
            onValid: function (validator) {
                validator.erroShowMesage = false;
                validatorX.alterBehavior(controlGroupBehavior.normal);
                if (self.onValid)
                    self.onValid(validator);
            },
            onInvalid: function (validator) {
                function onAfterShow() {
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }

                    validator.clear();
                    validator.alterBehavior(controlGroupBehavior.warning);
                    validator.focus();

                    if (self.onInvalid)
                        self.onInvalid(validator);
                }

                validator.erroShowMesage = false;
                validator.erroType = "DataInvalida";

                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }

                if (!validator.isEmptyValid && (validator.getValue() === "" || validator.getValue() === "00/00/0000")) {
                    validator.erroShowMesage = true;
                    u.dialogOk("Data inválida.", null, true, onAfterShow, alertBehavior.warning);
                }
                else if (validator.isMMAAAA) {
                    if (!validator.input.value.match(/^\d{2}\/\d{4}$/))
                        u.dialogOk('Informe uma data com o formato MM/AAAA.', null, true, onAfterShow, alertBehavior.warning);
                    else
                        u.dialogOk('A data: "{0}" não é uma data válida'.format(validator.input.value), null, true, onAfterShow, alertBehavior.warning);
                }
                else {
                    if (validator.input.value.match(/^\d{2}\/\d{2}\/\d{2}$/))
                        u.dialogOk('Informe uma data com o formato DD/MM/AAAA.', null, true, onAfterShow, alertBehavior.warning);
                    else
                        u.dialogOk('A data: "{0}" não é uma data válida'.format(validator.input.value), null, true, onAfterShow, alertBehavior.warning);
                }
            },
            onEmpty: function (validator) {
                validator.erroShowMesage = false;
                validator.alterBehavior(controlGroupBehavior.normal);
                if (self.onEmpty)
                    self.onEmpty(validator);
            },
            onChange: function (validator) {
                if (self.onChange)
                    self.onChange(validator);
            }
        });
        self.validator = validatorX;

        // compara se data do validator eh maior que data do compare
        if (self.compareGreater) {
            self.comparer = new DateComparer({
                idA: self.compareGreater,
                idB: self.idInput,
                v2: true,
                verb: "less",

                onInvalid: function (data) {
                    function onAfterShow() {
                        if (self.idModalHideShow) {
                            $("#" + self.idModalHideShow).modal("show");
                        }

                        self.validator.clear();
                        self.validator.alterBehavior(controlGroupBehavior.warning);
                        self.validator.focus();
                    }

                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("hide");
                    }

                    u.dialogOk(self.compareGreaterMsg ? self.compareGreaterMsg : "Data final deve ser igual ou maior que à data inicial.", null, true, onAfterShow, alertBehavior.warning);
                },

                onValid: function (data) {
                    self.validator.alterBehavior(controlGroupBehavior.normal);
                }
            });
        }

        return validatorX;
    }

    ValidatorDate.prototype.clear = function () {
        "use strict";
        var self = this;

        self.validator.clear();
    }

    function ValidatorMemo(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];
        self.input = $("#" + self.idInput);

        // valores padroes
        if (self.attr === undefined) self.attr = { };
        if (self.attr.disabled) self.input.attr("disabled", self.attr.disabled);
        self.input.attr("maxlength", self.attr.maxlength ? self.attr.maxlength : "1000");

        if (self.css === undefined) self.css = { };

        self.input.css("height", self.css.height ? self.css.height : "16px");
        self.input.css("width", self.css.width ? self.css.width : "400px");

        self.input.css("margin-left", self.css.padding_right ? self.css.padding_right : "5px");

        self.input.css("padding-top", self.css.padding_top ? self.css.padding_top : "2px");
        self.input.css("padding-bottom", self.css.padding_bottom ? self.css.padding_bottom : "2px");
        self.input.css("padding-left", self.css.padding_left ? self.css.padding_left : "3px");
        self.input.css("padding-right", self.css.padding_right ? self.css.padding_right : "3px");

        self.input.css("resize", self.css.resize ? self.css.resize : "none");
        self.input.css("overflow", self.css.overflow ? self.css.overflow : "hidden");

        // listen
        self.input.on("focus", function () {
            self.input.attr("bkp", self.input.val());
        });

        self.input.on("blur", function () {
            if (self.input.attr("bkp") !== self.input.val() && self.onChange) {
                self.onChange();
            }
            self.input.attr("bkp", self.input.val());
        });

        self.input.on("keydown", function (ev) {
            var evCodeKey = (ev.keyCode || ev.which);
            // F4 consulta
            if (evCodeKey == "115") {
                ev.preventDefault();
                ev.preventBubble = true;
                self.inputLink.click();
            }
        });

        // binding
        if (self.idLink) {
            // cria o html e evendo do modal
            self.titleModal = self.titleModal ? self.titleModal : "";
            // usa label do campo como titulo do modal, caso nao informa o titulo do modal
            if (self.titleModal === "") {
                self.titleModal = "Título não Informado";
                try {
                    var text = $(self.input).parent().parent().find("label").text();
                    if (text[text.length - 1] === ":" && text.length > 1) {
                        self.titleModal = text.substring(0, text.length - 1);
                    }
                }
                catch (err) {
                }
            }
            self.makeModal();

            // quando clicar no link para chamar o modal, faz copia do conteudo textarea para o textarea do modal
            self.inputLink = $("#" + self.idLink);

            // precisa do atributo href na tag "<a>" para ajusta corretament o ponteiro do mouse na tag "<i>"
            if (self.inputLink.attr("href") === undefined) {
                self.inputLink.attr("href", "#");
            }

            self.inputLink.live("click", function () {
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }

                $("#modalObservacao_" + self.idInput).modal("show");
                $("#textareaObservacao_" + self.idInput).val($("#" + self.idInput).val());
                if (self.input.attr("disabled"))
                    $("#textareaObservacao_" + self.idInput).attr("disabled", "disabled");
                else
                    $("#textareaObservacao_" + self.idInput).removeAttr("disabled");
            });
        }
    }

    ValidatorMemo.prototype.makeModal = function () {
        "use strict";
        var self = this;

        var htmlModal =
            '<div id="modalObservacao_' + self.idInput + '" class="modal hide modal-ajust" tabindex="-2" role="dialog" aria-hidden="true">'
            + '    <div class="modal-header">'
            + '        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'
            + '        <h4 style="color: white">' + self.titleModal + '</h4>'
            + '    </div>'
            + '    <div class="modal-body">'
            + '        <textarea id="textareaObservacao_' + self.idInput + '" maxlength="' + self.input.attr("maxlength") + '" style="width: 95%; height: 290px; resize: none"></textarea>'
            + '    </div>'
            + '    <div class="modal-footer">'
            + '        <button id="buttonOKObservacao_' + self.idInput + '" class="btn btn-inverse" data-dismiss="modal" style="width: 80px")">OK</button>'
            + '        <button id="buttonCancelarObservacao_' + self.idInput + '" class="btn btn-inverse" data-dismiss="modal" style="width: 80px">Cancelar</button>'
            + '    </div>'
            + '</div>';
        $("#modalDiv").append(htmlModal);

        $("#textareaObservacao_" + self.idInput).on("focus", function () {
            $("#textareaObservacao_" + self.idInput).attr("bkp", $("#textareaObservacao_" + self.idInput).val());
        });

        $("#buttonOKObservacao_" + self.idInput).live("click", function () {
            if ($("#textareaObservacao_" + self.idInput).val() !== $("#textareaObservacao_" + self.idInput).attr("bkp")) {
                self.input.val($("#textareaObservacao_" + self.idInput).val());
                if (self.onChange) {
                    self.onChange();
                }
            }
        });

        $("#modalObservacao_" + self.idInput).on("hidden", function () {
            if (self.idModalHideShow) {
                $("#" + self.idModalHideShow).modal("show");
            }
            self.input.focus();
        });
    }

    ValidatorMemo.prototype.clear = function () {
        "use strict";
        var self = this;

        self.input.val("");
        self.input.attr("bkp", "");
    }

    ValidatorMemo.prototype.set = function (val, executeOnChange) {
        "use strict";
        var self = this;

        if (executeOnChange === undefined)
            executeOnChange = true;

        if (self.input.attr("bkp") !== val && self.onChange && executeOnChange) {
            self.onChange();
        }
        self.input.val(val);
        self.input.attr("bkp", val);
    }

    ValidatorMemo.prototype.get = function () {
        "use strict";
        var self = this;

        return self.input.val();
    }

    ValidatorMemo.prototype.focus = function () {
        "use strict";
        var self = this;

        return $(self.input).focus();
    }

    ValidatorMemo.prototype.enable = function (val) {
        "use strict";
        var self = this;

        if (val)
            self.input.removeAttr("disabled");
        else
            self.input.attr("disabled", "disabled");
    }

    // ModalMemo
    // TODO: melhorar, renomear
    function ValidatorModalMemo(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];

        // id do button
        self.input = $("#" + self.idInput);

        // valores padroes
        self.attr = self.attr || {};
        self.input.attr("disabled", "disabled");
        self.css = self.css || {};
        self.titleModal = self.titleModal ? self.titleModal : "Título não Informado";

        // cria o html e evendo do modal
        self.makeModal();
        $("#textareaObservacao_" + self.idInput).val(self.value);

        self.input.on("click", function () {
            $("#modalObservacao_" + self.idInput).modal("show");
        });
    }

    ValidatorModalMemo.prototype.makeModal = function () {
        "use strict";
        var self = this;

        var htmlModal =
            '<div id="modalObservacao_' + self.idInput + '" class="modal hide modal-ajust" tabindex="-2" role="dialog" aria-hidden="true">'
            + '    <div class="modal-header">'
            + '        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'
            + '        <h4 style="color: white">' + self.titleModal + '</h4>'
            + '    </div>'
            + '    <div class="modal-body">'
            + '        <textarea id="textareaObservacao_' + self.idInput + '" readonly="readonly" style="width: 95%; height: 290px; resize: none"></textarea>'
            + '    </div>'
            + '    <div class="modal-footer">'
            + '        <button id="buttonCancelarObservacao_' + self.idInput + '" class="btn btn-inverse" data-dismiss="modal" style="width: 80px">Cancelar</button>'
            + '    </div>'
            + '</div>';
        $("#modalDiv").append(htmlModal);
    }

    ValidatorModalMemo.prototype.clear = function () {
        "use strict";
        var self = this;

        $("#textareaObservacao_" + self.idInput).val("");
    }

    ValidatorModalMemo.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        $("#textareaObservacao_" + self.idInput).val(val);
    }

    ValidatorModalMemo.prototype.getValue = function () {
        "use strict";
        var self = this;

        return $("#textareaObservacao_" + self.idInput).val();
    }

    ValidatorModalMemo.prototype.enable = function (val) {
        "use strict";
        var self = this;

        if (val)
            self.input.removeAttr("disabled");
        else
            self.input.attr("disabled", "disabled");
    }

    // o event input nao funciona quando usar o autoNumeric para criar a mascara,
    // por isso foi criado o ValidatorNumber
    function ValidatorMask(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];

        $("#" + self.idInput).on("focus", function () {
            $("#" + self.idInput).attr("bkp", $("#" + self.idInput).val());
        });

        $("#" + self.idInput).on("blur", function () {
            $("#" + self.idInput).parent().parent().removeClass(alertBehavior.success);
            $("#" + self.idInput).parent().parent().removeClass(alertBehavior.warning);

            if (self.isEmptyValid !== undefined && !self.isEmptyValid && self.getValue() === "") {
                self.setValue(self.defaultValue);
            }
            if ($("#" + self.idInput).attr("bkp") !== $("#" + self.idInput).val() && self.onChange) {
                self.onChange();
            }
        });

        $("#" + self.idInput).on("change", self.onChange);

        self.makeMask();

        if (self.setDefaulValue) {
            $("#" + self.idInput).attr("bkp", self.defaultValue);
            $("#" + self.idInput).val(self.defaultValue);
        }
    }

    ValidatorMask.prototype.changeMask = function (value) {
        "use strict";
        var self = this;

        self.mask = value;
        self.makeMask();
    }

    ValidatorMask.prototype.getDefaultValue = function () {
        "use strict";
        var self = this;

        if ($.mask.masks[self.mask].defaultValueValidator) {
            return $.mask.masks[self.mask].defaultValueValidator;
        }
    }

    ValidatorMask.prototype.makeMask = function (value) {
        "use strict";
        var self = this;

        $("#" + self.idInput).unsetMask ? $("#" + self.idInput).unsetMask() : false;
        $("#" + self.idInput).autoNumeric ? $("#" + self.idInput).autoNumeric("destroy") : false;

        $("#" + self.idInput).attr("radarmask", self.mask);
        if (self.mask.startsWith("radar-valor")) {
            var params = self.mask.split("valor");
            if (params.length == 1) {
                $("#" + self.idInput).setMask();
            }
            else {
                var integer = params[1].split("-")[1];
                var decimal = params[1].split("-")[2];
                if (decimal === undefined)
                    $("#" + self.idInput).setMask();
                else {
                    $("#" + self.idInput).autoNumeric("destroy");
                    $("#" + self.idInput).autoNumeric("init", getAutoNumericOptions(integer, decimal));
                }
            }
        }
        else {
            $("#" + self.idInput).setMask();
        }
    }

    ValidatorMask.prototype.enable = function (value) {
        "use strict";
        var self = this;

        if (value)
            $("#" + self.idInput).removeAttr("disabled");
        else
            $("#" + self.idInput).attr("disabled", "disabled");
    }

    ValidatorMask.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        if (self.isEmptyValid !== undefined && !self.isEmptyValid && (val === undefined || val === "" || val === null)) {
            val = self.defaultValue;
        }

        $("#" + self.idInput).val(val);
        self.makeMask();
    }

    ValidatorMask.prototype.clear = function () {
        "use strict";
        var self = this;

        if (self.isEmptyValid !== undefined && !self.isEmptyValid) {
            $("#" + self.idInput).val(self.defaultValue);
            $("#" + self.idInput).attr("bkp", self.defaultValue);
        }
        else {
            $("#" + self.idInput).val("");
            $("#" + self.idInput).attr("bkp", "");
        }
    }

    ValidatorMask.prototype.getValue = function () {
        "use strict";
        var self = this;

        return $("#" + self.idInput).val();
    }

    ValidatorMask.prototype.getValueNumber = function () {
        "use strict";
        var self = this;

        return convertStringDecimalPtBrToFloat($("#" + self.idInput).val());
    }

    ValidatorMask.prototype.isValid = function () {
        "use strict";
        var self = this;

        if ($("#" + self.idInput).val())
            return true;
        else
            return false;
    }

    ValidatorMask.prototype.isEmptyOrZeros = function () {
        "use strict";
        var self = this;

        if (self.isHora) {
            if ($("#" + self.idInput).val() === "" || (parseFloat($("#" + self.idInput).val().replace(":", "")) === 0))
                return true;
            else
                return false;
        }
        else {
            if (parseFloat($("#" + self.idInput).val().replace(".", "").replace(",", ".")) === 0)
                return true;
            else
                return false;
        }
    }

    ValidatorMask.prototype.isEmpty = function () {
        "use strict";
        var self = this;

        return $("#" + self.idInput).val().length === 0;
    }

    ValidatorMask.prototype.focus = function (value) {
        "use strict";
        var self = this;

        $("#" + self.idInput).focus();
    }

    ValidatorMask.prototype.alterBehavior = function (behavior) {
        "use strict";
        var self = this;

        $("#" + self.idInput).parent().parent().addClass(behavior)
    };

    ValidatorMask.prototype.focusError = function () {
        "use strict";
        var self = this;

        self.focus();
        self.isValid = false;
        self.alterBehavior(controlGroupBehavior.warning);
    };

    // o event input nao funciona quando usar o autoNumeric para criar a mascara,
    // por isso foi criado o ValidatorNumber
    function ValidatorNumber(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];
        self.isEmptyValid = self.isEmptyValid ? self.isEmptyValid : false;
        self.defaultValue = self.defaultValue ? self.defaultValue : "0";
        self.maxLength = self.maxLength ? self.maxLength : 5;

        self.input = $("#" + self.idInput);
        self.input.attr("maxlength", self.maxLength)

        self.executouInput = false;
        self.input.on("input", function () {
            // se jah esta no tamanho maximo do campo, nao adianta chamar o onInput,
            // pois nao tem nenhuma alteracao no campo, apesar do mesmo continuar a gerar
            // o evento input
            if (self.input.val().length < self.maxLength)
                self.executouInput = false;
            if ((self.input.val().length < self.maxLength || (self.input.val().length === self.maxLength && self.executouInput === false)) && self.onInput) {
                if (self.input.val().length === self.maxLength) {
                    self.executouInput = true;
                }
                self.onInput();
            }
        });

        self.input.on("blur", function () {
            self.setDefault(self.input.val());
        });

        // TODO: no setValue ou aqui, tem que tratar o tipo de conteudo que o campo permite
        self.input.on("keypress", function (evt) {
            var theEvent = evt || window.event;
            var key = theEvent.keyCode || theEvent.which;
            key = String.fromCharCode(key);
            var regex = /[0-9]/;
            if (!regex.test(key)) {
                theEvent.returnValue = false;
                if (theEvent.preventDefault) theEvent.preventDefault();
            }
        });
    }

    ValidatorNumber.prototype.focus = function (value) {
        "use strict";
        var self = this;

        self.input.focus();
    }

    ValidatorNumber.prototype.enable = function (value) {
        "use strict";
        var self = this;

        if (value)
            self.input.removeAttr("disabled");
        else
            self.input.attr("disabled", "disabled");
    }

    ValidatorNumber.prototype.setDefault = function (val) {
        "use strict";
        var self = this;

        // se nao aceita vazio, seta valor padrao
        if (!self.isEmptyValid && (parseFloat(val) === 0 || val === "")) {
            self.input.val(self.defaultValue);
            return true;
        }
        else {
            return false;
        }
    }

    ValidatorNumber.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        if (typeof val !== "string" && typeof val !== "number"){
            throw new Error("ValidatorNumber id=\"{0}\": Tipo (\"{1}\") inválido.".format(self.idInput, typeof val));
        }

        if (self.setDefault(val)) {
            return;
        }

        // se chegou aqui, eh porque aceita vazio
        if (typeof val === "string" && val === "") {
            self.input.val(val);
            return;
        }

        // verifica se eh um valor valido
        var nro = parseInt(val);
        if (typeof nro !== "number" || isNaN(nro) || nro === Infinity)
            throw new Error("ValidatorNumber id=\"{0}\": Conteúdo (\"{1}\") ou tipo (\"{2}\") inválido.".format(self.idInput, val, typeof nro));
        if (nro.toString().length > self.maxLength)
            throw new Error("ValidatorNumber id=\"{0}\": Conteúdo (Tamanho=\"{1}\") maior que o permitido (MaxLength={2}).".format(self.idInput, nro.toString().length, self.maxLength));

        self.input.val(parseInt(val));
    }

    ValidatorNumber.prototype.getValue = function () {
        "use strict";
        var self = this;

        return self.input.val();
    }

    ValidatorNumber.prototype.getValueNumber = function () {
        "use strict";
        var self = this;

        return convertStringDecimalPtBrToFloat(self.input.val());
    }

    ValidatorNumber.prototype.isValid = function () {
        "use strict";
        var self = this;

        if (self.input.val())
            return true;
        else
            return false;
    }

    ValidatorNumber.prototype.clear = function () {
        "use strict";
        var self = this;

        self.input.val("");
    }

    ValidatorNumber.prototype.isEmptyOrZeros = function () {
        "use strict";
        var self = this;

        // TODO: vai depender do tipo de conteudo que o campo permite
        if (parseFloat(self.input.val()) === 0 || self.input.val() === "")
            return true;
        else
            return false;
    }

    ValidatorNumber.prototype.isZeros = function () {
        "use strict";
        var self = this;

        // TODO: vai depender do tipo de conteudo que o campo permite
        if (parseFloat(self.input.val()) === 0)
            return true;
        else
            return false;
    }

    function ValidatorAlphanumeric(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];
        //self.isEmptyValid = self.isEmptyValid ? self.isEmptyValid : false;
        //self.defaultValue = self.defaultValue ? self.defaultValue : "";
        self.maxLength = self.maxLength ? self.maxLength : 50;

        self.input = $("#" + self.idInput);
        self.input.attr("maxlength", self.maxLength)

        $(self.input).on("change", self.onChange);

        // autocompletar quando precisar
        //self.executouInput = false;
        //self.input.on("input", function () {
        //    // se jah esta no tamanho maximo do campo, nao adianta chamar o onInput,
        //    // pois nao tem nenhuma alteracao no campo, apesar do mesmo continuar a gerar
        //    // o evento input
        //    if (self.input.val().length < self.maxLength)
        //        self.executouInput = false;
        //    if ((self.input.val().length < self.maxLength || (self.input.val().length === self.maxLength && self.executouInput === false)) && self.onInput) {
        //        if (self.input.val().length === self.maxLength) {
        //            self.executouInput = true;
        //        }
        //        self.onInput();
        //    }
        //});

        //self.input.on("blur", function () {
        //    self.setDefault(self.input.val());
        //});

        // autocompletar quando precisar
        //self.input.on("keypress", function (evt) {
        //    var theEvent = evt || window.event;
        //    var key = theEvent.keyCode || theEvent.which;
        //    key = String.fromCharCode(key);
        //    var regex = /[0-9]/;
        //    if (!regex.test(key)) {
        //        theEvent.returnValue = false;
        //        if (theEvent.preventDefault) theEvent.preventDefault();
        //    }
        //});
    }

    ValidatorAlphanumeric.prototype.clear = function () {
        "use strict";
        var self = this;

        return $("#" + self.idInput).val("");
    }

    ValidatorAlphanumeric.prototype.isEmpty = function () {
        "use strict";
        var self = this;

        return $("#" + self.idInput).val().length === 0;
    }

    ValidatorAlphanumeric.prototype.alterBehavior = function (behavior) {
        "use strict";
        var self = this;

        $("#" + self.idInput).parent().parent().addClass(behavior)
    };

    ValidatorAlphanumeric.prototype.focusError = function () {
        "use strict";
        var self = this;

        self.focus();
        self.isValid = false;
        self.alterBehavior(controlGroupBehavior.warning);
    };

    ValidatorAlphanumeric.prototype.focus = function (value) {
        "use strict";
        var self = this;

        self.input.focus();
    }

    ValidatorAlphanumeric.prototype.enable = function (value) {
        "use strict";
        var self = this;

        if (value)
            self.input.removeAttr("disabled");
        else
            self.input.attr("disabled", "disabled");
    }

    ValidatorAlphanumeric.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        //if (typeof val !== "string" && typeof val !== "number"){
        //    throw new Error("ValidatorAlphanumeric id=\"{0}\": Tipo (\"{1}\") inválido.".format(self.idInput, typeof val));
        //}

        //if (self.setDefault(val)) {
        //    return;
        //}

        //// se chegou aqui, eh porque aceita vazio
        //if (typeof val === "string" && val === "") {
        //    self.input.val(val);
        //    return;
        //}

        self.input.val(val);
    }

    ValidatorAlphanumeric.prototype.getValue = function () {
        "use strict";
        var self = this;

        return self.input.val();
    }

    //ValidatorAlphanumeric.prototype.isValid = function () {
    //    "use strict";
    //    var self = this;

    //    if (self.input.val())
    //        return true;
    //    else
    //        return false;
    //}

    //ValidatorAlphanumeric.prototype.setDefault = function (val) {
    //    "use strict";
    //    var self = this;

    //    //// se nao aceita vazio, seta valor padrao
    //    //if (!self.isEmptyValid && (parseFloat(val) === 0 || val === "")) {
    //    //    self.input.val(self.defaultValue);
    //    //    return true;
    //    //}
    //    //else {
    //    //    return false;
    //    //}
    //}

    function ValidatorHidden(options) {
        "use strict";
        var self = this;

        self.field = options.field;
        self.value = options.value;
        self.invalid = false;
    }

    ValidatorHidden.prototype.getObj = function () {
        "use strict";
        var self = this;

        var obj = {};
        obj[self.field] = self.value;

        return obj;
    }

    ValidatorHidden.prototype.getObjJSON = function () {
        "use strict";
        var self = this;

        var obj = {};
        obj[self.field] = self.value;

        return JSON.stringify(obj);
    }

    ValidatorHidden.prototype.addParam = function (objParam) {
        "use strict";
        var self = this;

        var obj = objParam;
        obj[self.field] = self.value;

        return obj;
    }

    ValidatorHidden.prototype.getParamUrl = function (And) {
        "use strict";
        var self = this;

        if (And)
            return "&GuidProxy=" + self.value;
        else
            return "?GuidProxy=" + self.value;
    }

    ValidatorHidden.prototype.addParamUrl = function (url, And) {
        "use strict";
        var self = this;

        if (And)
            return url + "&GuidProxy=" + self.value;
        else
            return url + "?GuidProxy=" + self.value;
    }

    ValidatorHidden.prototype.clear = function () {
        "use strict";
        var self = this;

        self.value = null;
        self.invalid = true;
    }

    ValidatorHidden.prototype.isEmpty = function () {
        "use strict";
        var self = this;

        return self.value === null;
    }

    ValidatorHidden.prototype.setValue = function (val) {
        "use strict";
        var self = this;

        self.value = val;
        self.invalid = (val === null);
    }

    ValidatorHidden.prototype.getValue = function () {
        "use strict";
        var self = this;

        return self.value;
    }

    function ValidatorCheckbox(options) {
        "use strict";
        var self = this;

        for (var params in options) self[params] = options[params];

        self.input = $("#" + self.idInput);

        $(self.input).on("change", self.onChange);
    }

    ValidatorCheckbox.prototype.setValue = function (value) {
        "use strict";
        var self = this;

        var obj = document.getElementById(self.idInput);
        obj.checked = value;
    }

    ValidatorCheckbox.prototype.getValue = function (value) {
        "use strict";
        var self = this;

        var obj = document.getElementById(self.idInput);
        return obj.checked;
    }

    // TODO: remover e padronizar
    ValidatorCheckbox.prototype.disable = function () {
        "use strict";
        var self = this;

        byId(self.idInput).disabled = true;
    }

    // TODO: remover e padronizar
    ValidatorCheckbox.prototype.enable = function () {
        "use strict";
        var self = this;

        byId(self.idInput).disabled = false;
    }

    ValidatorCheckbox.prototype.enable2 = function (op) {
        "use strict";
        var self = this;

        byId(self.idInput).disabled = !op;
    }

    // TODO: diff ValidatorNumber e ValidateInteger
    function ValidateInteger(evt) {
        var theEvent = evt || window.event;
        var key = theEvent.keyCode || theEvent.which;
        key = String.fromCharCode(key);
        var regex = /[0-9]/;
        if (!regex.test(key)) {
            theEvent.returnValue = false;
            if (theEvent.preventDefault) theEvent.preventDefault();
        }
    }

    function ValidateCurrency(evt) {
        var field = $("#" + evt.target.id);
        var regex;
        if (field.val().indexOf(",") >= 0 || field.val().indexOf(".") >= 0)
            regex = /[0-9]/;
        else
            regex = /[0-9]|\.|,/;

        var theEvent = evt || window.event;
        var key = theEvent.keyCode || theEvent.which;
        key = String.fromCharCode(key);
        if (!regex.test(key)) {
            theEvent.returnValue = false;
            if (theEvent.preventDefault) theEvent.preventDefault();
        }
    }

    function ValidatorLookup(options) {
        "use strict";
        var self = this;

        for (var params in options)
            self[params] = options[params];

        if (self.abrev && !self.idInputCodigo)
            self.idInputCodigo = "input" + self.abrev;
        if (self.abrev && !self.idLinkButtonModal)
            self.idLinkButtonModal = "linkButtonModal" + self.abrev;
        if (self.abrev && !self.idInputDescription)
            self.idInputDescription = "description" + self.abrev;
        if (self.abrev && !self.idLinkButtonModalGrupoContas)
            self.idLinkButtonModalGrupoContas = "linkButtonModalGrupoContas" + self.abrev;
        // se passar o "idModalGrupoContas", passar apenas a parte final, pq o objeto
        // grupo de contas monta "ModalGrupoContas_" + id
        if (self.abrev && !self.idModalGrupoContas)
            self.idModalGrupoContas = self.abrev;
        if (self.abrev && !self.idModal)
            self.idModal = "modal" + self.abrev;
        if (self.abrev && !self.idTable)
            self.idTable = "table" + self.abrev;
        if (!self.fieldCode)
            self.fieldCode = "Codigo";
        if (!self.fieldDescription)
            self.fieldDescription = "Nome";
        if (!self.msgPendencyMessage && self.msgPendencyMessagePartEnd)
            self.msgPendencyMessage = "Deve ser informado o código " + self.msgPendencyMessagePartEnd;
        if (options.maxLength)
            $("#" + self.idInputCodigo).attr("maxlength", options.maxLength);

        if (!self.optionsModal) {
            self.optionsModal = {};
            self.optionsModal.useClassePai = false;
            self.optionsModal.ClassePaiURL = "";
            self.optionsModal.TipoConta = ""; // todas
        }

        // validator
        var validatorX = new Validator({
            field: self.idInputCodigo,
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            fieldDescriptionId: self.idInputDescription,
            fieldSearch: self.fieldSearch,
            GuidProxy: self.GuidProxy,
            pendency: self.pendency,
            v2: "v3",
            onPendencyMessage: self.msgPendencyMessage,
            route: self.route,
            ModalGrupoContas: self.ModalGrupoContas,
            linkButtonModalGrupoContas: self.idLinkButtonModalGrupoContas,
            defaultValue: self.defaultValue,
            changeEmptyToAll: self.changeEmptyToAll,

            onValid: function (data) {
                // quando tiver "onValidOnly" declarado, usar somente ele, mais nenhum outro codigo,
                // feito inicialmente para o validator do Executor (Atendimento Técnico), que na verdade,
                // é uma consulta de usuário, não tem código, tem que digitar diretamente no input, no nome
                // do usuário, consequentemente, também não tem Description
                if (self.onValidOnly) {
                    self.onValidOnly(validatorX, data);
                }
                else if (self.optionsModal.TipoConta === "T" && data.Tipo !== "T") {
                    $("#" + self.tableX.idModalHideShow).modal("hide");
                    u.dialogOk("Conta deve ser do tipo título.", null, true, function () {
                        validatorX.clear();
                        validatorX.focusError();
                    }, alertBehavior.warning);
                }
                else if (self.optionsModal.TipoConta === "A" && data.Tipo !== "A") {
                    $("#" + self.tableX.idModalHideShow).modal("hide");
                    u.dialogOk("Conta deve ser do tipo analítica ou subanalítica.", null, true, function () {
                        validatorX.clear();
                        validatorX.focusError();
                    }, alertBehavior.warning);
                }
                else {
                    validatorX.setValues(data[self.fieldCode], data[self.fieldDescription]);
                    if (self.onValid) self.onValid(data, validatorX);
                }
                if (validatorX.getValue() === "0")
                    validatorX.all = true;
                else
                    validatorX.all = false;

                // TODO: refatorar
                if (self.onChange) self.onChange();
            },
            onInvalid: function (data) {
                validatorX.clear({ warning: true });
                validatorX.focus();
                if (self.onInvalid) self.onInvalid(data);

                // TODO: refatorar
                if (self.onChange) self.onChange();
            },
            onEmpty: function () {
                if (self.changeEmptyToAll) {
                    validatorX.setValueValidate("0");
                    validatorX.invalid = false;
                    validatorX.all = true;
                }
                else {
                    validatorX.clear();
                    validatorX.all = false;
                }
                if (self.onEmpty) self.onEmpty();

                // TODO: refatorar
                if (self.onChange) self.onChange();
            }
        });
        validatorX.listen();
        if (self.setDefaultValueInOldValueWhereCreateValidator)
            validatorX.oldValue = validatorX.defaultValue;

        // TODO: fieldDepende eh usado para detectar quando um campo dependente foi alterado para,
        // recarrega a tabela e nao usar o cache,
        // ele aceita apenas um campo e nao uma lista de campo, mas o o params eh usa lista de campos,
        // no momento, esta pegando o primeiro campo de params, mas futuramente tem que alterar
        var tableX = new Table({
            id: self.idTable,
            msgDialog: true,
            route: window.baseUrl + self.routeTable,
            GuidProxy: self.GuidProxy,
            columns: self.columnsTable,
            showFilter: true,
            params: self.params,
            paramsRequired: self.paramsRequired,
            paramsDefault: self.paramsDefault,
            fieldDepende: self.params ? self.params[0] : null,
            v2: true,
            onChange: function () {
                byId("inputF4ModalOk" + this.id).onclick = function () {
                    var data = tableX.getSelectedData();
                    validatorX.onValid(data);
                    validatorX.update();
                };
            },
            onDataBound: function () {
                $("#" + this.id + " table tr").on("dblclick", function () {
                    var data = tableX.getSelectedData();
                    validatorX.onValid(data);
                    validatorX.update();
                    $("#" + self.idModal).modal("hide");
                });
            },
            dataSourceType: "Filtered"
        });
        self.tableX = tableX;
        self.tableX.idModalHideShow = self.tableX.idModalHideShow;

        var modalX = new Modal(self.titleModal,
            byId(self.idLinkButtonModal),
            byId(self.idInputCodigo),
            tableX,
            function () {
                // usado nas telas de filtros das grids, pois antes de motras o modal do F4, tem que esconder a tela de filtro
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }
            },
            {
                validatorInput: validatorX,

                // classe pai
                useClassePai: self.optionsModal.useClassePai,
                ClassePaiURL: self.optionsModal.ClassePaiURL,

                // hierarquia
                showOpcaoExibir: self.optionsModal.showOpcaoExibir,
                urlBuscaHierarquia: self.optionsModal.urlBuscaHierarquia,
                allowContaTitulo: self.optionsModal.allowContaTitulo,
                exibirHierarquiaParams: self.optionsModal.exibirHierarquiaParams,
                onDblClickGetItem: function (event, dados) {
                    validatorX.onValid(dados);
                    validatorX.update();
                    $("#" + self.idModal).modal("hide");

                    if (self.optionsModal.onDblClickGetItem) {
                        self.optionsModal.onDblClickGetItem(event, dados);
                    }

                    // usado nas telas de filtros das grids, pois depois de esconder o modal do F4, tem que mostrar a tela de filtro novamente
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                },

                disableConsultation: self.disableConsultation,
                idDescription: self.idInputDescription,

                onHidden: function () {
                    // usado nas telas de filtros das grids, pois depois de esconder o modal do F4, tem que mostrar a tela de filtro novamente
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                }
            }
        )
        modalX.listen();

        // grupo contas
        if (self.ModalGrupoContas) {
            var modalGrupoContasX = new ModalGrupoContas({
                id: self.idModalGrupoContas,
                validatorInput: validatorX,
                modalHierarquia: modalX,
                validatorConta: {
                    fieldSearch: self.fieldSearch,
                    fieldNome: self.fieldDescription,
                    onPendencyMessage: self.msgPendencyMessage,
                    route: self.route,
                    onValid: self.onValid,
                    v2: "v3"
                },
                tableConta: {
                    showFilter: true,
                    route: window.baseUrl + self.routeTable,
                    columns: self.columnsTable
                },
                modalConta: self.optionsModal,
                onShow: function () {
                },
                onHidden: function () {
                }
            });
        }

        return validatorX;
    }

    function ValidatorLookupProduto(options) {
        "use strict";
        var self = this;

        // nao implementado ainda ModalGrupoContas

        // para usar na montagem dos ids, abrev="Principal"
        // <input type="text" id="inputPrincipalCodigoProduto" maxlength="60" style="width: 100px; margin: 0">
        // <input type="text" id="inputPrincipalCodigoGrade1" maxlength="5" style="width: 30px; margin: 0" disabled>
        // <input type="text" id="inputPrincipalCodigoGrade2" maxlength="5" style="width: 30px; margin: 0" disabled>
        // <input type="text" id="inputPrincipalCodigoGrade3" maxlength="5" style="width: 30px; margin: 0" disabled>
        // <a id="linkButtonModalPrincipalProduto" href="#modalPrincipalProduto" role="button" data-toggle="modal"><i class="icon-search"></i></a>
        // <a id="linkButtonModalPrincipalGrade1" href="#modalPrincipalGrade1" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>
        // <a id="linkButtonModalPrincipalGrade2" href="#modalPrincipalGrade2" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>
        // <a id="linkButtonModalPrincipalGrade3" href="#modalPrincipalGrade3" role="button" data-toggle="modal" hidden><i class="icon-search"></i></a>
        // <span id="descriptionPrincipalCodigoProduto" class="help-inline"></span>
        // <span id="descriptionPrincipalCodigoGrade1" class="help-inline"></span>
        // <span id="descriptionPrincipalCodigoGrade2" class="help-inline"></span>
        // <span id="descriptionPrincipalCodigoGrade3" class="help-inline"></span>
        // quando nao informa abrev, assume o padrao inputCodigoProduto/inputCodigoGrade1/inputCodigoGrade2/inputCodigoGrade3
        self.abrev = null;

        self.validatorProduto = null;
        self.validatorGrade1 = null;
        self.validatorGrade2 = null;
        self.validatorGrade3 = null;

        // se for usar o campo em um modal, automaticamente esconde/mostra,
        // o modal quando chamar o modal do F4 da consulta
        self.idModalHideShow = null;

        self.allowContaTitulo = false;

        for (var params in options)
            self[params] = options[params];

        // produto
        var validatorProduto = new Validator({
            field: "input" + self.abrev + "CodigoProduto",
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            fieldDescriptionId: "description" + self.abrev + "CodigoProduto",
            fieldSearch: "CodigoProduto",
            v2: "v3",
            onPendencyMessage: "Deve ser informado o código do produto.",
            route: self.allowContaTitulo ? "Empresarial/F4Produto/GetProdutoClasse" : "Empresarial/F4Produto/GetProduto", // hierarquia
            GuidProxy: self.GuidProxy,
            pendency: options.pendency,
            onValid: function (data) {
                validatorProduto.setChange(true);
                validatorProduto.setValues(data["Codigo"], data["Nome"]);
                validatorProduto.PropertiesSpecifyField = {
                    Classificacao: data.Classificacao,
                    HaveGrade1: data.HaveGrade1,
                    HaveGrade2: data.HaveGrade2,
                    HaveGrade3: data.HaveGrade3
                };

                validatorGrade1.clear({ disable: true });
                validatorGrade2.clear({ disable: true });
                validatorGrade3.clear({ disable: true });

                if (validatorProduto.PropertiesSpecifyField.HaveGrade1) {
                    validatorGrade1.enable();
                    validatorGrade1.focus();
                } else {
                    $("#linkButtonModal" + self.abrev + "Produto").focus();
                }

                if (validatorProduto.PropertiesSpecifyField.HaveGrade2)
                    validatorGrade2.enable();

                if (validatorProduto.PropertiesSpecifyField.HaveGrade3)
                    validatorGrade3.enable();

                if (self.onValid)
                    self.onValid(data);
            },
            onInvalid: function (data) {
                validatorProduto.setChange(true);
                validatorProduto.clear({ warning: true });
                validatorProduto.focus();
                validatorGrade1.clear({ warning: true, disable: true });
                validatorGrade2.clear({ warning: true, disable: true });
                validatorGrade3.clear({ warning: true, disable: true });
                validatorProduto.PropertiesSpecifyField = {};

                if (self.onInvalid)
                    self.onInvalid(data);
            },
            onEmpty: function () {
                validatorProduto.setChange(true);
                validatorProduto.clear();
                validatorGrade1.clear({ disable: true });
                validatorGrade2.clear({ disable: true });
                validatorGrade3.clear({ disable: true });
                validatorProduto.PropertiesSpecifyField = {};
                $("#linkButtonModal" + self.abrev + "Produto").focus();

                if (self.onEmpty)
                    self.onEmpty();
            }
        });
        self.validatorProduto = validatorProduto;
        validatorProduto.listen();
        $("#input" + self.abrev + "CodigoProduto").attr("maxlength", 60);

        var tableProduto = new Table({
            id: "table" + self.abrev + "Produto",
            msgDialog: true,
            route: window.baseUrl + "Empresarial/F4Produto/GetProdutos",
            showFilter: true,
            GuidProxy: self.GuidProxy,
            dataSourceType: "Filtered",
            columns: [
                { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Unidade", field: "Unidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: "Preço", field: "ValorUnitario", width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                { title: "Classificação", field: "Classificacao", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
            ],
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = tableProduto.getSelectedData(),
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    // hierarquia
                    getJsonFromRoute(self.allowContaTitulo ? "Empresarial/F4Produto/GetProdutoClasse" : "Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProduto.onValid(data);
                        validatorProduto.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = tableProduto.getSelectedData(),
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    // hierarquia
                    getJsonFromRoute(self.allowContaTitulo ? "Empresarial/F4Produto/GetProdutoClasse" : "Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProduto.onValid(data);
                        validatorProduto.update();
                    });
                    $("#modal" + self.abrev + "Produto").modal("hide");
                });
            }
        });

        var modalProduto = new Modal(
            "Produto",
            byId("linkButtonModal" + self.abrev + "Produto"),
            byId("input" + self.abrev + "CodigoProduto"),
            tableProduto,
            function () {
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }
            },
            {
                // hierarquia
                showOpcaoExibir: true,
                urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                allowContaTitulo: self.allowContaTitulo,
                onDblClickGetItem: function (event, dados) {
                    // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                    var data = dados,
                        search = {};
                    search["CodigoProduto"] = data["Codigo"];
                    getJsonFromRoute(self.allowContaTitulo ? "Empresarial/F4Produto/GetProdutoClasse" : "Empresarial/F4Produto/GetProduto", search).done(function (data) {
                        validatorProduto.onValid(data);
                        validatorProduto.update();
                    });
                    $("#modal" + self.abrev + "Produto").modal("hide");
                },

                onHidden: function () {
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                }
            }
        ).listen();

        // grades
        var columnsGrade = [
            { title: "Código", field: "Codigo", width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
            { title: "Descrição", field: "Descricao", width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
        ];

        // grade1
        var validatorGrade1 = new Validator({
            field: "input" + self.abrev + "CodigoGrade1",
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            fieldDescriptionId: "description" + self.abrev + "CodigoGrade1",
            fieldSearch: "CodigoGrade1",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 1.",
            route: "Empresarial/F4Produto/GetItemGrade1",
            GuidProxy: self.GuidProxy,
            pendency: options.pendency ? [validatorProduto].concat(options.pendency) : [validatorProduto],
            onValid: function (data) {
                validatorGrade1.setChange(true);
                validatorGrade1.setValues(data["Codigo"], " - " + data["Descricao"]);

                if (validatorProduto.PropertiesSpecifyField.HaveGrade2) {
                    validatorGrade2.focus();
                }
            },
            onInvalid: function (data) {
                validatorGrade1.setChange(true);
                validatorGrade1.clear({ warning: true });
                validatorGrade1.focus();
            },
            onEmpty: function () {
                validatorGrade1.setChange(true);
                validatorGrade1.clear();
                validatorGrade2.clear();
                validatorGrade3.clear();
            }
        });
        self.validatorGrade1 = validatorGrade1;
        validatorGrade1.listen();
        $("#input" + self.abrev + "CodigoGrade1").attr("maxlength", 5);

        var tableGrade1 = new Table({
            id: "table" + self.abrev + "Grade1",
            msgDialog: true,
            route: window.baseUrl + "Empresarial/F4Produto/List1",
            showFilter: true,
            GuidProxy: self.GuidProxy,
            dataSourceType: "Parameter",
            columns: columnsGrade,
            params: [validatorProduto],
            fieldDepende: validatorProduto,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade1.getSelectedData();
                    requestLeg(function () {
                        validatorGrade1.onValid(data);
                        validatorGrade1.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade1.getSelectedData();
                    requestLeg(function () {
                        validatorGrade1.onValid(data);
                        validatorGrade1.update();
                    });
                    $("#modal" + self.abrev + "Grade1").modal("hide");
                });
            }
        });

        var modalGrade1 = new Modal("Grade",
            byId("linkButtonModal" + self.abrev + "Grade1"),
            byId("input" + self.abrev + "CodigoGrade1"),
            tableGrade1,
            function () {
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }
            },
            {
                onHidden: function () {
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                },
            }
        ).listen();

        // grade2
        var validatorGrade2 = new Validator({
            field: "input" + self.abrev + "CodigoGrade2",
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            fieldDescriptionId: "description" + self.abrev + "CodigoGrade2",
            fieldSearch: "CodigoGrade2",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 2.",
            route: "Empresarial/F4Produto/GetItemGrade2",
            GuidProxy: self.GuidProxy,
            pendency: options.pendency ? [validatorGrade1, validatorProduto].concat(options.pendency) : [validatorGrade1, validatorProduto],
            onValid: function (data) {
                validatorGrade2.setChange(true);
                validatorGrade2.setValues(data["Codigo"], " - " + data["Descricao"]);

                if (validatorProduto.PropertiesSpecifyField.HaveGrade3) {
                    validatorGrade3.focus();
                }
            },
            onInvalid: function (data) {
                validatorGrade2.setChange(true);
                validatorGrade2.clear({ warning: true });
                validatorGrade2.focus();
            },
            onEmpty: function () {
                validatorGrade2.setChange(true);
                validatorGrade2.clear();
                validatorGrade3.clear();
            }
        });
        self.validatorGrade2 = validatorGrade2;
        validatorGrade2.listen();
        $("#input" + self.abrev + "CodigoGrade2").attr("maxlength", 5);

        var tableGrade2 = new Table({
            id: "table" + self.abrev + "Grade2",
            msgDialog: true,
            route: window.baseUrl + "Empresarial/F4Produto/List2",
            showFilter: true,
            GuidProxy: self.GuidProxy,
            dataSourceType: "Parameter",
            columns: columnsGrade,
            params: [validatorGrade1, validatorProduto],
            fieldDepende: validatorGrade1,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade2.getSelectedData();
                    requestLeg(function () {
                        validatorGrade2.onValid(data);
                        validatorGrade2.update();
                    });
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade2.getSelectedData();
                    requestLeg(function () {
                        validatorGrade2.onValid(data);
                        validatorGrade2.update();
                    });
                    $("#modal" + self.abrev + "Grade2").modal("hide");
                });
            }
        });

        var modalGrade2 = new Modal("Grade",
            byId("linkButtonModal" + self.abrev + "Grade2"),
            byId("input" + self.abrev + "CodigoGrade2"),
            tableGrade2,
            function () {
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }
            },
            {
                onHidden: function () {
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                },
            }
        ).listen();

        // grade3
        var validatorGrade3 = new Validator({
            field: "input" + self.abrev + "CodigoGrade3",
            msgDialog: true,
            idModalHideShow: self.idModalHideShow,
            fieldDescriptionId: "description" + self.abrev + "CodigoGrade3",
            fieldSearch: "CodigoGrade3",
            v2: "v3",
            onPendencyMessage: "Deve ser informada a grade 3.",
            route: "Empresarial/F4Produto/GetItemGrade3",
            GuidProxy: self.GuidProxy,
            pendency: options.pendency ? [validatorGrade2, validatorGrade1, validatorProduto].concat(options.pendency) : [validatorGrade2, validatorGrade1, validatorProduto],
            onValid: function (data) {
                validatorGrade3.setChange(true);
                validatorGrade3.setValues(data["Codigo"], " - " + data["Descricao"]);
            },
            onInvalid: function (data) {
                validatorGrade3.setChange(true);
                validatorGrade3.clear({ warning: true });
                validatorGrade3.focus();
            },
            onEmpty: function () {
                validatorGrade3.setChange(true);
                validatorGrade3.clear();
            }
        });
        self.validatorGrade3 = validatorGrade3;
        validatorGrade3.listen();
        $("#input" + self.abrev + "CodigoGrade3").attr("maxlength", 5);

        var tableGrade3 = new Table({
            id: "table" + self.abrev + "Grade3",
            msgDialog: true,
            route: window.baseUrl + "Empresarial/F4Produto/List3",
            showFilter: true,
            dataSourceType: "Parameter",
            GuidProxy: self.GuidProxy,
            columns: columnsGrade,
            params: [validatorGrade2, validatorGrade1, validatorProduto],
            fieldDepende: validatorGrade2,
            onChange: function () {
                $("#inputF4ModalOk" + this.id).on("click", function () {
                    var data = tableGrade3.getSelectedData();
                    validatorGrade3.onValid(data);
                    validatorGrade3.update();
                });
            },
            onDataBound: function () {
                $("#" + this.id + " table  tr").on("dblclick", function () {
                    var data = tableGrade3.getSelectedData();
                    validatorGrade3.onValid(data);
                    validatorGrade3.update();
                    $("#modal" + self.abrev + "Grade3").modal("hide");
                });
            },
        });

        var modalGrade3 = new Modal("Grade",
            byId("linkButtonModal" + self.abrev + "Grade3"),
            byId("input" + self.abrev + "CodigoGrade3"),
            tableGrade3,
            function () {
                if (self.idModalHideShow) {
                    $("#" + self.idModalHideShow).modal("hide");
                }
            },
            {
                onHidden: function () {
                    if (self.idModalHideShow) {
                        $("#" + self.idModalHideShow).modal("show");
                    }
                },
            }
        ).listen();

        self.listenToggleProdutoGradesF4(self.id);

        // end
        return self;
    };

    ValidatorLookupProduto.prototype.listenToggleProdutoGradesF4 = function () {
        "use strict";
        var self = this;

        // se alterar aqui, verificar se tem que alterar em:
        // listenToggleProdutoGradesF4
        // ModalGrupoContas.prototype.listenToggleProdutoGradesF4
        // ValidatorLookupProduto.prototype.listenToggleProdutoGradesF4

        $("#input" + self.abrev + "CodigoProduto").on("focus", function () {
            $("#linkButtonModal" + self.abrev + "Produto").show();
            $("#linkButtonModal" + self.abrev + "Grade1").hide();
            $("#linkButtonModal" + self.abrev + "Grade2").hide();
            $("#linkButtonModal" + self.abrev + "Grade3").hide();
        });
        $("#input" + self.abrev + "CodigoGrade1").on("focus", function () {
            $("#linkButtonModal" + self.abrev + "Produto").hide();
            $("#linkButtonModal" + self.abrev + "Grade1").show();
            $("#linkButtonModal" + self.abrev + "Grade2").hide();
            $("#linkButtonModal" + self.abrev + "Grade3").hide();
        });
        $("#input" + self.abrev + "CodigoGrade2").on("focus", function () {
            $("#linkButtonModal" + self.abrev + "Produto").hide();
            $("#linkButtonModal" + self.abrev + "Grade1").hide();
            $("#linkButtonModal" + self.abrev + "Grade2").show();
            $("#linkButtonModal" + self.abrev + "Grade3").hide();
        });
        $("#input" + self.abrev + "CodigoGrade3").on("focus", function () {
            $("#linkButtonModal" + self.abrev + "Produto").hide();
            $("#linkButtonModal" + self.abrev + "Grade1").hide();
            $("#linkButtonModal" + self.abrev + "Grade2").hide();
            $("#linkButtonModal" + self.abrev + "Grade3").show();
        });
    }

    ValidatorLookupProduto.prototype.clear = function (dados) {
        "use strict";
        var self = this;

        self.validatorProduto.setValues("", "");

        self.validatorProduto.PropertiesSpecifyField.Classificacao = "";
        self.validatorProduto.PropertiesSpecifyField.HaveGrade1 = false;
        self.validatorProduto.PropertiesSpecifyField.HaveGrade2 = false;
        self.validatorProduto.PropertiesSpecifyField.HaveGrade3 = false;

        self.validatorGrade1.disable();
        self.validatorGrade1.setValues("", "");
        self.validatorGrade2.disable();
        self.validatorGrade2.setValues("", "");
        self.validatorGrade3.disable();
        self.validatorGrade3.setValues("", "");
    }

    ValidatorLookupProduto.prototype.setProdutoGrades = function (dados) {
        "use strict";
        var self = this;

        self.validatorProduto.setValues(dados.CodigoProduto, dados.DescricaoProduto);

        self.validatorProduto.PropertiesSpecifyField.Classificacao = dados.Classificacao;
        self.validatorProduto.PropertiesSpecifyField.HaveGrade1 = dados.HaveGrade1;
        self.validatorProduto.PropertiesSpecifyField.HaveGrade2 = dados.HaveGrade2;
        self.validatorProduto.PropertiesSpecifyField.HaveGrade3 = dados.HaveGrade3;

        if (dados.HaveGrade1) {
            self.validatorGrade1.enable();
            self.validatorGrade1.setValues(dados.CodigoGrade1, " - " + dados.DescricaoGrade1);
        }

        if (dados.HaveGrade2) {
            self.validatorGrade2.enable();
            self.validatorGrade2.setValues(dados.CodigoGrade2, " - " + dados.DescricaoGrade2);
        }

        if (dados.HaveGrade3) {
            self.validatorGrade3.enable();
            self.validatorGrade3.setValues(dados.CodigoGrade3, " - " + dados.DescricaoGrade3);
        }
    }

    // usado inicialmente no filtro dos pedidos, pois o mesmo nao salve a descricao do campo, entao
    // tem que ler novamente para carregar
    ValidatorLookupProduto.prototype.validateAllFields = function (dados) {
        "use strict";
        var self = this;

        self.validatorProduto.validate();

        if (self.validatorProduto.PropertiesSpecifyField.HaveGrade1) {
            self.validatorGrade1.validate();
        }
        if (self.validatorProduto.PropertiesSpecifyField.HaveGrade2) {
            self.validatorGrade2.validate();
        }
        if (self.validatorProduto.PropertiesSpecifyField.HaveGrade3) {
            self.validatorGrade3.validate();
        }
    }

    ValidatorLookupProduto.prototype.enable = function (op) {
        "use strict";
        var self = this;

        self.validatorProduto.enable2(op);
        self.validatorGrade1.enable2(op);
        self.validatorGrade2.enable2(op);
        self.validatorGrade3.enable2(op);
    }

    ValidatorLookupProduto.prototype.getProdutoGrades = function () {
        "use strict";
        var self = this;

        return {
            CodigoProduto: self.validatorProduto.getValue(),
            DescricaoProduto: self.validatorProduto.getDescription(),
            Classificacao: self.validatorProduto.PropertiesSpecifyField.Classificacao,

            HaveGrade1: self.validatorProduto.PropertiesSpecifyField.HaveGrade1,
            CodigoGrade1: self.validatorGrade1.getValue(),
            DescricaoGrade1: self.validatorGrade1.getDescription().replace(" - ", ""),

            HaveGrade2: self.validatorProduto.PropertiesSpecifyField.HaveGrade2,
            CodigoGrade2: self.validatorGrade2.getValue(),
            DescricaoGrade2: self.validatorGrade2.getDescription().replace(" - ", ""),

            HaveGrade3: self.validatorProduto.PropertiesSpecifyField.HaveGrade3,
            CodigoGrade3: self.validatorGrade3.getValue(),
            DescricaoGrade3: self.validatorGrade3.getDescription().replace(" - ", "")
        }
    }

    ValidatorLookupProduto.prototype.isEmpty = function () {
        "use strict";
        var self = this;

        return self.validatorProduto.isEmpty();
    }

    ValidatorLookupProduto.prototype.focusError = function () {
        "use strict";
        var self = this;

        self.validatorProduto.focusError();
    }

    Home = (function () {
        return {
            Menu: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    carregaLogoCliente();

                    function carregaLogoCliente() {
                        var src = window.baseUrl + "Empresarial/Imagens/GetLogoCliente";
                        $("#logoCliente").attr("src", src);

                        $("#logoCliente").on("load", function () {
                            var logoCiente = document.getElementById("logoCliente");
                            var maxWidth = logoCliente.style.maxWidth.asInt();
                            var maxHeight = logoCliente.style.maxHeight.asInt();
                            var width = $("#logoCliente").width();
                            var height = $("#logoCliente").height();

                            if (height < width) {
                                var diff = maxHeight - height;
                                if (diff > 0)
                                    logoCliente.style.marginTop = Math.round(diff / 2) + "px";
                            }
                        });

                        $("#linkLogoCliente").on("click", (function () {
                            window.location = window.baseUrl;
                        }));

                        $("#linkLogoRadarWeb").on("dblclick", (function () {
                            window.open(window.location);
                        }));
                    }

                    if (navigator.userAgent.toLowerCase().indexOf("ipad") > -1) {
                        // por algum motivo, menus do bootstrap nao funciona direito com o evento touchstart,
                        // estão estou convertendo o evento touchstart para um click
                        $("ul.nav > li.dropdown > a.dropdown-toggle").on('touchstart', function (e) {
                            // se já esta visivel, nao gerar o evento novamente, pois senao, apenas abre e fecha o menu
                            if (e.style.display.toLowerCase() === "none") {
                                $(e.srcElement).trigger("click");
                            }
                            e.stopPropagation();
                        });
                    }

                    $(".dropdown-submenu > a").on("click", function (e) {
                        e.stopPropagation();
                    });
                }(params));
            },

            Personalizar: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // TODO: melhorar, colocar no repositorio menu
                    var inputOpcao = new ValidatorDropDown({
                        idInputCodigo: "inputOpcao",
                        dataSource: []
                    });

                    byId("buttonOK").onclick = function () {
                        if (isFieldEnabled("buttonOK")) {
                            request("Config/Save",
                                {
                                    id: "paginaInicial",
                                    content: inputOpcao.getValue()
                                },
                                function (model) {
                                    try {
                                        if (model.IsAlert) {
                                            u.dialogOk(model.Message, null, true, null, alertBehavior.warning);
                                        } else {
                                            u.dialogOk("Configurações salvas com sucesso.", null, true, null, alertBehavior.success);
                                        }
                                    }
                                    catch (err) {
                                        u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                    }
                                },
                                function (err) {
                                    if (err.jqxhr.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                        window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.baseUrl + "/Personalizar";
                                    }
                                    else {
                                        u.dialogOk(err.jqxhr.status + "-" + err.jqxhr.statusText + "-" + err.textStatus, null, true, null, alertBehavior.warning);
                                    }
                                },
                                true
                            );
                        }
                    }

                    // load
                    request("Config/Get",
                        {
                            id: "paginaInicial"
                        },
                        function (model) {
                            try {
                                if (model.IsAlert) {
                                    // default = 0
                                } else {
                                    inputOpcao.setDataSource(model.Options);
                                    inputOpcao.setValue(model.Option.toString());
                                }
                            }
                            catch (err) {
                                u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                            }
                        },
                        function (err) {
                            if (err.jqxhr.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.baseUrl + "/Personalizar";
                            }
                            else {
                                u.dialogOk(err.jqxhr.status + "-" + err.jqxhr.statusText + "-" + err.textStatus, null, true, null, alertBehavior.warning);
                            }
                        },
                        true
                    );
                }(params));
            }
        }
    }());

    Empresarial.Manager = (function () {
        var util = new Util();
        var u = new Util(); // TODO: refatorando por partes, "padronizando"

        var mostrarVigencia = false;
        var firstState;

        var template =
         "<span style='float:left; width: NaN;'>" +
         "    <span style='font-size: large; font-weight: 800; text-align: center; ' id='tableTitle'></span>" +
         "</span>" +
         "<span style='float:right'>" +
         "    <button id='inputFilter' type='button' class='btn btn-small btn-filtro'>" +
         "        <span class='k-icon k-i-funnel'>Atualiza</span> Filtro" +
         "    </button>" +
         "    <button id='buttonCadastrar' type='button' class='btn btn-small btn-filtro'>" +
         "        <span class='k-icon k-i-plus'>Atualiza</span>Novo" +
         "    </button>" +
         "</span>";

        var promptDataVigenciaOptions = {
            'id': 'dataVigenciaModal',
            'title': 'Data final de Vigência',
            'template':
                "<div>\
                    <label> Data Vigência\
                        <input type='text' id='inputDataFinalVigencia' class='radar-date-picker' vm-model='prompt-viewmodel' vm-field='DataVigencia' value='" + getDateNowDDMMYYYY() + "'/>\
                    </label>\
                </div>",
            'onOk': function (model) {
            },
            'onCancel': function () {
            }
        };

        var promptDataVigencia = new PromptDialog(promptDataVigenciaOptions);

        var baseTable = new Table({
            'id': null,
            'route': null,
            'showFilter': false,
            'columns': [
                { title: 'Código', field: 'Codigo', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'CPF/CNPJ', field: 'CnpjCpf', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Razão Social', field: 'RazaoSocial', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'UF', field: 'Uf', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Município', field: 'Municipio', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Telefone1', field: 'Telefone1', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'E-mail', field: 'Email', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Contato', field: 'Contato', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
            ],
            'onChange': function () {
                "use strict";
                var self = this;
                var data = self.getSelectedData();
            },
            'toolbar': template,
            'onDataBound': function () {
                "use strict";
                var self = this;
                $('#' + self.id + ' table tr').on('dblclick', function () {
                    var data = self.getSelectedData();
                });
                var el = $('#' + self.id + ' .k-grid-content');
                el[0].style.height = "auto";
                msgWait.hide();
            },
            'dataSourceType': "Filtered",
            'pageable': {
                refresh: true,
                numeric: true,
                pageSizes: [10, 20, 30, 40, 50],
                buttonCount: 5
            }
        });

        var baseTableEndereco = new Table({
            'id': null,
            'route': null,
            'showFilter': false,
            'columns': [
                { title: 'Tipo Endereço', field: 'TipoEndereco', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'UF', field: 'Uf', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Município', field: 'Municipio', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'Telefone 1', field: 'Telefone1Numero', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                { title: 'E-mail', field: 'Email', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
            ],
            'onChange': function () {
                "use strict";
                var self = this;
                var data = self.getSelectedData();
            },
            'onDataBound': function () {
                "use strict";
                var el = $('#gridEnderecos .k-grid-content');
                el[0].style.height = "108px";
            },
            'dataSourceType': "Filtered"
        });

        var dropDownUf = new DropDown({
            'id': 'selectUf',
            'route': 'Empresarial/Combos/GetUf'
        });

        $('#inputInscricaoEstadual').setMask('insc-estadual');

        var dropDownUfEnderecos = new DropDown({
            'id': 'selectUfEnderecos',
            'route': 'Empresarial/Combos/GetUf'
        });

        function updateMascaraInscricaoEstadual() {
            $.post(window.baseUrl + 'Empresarial/Cadastros/Get/MascaraInscricaoEstadual')
                .done(function (data) {
                    $('#inputInscricaoEstadual').setMask({ mask: data.mascara });
                })
               .fail(function () {
                   $('#inputInscricaoEstadual').setMask('999.999.999');
               });
        }

        function bindMunicipoEnderecoData(data) {
            if (data !== undefined) {
                dropDownUfEnderecos.set(data.Uf);
                dropDownUfEnderecos.change();
                document.getElementById('inputCodigoMunicipioEndereco').value = data.Codigo;
                document.getElementById('descriptionCodigoMunicipioEndereco').innerHTML = data.Nome;
            } else {
                dropDownUfEnderecos.setIndex(0);
                dropDownUfEnderecos.change();
                document.getElementById('inputCodigoMunicipioEndereco').value = "";
                document.getElementById('descriptionCodigoMunicipioEndereco').innerHTML = "";
            }
        }

        function selectModeAlteracao(drop, option) {
            drop.enable(!option);
        };

        function adicionandoEndereco(option) {
            document.getElementById('buttonAlterarEndereco').disabled = option;
            document.getElementById('buttonRemoverEndereco').disabled = option;
            document.getElementById('buttonAdicionarEndereco').disabled = !option;
        }

        function checkRequiredCadastro() {
            return checkRequired('#principal input[required=required]');
        }

        function checkRequiredEndereco() {
            return checkRequired('#endereco input[required=required]');
        }

        function checkRequired(selector) {
            var requireds = document.querySelectorAll(selector), l = requireds.length;
            for (var i = 0; i < l; i++) {
                var required = requireds[i];
                if (required.value == "") {
                    if (!$(required).attr("hidden")) // no IE9 XXX.hidden retorna "undefined" ao inves de "hidden"
                        return required;
                }
            }
            return false;
        }

        function temEnderecoTipo(view, tipo) {
            var m = view.filter(function (m) { return m.Tipo == tipo; });
            return m.length > 0;
        }

        function temEnderecoAlteracaoMesmoTipo(novoEndereco, view, enderecoDaGrid) {
            for (var i = 0; i < view.length; i = i + 1) {
                var enderecoAtual = view[i];

                if (enderecoAtual.Index !== enderecoDaGrid.Index && enderecoAtual.Tipo.toString() === novoEndereco.Tipo)
                    return i;
            }

            return -1;
        }

        function masker(isListar) {
            if (isListar) {
                $('#inputCpf').setMask('cpf2');
                $('#inputCnpj').setMask('cnpj2');
            } else {
                $('#inputCpf').setMask('cpf');
                $('#inputCnpj').setMask('cnpj');
            }

            //$('#inputCep').setMask('radar-cep'); cep não possuirá máscara conforme #1403-00721-1
        }

        function criaCf(tipo, cf, drop) {
            var postUrl = window.baseUrl + 'Empresarial/Cadastros/Crud/Create/' + tipo;
            $.post(postUrl, cf)
                .done(function (data) {
                    if (data.Valido) {
                        document.getElementById('inputCodigo').value = data.CodigoProprio;
                        u.alert("Cadastro realizado com sucesso.", alertBehavior.success);
                        selectModeAlteracao(drop, true);
                        updateFirstState();
                    } else {
                        u.alert(data.Message, alertBehavior.warning);
                    }

                    document.querySelector('a[href="#principal"]').click();
                    masker();
                });
        }

        function alteraCf(tipo, cf, drop, gravarHistorico, prompt) {
            var postUrl = window.baseUrl + 'Empresarial/Cadastros/Crud/Update/' + tipo;
            var required = checkRequiredCadastro();
            if (!required) {
                if (gravarHistorico) {
                    prompt.onOk = function (clbData) {
                        cf.DataVigencia = clbData.DataVigencia;
                        postDoneCf(postUrl, cf, drop);
                    };
                    prompt.make();
                    prompt.listen();
                    prompt.show(true);
                    makeDatePicker('#inputDataFinalVigencia');
                } else {
                    postDoneCf(postUrl, cf, drop);
                }
            } else {
                // IE9 nao suporta o dataset
                //var message = required.dataset.message;
                var message = required.getAttribute("data-message");
                required.focus();
                u.dialogOk(message, function () {
                    setTimeout(function () { required.focus(); }, 20);
                }, true);
            }
        }

        function postDoneCf(postUrl, cfData, drop) {
            $.post(postUrl, cfData).done(function () {
                u.alert("Alteração realizada com sucesso.", alertBehavior.success);
                selectModeAlteracao(drop, true);
                document.querySelector('a[href="#principal"]').click();
                masker();
                updateFirstState();
                updateMascaraInscricaoEstadual();
            });
        }

        function checkCadastroCf(options, callback) {
            // busca campos requeridos
            var required = checkRequiredCadastro();

            if (!required) {
                var view = baseTableEndereco.grid.dataSource.view().toJSON();
                if (view.length == 0 || !temEnderecoTipo(view, 80)) {
                    u.dialogOk("Deve ser informado um endereço padrão.", function () {
                        setTimeout(function () {
                            document.querySelector('a[href="#endereco"]').click();
                        }, 20);
                    }, true);
                    return;
                }
            } else {
                // IE9 nao suporta o dataset
                // var message = required.dataset.message;
                var message = required.getAttribute("data-message");
                u.dialogOk(message, function () {
                    document.querySelector('a[href="#principal"]').click();
                    setTimeout(function () {
                        required.focus();
                    }, 300);
                }, true);
                return;
            }
            var inscricaoEstadual = document.getElementById('inputInscricaoEstadual');
            var showInscricaoEstadualPrompts = !inscricaoEstadual.disabled;
            var inscricaoEstadualValue = inscricaoEstadual.value;
            var emptyInscricaoEstadual = inscricaoEstadualValue.removeOccurrencesOf(/\.|\/|-/g).asInt() === 0 || inscricaoEstadualValue.empty();

            if (options.cf.TipoPessoa == PessoaType.JURIDICA && emptyInscricaoEstadual && options.cf.TipoContribuinte == IcmsType.CONTRIBUINTE && showInscricaoEstadualPrompts) {
                u.dialogOk("Inscrição estadual deve ser informada.", function () {
                    document.querySelector('a[href="#inscricoesLegais"]').click();
                    setTimeout(function () {
                        document.getElementById('inputInscricaoEstadual').focus();
                    }, 300);
                }, true);
                return;
            }

            var validarCpfCnpjUrl = window.baseUrl + 'Api/Validar/ValidateCpfCnpj';
            var dataValidarCpfCnpj = { Data: options.cf.CnpjCpf, TipoCfrt: options.tipo, TipoPessoa: options.cf.TipoPessoa, Codigo: options.cf.Codigo };
            var postValidarCpfCnpj = $.post(validarCpfCnpjUrl, dataValidarCpfCnpj);

            var validarInscricaoEstadualUrl = window.baseUrl + 'Api/Validar/ValidateInscricaoEstadual';

            // pega o UF do endereco padrao
            var dataValidarInscricaoEstadual = { Data: options.cf.InscricaoEstadual };
            $.each(baseTableEndereco.getDataSource().data(), function (i, el) {
                if (el.Tipo === options.CodigoTipoEnderecoPadrao) {
                    dataValidarInscricaoEstadual.Uf = el.Uf;
                }
            });

            var postValidarInscricaoEstadual = $.post(validarInscricaoEstadualUrl, dataValidarInscricaoEstadual);
            var validarEmailUrl = window.baseUrl + 'Api/Validar/ValidateEmail';
            var dataValidarEmail = { Data: options.cf.Email };
            var postValidarEmail = $.post(validarEmailUrl, dataValidarEmail);

            $.when(
                postValidarCpfCnpj,
                postValidarInscricaoEstadual,
                postValidarEmail
            ).done(function (resultCpfCnpj, resultInscricaoEstadual, resultEmail) {
                var dataCpfCnpj = resultCpfCnpj[0],
                    dataInscricaoEstadual = resultInscricaoEstadual[0],
                    dataEmail = resultEmail[0];
                var inputDisabled = options.cf.TipoPessoa == PessoaType.FISICA || document.querySelectorAll('#inputInscricaoEstadual:disabled').length > 0;

                checkaPost(
                    dataCpfCnpj,
                    dataInscricaoEstadual,
                    dataEmail
                ).then(function (data, dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                    //Confere Inscrição Estadual (sim/não)
                    if (dataInscricaoEstadual.Valido && dataInscricaoEstadual.Message != undefined && !inputDisabled && showInscricaoEstadualPrompts) {
                        data.setPromptInscricoesLegaisYesNo(true, dataInscricaoEstadual.Message);
                    }
                }).then(function (data, dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                    //Confere Inscrição Estadual (ok)
                    if (!dataInscricaoEstadual.Valido && dataInscricaoEstadual.Message != undefined && !inputDisabled && showInscricaoEstadualPrompts) {
                        data.setPromptInscricoresLegaisConfirm(true, dataInscricaoEstadual.Message);
                    }
                }).then(function (data, dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                    //Confere CNPJ/CPF (sim/não)
                    if (dataCpfCnpj.Valido && dataCpfCnpj.Message != undefined) {
                        data.setPromptCpfCnpjYesNo(true, dataCpfCnpj.Message);
                    }
                }).then(function (data, dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                    //Confere CNPJ/CPF (ok)
                    if (!dataCpfCnpj.Valido && dataCpfCnpj.Message != undefined) {
                        data.setPromptCpfCnpjConfirm(true, dataCpfCnpj.Message);
                    }
                }).then(function (data, dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                    //Confere Email (ok)
                    if (!dataEmail.Valido && dataEmail.Message != undefined) {
                        data.setPromptEmailConfirm(true, dataEmail.Message);
                    }
                }).done(function (data) {
                    data.done(callback);
                });
            });

            var checkaPost = function (dataCpfCnpj, dataInscricaoEstadual, dataEmail) {
                var deferred = new $.Deferred();

                var data = (function (o) {
                    var _valid = o.valid;
                    var _promptCpfCnpjYesNo = false;
                    var _promptCpfCnpjConfirm = false;
                    var _promptInscricoesLegaisYesNo = false;
                    var _promptInscricoresLegaisConfirm = false;
                    var _promptEmailConfirm = false;
                    var _msgCpfCnpjYesNo = '';
                    var _msgCpfCnpjConfirm = '';
                    var _msgInscricoesLegaisYesNo = '';
                    var _msgInscricoresLegaisConfirm = '';
                    var _msgEmailConfirm = '';

                    function done(callback) {
                        if (_promptEmailConfirm) {
                            promptEmailConfirm();
                        } else if (_promptCpfCnpjConfirm) {
                            promptCpfCnpjConfirm();
                        } else if (_promptCpfCnpjYesNo) {
                            promptCpfCnpjYesNo(callback);
                        } else if (_promptInscricoresLegaisConfirm) {
                            promptInscricoresLegaisConfirm();
                        } else if (_promptInscricoesLegaisYesNo) {
                            promptInscricoesLegaisYesNo(callback);
                        } else {
                            callback();
                        }
                    }

                    function promptEmailConfirm() {
                        var promptOptions = {
                            'id': 'emailInvalido',
                            'title': 'E-mail.',
                            'template': "<div><span>" + _msgEmailConfirm + "</span></div>",
                            'onOk': function () {
                                this.show(false);
                                document.querySelector('a[href="#principal"]').click();
                                setTimeout(function () {
                                    document.getElementById('inputEmail').focus();
                                }, 300);
                            }
                        };
                        var prompt = new PromptDialog(promptOptions);
                        prompt.make();
                        prompt.listen();
                        prompt.show(true);
                    }

                    function promptCpfCnpjConfirm() {
                        var promptOptions = {
                            'id': 'cpfCnpfInvalido',
                            'title': 'CNPJ/CPF',
                            'template': "<div><span>" + _msgCpfCnpjConfirm + "</span></div>",
                            'onOk': function () {
                                this.show(false);
                                document.querySelector('a[href="#principal"]').click();
                                setTimeout(function () {
                                    var cpf = document.getElementById('inputCpf');
                                    var cnpj = document.getElementById('inputCnpj');
                                    if ($(cpf).attr("hidden")) // no IE9 XXX.hidden retorna "undefined" ao inves de "hidden"
                                        cnpj.focus();
                                    else if ($(cnpj).attr("hidden")) // no IE9 XXX.hidden retorna "undefined" ao inves de "hidden"
                                        cpf.focus();
                                }, 300);
                            }
                        };
                        var prompt = new PromptDialog(promptOptions);
                        prompt.make();
                        prompt.listen();
                        prompt.show(true);
                    }

                    function promptCpfCnpjYesNo(callback) {
                        var promptOptions = {
                            'id': 'naoBloquearCnpjCpfInvalido',
                            'title': 'CNPJ/CPF',
                            'template': "<div><span>" + _msgCpfCnpjYesNo + "\nConfirma o cadastro?</span></div>",
                            'onYes': function () {
                                this.show(false);
                                if (_promptInscricoesLegaisYesNo) {
                                    promptInscricoesLegaisYesNo(callback);
                                } else if (_promptInscricoresLegaisConfirm) {
                                    promptInscricoresLegaisConfirm();
                                } else {
                                    callback();
                                }
                            },
                            'onNo': function () {
                                this.show(false);
                                document.querySelector('a[href="#principal"]').click();
                                setTimeout(function () {
                                    document.getElementById('inputInscricaoEstadual').focus();
                                }, 300);
                            }
                        };
                        var prompt = new PromptDialogYesNo(promptOptions);
                        prompt.make();
                        prompt.listen();
                        prompt.show(true);
                    }

                    function promptInscricoresLegaisConfirm() {

                        var promptOptions = {
                            'id': 'inscricaoEstadualInvalida',
                            'title': 'Inscrição Estadual.',
                            'template': "<div><span>" + _msgInscricoresLegaisConfirm + "</span></div>",
                            'onOk': function () {
                                this.show(false);
                                document.querySelector('a[href="#inscricoesLegais"]').click();
                                setTimeout(function () {
                                    document.getElementById('inputInscricaoEstadual').focus();
                                }, 300);
                            }
                        };
                        var prompt = new PromptDialog(promptOptions);
                        prompt.make();
                        prompt.listen();
                        prompt.show(true);
                    }

                    function promptInscricoesLegaisYesNo(callback) {
                        var promptOptions = {
                            'id': 'naoBloquearInscricaoEstadualInvalida',
                            'title': 'Inscrição Estadual.',
                            'template': "<div><span>" + _msgInscricoesLegaisYesNo + "\nConfirma o cadastro?</span></div>",
                            'onYes': function () {
                                this.show(false);
                                callback();
                            },
                            'onNo': function () {
                                this.show(false);
                                document.querySelector('a[href="#inscricoesLegais"]').click();
                                setTimeout(function () {
                                    document.getElementById('inputInscricaoEstadual').focus();
                                }, 300);
                            }
                        };
                        var prompt = new PromptDialogYesNo(promptOptions);
                        prompt.make();
                        prompt.listen();
                        prompt.show(true);
                    }

                    return {
                        isValid: function () {
                            return _valid;
                        },
                        setValid: function (valid) {
                            _valid = valid;
                        },
                        setPromptCpfCnpjYesNo: function (promptCpfCnpjYesNo, msgCpfCnpjYesNo) {
                            _promptCpfCnpjYesNo = promptCpfCnpjYesNo;
                            _msgCpfCnpjYesNo = msgCpfCnpjYesNo;
                        },
                        setPromptCpfCnpjConfirm: function (promptCpfCnpjConfirm, msgCpfCnpjConfirm) {
                            _promptCpfCnpjConfirm = promptCpfCnpjConfirm;
                            _msgCpfCnpjConfirm = msgCpfCnpjConfirm;
                        },
                        setPromptInscricoesLegaisYesNo: function (promptInscricoesLegaisYesNo, msgInscricoesLegaisYesNo) {
                            _promptInscricoesLegaisYesNo = promptInscricoesLegaisYesNo;
                            _msgInscricoesLegaisYesNo = msgInscricoesLegaisYesNo;
                        },
                        setPromptInscricoresLegaisConfirm: function (promptInscricoresLegaisConfirm, msgInscricoresLegaisConfirm) {
                            _promptInscricoresLegaisConfirm = promptInscricoresLegaisConfirm;
                            _msgInscricoresLegaisConfirm = msgInscricoresLegaisConfirm;
                        },
                        setPromptEmailConfirm: function (promptEmailConfirm, msgEmailConfirm) {
                            _promptEmailConfirm = promptEmailConfirm;
                            _msgEmailConfirm = msgEmailConfirm;
                        },
                        done: done
                    };
                })({ valid: true });

                deferred.resolve(data, dataCpfCnpj, dataInscricaoEstadual, dataEmail);
                return deferred.promise();
            };
        };

        function updateFirstState() {
            firstState.TipoPessoa = document.getElementById('selectTipoPessoa').value;

            if (firstState.TipoPessoa == PessoaType.FISICA) {
                firstState.CnpjCpf = document.getElementById('inputCpf').value;
            } else if (firstState.TipoPessoa == PessoaType.JURIDICA) {
                firstState.CnpjCpf = document.getElementById('inputCnpj').value;
            }

            firstState.InscricaoEstadual = document.getElementById('inputInscricaoEstadual').value;
            firstState.RazaoSocial = document.getElementById('inputRazaoSocial').value;
            mostrarVigencia = false;
        }

        function equalsObject(right, left) {
            var a = JSON.stringify(right);
            var b = JSON.stringify(left);
            return a == b;
        }

        return {
            Listar: function (params) {
                return (function () {
                    var modoCf = '';

                    if (params.Option == 'Clientes')
                        modoCf = 'Cliente';
                    else
                        modoCf = 'Fornecedor';

                    baseTable.id = 'grid' + params.Option;
                    baseTable.route = window.baseUrl + 'Empresarial/Cadastros/Get/' + params.Option;
                    baseTable.make();
                    baseTable.listen();
                    baseTable.onChange = function () {
                        "use strict";
                        var self = this;
                        var $data = self.getSelectedData();
                        window.location = window.baseUrl + 'Empresarial/Cadastros/' + params.Option + '/' + $data.Codigo;
                    };

                    var switcherOptions = {
                        groupSelector: '[name=tipoPessoa]',
                        onChange: function (input) {
                            var value = input.value;

                            var $inputCpf = $('#inputCpf');
                            var $labelCpf = $('#labelCpf');
                            var $inputCnpj = $('#inputCnpj');
                            var $labelCnpj = $('#labelCnpj');

                            var labelRazaoSocial = document.getElementById('labelFiltroRazaoSocial');

                            if (value == 70) {
                                labelRazaoSocial.innerHTML = 'Nome:';
                                $inputCnpj.val('');
                                $inputCnpj.hide();
                                $inputCnpj.attr('hidden', 'hidden');
                                $labelCnpj.hide();

                                //$inputCpf.val('000.000.000-00');
                                $inputCpf.show();
                                $inputCpf.removeAttr('hidden');
                                $labelCpf.show();
                            } else if (value == 74 || value == 0) {
                                labelRazaoSocial.innerHTML = 'Razão Social:';
                                $inputCpf.val('');
                                $inputCpf.hide();
                                $labelCpf.hide();
                                $inputCpf.attr('hidden', 'hidden');

                                //$inputCnpj.val('00.000.000/0000-00');
                                $inputCnpj.show();
                                $inputCnpj.removeAttr('hidden');
                                $labelCnpj.show();
                            }

                            masker(true);
                        }
                    };
                    var switcher = new RadioSwitcher(switcherOptions);

                    dropDownUf.route = 'Empresarial/Combos/GetUfAndEmpty';
                    dropDownUf.make();

                    var validatorMunicipio = new Validator({
                        field: 'CodigoMunicipio',
                        onPendencyMessage: 'Deve ser informado o código do município.',
                        route: 'Empresarial/F4Municipio/GetMunicipio',
                        onValid: function (data) {
                            document.getElementById('inputCodigoMunicipio').value = data.Codigo;
                            document.getElementById('descriptionCodigoMunicipio').innerHTML = data.Nome;
                            dropDownUf.set(data.Uf);
                            dropDownUf.disable();
                        },
                        onInvalid: function () {
                            var self = this;
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                            dropDownUf.enable();
                        },
                        onEmpty: function () {
                            dropDownUf.enable();
                        }
                    });
                    validatorMunicipio.listen();

                    function toggleMunicipio() {
                        var data = tableMunicipios.getSelectedData();
                        document.getElementById('inputCodigoMunicipio').value = data.Codigo;
                        document.getElementById('descriptionCodigoMunicipio').innerHTML = data.Nome;

                        validatorMunicipio.update();
                        validatorMunicipio.validate();
                        $('#modalMunicipio').modal('hide');
                        $('#filtroModal').modal('show');
                    }
                    var tableMunicipios = new Table({
                        'id': 'tableMunicipios',
                        'route': window.baseUrl + 'Empresarial/F4Municipio/GetMunicipios',
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Nome', field: 'Nome', width: 240, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'UF', field: 'Uf', width: 35, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'showFilter': true,
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                toggleMunicipio();
                            };
                        },
                        'onDataBound': function () {
                            $('#filtroModal').modal('hide');
                            $('#tableMunicipios table  tr').on('dblclick', function () {
                                toggleMunicipio();
                            });

                            var $ok = $('#inputF4ModalOk' + this.id);
                            var $cancel = $ok.next();
                            $cancel.on('click', function () {
                                $('#modalMunicipio').modal('hide');
                                $('#filtroModal').modal('show');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalMunicipios = document.getElementById('linkButtonModalMunicipios');
                    var inputMunicipios = document.getElementById('inputCodigoMunicipio');
                    var modalMunicipios = new Modal('Municípios', linkButtonModalMunicipios, inputMunicipios, tableMunicipios);
                    modalMunicipios.listen();

                    $('#doFilter').on('click', function () {
                        doFilter();
                    });
                    $('#removeFilter').on('click', function () {
                        validatorMunicipio.setValue('');
                        dropDownUf.setIndex(0);
                        dropDownUf.enable();
                        document.getElementById('radioFisica').checked = true;
                        document.getElementById('inputFiltroRazaoSocial').value = '';
                        document.getElementById('inputCnpj').value = '';
                        document.getElementById('inputCpf').value = '';
                        document.querySelector("input[name=tipoPessoa][value='0']").checked = true;

                        var dataSource = new kendo.data.DataSource(
                            baseTable.getFilteredDataSource()
                        );
                        baseTable.setDataSource(dataSource);
                    });
                    $('#inputFilter').on('click', function () {
                        $("#filtroModal").modal('show');
                    });

                    if (!params.UsuarioAtualPodeIncluirAlterar) {
                        $("#buttonCadastrar").attr("disabled", "disabled");
                    } else {
                        $("#buttonCadastrar").on('click', function () {
                            window.location.href = window.baseUrl + 'Empresarial/Cadastros/' + params.Option;
                        });
                    }

                    function onCpfCnpjExistente(tipo, filter, existenteCall, inexistenteCall) {
                        var validarCpfCnpjUrl = window.baseUrl + 'Api/Validar/IsCnpjCpfExistente';

                        var data = { Data: filter.CnpjCpf, TipoCfrt: tipo, TipoPessoa: filter.TipoPessoa };

                        $.post(validarCpfCnpjUrl, data).done(function (mess) {
                            if (mess.IsExistente) {
                                existenteCall(filter);
                            } else {
                                inexistenteCall(filter);
                            }
                        });
                    }

                    function doFilter() {
                        var filter = {};
                        filter.CodigoMunicipio = validatorMunicipio.getValue();
                        filter.Uf = dropDownUf.get();
                        filter.Pessoa = $('input[name=tipoPessoa]:checked').val();
                        filter.RazaoSocial = document.getElementById('inputFiltroRazaoSocial').value;

                        if (filter.Pessoa == 70)
                            filter.CnpjCpf = document.getElementById('inputCpf').value;
                        else
                            filter.CnpjCpf = document.getElementById('inputCnpj').value;

                        onCpfCnpjExistente(modoCf, filter, function (filtro) {
                            var dataSource = new kendo.data.DataSource(
                                baseTable.getFilteredDataSource(filtro));
                            baseTable.setDataSource(dataSource);
                        }, function (filtro) {
                            u.dialogOk("Não existem dados para o filtro selecionado.",
                             function () {
                                 filtro.CnpjCpf = null;
                                 //var dataSource = new kendo.data.DataSource(
                                 //baseTable.getFilteredDataSource(filtro));
                                 var dataSource = new kendo.data.DataSource();
                                 baseTable.setDataSource(dataSource);
                             }, true);
                        });
                    }

                    document.getElementById('tableTitle').innerHTML = params.Option;

                    masker(true);
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Empresarial - Cadastros - Clientes/Fornecedores");
                })(params);
            },

            Cadastros: function (params) {
                return (function () {
                    var isAlteracao = params.Method == 'update' ? true : false;
                    var podeIncluirAlterar = params.UsuarioAtualPodeIncluirAlterar;

                    var lastEnderecoStatus = {
                        Endereco: '',
                        IsSemNumero: false,
                        Numero: '',
                        Complemento: '',
                        Bairro: ''
                    };
                    var gravarHistorico = params.GravarHistorico;

                    var modoCf = '';
                    if (params.Option == 'Clientes')
                        modoCf = 'Cliente';
                    else
                        modoCf = 'Fornecedor';

                    baseTableEndereco.id = 'gridEnderecos';
                    baseTableEndereco.route = window.baseUrl + 'Empresarial/Cadastros/Get/Enderecos';
                    baseTableEndereco.make();
                    baseTableEndereco.listen();
                    baseTableEndereco.onChange = function () {
                        "use strict";
                        var self = this;
                        var $data = self.getSelectedData();
                        currentEndereco($data);
                        if (gravarHistorico && isAlteracao) {
                            setEnderecoLastStatus($data);
                        }
                        if (podeIncluirAlterar) {
                            adicionandoEndereco(false);
                        }
                    };

                    var icmsSwitcherOptions = {
                        groupSelector: '[name=tipoIcms]',
                        onChange: function (input) {
                            var value = input.value;

                            if (value == IcmsType.NAO_CONTRIBUINTE || IcmsType.ISENTO) {
                                enableInputInscricaoEstadual(false);
                            }

                            if (value == IcmsType.CONTRIBUINTE) {
                                enableInputInscricaoEstadual(true);
                            }
                        }
                    };
                    var icmsSwitcher = new RadioSwitcher(icmsSwitcherOptions);

                    function enableInputInscricaoEstadual(option) {
                        var inputInscricaoEstadual = document.getElementById('inputInscricaoEstadual');
                        inputInscricaoEstadual.disabled = !option;
                        inputInscricaoEstadual.required = option;
                    }

                    function setEnderecoLastStatus(data) {
                        lastEnderecoStatus.Endereco = data.Endereco;
                        lastEnderecoStatus.IsSemNumero = data.IsSemNumero;
                        lastEnderecoStatus.Numero = data.Numero;
                        lastEnderecoStatus.Complemento = data.Complemento;
                        lastEnderecoStatus.Bairro = data.Bairro;
                    }

                    function checkEnderecoLastStatus(data) {
                        if (lastEnderecoStatus.Endereco != data.Endereco)
                            return false;
                        if (lastEnderecoStatus.IsSemNumero != data.IsSemNumero)
                            return false;
                        if (lastEnderecoStatus.Numero != data.Numero)
                            return false;
                        if (lastEnderecoStatus.Complemento != data.Complemento)
                            return false;
                        if (lastEnderecoStatus.Bairro != data.Bairro)
                            return false;

                        return true;
                    }

                    function gravarHistoricoAction(endereco) {
                        var result = checkEnderecoLastStatus(endereco);
                        if (!result) {
                            mostrarVigencia = true;
                        }
                    }

                    dropDownUfEnderecos.make();
                    dropDownUfEnderecos.disable();

                    promptDataVigencia.make();
                    promptDataVigencia.listen();

                    var dropTipoPessoa = $('#selectTipoPessoa').kendoDropDownList({
                        change: function () {
                            var value = this.value();

                            var $inputCpf = $('#inputCpf');
                            var $labelCpf = $('#labelCpf');
                            var $inputCnpj = $('#inputCnpj');
                            var $labelCnpj = $('#labelCnpj');

                            var labelRazaoSocial = document.getElementById('labelRazaoSocial');
                            var labelNomeFantasia = document.getElementById('labelNomeFantasia');

                            if (value == PessoaType.FISICA) {
                                labelRazaoSocial.innerHTML = 'Nome:';
                                labelNomeFantasia.innerHTML = 'Apelido:';

                                $inputCnpj.val('');
                                $inputCnpj.hide();
                                $inputCnpj.attr('hidden', 'hidden');
                                $labelCnpj.hide();

                                $inputCpf.val('000.000.000-00');
                                $inputCpf.show();
                                $inputCpf.removeAttr('hidden');
                                $labelCpf.show();

                                enableInputInscricaoEstadual(false);
                                $('#liTabInscLegais').attr('hidden', 'hidden');
                            } else if (value == PessoaType.JURIDICA) {
                                labelRazaoSocial.innerHTML = 'Razão Social:';
                                labelNomeFantasia.innerHTML = 'Nome Fantasia:';

                                $inputCpf.val('');
                                $inputCpf.hide();
                                $labelCpf.hide();
                                $inputCpf.attr('hidden', 'hidden');

                                $inputCnpj.val('00.000.000/0000-00');
                                $inputCnpj.show();
                                $inputCnpj.removeAttr('hidden');
                                $labelCnpj.show();

                                enableInputInscricaoEstadual(true);
                                $('#liTabInscLegais').removeAttr('hidden');
                            }
                        }
                    }).data('kendoDropDownList');
                    var dropTipoEndereco = $('#selectTipoEndereco').kendoDropDownList().data('kendoDropDownList');

                    var validatorMunicipioEndereco = new ValidatorEx({
                        field: 'CodigoMunicipio',
                        inputId: 'inputCodigoMunicipioEndereco',
                        descriptionId: 'descriptionCodigoMunicipioEndereco',
                        onPendencyMessage: 'Deve ser informado o código do município.',
                        route: 'Empresarial/F4Municipio/GetMunicipio',
                        onValid: function (data) {
                            bindMunicipoEnderecoData(data);
                        },
                        onInvalid: function () {
                            var self = this;
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        },
                        onEmpty: function () {
                            bindMunicipoEnderecoData();
                        }
                    });
                    validatorMunicipioEndereco.listen();

                    var tableMunicipiosEndereco = new Table({
                        'id': 'tableMunicipiosEndereco',
                        'route': window.baseUrl + 'Empresarial/F4Municipio/GetMunicipios',
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Nome', field: 'Nome', width: 240, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'UF', field: 'Uf', width: 35, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'showFilter': true,
                        'onChange': function () {
                            "use strict";
                            var self = this;
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var $data = self.getSelectedData();
                                bindMunicipoEnderecoData($data);
                            };
                        },
                        'onDataBound': function () {
                            var self = this;
                            $('#' + self.id + ' table tr').on('dblclick', function () {
                                var $data = self.getSelectedData();
                                bindMunicipoEnderecoData($data);
                                $cancel.click();
                            });

                            var $ok = $('#inputF4ModalOk' + self.id);
                            var $cancel = $ok.next();
                            $cancel.onclick = function (ev) {
                                ev.preventDefault();
                            };
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalMunicipiosEndereco = document.getElementById('linkButtonModalMunicipiosEndereco');
                    var inputMunicipiosEndereco = document.getElementById('inputCodigoMunicipioEndereco');
                    var modalMunicipiosEndereco = new Modal('Municípios', linkButtonModalMunicipiosEndereco, inputMunicipiosEndereco, tableMunicipiosEndereco);
                    modalMunicipiosEndereco.listen();

                    $('#buttonAdicionarEndereco').on('click', function (ev) {
                        currentEndereco(function (endereco) {
                            var url = window.baseUrl + 'Empresarial/Cadastros/Crud/Enderecos/{0}';
                            var postUrl = url.format('Create');
                            var view = baseTableEndereco.grid.dataSource.view().toJSON();
                            var required = checkRequiredEndereco();
                            if (!required) {
                                if (temEnderecoTipo(view, endereco.Tipo)) {
                                    u.dialogOk("Tipo de endereço já cadastrado.", null, true);
                                } else {
                                    $.post(postUrl, endereco)
                                        .done(function (data) {
                                            baseTableEndereco.refresh();
                                            currentEndereco(data);
                                            updateMascaraInscricaoEstadual();
                                        });
                                }
                            } else {
                                // IE9 nao suporta o dataset
                                //var message = required.dataset.message;
                                var message = required.getAttribute("data-message");
                                u.dialogOk(message, function () {
                                    setTimeout(function () {
                                        required.focus();
                                    }, 20);
                                }, true);
                            }

                            masker();
                        });
                    });
                    $('#buttonAlterarEndereco').on('click', function (ev) {
                        currentEndereco(function (endereco) {
                            var url = window.baseUrl + 'Empresarial/Cadastros/Crud/Enderecos/{0}';
                            var postUrl = url.format('Update');
                            var view = baseTableEndereco.grid.dataSource.view().toJSON();
                            var selectedData = baseTableEndereco.getSelectedData();
                            var required = checkRequiredEndereco();
                            if (!required) {
                                var index = temEnderecoAlteracaoMesmoTipo(endereco, view, selectedData);
                                if (index >= 0) {
                                    baseTableEndereco.clearSelectedData();
                                    $($('#gridEnderecos tr')[index + 1]).addClass('k-state-selected');
                                    var selLocal = baseTableEndereco.getSelectedData();
                                    currentEndereco(selLocal);
                                } else {
                                    endereco.Index = selectedData.Index;
                                    if (gravarHistorico && isAlteracao) {
                                        gravarHistoricoAction(endereco);
                                    }
                                    $.post(postUrl, endereco).done(function (data) {
                                        baseTableEndereco.refresh();
                                        currentEndereco(data);
                                        adicionandoEndereco(true);
                                        updateMascaraInscricaoEstadual();
                                    });
                                }
                            } else {
                                // IE9 nao suporta o dataset
                                //var message = required.dataset.message;
                                var message = required.getAttribute("data-message");
                                u.dialogOk(message, function () {
                                    setTimeout(function () {
                                        required.focus();
                                    }, 20);
                                }, true);
                            }

                            masker();
                        });
                    });

                    $('#buttonRemoverEndereco').on('click', function (ev) {
                        currentEndereco(function (endereco) {
                            var postUrl = window.baseUrl + 'Empresarial/Cadastros/Crud/Enderecos/Delete';
                            $.post(postUrl, endereco).done(function (data) {
                                baseTableEndereco.refresh();
                                adicionandoEndereco(true);
                                currentEndereco(data);
                                updateMascaraInscricaoEstadual();
                                if (gravarHistorico && isAlteracao) {
                                    mostrarVigencia = true;
                                }
                            });
                            masker();
                        });
                    });

                    $('#inputNumero').setMask('integer');

                    $("#checkSemNumero").on("click", function () {
                        if (isChecked("checkSemNumero")) {
                            $("#inputNumero").val("");
                            $("#inputNumero").attr("disabled", "disabled");
                        } else {
                            $("#inputNumero").removeAttr("disabled");
                        }
                    });

                    function currentEndereco(callback) {
                        if (callback == undefined)
                            return;

                        if (typeof callback == 'function') {
                            var endereco = {};

                            endereco.Tipo = dropTipoEndereco.value();
                            endereco.Endereco = document.getElementById("inputEndereco").value;
                            endereco.Complemento = document.getElementById("inputComplemento").value;
                            endereco.Bairro = document.getElementById("inputBairro").value;
                            endereco.Cep = document.getElementById("inputCep").value;
                            endereco.CodigoMunicipio = document.getElementById("inputCodigoMunicipioEndereco").value;
                            endereco.Uf = document.getElementById("selectUfEnderecos").value;
                            endereco.Telefone1Codigo = document.getElementById("inputTelefone1Codigo").value;
                            endereco.Telefone1Numero = document.getElementById("inputTelefone1Numero").value;
                            endereco.Telefone2Codigo = document.getElementById("inputTelefone2Codigo").value;
                            endereco.Telefone2Numero = document.getElementById("inputTelefone2Numero").value;
                            endereco.Contato = document.getElementById("inputEnderecoContato").value;
                            endereco.Email = document.getElementById("inputEnderecoEmail").value;
                            endereco.IsSemNumero = document.getElementById("checkSemNumero").checked;

                            if (endereco.IsSemNumero) {
                                $("#inputNumero").val("");
                                $("#inputNumero").attr("disabled", "disabled");
                            } else {
                                endereco.Numero = document.getElementById("inputNumero").value;
                            }

                            callback(endereco);
                            updateMascaraInscricaoEstadual();
                            bindMunicipoEnderecoData();
                        }

                        if (typeof callback == 'object') {
                            // no IE9 seta como "null" na tag span, quando o conteudo eh null
                            // atribui "" para todos os campos null
                            $.each(callback, function (i, el) {
                                if (el === null)
                                    callback[i] = "";
                            });

                            dropTipoEndereco.value(callback.Tipo);

                            document.getElementById("inputEndereco").value = callback.Endereco;
                            document.getElementById("inputComplemento").value = callback.Complemento;
                            document.getElementById("inputBairro").value = callback.Bairro;
                            document.getElementById("inputCep").value = callback.Cep;
                            document.getElementById("inputCodigoMunicipioEndereco").value = callback.CodigoMunicipio;
                            document.getElementById("descriptionCodigoMunicipioEndereco").innerHTML = callback.Municipio === null ? "" : callback.Municipio;
                            document.getElementById("inputTelefone1Codigo").value = callback.Telefone1Codigo;
                            document.getElementById("inputTelefone1Numero").value = callback.Telefone1Numero;
                            document.getElementById("inputTelefone2Codigo").value = callback.Telefone2Codigo;
                            document.getElementById("inputTelefone2Numero").value = callback.Telefone2Numero;
                            document.getElementById("inputEnderecoContato").value = callback.Contato;
                            document.getElementById("inputEnderecoEmail").value = callback.Email;
                            document.getElementById("checkSemNumero").checked = callback.IsSemNumero;

                            dropDownUfEnderecos.set(callback.Uf);
                            dropDownUfEnderecos.change();

                            if (callback.IsSemNumero) {
                                $("#inputNumero").val("");
                                $("#inputNumero").attr("disabled", "disabled");
                            } else {
                                document.getElementById("inputNumero").value = callback.Numero;
                                $("#inputNumero").removeAttr("disabled");
                            }
                        }
                    }

                    $('#buttonCadastrarCf').on('click', function (ev) {
                        var options = {};
                        options.cf = currentCf();
                        options.tipo = modoCf; // params.Option 'Clientes'/'Fornecedores'
                        options.drop = dropTipoPessoa;
                        options.mostrarVigencia = mostrarVigencia;
                        options.CodigoTipoEnderecoPadrao = params.CodigoTipoEnderecoPadrao;

                        checkCadastroCf(options, function () {
                            var cf = currentCf();
                            if (!isAlteracao) {
                                mostrarVigencia = false;
                                criaCf(modoCf, cf, dropTipoPessoa);
                                isAlteracao = true;
                            } else {
                                checkMostrarVigencia(cf);
                                alteraCf(modoCf, cf, dropTipoPessoa, mostrarVigencia, promptDataVigencia);
                            }
                        });
                    });
                    $('#buttonCancelarCf').on('click', function (ev) {
                        var current = currentCf();
                        if (!equalsObject(firstState, current)) {
                            u.dialog("Aviso", "Deseja abandonar as alterações?", abandonarAlteracoes);
                            $('#linkDialogModal').click();
                        } else {
                            abandonarAlteracoes();
                        }

                        function abandonarAlteracoes() {
                            "use strict";
                            var url = window.baseUrl + 'Empresarial/Cadastros/Set/{0}/{1}';
                            var postUrl = url.format('New', modoCf);
                            $.post(postUrl)
                                    .done(function () {
                                        window.location = window.baseUrl + 'Empresarial/Cadastros/Listar/' + params.Option;
                                    });
                        }
                    });
                    $('#buttonNovoCf').on('click', function (ev) {
                        window.location = window.baseUrl + 'Empresarial/Cadastros/' + params.Option;
                    });

                    function checkMostrarVigencia(cf) {
                        if (firstState.CnpjCpf != cf.CnpjCpf)
                            mostrarVigencia = true;
                        if (firstState.InscricaoEstadual != cf.InscricaoEstadual)
                            mostrarVigencia = true;
                        if (firstState.RazaoSocial != cf.RazaoSocial)
                            mostrarVigencia = true;
                    }

                    function currentCf(callback) {
                        var cf;
                        if (callback == undefined) {
                            cf = getCf();
                            return cf;
                        }

                        if (typeof callback == 'function') {
                            cf = getCf();
                            callback(cf);
                        }

                        if (typeof callback == 'object') {
                            if (isAlteracao)
                                document.getElementById('inputCodigo').value = callback.Codigo;

                            dropTipoPessoa.value(callback.TipoPessoa);
                            dropTipoPessoa.trigger('change');
                            document.getElementById('selectTipoPessoa').value = callback.TipoPessoa;

                            if (callback.TipoPessoa == 70) {
                                document.getElementById('inputCpf').value = callback.CnpjCpf;
                            } else if (callback.TipoPessoa == 74) {
                                document.getElementById('inputCnpj').value = callback.CnpjCpf;
                            }

                            document.getElementById('inputClassificao').value = callback.Classificacao;
                            document.getElementById('inputRazaoSocial').value = callback.RazaoSocial;
                            document.getElementById('inputNomeFantasia').value = callback.NomeFantasia;
                            document.getElementById('inputContato').value = callback.Contato;
                            document.getElementById('inputEmail').value = callback.Email;
                            document.getElementById('inputHomepage').value = callback.Homepage;
                            document.querySelector("input[name=tipoIcms][value='" + callback.TipoContribuinte + "']").click();
                            document.getElementById('inputInscricaoEstadual').value = callback.InscricaoEstadual;
                        }
                    };

                    function getCf() {
                        var cf = {};

                        if (isAlteracao)
                            cf.Codigo = document.getElementById('inputCodigo').value;

                        cf.TipoPessoa = dropTipoPessoa.value();
                        var $input = $('.cpf-cnpj input').not('[hidden=hidden]');
                        cf.CnpjCpf = $input.val();
                        cf.Classificacao = document.getElementById('inputClassificao').value;
                        cf.RazaoSocial = document.getElementById('inputRazaoSocial').value;
                        cf.NomeFantasia = document.getElementById('inputNomeFantasia').value;
                        cf.Contato = document.getElementById('inputContato').value;
                        cf.Email = document.getElementById('inputEmail').value;
                        cf.Homepage = document.getElementById('inputHomepage').value;
                        cf.TipoContribuinte = document.querySelector('[name=tipoIcms]:checked').value;
                        cf.InscricaoEstadual = document.getElementById('inputInscricaoEstadual').value;
                        cf.Uf = dropDownUfEnderecos.get();
                        return cf;
                    }

                    function postAction() {
                        selectModeAlteracao(dropTipoPessoa, true);
                        document.querySelector('a[href="#principal"]').click();
                        isAlteracao = true;
                        firstState = currentCf();
                        masker();
                    };

                    if (!isAlteracao) {
                        selectModeAlteracao(dropTipoPessoa, false);
                        icmsSwitcher.change();
                    } else {
                        selectModeAlteracao(dropTipoPessoa, true);
                        icmsSwitcher.change();
                    }

                    adicionandoEndereco(true);
                    currentCf(params.Model);
                    firstState = currentCf();

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Empresarial - Cadastros - Clientes/Fornecedores");
                    makeDatePicker("#inputDataFinalVigencia");
                    updateMascaraInscricaoEstadual();
                    masker();

                    if (!podeIncluirAlterar) {
                        disableAllInputs();
                        $('#selectTipoPessoa').attr("disabled", "disabled");
                        $('#selectTipoEndereco').attr("disabled", "disabled");
                        $('#selectUfEnderecos').attr("disabled", "disabled");
                        $('#buttonAlterarEndereco').attr("disabled", "disabled");
                        $('#buttonRemoverEndereco').attr("disabled", "disabled");
                    }
                })(params);
            },

            CadastrosFiliais: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // grid
                    var grid = new Table({
                        id: "gridFiliais",
                        route: window.baseUrl + "Empresarial/Filiais/GetFiliais",
                        showFilter: false,
                        columns: [
                            { title: "Código", field: "Codigo", width: 50, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { title: "Identificação", field: "Identificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 160, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CnpjCpf", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "DDD+Telefone", field: "DddTelefone", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Status", field: "Status", width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        toolbar:
                            "<span style='float:left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Empresas/Filiais</span>" +
                            "</span>" +
                            "<span style='float:right'>" +
                            "    <button id='inputFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'>Atualiza</span>Filtro" +
                            "    </button>" +
                            "</span>",
                        dataSourceType: "Filtered",
                        pageable: {
                            refresh: true,
                            numeric: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        onChange: function () {
                            "use strict";
                            var self = this;
                            var $data = self.getSelectedData();
                            window.location = window.baseUrl + "Empresarial/Filiais/Filial?codigo=" + $data.Codigo;
                        },
                        onDataBound: function () {
                            "use strict";
                            var self = this;
                            $("#" + self.id + " table tr").on("dblclick",
                                function () {
                                    var data = self.getSelectedData();
                                }
                            );
                            var el = $("#" + self.id + " .k-grid-content");
                            el[0].style.height = "auto";
                        }
                    });
                    grid.make();
                    grid.listen();

                    // filtros campos

                    // filial inicial
                    var validatorCodigoInicial = new ValidatorLookup({
                        abrev: "CodigoFilialInicial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialExTodas",
                        routeTable: "Empresarial/F4Filial/GetFiliaisTodas",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais",
                        idModalHideShow: "modalFiltro",
                        changeEmptyToAll: true,
                        disableConsultation: true
                    });

                    // filial final
                    var validatorCodigoFinal = new ValidatorLookup({
                        abrev: "CodigoFilialFinal",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialExTodas",
                        routeTable: "Empresarial/F4Filial/GetFiliaisTodas",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais",
                        idModalHideShow: "modalFiltro",
                        changeEmptyToAll: true,
                        disableConsultation: true
                    });

                    // tipo pessoa
                    var inputTipoPessoa = $("#inputTipoPessoa").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Ambas" },
                            { Value: "1", Text: "Jurídica" },
                            { Value: "2", Text: "Física" },
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0",
                        change: function (el) {
                            if ($("#inputTipoPessoa").val() === "0") {
                                $("#inputCNPJCPF").attr("disabled", "disabled");
                                $("#inputCNPJCPF").val("");
                            }
                            else if ($("#inputTipoPessoa").val() === "1") {
                                $("#inputCNPJCPF").val("");
                                $("#inputCNPJCPF").setMask("cnpj");
                                $("#inputCNPJCPF").removeAttr("disabled");
                            }
                            else {
                                $("#inputCNPJCPF").val("");
                                $("#inputCNPJCPF").setMask("cpf");
                                $("#inputCNPJCPF").removeAttr("disabled");
                            }
                        },
                    });

                    // cnpj/cpf
                    $("#inputCNPJCPF").attr("disabled", "disabled");
                    $("#inputCNPJCPF").val("");

                    // filtro listen
                    $("#inputFilter").click(function () {
                        loadFilters();
                        $("#modalFiltro").modal("show");
                        validatorCodigoInicial.focus();
                    });

                    $("#doFilter").click(function () {
                        if (!checkFilters())
                            return;
                        saveFilters();
                        $("#modalFiltro").modal("hide");
                    });

                    $("#removeFilter").click(function () {
                        setFiltroDefault();
                    });

                    // filtro rotinas
                    function loadFilters() {
                        var filter = JSON.parse(currentUser.getSessionData("filtro_EmpresasFiliais"));
                        if (filter != null) {
                            setFiltroInFields(filter);

                            var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource(filter));
                            grid.setDataSource(dataSource);
                        }
                        else {
                            setFiltroDefault();
                        }
                    }

                    function setFiltroDefault() {
                        var filtroDefault = {
                            inputCodigoFilialInicial: "0",
                            inputCodigoFilialFinal: "0",
                            inputIdentificacao: "",
                            inputRazaoSocial: "",
                            inputTipoPessoa: "0",
                            inputCNPJCPF: ""
                        };

                        setFiltroInFields(filtroDefault);

                        var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource());
                        grid.setDataSource(dataSource);

                        currentUser.setSessionData("filtro_EmpresasFiliais", JSON.stringify(filtroDefault));
                    }

                    function setFiltroInFields(filter) {
                        validatorCodigoInicial.setValueValidate(filter.inputCodigoFilialInicial);
                        validatorCodigoFinal.setValueValidate(filter.inputCodigoFilialFinal);
                        setVal("inputIdentificacao", filter.inputIdentificacao);
                        setVal("inputRazaoSocial", filter.inputRazaoSocial);
                        inputTipoPessoa.data().kendoDropDownList.select(filter.inputTipoPessoa.toInt());
                        setVal("inputCNPJCPF", filter.inputCNPJCPF);
                    }

                    function checkFilters() {
                        if (validatorCodigoInicial.all && !validatorCodigoFinal.all) {
                            u.dialogOk("Favor insira o código inicial", null, true,
                                function () {
                                    $("#modalFiltro").modal("show");
                                    validatorCodigoInicial.focus();
                                },
                                alertBehavior.warning,
                                function () {
                                    $("#modalFiltro").modal("hide");
                                });
                            return false;
                        }

                        if (!validatorCodigoInicial.all && validatorCodigoFinal.all) {
                            u.dialogOk("Favor insira o código final", null, true,
                                function () {
                                    $("#modalFiltro").modal("show");
                                    validatorCodigoFinal.focus();
                                },
                                alertBehavior.warning,
                                function () {
                                    $("#modalFiltro").modal("hide");
                                });
                            return false;
                        }

                        return true;
                    }

                    function saveFilters() {
                        var filter = {};
                        filter.inputCodigoFilialInicial = validatorCodigoInicial.getValue();
                        filter.inputCodigoFilialFinal = validatorCodigoFinal.getValue();
                        filter.inputIdentificacao = getVal("inputIdentificacao");
                        filter.inputRazaoSocial = getVal("inputRazaoSocial");
                        filter.inputTipoPessoa = getVal("inputTipoPessoa");
                        filter.inputCNPJCPF = getVal("inputCNPJCPF");

                        var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource(filter));
                        grid.setDataSource(dataSource);

                        currentUser.setSessionData("filtro_EmpresasFiliais", JSON.stringify(filter));
                    }

                    // para carregar a grid com os dados ja filtrados
                    loadFilters();
                })(params);
            },

            CadastrosFilial: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var defaultSituacao = null;

                    request(
                        "Empresarial/Filiais/GetFilial", { codigo: params.codigo },
                        function (model) {
                            if (model.IsAlert) {
                                u.alert(model.Message, alertBehavior.warning);
                            } else {
                                setVal("inputInformacoesCodigo", model.Codigo);

                                if (model.IsAtiva) {
                                    setChecked("inputInformacoesAtiva", true);
                                    defaultSituacao = "a";
                                }
                                else {
                                    setChecked("inputInformacoesInativa", true);
                                    defaultSituacao = "i";
                                }
                                if (model.TemPermissao_DF_ATIVAR_FILIAIS) {
                                    $("#inputInformacoesAtiva").removeAttr("disabled");
                                    $("#inputInformacoesInativa").removeAttr("disabled");
                                }

                                setVal("inputInformacoesRazaoSocial", model.RazaoSocial);
                                setVal("inputInformacoesIdentificacao", model.Identificacao);
                                setVal("inputInformacoesCNPJCPF", model.CNPJCPF);

                                setVal("inputInformacoesCEP", model.CEP);
                                setVal("inputInformacoesEndereco", model.Rua);
                                setVal("inputInformacoesNumero", model.Numero);
                                setVal("inputInformacoesComplemento", model.Complemento);
                                setVal("inputInformacoesBairro", model.Bairro);
                                setVal("inputInformacoesMunicipio", model.CodigoMunicipio);
                                setHtml("descriptionInformacoesMunicipio", model.NomeMunicipio);

                                setVal("inputInformacoesDDD", model.DDD);
                                setVal("inputInformacoesTelefone", model.Telefone);
                                setVal("inputInformacoesCelular", model.Celular);
                                setVal("inputInformacoesFax", model.Fax);
                                setVal("inputInformacoesEmail", model.Email);
                                setVal("inputInformacoesHomepage", model.Homepage);
                            }
                        }
                    );

                    function changeSituacao() {
                        if (defaultSituacao === "a" && isChecked("inputInformacoesInativa") || defaultSituacao === "i" && isChecked("inputInformacoesAtiva")) {
                            return true;
                        }
                        else {
                            return false;
                        }
                    }

                    // botoes tela
                    byId("buttonOK").onclick = function () {
                        if (!$("#buttonOK").attr("disabled")) {
                            if (changeSituacao()) {
                                requestNoAsync(window.baseUrl + "Empresarial/Filiais/AtivaDesativaFilial", { codigo: getVal("inputInformacoesCodigo") },
                                    function (data) {
                                        $("#waiting").hide();
                                        if (data.IsAlert) {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        } else {
                                            window.location.href = window.baseUrl + "Empresarial/Filiais/Filiais";
                                        }
                                    },
                                    function (data) {
                                        $("#waiting").hide();
                                    }, true
                                );
                            }
                            else {
                                window.location.href = window.baseUrl + "Empresarial/Filiais/Filiais";
                            }
                        }
                    }

                    byId("buttonCancelar").onclick = function () {
                        if (changeSituacao()) {
                            u.dialog(
                                null,
                                "Deseja realmente abandonar as alterações?",
                                function () {
                                    window.location.href = window.baseUrl + "Empresarial/Filiais/Filiais";
                                }
                            );
                        }
                        else {
                            window.location.href = window.baseUrl + "Empresarial/Filiais/Filiais";
                        }
                    }
                })(params);
            },

            RelatoriosPlanoEmpresarial: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // contabil
                    var inputCodigoContaContabil = new ValidatorLookup({
                        abrev: "CodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        msgPendencyMessagePartEnd: "da Conta Contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        routeTable: "Empresarial/F4ContaContabil/GetContasContabeis",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Plano Empresarial",
                        optionsModal: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                            TipoConta: "T"
                        }
                    });

                    // relatorio
                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Empresarial/Relatorios/GetModelosPlanoEmpresarial"
                    });
                    inputRelatorio.make();

                    // rotinas
                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("emp_rel_planoempresarial");
                    if (inputs === null || inputs === "") {
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputCodigoContaContabil.setValue(inputs.ContaContabil);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            ContaContabil: inputCodigoContaContabil.getValue()
                        }
                        currentUser.setCustomData("emp_rel_planoempresarial", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Empresarial/Relatorios/GeraRelatorioPlanoEmpresarial?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&ContaContabil=" + getVal("inputCodigoContaContabil")
                        );
                    });
                })(params);
            },

            RelatoriosPlanoGerencial: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // gerencial
                    var inputCodigoContaGerencial = new ValidatorLookup({
                        abrev: "CodigoContaGerencial",
                        fieldSearch: "CodigoContaGerencial",
                        msgPendencyMessagePartEnd: "da Conta Gerencial.",
                        route: "Empresarial/F4ContaGerencial/GetContaGerencial",
                        routeTable: "Empresarial/F4ContaGerencial/GetContasGerenciais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Plano Gerencial",
                        optionsModal: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaGerencial/GetClassesPai",
                            TipoConta: "T"
                        }
                    });

                    // relatorio
                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Empresarial/Relatorios/GetModelosPlanoGerencial"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("emp_rel_planogerencial");
                    if (inputs === null || inputs === "") {
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputCodigoContaGerencial.setValue(inputs.ContaGerencial);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            ContaGerencial: inputCodigoContaGerencial.getValue()
                        }
                        currentUser.setCustomData("emp_rel_planogerencial", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Empresarial/Relatorios/GeraRelatorioPlanoGerencial?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&ContaGerencial=" + getVal("inputCodigoContaGerencial")
                        );
                    });
                })(params);
            },

            Propriedades: function (params) {
                return (function () {
                    // TODO: nao esta sendo usado no momento
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("empresarial_propriedades");
                    if (inputs === null || inputs === "") {
                    }
                    else {
                        inputs = JSON.parse(inputs);
                    }
                })(params);
            },
        };
    })();

    Contabil.Manager = (function () {
        return {
            MovimentosLancamentos: function (params) {
                return (function () {
                    msgWait.show();
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // grid
                    var grid = new Table({
                        id: "gridLancamentos",
                        route: window.baseUrl + "Contabil/Movimentos/GetLancamentos",
                        showFilter: false,
                        columns: [
                            { title: "Chave", field: "Chave", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Data", field: "Data", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Débito", field: "CodigoContaDebito", width: 70, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Crédito", field: "CodigoContaCredito", width: 70, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Valor", field: "Valor", width: 70, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Histórico", field: "CodigoContaHistorico", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Filial", field: "IdFilial", width: 50, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: "Documento", field: "IdDocumento", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } }
                        ],
                        toolbar:
                            "<span style='float: left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Lançamentos</span>" +
                            "</span>" +
                            "<span style='float: right'>" +
                            "    <button id='inputFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'>Atualiza</span>Filtro" +
                            "    </button>" +
                            "</span>",
                        dataSourceType: "Filtered",
                        pageable: {
                            refresh: true,
                            numeric: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        onChange: function () {
                            "use strict";
                            var self = this;
                            var $data = self.getSelectedData();
                            window.location = window.baseUrl + "Contabil/Movimentos/Lancamento?id=" + $data.Id + "&dataEmissao=" + $data.Data;
                        },
                        onDataBound: function () {
                            "use strict";
                            var self = this;
                            $("#" + self.id + " table tr").on("dblclick",
                                function () {
                                    var data = self.getSelectedData();
                                }
                            );
                            var el = $("#" + self.id + " .k-grid-content");
                            el[0].style.height = "auto";
                            msgWait.hide();
                        }
                    });
                    grid.make();
                    //grid.listen();

                    // filters fields

                    // chave inicial
                    var inputFilterChaveInicial = new ValidatorMask({
                        idInput: "inputFilterChaveInicial",
                        mask: "chave"
                    });

                    $("#inputFilterChaveInicial").on("blur", function () {
                        if (getVal("inputFilterChaveInicial") && !getVal("inputFilterChaveFinal")) {
                            setVal("inputFilterChaveFinal", getVal("inputFilterChaveInicial"));
                        }
                    });

                    // chave final
                    var inputFilterChaveFinal = new ValidatorMask({
                        idInput: "inputFilterChaveFinal",
                        mask: "chave"
                    });

                    // data inicial
                    var inputFilterDataInicial = new DateValidator({
                        id: "inputFilterDataInicial",
                        v2: true,
                        forceToStayFieldWhereErro: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                            if (!inputFilterDataFinal.getValue()) {
                                inputFilterDataFinal.setValue(inputFilterDataInicial.getValue());
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            validator.focus();
                        },
                        onEmpty: function () {
                        }
                    });

                    // data final
                    var inputFilterDataFinal = new DateValidator({
                        id: "inputFilterDataFinal",
                        v2: true,
                        forceToStayFieldWhereErro: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            validator.focus();
                        },
                        onEmpty: function () {
                        }
                    });

                    var compareFilterDataInicial_FilterDataFinal = new DateComparer({
                        idA: "inputFilterDataInicial",
                        idB: "inputFilterDataFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // documento inicial
                    $("#inputFilterDocumentoInicial").on("blur", function () {
                        if (!getVal("inputFilterDocumentoFinal")) {
                            setVal("inputFilterDocumentoFinal", getVal("inputFilterDocumentoInicial"));
                        }
                    });

                    // contabil
                    var inputFilterCodigoContaContabil = new ValidatorLookup({
                        abrev: "FilterCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        msgPendencyMessagePartEnd: "da Conta Contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        routeTable: "Empresarial/F4ContaContabil/GetContasContabeis",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        idModalHideShow: "modalFiltro",
                        titleModal: "Plano Empresarial",
                        optionsModal: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai"
                        },
                        onValid: function (data, validatorAtual) {
                            if (data.Tipo !== "A") {
                                u.alert("Conta deve ser do tipo analítica ou subanalítica", alertBehavior.warning);
                                validatorAtual.clear({ error: true });
                                validatorAtual.update();
                            }
                        }
                    });

                    // historico
                    var inputFilterCodigoHistorico = new ValidatorLookup({
                        abrev: "FilterCodigoHistorico",
                        fieldSearch: "CodigoHistorico",
                        fieldCode: "Codigo",
                        msgPendencyMessagePartEnd: "do Histórico.",
                        route: "Empresarial/F4Historico/GetHistorico",
                        routeTable: "Empresarial/F4Historico/GetHistoricos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Descrição", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        idModalHideShow: "modalFiltro",
                        titleModal: "Relação de Históricos"
                    });

                    // filial
                    var inputFilterCodigoFilial = new ValidatorLookup({
                        abrev: "FilterCodigoFilial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        routeTable: "Empresarial/F4Filial/GetFiliais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais",
                        idModalHideShow: "modalFiltro"
                    });

                    // filters listen
                    $("#inputFilter").click(function () {
                        //loadFilters(false);
                        $("#modalFiltro").modal("show");

                        getJsonFromRoute("Contabil/Movimentos/GetRangeDatas").done(
                            function (data) {
                                inputFilterDataInicial.setValue(data.DataInicial);
                                inputFilterDataFinal.setValue(data.DataFinal);
                            }
                        );

                        $("#inputFilterChaveInicial").focus();
                    });

                    $("#doFilter").click(function () {
                        saveFilters();
                        $("#modalFiltro").modal("hide");
                    });

                    $("#removeFilter").click(function () {
                        setFiltroDefault(false);
                    });

                    $("#modalFiltro").on("hidden", function () {
                        // TODO:
                        // quando o campo data esta com um valor invalido, ele fica em vermelho,
                        // se precionar a tecla "esc" para sair da tela do filtro, se voltar para o
                        // filtro logo em seguida, o campo continua vermelho e vazio, o comando
                        // abaixo forca o campo a ficar normal
                        if (!inputFilterDataInicial.isValid) {
                            inputFilterDataInicial.setValue("");
                        }
                        if (!inputFilterDataFinal.isValid) {
                            inputFilterDataFinal.setValue("");
                        }

                        // TODO:
                        // se precionar a tecla "esc" para sair da tela do filtro, e o campo data
                        // estiver com o foco, esconde a tela do filtro e o calendario do campo
                        // data continua na tela, o comando abaixo forca o calendario a sumir
                        $("#datepicker").css("display", "none");
                    });

                    // filters functions
                    function loadFilters(setGrid) {
                        var filter = JSON.parse(currentUser.getSessionData("filters_con_con_lanc"));
                        if (filter != null) {

                            // se possuir apenas uma filial ativa, nao deixar selecionar a filial, igual desktop
                            if (params.QuantidadeFiliaisAtivas === "1") {
                                filter.inputFilterCodigoFilial = "";
                                inputFilterCodigoFilial.setValues("", "");
                                inputFilterCodigoFilial.disable();
                            }

                            setFiltroInFields(filter);

                            if (setGrid) {
                                var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource(filter));
                                grid.setDataSource(dataSource);
                            }
                        }
                        else {
                            setFiltroDefault(setGrid);
                        }
                    }

                    function setFiltroDefault(setGrid) {
                        var filtroDefault = {
                            inputFilterChaveInicial: inputFilterChaveInicial.getDefaultValue(),
                            inputFilterChaveFinal: inputFilterChaveFinal.getDefaultValue(),
                            inputFilterDataInicial: "",
                            inputFilterDataFinal: "",
                            inputFilterDocumentoInicial: "",
                            inputFilterDocumentoFinal: "",
                            inputFilterCodigoContaContabil: "",                            
                            inputFilterCodigoHistorico: "",
                            inputFilterComplemento: "",
                            inputFilterCodigoFilial: "",
                            inputFilterIFRS: false
                        };

                        // se possuir apenas uma filial ativa, nao deixar selecionar a filial, igual desktop
                        if (params.QuantidadeFiliaisAtivas === "1") {
                            filtroDefault.inputFilterCodigoFilial = "";
                            inputFilterCodigoFilial.setValues("", "");
                            inputFilterCodigoFilial.disable();
                        }

                        setFiltroInFields(filtroDefault);

                        if (setGrid) {
                            var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource());
                            grid.setDataSource(dataSource);

                            currentUser.setSessionData("filters_con_con_lanc", JSON.stringify(filtroDefault));
                        }
                    }

                    function setFiltroInFields(filter) {
                        setVal("inputFilterChaveInicial", filter.inputFilterChaveInicial);
                        setVal("inputFilterChaveFinal", filter.inputFilterChaveFinal);
                        setVal("inputFilterDataInicial", filter.inputFilterDataInicial);
                        setVal("inputFilterDataFinal", filter.inputFilterDataFinal);
                        setVal("inputFilterDocumentoInicial", filter.inputFilterDocumentoInicial);
                        setVal("inputFilterDocumentoFinal", filter.inputFilterDocumentoFinal);
                        setVal("inputFilterComplemento", filter.inputFilterComplemento);
                        setChecked("inputFilterIFRS", filter.inputFilterIFRS);

                        if (filter.inputFilterCodigoContaContabil === "")
                            inputFilterCodigoContaContabil.clear();
                        else
                            inputFilterCodigoContaContabil.setValueValidate(filter.inputFilterCodigoContaContabil);

                        if (filter.inputFilterCodigoHistorico === "")
                            inputFilterCodigoHistorico.clear();
                        else
                            inputFilterCodigoHistorico.setValueValidate(filter.inputFilterCodigoHistorico);

                        if (filter.inputFilterCodigoFilial === "")
                            inputFilterCodigoFilial.clear();
                        else
                            inputFilterCodigoFilial.setValueValidate(filter.inputFilterCodigoFilial);
                    }

                    function saveFilters() {
                        var filter = {};
                        filter.inputFilterChaveInicial = getVal("inputFilterChaveInicial");
                        filter.inputFilterChaveFinal = getVal("inputFilterChaveFinal");
                        filter.inputFilterDataInicial = getVal("inputFilterDataInicial");
                        filter.inputFilterDataFinal = getVal("inputFilterDataFinal");
                        filter.inputFilterDocumentoInicial = getVal("inputFilterDocumentoInicial");
                        filter.inputFilterDocumentoFinal = getVal("inputFilterDocumentoFinal");
                        filter.inputFilterCodigoContaContabil = inputFilterCodigoContaContabil.getValue();
                        filter.inputFilterCodigoHistorico = inputFilterCodigoHistorico.getValue();
                        filter.inputFilterComplemento = getVal("inputFilterComplemento");
                        filter.inputFilterCodigoFilial = inputFilterCodigoFilial.getValue();
                        filter.inputFilterIFRS = isChecked("inputFilterIFRS");

                        var dataSource = new kendo.data.DataSource(grid.getFilteredDataSource(filter));
                        grid.setDataSource(dataSource);

                        currentUser.setSessionData("filters_con_con_lanc", JSON.stringify(filter));
                    }

                    // para carregar a grid com os dados ja filtrados
                    loadFilters(true);
                })(params);
            },

            MovimentosLancamento: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    requestNoAsync(window.baseUrl + "Contabil/Movimentos/GetLancamento",
                        {
                            id: params.id,
                            dataEmissao: params.dataEmissao
                        },
                        function (model) {
                            if (model.IsAlert) {
                                u.alert(model.Message, alertBehavior.warning);
                            } else {
                                setVal("inputGeralChave", model.Chave);
                                setVal("inputGeralDocumento", model.Documento);
                                setVal("inputGeralValor", model.Valor);
                                setVal("inputGeralData", model.Data);
                                setChecked("inputGeralIFRS", model.Ifrs);
                                setHtml("descriptionGeralData", model.DiaDaSemana);
                                setVal("inputGeralCodigoFilial", model.CodigoFilial);
                                setHtml("descriptionGeralCodigoFilial", model.NomeFilial);
                                setVal("inputGeralContaDebito", model.CodigoDebito);
                                setHtml("descriptionGeralContaDebito", model.ClassificacaoDebito + " " + model.NomeDebito);
                                setVal("inputGeralContaCredito", model.CodigoCredito);
                                setHtml("descriptionGeralContaCredito", model.ClassificacaoCredito + " " + model.NomeCredito);
                                setVal("inputGeralHistorico", model.CodigoHistorico);
                                setVal("inputGeralComplemento", model.Complemento);
                            }
                        }
                    );

                    byId("buttonCancelar").onclick = function () {
                        window.location.href = window.baseUrl + "Contabil/Movimentos/Lancamentos";
                    }
                })(params);
            },

            ConsultasSaldoContabil: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // conta contabil
                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da Conta Contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                            validatorContaContabil.update();
                            executaConsulta();
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                            zeraCampos();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                            zeraCampos();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var options = {
                        useClassePai: true,
                        ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai"
                    }
                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, options).listen();

                    // periodo
                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                            else {
                                executaConsulta();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                            else {
                                executaConsulta();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_con_saldocontail");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    } else {
                        inputs = JSON.parse(inputs);
                        validatorContaContabil.setValue(inputs.ContaContabil);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                    }

                    function zeraCampos() {
                        if (validatorContaContabil.invalid || !inputPeriodoInicial.isValid || !inputPeriodoFinal.isValid) {
                            setHtml("spanSaldoAnterior", "");
                            setHtml("spanDebitos", "");
                            setHtml("spanCreditos", "");
                            setHtml("spanSaldoAtual", "");
                        }
                    }

                    function executaConsulta() {
                        if (!validatorContaContabil.invalid && inputPeriodoInicial.isValid && inputPeriodoFinal.isValid) {
                            inputs = {
                                ContaContabil: validatorContaContabil.getValue(),
                                PeriodoInicial: inputPeriodoInicial.getValue(),
                                PeriodoFinal: inputPeriodoFinal.getValue()
                            }
                            currentUser.setCustomData("con_con_saldocontail", JSON.stringify(inputs));

                            request(
                                "Contabil/Consultas/GetSaldoContabil", {
                                    ContaContabil: getVal("inputCodigoContaContabil"),
                                    DataInicial: getVal("inputPeriodoInicial"),
                                    DataFinal: getVal("inputPeriodoFinal")
                                },
                                function (model) {
                                    if (model.IsAlert) {
                                        zeraCampos();
                                        u.alert(model.Message, alertBehavior.warning);
                                    } else {
                                        setHtml("spanSaldoAnterior", model.SaldoAnterior);
                                        setHtml("spanDebitos", model.Debitos);
                                        setHtml("spanCreditos", model.Creditos);
                                        setHtml("spanSaldoAtual", model.SaldoAtual);
                                    }
                                }
                            );
                        }
                    }
                })(params);
            },

            ConsultasAcompanhamento: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // conta contabil
                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                            validatorContaContabil.update();
                            executaConsulta();
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                            zeraCampos();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                            zeraCampos();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var options = {
                        useClassePai: true,
                        ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai"
                    }
                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, options).listen();

                    // periodo
                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isMMAAAA: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePickerMMAAAA("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDateDDMMYYYY() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                            else {
                                executaConsulta();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isMMAAAA: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePickerMMAAAA("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDateDDMMYYYY() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                            else {
                                executaConsulta();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        isMMAAAA: true,
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    $("#inputDiario").on("change", function () {
                        if (!validatorContaContabil.invalid && inputPeriodoInicial.isValid && inputPeriodoFinal.isValid)
                            executaConsulta();
                    });

                    // grid

                    var gridResultado = new Table({
                        "id": "gridResultado",
                        "pageable": false,
                        "columns": [
                            { field: "Data", title: "Data", width: 40, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "Debitos", title: "Débitos", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Creditos", title: "Créditos", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: right;" } },
                            { field: "SaldoAtual", title: "Saldo Atual", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: right;" } }
                        ],
                        "dataSourceType": "Object"
                    });
                    gridResultado.make();

                    // formata os heads da grid
                    var selector_Header = ".acompanhamento > fieldset > .radar-row > .radar-control > .control-group > .controls > label";
                    var cssgridResultado_Header = {
                        "font-family": $(selector_Header).css("font-family"),
                        "font-size": $(selector_Header).css("font-size"),
                        "font-weight": $(selector_Header).css("font-weight"),
                        "color": $(selector_Header).css("color"),
                    }
                    $("#gridResultado > .k-grid-header > .k-grid-header-wrap > table > thead > tr > th > .k-link ").css(cssgridResultado_Header);

                    // seta a altura do grid
                    $("#gridResultado .k-grid-content").height(500);

                    // valores padroes / ultimos filtros usados
                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_con_acompanhamento");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        validatorContaContabil.setValue(inputs.ContaContabil);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        setChecked("inputDiario", inputs.Diario);
                    }

                    function zeraCampos() {
                        if (validatorContaContabil.invalid || !inputPeriodoInicial.isValid || !inputPeriodoFinal.isValid) {
                            setHtml("spanSaldoAnterior", "");
                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridResultado").data("kendoGrid").setDataSource(data);
                        }
                    }

                    function executaConsulta() {
                        if (!validatorContaContabil.invalid && inputPeriodoInicial.getValue() && inputPeriodoInicial.isValid && inputPeriodoFinal.getValue() && inputPeriodoFinal.isValid) {
                            inputs = {
                                ContaContabil: validatorContaContabil.getValue(),
                                PeriodoInicial: inputPeriodoInicial.getValue(),
                                PeriodoFinal: inputPeriodoFinal.getValue(),
                                Diario: isChecked("inputDiario")
                            }
                            currentUser.setCustomData("con_con_acompanhamento", JSON.stringify(inputs));

                            request(
                                "Contabil/Consultas/GetAcompanhamento", {
                                    ContaContabil: getVal("inputCodigoContaContabil"),
                                    DataInicial: getVal("inputPeriodoInicial"),
                                    DataFinal: getVal("inputPeriodoFinal"),
                                    Diario: isChecked("inputDiario")
                                },
                                function (model) {
                                    if (model.IsAlert) {
                                        zeraCampos();
                                        u.alert(model.Message, alertBehavior.warning);
                                    } else {
                                        setHtml("spanSaldoAnterior", model.SaldoAnterior);
                                        var data = new kendo.data.DataSource({ data: [] });

                                        for (var atual in model.Saldos) {
                                            data.options.data.push({
                                                Data: model.Saldos[atual].Data,
                                                Debitos: model.Saldos[atual].Debitos,
                                                Creditos: model.Saldos[atual].Creditos,
                                                SaldoAtual: model.Saldos[atual].SaldoAtual
                                            });
                                        }

                                        $("#gridResultado").data("kendoGrid").setDataSource(data);
                                    }
                                }
                            );
                        }
                    }
                })(params);
            },

            RelatoriosBalancete: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // data inicial
                    var inputPeriodoInicial = new ValidatorDate({
                        idInput: "inputPeriodoInicial",
                        isEmptyValid: true,
                        onValid: function (validator) {
                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.dialogOk("Data fora do limite do período contábil.", null, true, function () {
                                    inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                    inputPeriodoInicial.clear();
                                    inputPeriodoInicial.focus();
                                }, alertBehavior.warning);
                            }
                        }
                    });

                    // data final
                    var inputPeriodoFinal = new ValidatorDate({
                        idInput: "inputPeriodoFinal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial do periodo deve ser anterior à data final.",
                        isEmptyValid: true,
                        onValid: function (validator) {
                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.dialogOk("Data fora do limite do período contábil.", null, true, function () {
                                    inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                    inputPeriodoFinal.clear();
                                    inputPeriodoFinal.focus();
                                }, alertBehavior.warning);
                            }
                        }
                    });

                    // conta contabil
                    var inputCodigoContaContabil = new ValidatorLookup({
                        abrev: "CodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        msgPendencyMessagePartEnd: "da Conta Contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        routeTable: "Empresarial/F4ContaContabil/GetContasContabeis",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Plano Empresarial",
                        optionsModal: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                        },
                        ModalGrupoContas: true
                    });

                    // totaliza pra cima
                    var inputTotalizaPraCima = $("#inputTotalizaPraCima").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Total acima" },
                            { Value: "1", Text: "Total abaixo" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "1"
                    });

                    // oculta a linha interado do inputMostrarContasSubAnaliticas
                    document.getElementById("inputMostrarContasSubAnaliticas").disabled = !params.MostrarContasSubanaliticas;

                    // relatorio
                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosBalancete"
                    });
                    inputRelatorio.make();

                    // rotinas
                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_balancete");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputCodigoContaContabil.setGrupoContasOuConta(inputs.ContaContabil);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        inputTotalizaPraCima.data().kendoDropDownList.select(inputs.TotalizaPraCima.toInt());
                        setChecked("inputMostrarContasSubAnaliticas", inputs.MostrarContasSubAnaliticas);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            ContaContabil: inputCodigoContaContabil.getGrupoContasOuConta(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            TotalizaPraCima: inputTotalizaPraCima.val(),
                            MostrarContasSubAnaliticas: isChecked("inputMostrarContasSubAnaliticas")
                        }
                        currentUser.setCustomData("con_rel_balancete", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioBalancete?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&ContaContabil=" + inputCodigoContaContabil.getGrupoContasStringOuConta()
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&TotalizaPraCima=" + (getVal("inputTotalizaPraCima") === "0" ? true : false)
                            + "&MostrarContasSubAnaliticas=" + isChecked("inputMostrarContasSubAnaliticas")
                        );
                    });
                })(params);
            },

            RelatoriosRazao: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "Nome",
                        linkButton: "linkButtonModalContaContabil",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasContaContabil",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, {
                            validatorInput: validatorContaContabil,
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                            onHidden: function () {
                            }
                        }
                     ).listen();

                    var modalGrupoContasContaContabil = new ModalGrupoContas({
                        id: "ContaContabil",
                        validatorInput: validatorContaContabil,
                        validatorConta: {
                            fieldSearch: "CodigoContaContabil",
                            onPendencyMessage: "Deve ser informado o código da conta contábil.",
                            route: "Empresarial/F4ContaContabil/GetContaContabil",
                            v2: "v3",
                            fieldNome: "Nome"
                        },
                        tableConta: {
                            route: window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        },
                        modalConta: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                        },
                        onShow: function () {
                        },
                        onHidden: function () {
                        }
                    });

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosRazao"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_razao");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);

                        // filtro unico
                        if (typeof inputs.ContaContabil === 'string') {
                            validatorContaContabil.setValue(inputs.ContaContabil);
                        }
                        else {
                            // filtro GrupoContas
                            validatorContaContabil.setGrupoContasLista(inputs.ContaContabil);
                            validatorContaContabil.setVarios(true);
                        }

                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            ContaContabil: validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasLista() : validatorContaContabil.getValue(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue()
                        }
                        currentUser.setCustomData("con_rel_razao", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioRazao?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&ContaContabil=" + (validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasString() : getVal("inputCodigoContaContabil"))
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                        );
                    });
                })(params);
            },

            RelatoriosDiarioDetalhado: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "Nome",
                        linkButton: "linkButtonModalContaContabil",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasContaContabil",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, {
                            validatorInput: validatorContaContabil,
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                            onHidden: function () {
                            }
                        }
                     ).listen();

                    var modalGrupoContasContaContabil = new ModalGrupoContas({
                        id: "ContaContabil",
                        validatorInput: validatorContaContabil,
                        validatorConta: {
                            fieldSearch: "CodigoContaContabil",
                            onPendencyMessage: "Deve ser informado o código da conta contábil.",
                            route: "Empresarial/F4ContaContabil/GetContaContabil",
                            v2: "v3",
                            fieldNome: "Nome"
                        },
                        tableConta: {
                            route: window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        },
                        modalConta: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                        },
                        onShow: function () {
                        },
                        onHidden: function () {
                        }
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosDiarioDetalhado"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_diariodetalhado");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(params.DataInferiorIntegracao);
                        inputPeriodoFinal.setValue(params.DataSuperiorIntegracao);
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);

                        // filtro unico
                        if (typeof inputs.ContaContabil === 'string') {
                            validatorContaContabil.setValue(inputs.ContaContabil);
                        }
                        else {
                            // filtro GrupoContas
                            validatorContaContabil.setGrupoContasLista(inputs.ContaContabil);
                            validatorContaContabil.setVarios(true);
                        }

                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                    }

                    $("#buttonOK").on("click", function () {
                        if (!inputPeriodoInicial.isValid) {
                            u.alert("Informe uma data inicial válida.", alertBehavior.warning);
                            $(inputPeriodoInicial).focus();
                        }
                        else if (!inputPeriodoFinal.isValid) {
                            u.alert("Informe uma data final válida.", alertBehavior.warning);
                            $(inputPeriodoFinal).focus();
                        }
                        else if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao) || inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                            u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                            $(inputPeriodoInicial).focus();
                        }
                        else {
                            inputs = {
                                Relatorio: inputRelatorio.get(),
                                ContaContabil: validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasLista() : validatorContaContabil.getValue(),
                                PeriodoInicial: inputPeriodoInicial.getValue(),
                                PeriodoFinal: inputPeriodoFinal.getValue()
                            }
                            currentUser.setCustomData("con_rel_diariodetalhado", JSON.stringify(inputs));

                            window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioDiarioDetalhado?"
                                + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                                + "&ContaContabil=" + (validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasString() : getVal("inputCodigoContaContabil"))
                                + "&DataInicial=" + getVal("inputPeriodoInicial")
                                + "&DataFinal=" + getVal("inputPeriodoFinal")
                            );
                        }
                    });
                })(params);
            },

            RelatoriosAcompanhamentoMensal: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "Nome",
                        linkButton: "linkButtonModalContaContabil",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasContaContabil",
                        onValid: function (data) {
                            if (data.Tipo !== "T") {
                                u.alert("Conta deve ser do tipo \"Título\".", alertBehavior.warning);
                                validatorContaContabil.clear({ error: true });
                                validatorContaContabil.update();
                            }
                            else {
                                $("#inputCodigoContaContabil").val(data.Codigo);
                                $("#descriptionCodigoContaContabil").html(data.Nome);
                            }
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, {
                            validatorInput: validatorContaContabil,
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai"
                        }
                     ).listen();

                    var modalGrupoContasContaContabil = new ModalGrupoContas({
                        id: "ContaContabil",
                        validatorInput: validatorContaContabil,
                        validatorConta: {
                            fieldSearch: "CodigoContaContabil",
                            onPendencyMessage: "Deve ser informado o código da conta contábil.",
                            route: "Empresarial/F4ContaContabil/GetContaContabil",
                            v2: "v3",
                            fieldNome: "Nome",
                            onValid: function (data, validatorAtual) {
                                if (data.Tipo !== "T") {
                                    u.alert("Conta deve ser do tipo título", alertBehavior.warning);
                                    validatorAtual.clear({ error: true });
                                    validatorAtual.update();
                                }
                            }
                        },
                        tableConta: {
                            route: window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        },
                        modalConta: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai",
                        },
                        onShow: function () {
                        },
                        onHidden: function () {
                        }
                    });

                    var inputMesAno = new DateValidator({
                        id: "inputMesAno",
                        v2: true,
                        isMMAAAA: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePickerMMAAAA("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputMesAno.getValueDateDDMMYYYY() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao) || inputMesAno.getValueDateDDMMYYYY() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputMesAno.alterBehavior(controlGroupBehavior.warning);
                                inputMesAno.setValue("");
                                $(inputMesAno).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var inputTotalizaPraCima = $("#inputTotalizaPraCima").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Total acima" },
                            { Value: "1", Text: "Total abaixo" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "1"
                    });

                    var inputTipoValor = $("#inputTipoValor").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Débitos" },
                            { Value: "1", Text: "Créditos" },
                            { Value: "2", Text: "Movimentos" },
                            { Value: "3", Text: "Saldo" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0"
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosAcompanhamentoMensal"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_acompanhamentomensal");
                    if (inputs === null || inputs === "") {
                        inputMesAno.setValue(getDateNowMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);

                        // filtro unico
                        if (typeof inputs.ContaContabil === 'string') {
                            validatorContaContabil.setValue(inputs.ContaContabil);
                        }
                        else {
                            // filtro GrupoContas
                            validatorContaContabil.setGrupoContasLista(inputs.ContaContabil);
                            validatorContaContabil.setVarios(true);
                        }

                        inputMesAno.setValue(inputs.MesAno);
                        inputTotalizaPraCima.data().kendoDropDownList.select(inputs.TotalizaPraCima.toInt());
                        inputTipoValor.data().kendoDropDownList.select(inputs.TipoValor.toInt());
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            ContaContabil: validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasLista() : validatorContaContabil.getValue(),
                            MesAno: inputMesAno.getValue(),
                            TotalizaPraCima: inputTotalizaPraCima.val(),
                            TipoValor: inputTipoValor.val()
                        }
                        currentUser.setCustomData("con_rel_acompanhamentomensal", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioAcompanhamentoMensal?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&ContaContabil=" + (validatorContaContabil.getVarios() ? validatorContaContabil.getGrupoContasString() : getVal("inputCodigoContaContabil"))
                            + "&MesAno=" + getVal("inputMesAno")
                            + "&TotalizaPraCima=" + (getVal("inputTotalizaPraCima") === 0 ? "true" : "false")
                            + "&TipoValor=" + getVal("inputTipoValor")
                        );
                    });
                })(params);
            },

            RelatoriosInversaoGerencialBalancete: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // conta contabil
                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaContabil/GetContaContabil",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaContabil/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var options = {
                        useClassePai: true,
                        ClassePaiURL: "Empresarial/F4ContaContabil/GetClassesPai"
                    }
                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, options).listen();

                    // conta gerencial
                    var validatorContaGerencial = new Validator({
                        field: "inputCodigoContaGerencial",
                        fieldDescriptionId: "descriptionCodigoContaGerencial",
                        fieldSearch: "CodigoContaGerencial",
                        onPendencyMessage: "Deve ser informado o código da conta gerencial.",
                        route: "Empresarial/F4ContaGerencial/GetContaGerencial",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaGerencial").val(data.Codigo);
                            $("#descriptionCodigoContaGerencial").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaGerencial.clear({ error: true });
                            validatorContaGerencial.focus();
                        },
                        onEmpty: function () {
                            validatorContaGerencial.clear();
                        }
                    });
                    validatorContaGerencial.listen();

                    var tableContaGerencial = new Table({
                        "id": "tableContaGerencial",
                        "route": window.baseUrl + "Empresarial/F4ContaGerencial/GetContasGerenciais",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaGerencial.getSelectedData();
                                validatorContaGerencial.onValid(data);
                                validatorContaGerencial.update();
                                $("#modalContaGerencial").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaGerencial").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaGerencial table tr").on("dblclick", function () {
                                var data = tableContaGerencial.getSelectedData();
                                validatorContaGerencial.onValid(data);
                                validatorContaGerencial.update();
                                $("#modalContaGerencial").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaGerencial").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var options = {
                        useClassePai: true,
                        ClassePaiURL: "Empresarial/F4ContaGerencial/GetClassesPai"
                    }
                    var modalContaGerencial = new Modal("Conta Gerencial",
                        byId("linkButtonModalContaGerencial"),
                        byId("inputCodigoContaGerencial"),
                        tableContaGerencial,
                        null, options).listen();

                    // relatorio
                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosInversaoGerencialBalancete"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_inversaogerencialbalancete");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        setVal("inputRelacionamento", inputs.Relacionamento);
                        validatorContaContabil.setValue(inputs.ContaContabil);
                        validatorContaGerencial.setValue(inputs.ContaGerencial);
                        setVal("inputMascaraInvertida", inputs.MascaraInvertida);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            Relacionamento: getVal("inputRelacionamento"),
                            ContaContabil: validatorContaContabil.getValue(),
                            ContaGerencial: validatorContaGerencial.getValue(),
                            MascaraInvertida: getVal("inputMascaraInvertida")
                        }
                        currentUser.setCustomData("con_rel_inversaogerencialbalancete", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioInversaoGerencialBalancete?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&Relacionamento=" + getVal("inputRelacionamento")
                            + "&ContaContabil=" + getVal("inputCodigoContaContabil")
                            + "&ContaGerencial=" + getVal("inputCodigoContaGerencial")
                            + "&MascaraInvertida=" + getVal("inputMascaraInvertida")
                        );
                    });
                })(params);
            },

            RelatoriosGerador: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoInicial.getValueDate() < convertDateStringDDMMYYYYToDate(params.DataInferiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoInicial.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoInicial.setValue("");
                                $(inputPeriodoInicial).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            if (inputPeriodoFinal.getValueDate() > convertDateStringDDMMYYYYToDate(params.DataSuperiorIntegracao)) {
                                u.alert("Data fora do limite do período contábil.", alertBehavior.warning);
                                inputPeriodoFinal.alterBehavior(controlGroupBehavior.warning);
                                inputPeriodoFinal.setValue("");
                                $(inputPeriodoFinal).focus();
                            }
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Contabil/Relatorios/GetModelosGerador"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("con_rel_gerador");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        setVal("inputPaginaInicial", inputs.PaginaInicial);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            PaginaInicial: getVal("inputPaginaInicial")
                        }
                        currentUser.setCustomData("con_rel_gerador", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Contabil/Relatorios/GeraRelatorioGerador?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&PaginaInicial=" + getVal("inputPaginaInicial")
                        );
                    });
                })(params);
            }
        };
    })();

    Comercial.Manager = (function () {
        return {
            MovimentosPedidos: (function (params) {
                return (function () {
                    var u = new Util();
                    currentUser.update(params.User);
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial - Pedidos - Movimentos");

                    // object grid
                    function Grid(options) {
                        this.id = options.id;
                        this.route = options.route;
                        this.columns = options.columns;
                        this.pageable = options.pageable;
                        this.onChange = options.onChange;
                        this.onDataBound = options.onDataBound;
                        this.onDataBinding = options.onDataBinding;
                        this.title = options.title;
                        this.grid = null;
                    }

                    Grid.prototype.make = function () {
                        "use strict";
                        var self = this;
                        $("#" + self.id).kendoGrid({
                            change: function (ev) {
                                var grid = this;

                                var ids = grid.select().map(function () {
                                    return grid.dataItem($(this)).Id;
                                }).toArray();

                                localStorage.setItem('settings_' + self.id + '_rows', JSON.stringify(ids));

                                if (self.onChange) {
                                    self.onChange(ev);
                                }
                                $('#waiting').show();
                            },
                            dataBound: function (ev) {
                                var grid = this;
                                var dataSource = grid.dataSource;

                                var state = kendo.stringify({
                                    page: dataSource.page(),
                                    pageSize: dataSource.pageSize(),
                                    sort: dataSource.sort(),
                                    group: dataSource.group(),
                                    filter: dataSource.filter()
                                });

                                currentUser.setCustomData("settings_" + self.id + "_state", state);
                                if (self.onDataBound) {
                                    self.onDataBound(ev);
                                }
                            },
                            dataBinding: function (ev) {
                                if (self.onDataBinding) {
                                    self.onDataBinding(ev);
                                }
                            },
                            columnReorder: function () {
                                self.saveState(this);
                                self.saveColumns(this);
                            },

                            toolbar: self.title,
                            reorderable: true,
                            resizable: true,
                            filterable: false,
                            selectable: true,
                            columnMenu: true,
                            sortable: {
                                allowUnsort: true
                            },
                            pageable: self.pageable !== undefined ? self.pageable : {
                                refresh: true,
                                numeric: true,
                                pageSizes: [5, 10, 15],
                                buttonCount: 5
                            },
                            columns: self.loadColumns()
                        });

                        self.grid = self.getGrid();
                        self.loadSettings();
                    };

                    Grid.prototype.listen = function () {
                        "use strict";
                        var self = this;
                        $("#" + self.id).on('mousemove', function () {
                            self.saveColumns();
                        });
                    };

                    Grid.prototype.getColumns = function () {
                        "use strict";
                        var self = this;
                        if (localStorage) {
                            var stringyColumns = currentUser.getCustomData("settings_" + self.id + "_columns");
                            var columns = JSON.parse(stringyColumns);
                            return columns;
                        }
                        return null;
                    };

                    Grid.prototype.saveColumns = function (grid) {
                        "use strict";
                        var self = this;
                        setTimeout(function () {
                            if (!grid) {
                                grid = self.grid;
                            }
                            var columns = grid.columns;
                            var stringyColumns = JSON.stringify(columns);
                            if (localStorage) {
                                currentUser.setCustomData("settings_" + self.id + "_columns", stringyColumns);
                            }
                        }, 100);
                    };

                    Grid.prototype.loadColumns = function () {
                        "use strict";
                        var self = this;
                        var result;
                        var columns = self.getColumns();
                        result = columns ? columns : self.columns;
                        return result;
                    };

                    Grid.prototype.getState = function () {
                        "use strict";
                        var self = this;
                        if (localStorage) {
                            return JSON.parse(currentUser.getCustomData("settings_" + self.id + "_state"));
                        }
                        return null;
                    };

                    Grid.prototype.saveState = function (grid) {
                        "use strict";
                        if (localStorage) {
                            var self = this;
                            var dataSource = grid.dataSource;
                            var state = kendo.stringify({
                                page: dataSource.page(),
                                pageSize: dataSource.pageSize(),
                                sort: dataSource.sort(),
                                group: dataSource.group(),
                                filter: dataSource.filter()
                            });
                            currentUser.setCustomData("settings_" + self.id + "_state", state);
                        }
                    };

                    Grid.prototype.loadState = function () {
                        "use strict";
                        var self = this;
                        var dataSource = self.getDataSource();
                        var state = self.getState();
                        if (state) {
                            if (state.filter) {
                                parseFilterDates(state.filter, dataSource.options.schema.model.fields);
                            }
                            dataSource.query(state);
                        } else {
                            dataSource.read();
                        }

                        function parseFilterDates(filter, fields) {
                            if (filter.filters) {
                                for (var i = 0; i < filter.filters.length; i++) {
                                    parseFilterDates(filter.filters[i], fields);
                                }
                            } else {
                                if (fields[filter.field].type == "date") {
                                    filter.value = kendo.parseDate(filter.value);
                                }
                            }
                        }
                    };

                    Grid.prototype.loadSettings = function () {
                        "use strict";
                        var self = this;
                        self.loadState();
                    };

                    Grid.prototype.getSortingOptions = function () {
                        "use strict";
                        var self = this;
                        var data = {};
                        if (self.grid) {
                            if (self.grid.dataSource["_sort"]) {
                                var sortingOptions = self.grid.dataSource['_sort'][0];
                                if (sortingOptions) {
                                    data['Field'] = sortingOptions.field;
                                    data['Sort'] = sortingOptions.dir;
                                }
                            } else {
                                data['Field'] = "DataEmissao";
                                data['Sort'] = "desc";
                            }
                        }
                        return data;
                    };

                    Grid.prototype.getPagingOptions = function (options) {
                        "use strict";
                        var data = {};
                        data['Page'] = options.data.page;
                        data['PageSize'] = options.data.pageSize;
                        data['Skip'] = options.data.skip;
                        data['Take'] = options.data.take;
                        return data;
                    };

                    Grid.prototype.getNormalDataSource = function () {
                        "use strict";
                        var self = this;

                        var defaultPageSize = 10;
                        var state = self.getState();
                        if (state) {
                            defaultPageSize = state.pageSize ? state.pageSize : defaultPageSize;
                        } else {
                            defaultPageSize = self.pageable ? self.pageable.pageSizes[0] : defaultPageSize;
                        }

                        var dataSource = {
                            type: "JSON",
                            transport: {
                                read: function (options) {
                                    var data = {};
                                    data["Sorting"] = self.getSortingOptions();
                                    data["Paging"] = self.getPagingOptions(options);
                                    $.ajax({
                                        headers: {
                                            'Accept': 'application/json',
                                            'Content-Type': 'application/json'
                                        },
                                        url: self.route,
                                        dataType: "json",
                                        type: "POST",
                                        data: JSON.stringify(data),
                                        success: function (result) {
                                            if (result.IsAlert) {
                                                $(".k-loading-mask").remove();
                                                options.success({ data: new Array(), total: 0 });
                                                u.dialogOk(result.Message, null, true, null, alertBehavior.warning);
                                                throw new Error(result.Message);
                                            } else {
                                                options.success(result);
                                            }
                                        },
                                        error: function (result) {
                                            $(".k-loading-mask").remove();
                                            u.dialogOk(result.status + "-" + result.statusText, null, true, null, alertBehavior.warning);
                                        }
                                    });
                                }
                            },
                            schema: {
                                data: 'data',
                                total: 'total'
                            },
                            serverPaging: true,
                            serverSorting: true,
                            pageSize: defaultPageSize
                        };
                        return dataSource;
                    };

                    Grid.prototype.getFilteredDataSource = function (filter) {
                        "use strict";
                        var self = this;

                        var defaultPageSize = 10;
                        var state = self.getState();
                        if (state) {
                            defaultPageSize = state.pageSize ? state.pageSize : defaultPageSize;
                        } else {
                            defaultPageSize = self.pageable ? self.pageable.pageSizes[0] : defaultPageSize;
                        }

                        var dataSource = {
                            type: "JSON",
                            transport: {
                                read: function (options) {
                                    var data = {};
                                    data["Sorting"] = self.getSortingOptions();
                                    data["Filter"] = filter;
                                    data["Paging"] = self.getPagingOptions(options);
                                    $.ajax({
                                        headers: {
                                            'Accept': 'application/json',
                                            'Content-Type': 'application/json'
                                        },
                                        url: window.baseUrl + "Comercial/Movimentos/GetFilteredPedidos",
                                        dataType: "json",
                                        type: "POST",
                                        data: JSON.stringify(data),
                                        success: function (result) {
                                            if (result.IsAlert) {
                                                $(".k-loading-mask").remove();
                                                options.success({ data: new Array(), total: 0 });
                                                u.dialogOk(result.Message, null, true, null, alertBehavior.warning);
                                                throw new Error(result.Message);
                                            } else {
                                                options.success(result);
                                            }
                                        },
                                        error: function (result) {
                                            $(".k-loading-mask").remove();
                                            u.dialogOk(result.status + "-" + result.statusText, null, true, null, alertBehavior.warning);
                                        }
                                    });
                                }
                            },
                            schema: {
                                data: 'data',
                                total: 'total'
                            },
                            serverPaging: true,
                            serverSorting: true,
                            pageSize: defaultPageSize
                        };
                        return dataSource;
                    };

                    Grid.prototype.refresh = function () {
                        "use strict";
                        var self = this;
                        var g = $("#" + self.id).data("kendoGrid");
                        g.dataSource.read();
                    };

                    Grid.prototype.getSelectedData = function () {
                        "use strict";
                        var self = this;
                        var grid = $("#" + self.id).data("kendoGrid");
                        var row = grid.select();
                        return grid.dataItem(row);
                    };

                    Grid.prototype.clearSelectedData = function () {
                        "use strict";
                        var self = this;
                        $("#" + self.id).data("kendoGrid").clearSelection();
                    };

                    Grid.prototype.getDataSource = function () {
                        "use strict";
                        var self = this;
                        return self.getGrid().dataSource;
                    };

                    Grid.prototype.getGrid = function () {
                        "use strict";
                        var self = this;
                        return $("#" + self.id).data("kendoGrid");
                    };

                    Grid.prototype.filters = function (filters) {
                        "use strict";
                        var self = this;
                        var dataSource = self.getDataSource();
                        dataSource.filter(filters);
                        self.refresh();
                    };

                    // titudo grid
                    var titulo = "<span style='float:left; width: NaN;'><span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Pedidos</span></span>";
                    var iconFilter = "<span class='k-icon k-i-funnel'>Atualiza</span>";
                    var inputFilter = "<button id='inputFilter' type='button' class='btn btn-small btn-filtro'>{0} Filtro</button>".format(iconFilter);
                    var incluirPedido = params.Permissoes.PodeIncluirNovoPedido ? "" : "disabled";
                    var iconPlus = "<span class='k-icon k-i-plus'>Atualiza</span>";
                    var inputNewPedido = "<button id='inputNewPedido' type='button' class='btn btn-small btn-filtro' style='float:right' {0}>{1} Novo</button>".format(incluirPedido, iconPlus);
                    var title = "{0}<span style='float:right'>{1}&nbsp{2}</span>".format(titulo, inputFilter, inputNewPedido);

                    // grid pedidos
                    var gridPedidos = new Grid({
                        id: "gridPedidos",
                        route: window.baseUrl + "Comercial/Movimentos/GetPedidos/",
                        columns: [
                            { field: "Numero", title: "Nr. Pedido", headerAttributes: { style: "color: black; font-weight: 800;" }, width: 100 },
                            { field: "Cliente", title: "Cliente", headerAttributes: { style: "color: black; font-weight: 800;" }, width: 120 },
                            { field: "DataEmissao", title: "Emissão", headerAttributes: { style: "color: black; font-weight: 800; text-align: center;" }, width: 90, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "DataEntrega", title: "Data Entrega", headerAttributes: { style: "color: black; font-weight: 800; text-align: center;" }, width: 90, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "Situacao", title: "Situação", headerAttributes: { style: "color: black; font-weight: 800;" }, width: 120 },
                            { field: "ValorTotal", title: "Valor Total&nbsp;", headerAttributes: { style: "color: black; font-weight: 800; text-align: right;" }, width: 90, attributes: { style: "text-align: right;" }, format: "{0:C}" }
                        ],
                        onChange: function () {
                            "use strict";
                            var grid = $("#gridPedidos").data("kendoGrid");
                            var row = grid.select();
                            var data = grid.dataItem(row[0]);

                            setTimeout(function () {
                                $('#waiting').show();
                            }, 200);
                            window.location.href = window.baseUrl + "Comercial/Movimentos/Pedido/" + data.Id;
                        },
                        onDataBound: function () {
                            "use strict";
                            msgWait.hide();
                            $("#gridPedidos table tbody tr").hover(function () {
                                $(this).toggleClass("k-state-hover");
                            });
                            var filter = document.getElementById('inputFilter');
                            filter.onclick = function () {
                                $('#filtroPedidosModal').modal('show');
                            };
                        },
                        pageable: {
                            refresh: true,
                            numeric: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        title: title
                    });
                    gridPedidos.make();
                    gridPedidos.listen();

                    // button novo pedido
                    $("#inputNewPedido").on("click", function () {
                        setTimeout(function () {
                            $('#waiting').show();
                        }, 200);

                        window.location.href = window.baseUrl + "Comercial/Movimentos/NovoPedido/";
                    });

                    // functions
                    function setPermissions() {
                        "use strict";
                        disableNegativePermissionsFields();
                        if (!params.Permissoes.PodeConsultarPedido) {
                            if (!params.Permissoes.PodeAlterarPedido) {
                                desabilitarGrid();
                            }
                        }
                    }

                    function desabilitarGrid() {
                        "use strict";
                        var tables = $('table');
                        var l = tables.length;
                        for (var i = 0; i < l; i = i + 1) {
                            var table = tables[i];
                            if (table.hasAttribute('data-role')) {
                                table.className = "";
                            }

                        }
                    }

                    //
                    // filtro
                    //

                    // data periodo inicial
                    var periodoInicialDateValidator = new ValidatorDate({
                        idInput: "inputPeriodoInicial",
                        idModalHideShow: "filtroPedidosModal",
                        isEmptyValid: true
                    });

                    // data periodo final
                    var periodoFinalDateValidator = new ValidatorDate({
                        idInput: "inputPeriodoFinal",
                        idModalHideShow: "filtroPedidosModal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial do periodo deve ser anterior à data final.",
                        isEmptyValid: true
                    });

                    // data entrega inicial
                    var dataEntregaInicialDateValidator = new ValidatorDate({
                        idInput: "inputDataEntregaInicial",
                        idModalHideShow: "filtroPedidosModal",
                        isEmptyValid: true
                    });

                    // data entrega final
                    var dataEntregaFinalDateValidator = new ValidatorDate({
                        idInput: "inputDataEntregaFinal",
                        idModalHideShow: "filtroPedidosModal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial da entrega deve ser anterior à data final.",
                        isEmptyValid: true
                    });

                    var compareDataEntregaInicialComPeriodoInicial = new DateComparer({
                        idA: 'inputDataEntregaInicial',
                        idB: 'inputPeriodoInicial',
                        verb: 'greater',
                        onInvalid: function (data) {
                            $('#filtroPedidosModal').modal('hide');
                            u.dialogOk('Data de entrega inicial deve ser posterior a data de período inicial.', null, true, function () {
                                $('#filtroPedidosModal').modal('show');
                                dataEntregaInicialDateValidator.clear();
                                dataEntregaInicialDateValidator.focusError();
                            }, alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                            alterControlGroupBehavior(data.idB, controlGroupBehavior.normal);
                        }
                    });

                    // valor inicial/valor final
                    var compareValorInicialComValorFinal = new CurrencyCompararer({
                        idA: 'inputValorInicial',
                        idB: 'inputValorFinal',
                        verb: 'less',
                        onInvalid: function (data) {
                            $('#filtroPedidosModal').modal('hide');
                            u.dialogOk('Valor inicial deve ser menor do que o valor final.', null, true, function () {
                                $('#filtroPedidosModal').modal('show');
                                alterControlGroupBehavior(data.idB, controlGroupBehavior.warning);
                                $("#" + data.idB).val("");
                                $("#" + data.idB).focus();
                            }, alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                            alterControlGroupBehavior(data.idB, controlGroupBehavior.normal);
                        }
                    });

                    // valor inicial
                    $('#inputValorInicial').on('change', function () {
                        $('#inputValorFinal').val(this.value);
                    });

                    // valor final
                    $('#inputValorInicial').on('blur', function () {
                        $('#inputValorFinal').val(this.value);
                    });

                    // numero pedido inicial
                    $('#inputNrPedidoInicial').on('change', function () {
                        $('#inputNrPedidoFinal').val(this.value);
                    });

                    $('#inputNrPedidoInicial').on('blur', function () {
                        $('#inputNrPedidoFinal').val(this.value);
                    });

                    // cliente
                    var validatorCliente = new Validator({
                        field: "inputCodigoCliente",
                        msgDialog: true,
                        idModalHideShow: "filtroPedidosModal",
                        fieldDescriptionId: "descriptionCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        v2: true,
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "RazaoSocial",
                        linkButton: "linkButtonModalClientes",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasClientes",
                        onPendencyMessage: 'Deve ser informado o código do cliente.',
                        route: 'Comercial/F4ClientePedido/GetCliente',
                        onValid: function (data) {
                            document.getElementById("inputCodigoCliente").value = data.Codigo;
                            document.getElementById("descriptionCodigoCliente").innerHTML = data.RazaoSocial;
                        },
                        onInvalid: function (data) {
                            validatorCliente.clear();
                            validatorCliente.focusError();
                        }
                    });
                    validatorCliente.listen();

                    var tableClientes = new Table({
                        'id': 'tableCliente',
                        'msgDialog': true,
                        'idModalHideShow': "filtroPedidosModal",
                        'route': window.baseUrl + "Comercial/F4ClientePedido/GetClientes",
                        'showFilter': true,
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Razão Social', field: 'RazaoSocial', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'CPF/CNPJ', field: 'CnpjCpf', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'columnsLegend': { CnpjCpf: 'Ex: 11.222.333/4444-55' },
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var cliente = tableClientes.getSelectedData();
                                document.getElementById("inputCodigoCliente").value = cliente.Codigo;
                                document.getElementById("descriptionCodigoCliente").innerHTML = cliente.RazaoSocial;
                                $('#modalCliente').modal('hide');
                                $('#filtroPedidosModal').modal('show');
                            };
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalCliente').modal('hide');
                                $('#filtroPedidosModal').modal('show');
                            };
                        },
                        'onDataBound': function () {
                            $('#tableCliente table tr').on('dblclick', function () {
                                var cliente = tableClientes.getSelectedData();
                                document.getElementById("inputCodigoCliente").value = cliente.Codigo;
                                document.getElementById("descriptionCodigoCliente").innerHTML = cliente.RazaoSocial;
                                validatorCliente.update();
                                $('#modalCliente').modal('hide');
                                $('#filtroPedidosModal').modal('show');
                            });
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalCliente').modal('hide');
                                $('#filtroPedidosModal').modal('show');
                            };
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalClientes = document.getElementById('linkButtonModalClientes');
                    var inputClientes = document.getElementById('inputCodigoCliente');

                    var options = {
                        validatorInput: validatorCliente,
                        onHidden: function () {
                            $("#filtroPedidosModal").modal("show");
                        }
                    }
                    var modalClientes = new Modal('Clientes',
                        linkButtonModalClientes,
                        inputClientes,
                        tableClientes,
                        function () {
                            $("#filtroPedidosModal").modal("hide");
                        },
                        options);
                    modalClientes.listen();

                    var modalGrupoContasClientes = new ModalGrupoContas({
                        id: "Clientes",
                        validatorInput: validatorCliente,
                        validatorConta: {
                            fieldSearch: "CodigoCliente",
                            onPendencyMessage: "Deve ser informado o código do cliente.",
                            route: "Comercial/F4ClientePedido/GetCliente",
                            fieldNome: "RazaoSocial"
                        },
                        tableConta: {
                            route: window.baseUrl + "Comercial/F4ClientePedido/GetClientes",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        },
                        onShow: function () {
                            $("#filtroPedidosModal").modal("hide");
                        },
                        onHidden: function () {
                            $("#filtroPedidosModal").modal("show");
                        }
                    });

                    // produto
                    // quando nao informa abrev, assume o padrao inputCodigoProduto/inputCodigoGrade1/inputCodigoGrade2/inputCodigoGrade3
                    var inputCodigoProduto = new ValidatorLookupProduto({
                        abrev: "",
                        idModalHideShow: "filtroPedidosModal"
                    });

                    // button filtrar
                    $("#doFilter").on('click', function () {
                        "use strict";

                        if (!(periodoInicialDateValidator.isValid &&
                            periodoFinalDateValidator.isValid &&
                            dataEntregaInicialDateValidator.isValid &&
                            dataEntregaFinalDateValidator.isValid &&
                            compareValorInicialComValorFinal.isValid)) {

                            var message = 'Erros no filtro.';
                            $(".k-loading-mask").remove();
                            $("#filtroPedidosModal").modal("hide");
                            u.dialogOk(message, null, true, null, alertBehavior.warning);
                            throw new Error(message);
                        }

                        var filtroVM = {};

                        filtroVM['PeriodoInicial'] = document.getElementById('inputPeriodoInicial').value;
                        filtroVM['PeriodoFinal'] = document.getElementById('inputPeriodoFinal').value;

                        filtroVM['DataEntregaInicial'] = document.getElementById('inputDataEntregaInicial').value;
                        filtroVM['DataEntregaFinal'] = document.getElementById('inputDataEntregaFinal').value;

                        filtroVM['ValorInicial'] = document.getElementById('inputValorInicial').value.replace('.', '').replace(',', '.');
                        filtroVM['ValorFinal'] = document.getElementById('inputValorFinal').value.replace('.', '').replace(',', '.');

                        filtroVM['NumeroInicial'] = document.getElementById('inputNrPedidoInicial').value;
                        filtroVM['NumeroFinal'] = document.getElementById('inputNrPedidoFinal').value;

                        filtroVM['IsEmAnalise'] = document.getElementById('check-filter-situacao-em-analise').checked;
                        filtroVM['IsBloqueado'] = document.getElementById('check-filter-situacao-bloqueado').checked;
                        filtroVM['IsPendente'] = document.getElementById('check-filter-situacao-pendente').checked;
                        filtroVM['IsCancelado'] = document.getElementById('check-filter-situacao-cancelado').checked;
                        filtroVM['IsParcialmenteFaturado'] = document.getElementById('check-filter-situacao-parcialmente-faturado').checked;
                        filtroVM['IsFaturado'] = document.getElementById('check-filter-situacao-faturado').checked;
                        filtroVM['IsParcialmenteAtendido'] = document.getElementById('check-filter-situacao-parcialmente-atendido').checked;
                        filtroVM['IsAtendido'] = document.getElementById('check-filter-situacao-atendido').checked;

                        if (validatorCliente.getVarios()) {
                            // filtro GrupoContas
                            filtroVM['CodigoCliente'] = "";
                            filtroVM['CodigosClientes'] = validatorCliente.getGrupoContasLista();
                        }
                        else {
                            // filtro unico
                            filtroVM['CodigoCliente'] = document.getElementById('inputCodigoCliente').value;
                            filtroVM['CodigosClientes'] = [];
                        }

                        filtroVM['CodigoProduto'] = document.getElementById('inputCodigoProduto').value;
                        filtroVM['CodigoGrade1'] = document.getElementById('inputCodigoGrade1').value;
                        filtroVM['CodigoGrade2'] = document.getElementById('inputCodigoGrade2').value;
                        filtroVM['CodigoGrade3'] = document.getElementById('inputCodigoGrade3').value;
                        filtroVM['NumeroOcCliente'] = document.getElementById('inputNumeroOc').value;

                        currentUser.setSessionData('filtro_pedidos', JSON.stringify(filtroVM));

                        var dataSource = new kendo.data.DataSource(
                            gridPedidos.getFilteredDataSource(filtroVM)
                        );
                        //dataSource.read(); comentado para não entrar em recursão no fill da Grid;

                        $("#gridPedidos").data("kendoGrid").setDataSource(dataSource);
                        //gridPedidos.loadSettings();
                    });

                    // button limpar filtro
                    $("#removeFilter").on('click', function () {
                        "use strict";
                        document.getElementById('inputPeriodoInicial').value = "";
                        document.getElementById('inputPeriodoFinal').value = "";
                        document.getElementById('inputDataEntregaInicial').value = "";
                        document.getElementById('inputDataEntregaFinal').value = "";
                        document.getElementById('inputValorInicial').value = "";
                        document.getElementById('inputValorFinal').value = "";
                        document.getElementById('inputNrPedidoInicial').value = "";
                        document.getElementById('inputNrPedidoFinal').value = "";
                        document.getElementById('check-filter-situacao-em-analise').checked = false;
                        document.getElementById('check-filter-situacao-bloqueado').checked = false;
                        document.getElementById('check-filter-situacao-pendente').checked = false;
                        document.getElementById('check-filter-situacao-cancelado').checked = false;
                        document.getElementById('check-filter-situacao-parcialmente-faturado').checked = false;
                        document.getElementById('check-filter-situacao-faturado').checked = false;
                        document.getElementById('check-filter-situacao-parcialmente-atendido').checked = false;
                        document.getElementById('check-filter-situacao-atendido').checked = false;
                        document.getElementById('inputCodigoCliente').value = "";
                        document.getElementById('descriptionCodigoCliente').innerHTML = "";

                        inputCodigoProduto.clear();

                        document.getElementById('inputNumeroOc').value = "";
                        currentUser.setSessionData('filtro_pedidos', null);

                        var dataSource = new kendo.data.DataSource(
                            gridPedidos.getNormalDataSource()
                        );

                        dataSource.read();
                        $("#gridPedidos").data("kendoGrid").setDataSource(dataSource);
                        gridPedidos.loadSettings();
                        setMask();
                    });

                    // functions filtro
                    function loadCustomFilter() {
                        var filtroVM = JSON.parse(currentUser.getSessionData('filtro_pedidos'));
                        if (filtroVM != null) {
                            document.getElementById('inputPeriodoInicial').value = filtroVM['PeriodoInicial'];
                            document.getElementById('inputPeriodoFinal').value = filtroVM['PeriodoFinal'];

                            document.getElementById('inputDataEntregaInicial').value = filtroVM['DataEntregaInicial'];
                            document.getElementById('inputDataEntregaFinal').value = filtroVM['DataEntregaFinal'];

                            document.getElementById('inputValorInicial').value = filtroVM['ValorInicial'];
                            document.getElementById('inputValorFinal').value = filtroVM['ValorFinal'];

                            document.getElementById('inputNrPedidoInicial').value = filtroVM['NumeroInicial'];
                            document.getElementById('inputNrPedidoFinal').value = filtroVM['NumeroFinal'];

                            document.getElementById('check-filter-situacao-em-analise').checked = filtroVM['IsEmAnalise'];
                            document.getElementById('check-filter-situacao-bloqueado').checked = filtroVM['IsBloqueado'];
                            document.getElementById('check-filter-situacao-pendente').checked = filtroVM['IsPendente'];
                            document.getElementById('check-filter-situacao-cancelado').checked = filtroVM['IsCancelado'];
                            document.getElementById('check-filter-situacao-parcialmente-faturado').checked = filtroVM['IsParcialmenteFaturado'];
                            document.getElementById('check-filter-situacao-faturado').checked = filtroVM['IsFaturado'];
                            document.getElementById('check-filter-situacao-parcialmente-atendido').checked = filtroVM['IsParcialmenteAtendido'];
                            document.getElementById('check-filter-situacao-atendido').checked = filtroVM['IsAtendido'];

                            if (filtroVM['CodigosClientes'].length > 1) {
                                // filtro GrupoContas
                                validatorCliente.setGrupoContasLista(filtroVM['CodigosClientes']);
                                validatorCliente.setVarios(true);
                            }
                            else {
                                // filtro unico
                                document.getElementById('inputCodigoCliente').value = filtroVM['CodigoCliente'];
                                validatorCliente.setValue(filtroVM['CodigoCliente']);
                            }

                            inputCodigoProduto.setProdutoGrades({
                                CodigoProduto: filtroVM['CodigoProduto'],
                                DescricaoProduto: "",
                                Classificacao: "",

                                HaveGrade1: filtroVM['CodigoGrade1'] ? true : false,
                                CodigoGrade1: filtroVM['CodigoGrade1'],
                                DescricaoGrade1: "",

                                HaveGrade2: filtroVM['CodigoGrade2'] ? true : false,
                                CodigoGrade2: filtroVM['CodigoGrade2'],
                                DescricaoGrade2: "",

                                HaveGrade3: filtroVM['CodigoGrade3'] ? true : false,
                                CodigoGrade3: filtroVM['CodigoGrade3'],
                                DescricaoGrade3: ""
                            });
                            inputCodigoProduto.validateAllFields();

                            document.getElementById('inputNumeroOc').value = filtroVM['NumeroOcCliente'];
                        }

                        $('#doFilter').click();
                    }

                    //
                    // load
                    //

                    $('.radar-drop-down').kendoDropDownList();
                    $('.radar-date-picker').setMask("99/99/9999");
                    loadCustomFilter();
                    kendo.culture("pt-BR");
                    setMask();
                    setPermissions();

                }(params));
            }),
            
            MovimentosPedido: function (params) {
                return (function () {
                    var lastFieldFocus = "";
                    var alterouCampo = false;
                    var u = new Util();
                    currentUser.update(params.User);
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial - Pedidos - Movimentos");

                    var GuidProxy = new ValidatorHidden({
                        field: "GuidProxy",
                        value: params.Pedido.GuidProxy
                    });

                    //
                    // aba principal
                    //

                    // data emissao
                    var inputDataEmissaoValidator = new DateValidator({
                        id: "inputDataEmissao",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker('#' + this.id);
                        },
                        isEmptyValid: true,
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalidDialog(validator, function () {
                                u.alterTab(0);
                                inputDataEmissaoValidator.clear();
                                inputDataEmissaoValidator.focus(alertBehavior.warning);
                            });
                        }
                    });

                    // filial
                    var validatorFilial = new Validator({
                        field: 'CodigoFilial',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        GuidProxy: GuidProxy.getValue(),
                        route: 'Comercial/F4FilialPedido/GetFilialProxy',
                        onValid: function (data) {
                            if (this.changed()) {
                                validatorCfopItem.setValue("");
                                validatorCfop.setValue("");
                                validatorOperacaoComercial.setValue("");

                                document.getElementById('inputCodigoFilial').value = data['Codigo'];
                                document.getElementById('descriptionCodigoFilial').innerHTML = data['Nome'];

                                document.getElementById('inputCodigoOpComercial').value = "";
                                document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                                validatorOperacaoComercial.update();
                                document.getElementById('inputCodigoCfop').value = "";
                                document.getElementById('descriptionCodigoCfop').innerHTML = "";
                                validatorCfop.update();
                                validatorCfopItem.update();
                                tableCfops.refresh();
                            }
                        },
                        onInvalid: function () {
                            u.alterTab(0);
                            validatorFilial.setValues("", "");
                            validatorFilial.focus(controlGroupBehavior.warning);

                            document.getElementById('inputCodigoOpComercial').value = "";
                            document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                            validatorOperacaoComercial.update();
                            document.getElementById('inputCodigoCfop').value = "";
                            document.getElementById('descriptionCodigoCfop').innerHTML = "";
                            validatorCfop.update();
                            validatorCfopItem.update();
                            tableCfops.refresh();
                        },
                        onEmpty: function () {
                            u.alterTab(0);
                            postJsonToRoute("Comercial/F4FilialPedido/SetEmpty", GuidProxy.getObjJSON());
                            postJsonToRoute('Comercial/F4OpComerciaisPedido/SetEmpty', GuidProxy.getObjJSON());
                            postJsonToRoute('Comercial/F4CfopPedido/SetEmpty', GuidProxy.getObjJSON());

                            document.getElementById('inputCodigoOpComercial').value = "";
                            document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                            validatorOperacaoComercial.update();
                            document.getElementById('inputCodigoCfop').value = "";
                            document.getElementById('descriptionCodigoCfop').innerHTML = "";
                            validatorCfop.update();
                            validatorCfopItem.update();
                            tableCfops.refresh();
                        }
                    });
                    validatorFilial.listen();
                    validatorFilial.update();

                    var tableFiliais = new Table({
                        'id': 'tableFilial',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4FilialPedido/GetFiliais',
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Nome', field: 'Nome', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'CNPJ/CPF', field: 'CpfCnpj', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'columnsLegend': { CpfCnpj: 'Ex: 11.222.333/4444-55' },
                        'showFilter': true,
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                onTableFilialChange();
                                tableOperacoesComerciais.refresh();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableFilial table tr').on('dblclick', function () {
                                onTableFilialChange();
                                $('#modalFilial').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });

                    function onTableFilialChange() {
                        var data = tableFiliais.getSelectedData();
                        document.getElementById('inputCodigoFilial').value = data.Codigo;
                        document.getElementById('descriptionCodigoFilial').innerHTML = data.Nome;
                        validatorFilial.update();
                        validatorFilial.validate();
                        validatorCfop.update();
                        validatorCfop.validate();
                        validatorCfopItem.update();
                        validatorCfopItem.validate();
                        tableCfops.refresh();
                        tableOperacoesComerciais.refresh();
                    }

                    var linkFiliais = document.getElementById('linkButtonModalFiliais');
                    var inputFiliais = document.getElementById('inputCodigoFilial');
                    var modalFiliais = new Modal('Filiais', linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    // cliente
                    var validatorCliente = new Validator({
                        field: 'CodigoCliente',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código do cliente.",
                        GuidProxy: GuidProxy.getValue(),
                        route: 'Comercial/F4ClientePedido/GetClienteProxy',
                        onValid: function (data) {
                            if (this.changed()) {
                                document.getElementById("inputCodigoCliente").value = data.Codigo;
                                document.getElementById("descriptionCodigoCliente").innerHTML = data.RazaoSocial;

                                if (data.VendaBloqueada) {
                                    u.dialogOk("Venda bloqueada para este cliente.", null, true);
                                    document.getElementById("descriptionCodigoCliente").style.color = "red";
                                    document.getElementById("descriptionCodigoCliente").innerHTML += "&nbsp;<b>(Venda bloqueada)</b>";
                                } else {
                                    document.getElementById("descriptionCodigoCliente").style.color = "#595959";
                                }

                                params.Pedido.VendaBloqueadaCliente = data.VendaBloqueada;
                                document.getElementById("inputCep").value = data.Cep;
                                document.getElementById("inputCodigoMunicipio").value = data.CodMunicipio;
                                document.getElementById("descriptionCodigoMunicipio").innerHTML = data.DescricaoMunicipio;
                                document.getElementById("inputUf").value = data.Uf;
                                document.getElementById("inputLocalEntrega").value = data.LocalEntrega;
                                document.getElementById("inputCodigoTabelaPrecos").value = data.CodTabelaPrecoProduto;
                                document.getElementById("descriptionCodigoTabelaPrecos").innerHTML = data.DescricaoTabelaPrecoProduto;
                                document.getElementById("inputCodigoTransportadora").value = data.CodTransp;
                                document.getElementById("descriptionCodigoTransportadora").innerHTML = data.DescricaoTransp;
                                document.getElementById("inputCodigoTransportadoraRedespacho").value = data.CodTranspRedespacho;
                                document.getElementById("descriptionCodigoTransportadoraRedespacho").innerHTML = data.DescricaoTranspRedespacho;

                                validatorCfopItem.setValue("");
                                validatorCfop.setValue("");
                                validatorOperacaoComercial.setValue("");

                                validatorTabelaPrecos.update();
                                dropDownCondicoesPagamento.set(data.IdCondicaoPagamento);
                                dropDownFormasPagamento.set(data.IdFormaPagamento);
                                dropDownTipoCobranca.set(data.IdTipoCobranca);
                                dropDownQuemtransporta.set(data.QuemTransporta);

                                document.getElementById('inputCodigoOpComercial').value = "";
                                document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                                validatorOperacaoComercial.update();
                                tableOperacoesComerciais.refresh();

                                document.getElementById('inputCodigoCfop').value = "";
                                document.getElementById('descriptionCodigoCfop').innerHTML = "";
                                validatorCfop.update();
                                validatorCfopItem.update();
                                tableCfops.refresh();
                            }
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(0);
                            self.focus();
                            self.value = "";
                            self.input.value = "";

                            document.getElementById('inputCodigoOpComercial').value = "";
                            document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                            validatorOperacaoComercial.update();
                            tableOperacoesComerciais.refresh();

                            document.getElementById('inputCodigoCfop').value = "";
                            document.getElementById('descriptionCodigoCfop').innerHTML = "";
                            validatorCfop.update();
                            validatorCfopItem.update();
                            tableCfops.refresh();
                        },
                        onEmpty: function () {
                            postJsonToRoute('Comercial/F4ClientePedido/SetEmpty', GuidProxy.getObjJSON());
                            postJsonToRoute('Comercial/F4OpComerciaisPedido/SetEmpty', GuidProxy.getObjJSON());
                            postJsonToRoute('Comercial/F4CfopPedido/SetEmpty', GuidProxy.getObjJSON());

                            document.getElementById('inputCodigoOpComercial').value = "";
                            document.getElementById('descriptionCodigoOpComercial').innerHTML = "";
                            validatorOperacaoComercial.update();
                            document.getElementById('inputCodigoCfop').value = "";
                            document.getElementById('descriptionCodigoCfop').innerHTML = "";
                            validatorCfop.update();
                            validatorCfopItem.update();
                            tableCfops.refresh();
                        }
                    });
                    validatorCliente.listen();
                    validatorCliente.update();

                    var tableClientes = new Table({
                        'id': 'tableCliente',
                        'msgDialog': true,
                        'params': [validatorFilial],
                        'onParams': function (){
                            u.alterTab(0);
                        },
                        'route': window.baseUrl + "Comercial/F4ClientePedido/GetClientes",
                        'showFilter': true,
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Razão Social', field: 'RazaoSocial', width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'CPF/CNPJ', field: 'CnpjCpf', width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'columnsLegend': { CnpjCpf: "Ex: 11.222.333/4444-55" },
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var search = {};
                                var selectedCliente = tableClientes.getSelectedData();

                                search['CodigoCliente'] = selectedCliente['Codigo'];
                                GuidProxy.addParam(search);

                                getJsonFromRoute('Comercial/F4ClientePedido/GetClienteProxy', search).done(function (data) {
                                    if (data.IsAlert)
                                        throw new Error(data.Message);

                                    document.getElementById("inputCodigoCliente").value = data.Codigo;
                                    document.getElementById("descriptionCodigoCliente").innerHTML = data.RazaoSocial;

                                    if (data.VendaBloqueada) {
                                        u.dialogOk("Venda bloqueada para este cliente.", null, true);
                                        document.getElementById("descriptionCodigoCliente").style.color = "red";
                                        document.getElementById("descriptionCodigoCliente").innerHTML += "&nbsp;<b>(Venda bloqueada)</b>";
                                    } else {
                                        document.getElementById("descriptionCodigoCliente").style.color = "#595959";
                                    }

                                    params.Pedido.VendaBloqueadaCliente = data.VendaBloqueada;
                                    document.getElementById("inputCep").value = data.Cep;
                                    validatorCliente.update();
                                    validatorCliente.validate();

                                    document.getElementById("inputCodigoMunicipio").value = data.CodMunicipio;
                                    document.getElementById("descriptionCodigoMunicipio").innerHTML = data.DescricaoMunicipio;
                                    document.getElementById("inputUf").value = data.Uf;
                                    document.getElementById("inputLocalEntrega").value = data.LocalEntrega;
                                    validatorMunicipio.update();
                                    validatorTabelaPrecos.validate();

                                    document.getElementById("inputCodigoTabelaPrecos").value = data.CodTabelaPrecoProduto;
                                    document.getElementById("descriptionCodigoTabelaPrecos").innerHTML = data.DescricaoTabelaPrecoProduto;
                                    validatorTabelaPrecos.update();
                                    validatorTabelaPrecos.validate();

                                    dropDownCondicoesPagamento.set(data.IdCondicaoPagamento);
                                    dropDownFormasPagamento.set(data.IdFormaPagamento);
                                    dropDownTipoCobranca.set(data.IdTipoCobranca);
                                    dropDownQuemtransporta.set(data.QuemTransporta);
                                    tableCfops.refresh();

                                    document.getElementById("inputCodigoTransportadora").value = data.CodTransp;
                                    document.getElementById("descriptionCodigoTransportadora").innerHTML = data.DescricaoTransp;
                                    validatorTransportadora.update();
                                    validatorTransportadora.validate();

                                    document.getElementById("inputCodigoTransportadoraRedespacho").value = data.CodTranspRedespacho;
                                    document.getElementById("descriptionCodigoTransportadoraRedespacho").innerHTML = data.DescricaoTranspRedespacho;
                                    validatorTransportadoraRedespacho.update();
                                    validatorTransportadoraRedespacho.validate();
                                });
                            };
                        },
                        'onDataBound': function () {
                            $('#tableCliente table tr').on('dblclick', function () {
                                var search = {};
                                var cliente = tableClientes.getSelectedData();

                                search['CodigoCliente'] = cliente['Codigo'];
                                GuidProxy.addParam(search);

                                getJsonFromRoute('Comercial/F4ClientePedido/GetClienteProxy', search).done(function (data) {
                                    if (data.IsAlert)
                                        throw new Error(data.Message);

                                    document.getElementById("inputCodigoCliente").value = data.Codigo;
                                    document.getElementById("descriptionCodigoCliente").innerHTML = data.RazaoSocial;

                                    if (data.VendaBloqueada) {
                                        u.dialogOk("Venda bloqueada para este cliente.", null, true);
                                        document.getElementById("descriptionCodigoCliente").style.color = "red";
                                        document.getElementById("descriptionCodigoCliente").innerHTML += "&nbsp;<b>(Venda bloqueada)</b>";
                                    } else {
                                        document.getElementById("descriptionCodigoCliente").style.color = "#595959";
                                    }

                                    params.Pedido.VendaBloqueadaCliente = data.VendaBloqueada;
                                    document.getElementById("inputCep").value = data.Cep;
                                    validatorCliente.update();
                                    validatorCliente.validate();

                                    document.getElementById("inputCodigoMunicipio").value = data.CodMunicipio;
                                    document.getElementById("descriptionCodigoMunicipio").innerHTML = data.DescricaoMunicipio;
                                    document.getElementById("inputUf").value = data.Uf;
                                    document.getElementById("inputLocalEntrega").value = data.LocalEntrega;
                                    validatorMunicipio.update();
                                    validatorMunicipio.validate();

                                    document.getElementById("inputCodigoTabelaPrecos").value = data.CodTabelaPrecoProduto;
                                    document.getElementById("descriptionCodigoTabelaPrecos").innerHTML = data.DescricaoTabelaPrecoProduto;
                                    validatorTabelaPrecos.update();
                                    validatorTabelaPrecos.validate();

                                    dropDownCondicoesPagamento.set(data.IdCondicaoPagamento);
                                    dropDownFormasPagamento.set(data.IdFormaPagamento);
                                    dropDownTipoCobranca.set(data.IdTipoCobranca);
                                    dropDownQuemtransporta.set(data.QuemTransporta);
                                    tableCfops.refresh();

                                    document.getElementById("inputCodigoTransportadora").value = data.CodTransp;
                                    document.getElementById("descriptionCodigoTransportadora").innerHTML = data.DescricaoTransp;
                                    validatorTransportadora.update();
                                    validatorTransportadora.validate();

                                    document.getElementById("inputCodigoTransportadoraRedespacho").value = data.CodTranspRedespacho;
                                    document.getElementById("descriptionCodigoTransportadoraRedespacho").innerHTML = data.DescricaoTranspRedespacho;
                                    validatorTransportadoraRedespacho.update();
                                    validatorTransportadoraRedespacho.validate();
                                });
                                $('#modalCliente').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalClientes = document.getElementById('linkButtonModalClientes');
                    var inputClientes = document.getElementById('inputCodigoCliente');
                    var modalClientes = new Modal('Clientes', linkButtonModalClientes, inputClientes, tableClientes);
                    modalClientes.listen();

                    // municipio
                    var validatorMunicipio = new Validator({
                        field: 'CodigoMunicipio',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informado o código do município.',
                        route: 'Empresarial/F4Municipio/GetMunicipio',
                        onValid: function (data) {
                            document.getElementById('inputCodigoMunicipio').value = data.Codigo;
                            document.getElementById('descriptionCodigoMunicipio').innerHTML = data.Nome;
                            document.getElementById('inputUf').value = data.Uf;
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(0);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorMunicipio.listen();
                    validatorMunicipio.update();

                    var tableMunicipios = new Table({
                        'id': 'tableMunicipios',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Empresarial/F4Municipio/GetMunicipios',
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Nome', field: 'Nome', width: 240, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'UF', field: 'Uf', width: 35, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'showFilter': true,
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableMunicipios.getSelectedData();
                                document.getElementById('inputCodigoMunicipio').value = data.Codigo;
                                document.getElementById('descriptionCodigoMunicipio').innerHTML = data.Nome;
                                document.getElementById('inputUf').value = data.Uf;
                                validatorMunicipio.update();
                                validatorMunicipio.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableMunicipios table  tr').on('dblclick', function () {
                                var data = tableMunicipios.getSelectedData();
                                document.getElementById('inputCodigoMunicipio').value = data.Codigo;
                                document.getElementById('descriptionCodigoMunicipio').innerHTML = data.Nome;
                                document.getElementById('inputUf').value = data.Uf;
                                validatorMunicipio.update();
                                validatorMunicipio.validate();
                                $('#modalMunicipio').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalMunicipios = document.getElementById('linkButtonModalMunicipios');
                    var inputMunicipios = document.getElementById('inputCodigoMunicipio');
                    var modalMunicipios = new Modal('Municípios', linkButtonModalMunicipios, inputMunicipios, tableMunicipios);
                    modalMunicipios.listen();

                    // data entrega
                    var inputPrincipalDataEntregaValidator = new DateValidator({
                        id: "inputPrincipalDataEntrega",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker('#' + this.id);
                        },
                        isEmptyValid: true,
                        onValid: function (validator) {
                            $("#inputDataEntrega").val($("#inputPrincipalDataEntrega").val());
                            validateDate('inputPrincipalDataEntrega', 0);
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalidDialog(validator, function () {
                                u.alterTab(0);
                                inputPrincipalDataEntregaValidator.clear();
                                inputPrincipalDataEntregaValidator.focus(alertBehavior.warning);
                            });
                        }
                    });

                    // operacao comercial
                    var validatorOperacaoComercial = new Validator({
                        field: 'CodigoOpComercial',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informada a operação comercial.',
                        route: 'Comercial/F4OpComerciaisPedido/GetOpComercialProxy',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorFilial, validatorCliente],
                        onValid: function (data) {
                            document.getElementById('inputCodigoOpComercial').value = data.Codigo;
                            document.getElementById('descriptionCodigoOpComercial').innerHTML = data.Descricao;
                            document.getElementById('inputCodigoCfop').value = "";
                            document.getElementById('descriptionCodigoCfop').innerHTML = "";
                            document.getElementById('inputCodigoCfopItem').value = "";
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = "";
                            validatorCfop.disable();
                            validatorCfopItem.disable();
                            setPermissions();
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(0);
                            validatorOperacaoComercial.clear({ warning: true, focus: true });
                            setPermissions();
                        },
                        onEmpty: function () {
                            postJsonToRoute('Comercial/F4OpComerciaisPedido/SetEmpty', GuidProxy.getObjJSON());
                            validatorCfop.enable();
                            validatorCfopItem.enable();
                            setPermissions();
                        }
                    });
                    validatorOperacaoComercial.listen();
                    validatorOperacaoComercial.update();

                    var tableOperacoesComerciais = new Table({
                        'id': 'tableOperacaoComercial',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4OpComerciaisPedido/GetOpComerciaisProxy',
                        'GuidProxy': GuidProxy.getValue(),
                        'showFilter': true,
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Descrição', field: 'Descricao', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'params': [validatorFilial, validatorCliente],
                        'onParams': function () {
                            u.alterTab(0);
                        },
                        'mixedFields': [inputCodigoOpComercial, inputCodigoCliente, inputCodigoFilial],
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableOperacoesComerciais.getSelectedData();
                                document.getElementById('inputCodigoOpComercial').value = data.Codigo;
                                document.getElementById('descriptionCodigoOpComercial').innerHTML = data.Descricao;
                                document.getElementById('inputCodigoCfop').value = "";
                                document.getElementById('descriptionCodigoCfop').innerHTML = "";
                                validatorCfop.disable();
                                validatorCfopItem.disable();
                                validatorOperacaoComercial.update();
                                validatorOperacaoComercial.validate();
                                setPermissions();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableOperacaoComercial table tr').on('dblclick', function () {
                                var data = tableOperacoesComerciais.getSelectedData();
                                document.getElementById('inputCodigoOpComercial').value = data.Codigo;
                                document.getElementById('descriptionCodigoOpComercial').innerHTML = data.Descricao;
                                document.getElementById('inputCodigoCfop').value = "";
                                document.getElementById('descriptionCodigoCfop').innerHTML = "";
                                validatorCfop.disable();
                                validatorCfopItem.disable();
                                validatorOperacaoComercial.update();
                                validatorOperacaoComercial.validate();
                                $('#modalOpComercial').modal('hide');
                            });
                        },
                        'dataSourceType': "Mixed"
                    });
                    var linkButtonModalOperacoesComerciais = document.getElementById('linkButtonModalOperacoesComerciais');
                    var inputOperacoesComerciais = document.getElementById('inputCodigoOpComercial');
                    var modalOperacoesComerciais = new Modal('Operações Comerciais', linkButtonModalOperacoesComerciais, inputOperacoesComerciais, tableOperacoesComerciais);
                    modalOperacoesComerciais.listen();

                    // cfop
                    var validatorCfop = new Validator({
                        field: 'CodigoCfop',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informada a CFOP.',
                        route: 'Comercial/F4CfopPedido/GetCfopProxy',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorFilial, validatorCliente],
                        onValid: function (data) {
                            document.getElementById('inputCodigoCfop').value = data.Classificacao;
                            document.getElementById('descriptionCodigoCfop').innerHTML = data.Nome;
                            document.getElementById('inputCodigoCfopItem').value = data.Classificacao;
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = data.Nome;                            
                            setPermissions();
                            validateIntegracaoCfopFinanceiro(data.EfetuarLancamentoFinanceiro);
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(0);
                            validatorCfop.clear({ warning: true, focus: true });
                            validatorCfopItem.setValue("");
                            document.getElementById('inputCodigoCfopItem').value = "";
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = "";
                            setPermissions();
                            validateIntegracaoCfopFinanceiro(true);
                        },
                        onEmpty: function () {
                            postJsonToRoute('Comercial/F4CfopPedido/SetEmpty', GuidProxy.getObjJSON());
                            validatorCfopItem.setValue("");
                            document.getElementById('inputCodigoCfopItem').value = "";
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = "";
                            setPermissions();
                            validateIntegracaoCfopFinanceiro(true);
                        }
                    });
                    validatorCfop.listen();
                    validatorCfop.update();

                    var tableCfops = new Table({
                        'id': 'tableCfops',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4CfopPedido/GetCfopsProxy',
                        'GuidProxy': GuidProxy.getValue(),
                        'showFilter': true,
                        'columns': [
                            { title: 'Classificação', field: 'Classificacao', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Nome', field: 'Nome', width: 275, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Filial', field: 'NomeFilial', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } }
                        ],
                        'columnsLegend': { Classificacao: "Ex: 1.101" },
                        'params': [validatorFilial, validatorCliente],
                        onParams: function () {
                            u.alterTab(0);
                        },
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableCfops.getSelectedData();
                                document.getElementById('inputCodigoCfop').value = data.Classificacao;
                                document.getElementById('descriptionCodigoCfop').innerHTML = data.Nome;
                                validatorCfop.update();
                                validatorCfop.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableCfops table  tr').on('dblclick', function () {
                                var data = tableCfops.getSelectedData();
                                document.getElementById('inputCodigoCfop').value = data.Classificacao;
                                document.getElementById('descriptionCodigoCfop').innerHTML = data.Nome;
                                validatorCfop.update();
                                validatorCfop.validate();
                                $('#modalCfop').modal('hide');
                            });
                        },
                        'dataSourceType': "Mixed"
                    });
                    var linkButtonModalCfops = document.getElementById('linkButtonModalCfops');
                    var inputaCfops = document.getElementById('inputCodigoCfop');
                    var modalCfops = new Modal('CFOPs', linkButtonModalCfops, inputaCfops, tableCfops);
                    modalCfops.listen();

                    // flag para indicar que o campo foi alterado manualmente, para não fazer mais sugestões,
                    // o evento 'change' somente é invocado quando o campo é alterado manualmente,
                    // quando altera o campo pelo rotina 'val()' do jquery, o evento não é disparado
                    $("#inputNumeroOc").on("change", function () {
                        // mesmo que o valor do campo inputNumeroOc for vazio, não vai mais deixar sugerir valor,
                        // porque o usuario pode querer que o valor do campo seja vazio
                        $("#inputNumeroOc").data("podesugerir", false);
                        // quando digita um novo codigo para o produto, e feito clear no campo inputNumeroOc,
                        // como foi um valor digitado, tenho que recuperar esse valor, por isso eh feito bkp e restaurado
                        // o mesmo, quando o codigo do produto eh alterado
                        $("#inputNumeroOc").attr("valorBkp", $("#inputNumeroOc").val());
                    });

                    // proxima aba
                    $('#fieldObservacoes').on('keydown', function (ev) {
                        var key = ev.which || ev.keyCode;
                        if (key == 9) {
                            u.alterTab(1);
                            $('#inputCodigoTabelaPrecos').focus();
                        }
                    });

                    //
                    // functions principal
                    //

                    $('#buttonSalvarPedido').on('click', salvarPedido);

                    $('#buttonCancelarAlteracaoPedido').on('click', cancelarAlteracao);

                    $('#buttonNovoPedido').on('click', function () {
                        "use strict";
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações e adicionar um novo pedido?",
                            function () {
                                window.location.replace(window.baseUrl + "Comercial/Movimentos/NovoPedido");
                            },
                            null,
                            lastFieldFocus
                        );
                    });

                    $("#buttonGeneratePdfPedido").on("click", function () {
                        "use strict";
                        window.open(window.baseUrl + "Comercial/Movimentos/ReportPdf?GuidProxy=" + GuidProxy.getValue());
                    });

                    function getCurrentPedido() {
                        "use strict";
                        var pedido = {};

                        pedido['codigoMunicipio'] = document.getElementById("inputCodigoMunicipio").value;
                        pedido['LocalEntrega'] = document.getElementById("inputLocalEntrega").value;
                        pedido['DataEntrega'] = document.getElementById("inputPrincipalDataEntrega").value;
                        pedido['NumeroOrdemCompraCliente'] = document.getElementById("fieldNumeroOrdemCompraCliente").value;
                        pedido['Observacoes'] = document.getElementById("fieldObservacoes").value;
                        pedido['QuemTransporta'] = document.getElementById("fieldSelectQuemTransporta").value;
                        pedido['codigoTransportadora'] = document.getElementById("inputCodigoTransportadora").value;
                        pedido['ViaTransporte'] = document.getElementById("fieldSelectViaTransporte").value;
                        pedido['codigoTransportadoraRedespacho'] = document.getElementById("inputCodigoTransportadoraRedespacho").value;
                        pedido['QuantidadeTotalVolumes'] = document.getElementById("fieldQuantidadeTotalVolumes").value.replace(/\./g, '');
                        pedido['Especie'] = document.getElementById("fieldEspecie").value;
                        pedido['Marca'] = document.getElementById("fieldMarca").value;
                        pedido['NumeroInicial'] = document.getElementById("fieldNumeroInicial").value;
                        pedido['PesoBruto'] = document.getElementById("fieldPesoBruto").value;
                        pedido['PesoLiquido'] = document.getElementById("fieldPesoLiquido").value;
                        GuidProxy.addParam(pedido);

                        return pedido;
                    }

                    function salvarPedido() {
                        "use strict";
                        validateDate('inputPrincipalDataEntrega', 0);
                        resolveValidators();
                        var pedido = getCurrentPedido();
                        var toutId = setTimeout(
                            function () {
                                $('#waiting').show();
                            },
                            200
                        );

                        getJsonFromRoute('Comercial/Movimentos/CheckPedido', GuidProxy.getObj()).done(
                            function (data) {
                                if (data.IsAlert) {
                                    //regras conforme http://conecte.wk.com.br/Chamado/Consulta.aspx?CodigoChamado=141001690 T43 e T65
                                    if (data.Level === alertLevel.question) {
                                        if (data.CodeError === -1) { //usuário COM permissão de desbloqueio
                                            if (params.Pedido.AplicarBloqueioAosPedidos && !params.Pedido.BloquearPedidosNaInclusao) {
                                                u.dialog(
                                                    "Confirmação",
                                                    data.Message,
                                                    function () { //SIM
                                                        pedido.IsBloqueado = false;
                                                        postPedido(pedido);
                                                    },
                                                    function () { //NÃO
                                                        //do nothing
                                                    },
                                                    null,
                                                    true
                                                );
                                            } else if (params.Pedido.AplicarBloqueioAosPedidos && params.Pedido.BloquearPedidosNaInclusao) {
                                                u.dialog(
                                                    "Confirmação",
                                                    data.Message,
                                                    function () { //SIM
                                                        pedido.IsBloqueado = false;
                                                        postPedido(pedido);
                                                    },
                                                    function () { //NÃO
                                                        pedido.IsBloqueado = true;
                                                        postPedido(pedido);
                                                    },
                                                    null,
                                                    true
                                                );
                                            } else {
                                                pedido.IsBloqueado = false;
                                                postPedido(pedido);
                                            }
                                        } else if (data.CodeError === -2) { //usuário SEM permissão de desbloqueio
                                            if (params.Pedido.AplicarBloqueioAosPedidos && !params.Pedido.BloquearPedidosNaInclusao) {
                                                u.dialogOk(data.Message.replace("Lançar mesmo assim?", ""), null, true);
                                            } else if (params.Pedido.AplicarBloqueioAosPedidos && params.Pedido.BloquearPedidosNaInclusao) {
                                                u.dialog(
                                                    "Confirmação",
                                                    data.Message,
                                                    function () { //SIM
                                                        pedido.IsBloqueado = true;
                                                        postPedido(pedido);
                                                    },
                                                    function () { //NÃO
                                                        //do nothing
                                                    },
                                                    null,
                                                    true
                                                );
                                            } else {
                                                pedido.IsBloqueado = false;
                                                postPedido(pedido);
                                            }
                                        } else { //demais casos
                                            u.dialog(
                                                "Confirmação",
                                                data.Message,
                                                function () { //SIM
                                                    postPedido(pedido);
                                                },
                                                function () { //NÃO
                                                    //do nothing
                                                },
                                                null,
                                                true
                                            );
                                        }

                                        $('#linkButtonSalvarPedido').click();
                                    } else {
                                        u.dialogOk(data.Message, null, true);
                                        $('#linkButtonSalvarPedido').click();
                                    }
                                } else {
                                    postPedido(pedido);
                                }

                                window.clearTimeout(toutId);
                                $('#waiting').hide();
                            }
                        );
                    }

                    function resolveValidators() {
                        if (validatorFilial.invalid) {
                            u.alterTab(0);
                            u.dialogOk(validatorFilial.onPendencyMessage, null, true, function () {
                                validatorFilial.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            throw new Error(validatorFilial.onPendencyMessage);
                        }

                        if (validatorCliente.invalid) {
                            u.alterTab(0);
                            u.dialogOk(validatorCliente.onPendencyMessage, null, true, function () {
                                validatorCliente.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            throw new Error(validatorCliente.onPendencyMessage);
                        }

                        if (validatorOperacaoComercial.invalid && !params.Pedido.Permissoes.IsOperacaoComercialOpcional) {
                            var message = "É obrigatório informar a Operação Comercial.";
                            u.alterTab(0);
                            u.dialogOk(message, null, true, function () {
                                validatorOperacaoComercial.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            throw new Error(message);
                        }

                        if (gridItens.getDataSource()._data.length == 0) {
                            var message = "Deve ser adicionado pelo menos um item.";
                            alterTab(1);
                            u.dialogOk(message, null, true, null, alertBehavior.warning);
                            throw new Error(message);
                        }
                    }

                    function postPedido(pedido) {
                        postJsonToRoute("Comercial/Movimentos/SavePedido", JSON.stringify(pedido)).done(function (data) {
                            if (data.IsAlert) {
                                if (data.Level == alertLevel.success) {
                                    var message = params.Pedido.IsAlteracao ? "Pedido salvo com sucesso." : "Pedido adicionado com sucesso.";
                                    u.dialogOk(message, null, true, function () {
                                        setTimeout(function () { $('#waiting').show(); }, 100);
                                        window.location.href = window.baseUrl + "Comercial/Movimentos/Pedido/{0}".format(data.Id);
                                    }, alertBehavior.success);
                                }
                                else if (data.Level == alertLevel.error)
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                else
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                            }
                        });
                    }

                    function cancelarAlteracao() {
                        "use strict";
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () {
                                    $('#waiting').show();
                                }, 200);
                                window.location.href = window.baseUrl + "Comercial/Movimentos/Pedidos";
                            },
                            null,
                            lastFieldFocus
                        );
                    }

                    function copiarPedido() {
                        "use strict";
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () {
                                    $('#waiting').show();
                                }, 200);
                                window.location.href = window.baseUrl + "Comercial/Movimentos/CopyPedido" + GuidProxy.getParamUrl();
                            },
                            null,
                            lastFieldFocus
                        );
                    }

                    function setPermissions() {
                        var message = "";
                        disableNegativePermissionsFields();

                        if (params.Pedido.IsAlteracao) {
                            $('#controlNumeroPedido').show();
                            $('#buttonGeneratePdfPedido').attr('disabled', false);

                            if (!params.Pedido.Permissoes.PodeCopiarPedido) {
                                $('#buttonCopiarPedido').attr('disabled', true);
                                $('#buttonCopiarPedido').on('click');
                            } else {
                                $('#buttonCopiarPedido').attr('disabled', false);
                                $('#buttonCopiarPedido').on('click', copiarPedido);
                            }
                        } else {
                            $('#controlNumeroPedido').hide();
                            $('#buttonGeneratePdfPedido').attr('disabled', true);
                            $('#buttonCopiarPedido').attr('disabled', true);
                            $('#buttonCopiarPedido').on('click');
                        }

                        if (params.Pedido.IsAlert && params.Pedido.IsAlteracao && !params.Pedido.PodeSerAlterado && params.Pedido.Level === alertLevel.error)
                            disablePedido();

                        var msg = "";

                        if (params.Pedido.IsAlteracao) {
                            if (!params.Pedido.Permissoes.PodeAlterarPedido) {
                                if (params.Pedido.Status == "Autorizado" && !params.Pedido.Permissoes.PodeAlterarPedidoAutorizado)
                                    msg = 'Pedido autorizado, não é permitida alteração.';
                                else
                                    msg = 'Este pedido não pode ser alterado.';
                            }

                            if (params.Pedido.Situacao == "Atendido" && !params.Pedido.Permissoes.PodeAlterarPedidoAtendido)
                                msg = 'Pedido atendido, não é permitida alteração.';

                            if (params.Pedido.Situacao == "Em Análise" && !params.Pedido.Permissoes.PodeAlterarPedidoEmAnalise)
                                msg = 'Pedido em análise, não é permitida alteração.';
                        }

                        if (params.Pedido.Permissoes.ContemProdutosNaoLiberados)
                            msg = 'Este pedido não pode ser alterado por conter produtos não liberados para uso no RadarWeb.';

                        if (msg !== "") {
                            disablePedido();
                            u.dialogOk(msg, null, true, null, alertBehavior.warning);
                        }
                    }

                    function disablePedido() {                        
                        disableAllInputs();
                        dropDownCondicoesPagamento.disable();
                        dropDownFormasPagamento.disable();
                        dropDownQuemtransporta.disable();
                        dropDownTipoCobranca.disable();
                        dropDownViaTransporte.disable();
                    }

                    function validateDate(field, abaIndex) {
                        if ($("#" + field).val() === "")
                            $("#" + field).val("00/00/0000")

                        if ($("#" + field).val() !== "00/00/0000" && $("#" + field).val() !== "00/00/00") {
                            var entregaMes = $("#" + field).val().substr(3, 3);
                            var entregaDia = $("#" + field).val().substr(0, 3);
                            var entregaAno = $("#" + field).val().substr(6, 4);
                            var entrega = new Date(entregaMes + entregaDia + entregaAno);

                            var emissaoMes = $("#inputDataEmissao").val().substr(3, 3);
                            var emissaoDia = $("#inputDataEmissao").val().substr(0, 3);
                            var emissaoAno = $("#inputDataEmissao").val().substr(6, 4);
                            var emissao = new Date(emissaoMes + emissaoDia + emissaoAno);

                            if (entrega < emissao) {
                                u.alterTab(abaIndex);
                                u.dialogOk("Prazo de entrega deve ser igual ou posterior à data de emissão do pedido.", null, true, function () {
                                    u.alterControlGroupBehavior(field, controlGroupBehavior.warning);
                                    $("#" + field).val("00/00/0000");
                                    $("#" + field).focus();
                                }, alertBehavior.warning);
                                throw new Error("Prazo de entrega deve ser igual ou posterior à data de emissão do pedido.");
                            } else {
                                u.alterControlGroupBehavior(field, controlGroupBehavior.normal);
                            }
                        } else {
                            u.alterControlGroupBehavior(field, controlGroupBehavior.normal);
                        }
                    }

                    //
                    // aba itens
                    //

                    // grid itens
                    var gridItens = new Table({
                        id: 'gridItens',
                        msgDialog: true,
                        route: window.baseUrl + 'Comercial/ItensPedido/GetItens',
                        GuidProxy: GuidProxy.getValue(),
                        columns: [
                            { title: '&nbsp', field: 'Status', width: 10, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "color: red; text-align: left;" } },
                            { title: 'Código', field: 'CodProduto', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Descrição', field: 'DescricaoProduto', width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Desc. Unit.', field: 'ValorDescontoUnitario', width: 50, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Grade 1', field: 'DescricaoItemGrade1', width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Grade 2', field: 'DescricaoItemGrade2', width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Grade 3', field: 'DescricaoItemGrade3', width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Quantidade', field: 'Quantidade', width: 50, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Vlr. Unit.', field: 'ValorUnitario', width: 50, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { title: 'Nome', field: 'NomeProduto', hidden: true },
                            { title: 'Vlr. Unit. Liquido', field: 'ValorUnitarioLiquido', hidden: true },
                            { title: 'Alíq. IPI', field: 'AliquotaIpi', width: 50, hidden: true },
                            { title: 'Alíq. ICMS', field: 'AliquotaIcms', width: 50, hidden: true },
                            { title: 'Alíq. ICMS/ST', field: 'AliquotaIcmsSt', width: 60, hidden: true },
                            { title: 'Núm. OC', field: 'NumeroOrdemCompra', width: 50, hidden: true },
                            { title: 'Complemento', field: 'Complemento', width: 100, hidden: true },
                            { title: 'Item Ped.', field: 'ItemPed', width: 30, hidden: true },
                            { title: 'Dt.Entrega', field: 'DataEntrega', width: 50, hidden: true }
                        ],
                        height: 400,
                        onChange: function () {
                            "use strict";
                            var data = gridItens.getSelectedData();

                            function returnIfDefined(param) {
                                if (param === undefined || param === null)
                                    return "";
                                else
                                    return param;
                            }

                            if (data) {
                                if (data.Status !== 'X') {
                                    validatorTabelaPrecos.enable();
                                    validatorCfopItem.enable();
                                    validatorProdutos.enable();
                                    validatorGrade1.enable();
                                    validatorGrade2.enable();
                                    validatorGrade3.enable();
                                    u.enable('fieldItemComplemento');
                                    u.enable('inputQuantidade');
                                    u.enable('inputValorUnitario');
                                    u.enable('inputValorAliquotaIcms');
                                    u.enable('inputValorAliquotaIpi');
                                    u.enable('inputValorAliquotaIcmsSt');
                                    u.enable('inputNumeroOc');
                                    u.enable('inputItemPed');
                                    u.enable('inputDataEntrega');
                                    u.enable('inputDescontoUnitario');
                                    u.enable('spanPercentualOuMoeda');
                                    u.enable('buttonAlterarItem');
                                    u.enable('buttonRemoverInvalidarItem');
                                    u.enable('inputLivreCobranca');
                                    u.enable('buttonAdicionarItem');
                                }

                                document.getElementById('inputCodigoTabelaPrecos').value = returnIfDefined(data['CodTabelaPrecos']);
                                document.getElementById('descriptionCodigoTabelaPrecos').innerHTML = returnIfDefined(data['DescricaoTabelaPrecos']);
                                validatorTabelaPrecos.update(returnIfDefined(data['CodTabelaPrecos']), returnIfDefined(data['DescricaoTabelaPrecos']));

                                document.getElementById('inputCodigoCfopItem').value = returnIfDefined(data['CodCfop']);
                                document.getElementById('descriptionCodigoCfopItem').innerHTML = returnIfDefined(data['DescricaoCfop']);
                                validatorCfopItem.update(returnIfDefined(data['CodCfop']), returnIfDefined(data['DescricaoCfop']));

                                document.getElementById('inputCodigoProduto').value = returnIfDefined(data['CodProduto']);
                                document.getElementById('descriptionCodigoProduto').innerHTML = returnIfDefined(data['DescricaoProduto']);
                                validatorProdutos.update();

                                document.getElementById('inputCodigoGrade1').value = returnIfDefined(data['CodItemGrade1']);
                                document.getElementById('descriptionCodigoGrade1').innerHTML = data['DescricaoItemGrade1'] ? ' - ' + returnIfDefined(data['DescricaoItemGrade1']) : "";
                                data['HaveGrade1'] ? validatorGrade1.enable() : validatorGrade1.disable();
                                validatorGrade1.update();

                                document.getElementById('inputCodigoGrade2').value = returnIfDefined(data['CodItemGrade2']);
                                document.getElementById('descriptionCodigoGrade2').innerHTML = data['DescricaoItemGrade2'] ? ' - ' + returnIfDefined(data['DescricaoItemGrade2']) : "";
                                data['HaveGrade2'] ? validatorGrade2.enable() : validatorGrade2.disable();
                                validatorGrade2.update();

                                document.getElementById('inputCodigoGrade3').value = returnIfDefined(data['CodItemGrade3']);
                                document.getElementById('descriptionCodigoGrade3').innerHTML = data['DescricaoItemGrade3'] ? ' - ' + returnIfDefined(data['DescricaoItemGrade3']) : "";
                                data['HaveGrade3'] ? validatorGrade3.enable() : validatorGrade3.disable();
                                validatorGrade3.update();

                                document.getElementById('fieldItemComplemento').value = returnIfDefined(data['Complemento']); //TODO: alterar para padrão
                                document.getElementById('inputQuantidade').value = returnIfDefined(data['Quantidade']).replace('.', '').replace(',', '.');
                                document.getElementById('inputValorUnitario').value = returnIfDefined(data['ValorUnitario']).replace('.', '').replace(',', '.');
                                document.getElementById('inputValorAliquotaIcms').value = returnIfDefined(data['AliquotaIcms']).replace('.', '').replace(',', '.');
                                document.getElementById('inputValorAliquotaIpi').value = returnIfDefined(data['AliquotaIpi']).replace('.', '').replace(',', '.');
                                document.getElementById('inputValorAliquotaIcmsSt').value = returnIfDefined(data['AliquotaIcmsSt']).replace('.', '').replace(',', '.');
                                document.getElementById('inputNumeroOc').value = returnIfDefined(data['NumeroOrdemCompra']);
                                document.getElementById('inputItemPed').value = returnIfDefined(data['ItemPed']);
                                document.getElementById('inputDataEntrega').value = returnIfDefined(data['DataEntrega']);

                                if (data['DesabilitarLivreCobranca']) {
                                    u.disable('inputLivreCobranca');
                                    document.getElementById('inputLivreCobranca').checked = true;
                                } else {
                                    u.enable('inputLivreCobranca');
                                    document.getElementById('inputLivreCobranca').checked = returnIfDefined(data['LivreCobranca']);
                                }

                                if (data['DescontoEmPercentual']) {
                                    document.getElementById('inputDescontoUnitario').value = returnIfDefined(data['PercentualDescontoUnitario']).replace('.', '').replace(',', '.');
                                    document.getElementById('spanPercentualOuMoeda').innerHTML = '%';
                                } else {
                                    document.getElementById('inputDescontoUnitario').value = returnIfDefined(data['ValorDescontoUnitario']).replace('.', '').replace(',', '.');
                                    document.getElementById('spanPercentualOuMoeda').innerHTML = '$';
                                }

                                $("#inputValorUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                $("#inputDescontoUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                $("#inputQuantidade")[0].setAttribute("radarmask", "radar-valor-8-" + data['CasasDecimaisQuantidade'] + "-R");
                                $('#spanPercentualOuMoeda').css('cursor', 'pointer');

                                if (data.Status === 'X') {
                                    setPermissions();
                                    setMask();
                                    validatorProdutos.update();

                                    validatorTabelaPrecos.disable();
                                    validatorCfopItem.disable();
                                    validatorProdutos.disable();
                                    validatorGrade1.disable();
                                    validatorGrade2.disable();
                                    validatorGrade3.disable();
                                    u.disable('fieldItemComplemento');
                                    u.disable('inputQuantidade');
                                    u.disable('inputValorUnitario');
                                    u.disable('inputValorAliquotaIcms');
                                    u.disable('inputValorAliquotaIpi');
                                    u.disable('inputValorAliquotaIcmsSt');
                                    u.disable('inputNumeroOc');
                                    u.disable('inputItemPed');
                                    u.disable('inputDataEntrega');
                                    u.disable('inputDescontoUnitario');
                                    u.disable('spanPercentualOuMoeda');
                                    u.disable('buttonAlterarItem');
                                    u.disable('buttonRemoverInvalidarItem');
                                    u.disable('inputLivreCobranca');
                                    u.disable('buttonAdicionarItem');
                                } else {
                                    u.enable('inputQuantidade');
                                    u.enable('inputValorUnitario');
                                    u.enable('inputDescontoUnitario');
                                    u.enable('spanPercentualOuMoeda');
                                    u.enable('buttonAlterarItem');
                                    u.enable('buttonRemoverInvalidarItem');
                                    u.disable('buttonAdicionarItem');

                                    setPermissions();
                                    setMask();
                                    validatorProdutos.update();
                                }
                            }
                        },
                        onDataBound: function () {
                            var el = $('.k-grid-content');
                            el[0].style.height = "118px";
                            el[1].style.height = "108px";
                            enableFieldSelectCondicaoPagamento();
                        },
                        dataSourceType: "Filtered"
                    });
                    gridItens.make();

                    // tabela preco
                    var validatorTabelaPrecos = new Validator({
                        field: 'CodigoTabelaPrecos',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da tabela de preços.",
                        route: 'Empresarial/F4TabelaPrecoProdutos/GetTabPreco',
                        onValid: function (data) {
                            document.getElementById('inputCodigoTabelaPrecos').value = data['Codigo'];
                            document.getElementById('descriptionCodigoTabelaPrecos').innerHTML = data['Nome'];
                            clearProdutoBeforeInsert();
                            tableProdutos.refresh();
                            modalProdutos.exibirHierarquia_SetParams("CodigoTabelaPrecos", validatorTabelaPrecos.value);
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(1);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                            modalProdutos.exibirHierarquia_SetParams("CodigoTabelaPrecos", validatorTabelaPrecos.value);
                        },
                        onEmpty: function () {
                            modalProdutos.exibirHierarquia_SetParams("CodigoTabelaPrecos", validatorTabelaPrecos.value);
                        }
                    });
                    validatorTabelaPrecos.listen();
                    validatorTabelaPrecos.update();

                    var tableTabelaPrecosProduto = new Table({
                        'id': 'tablePrecosProduto',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Empresarial/F4TabelaPrecoProdutos/GetTabPrecos',
                        'showFilter': true,
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Nome', field: 'Nome', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Validade', field: 'DataValidade', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'onChange': function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableTabelaPrecosProduto.getSelectedData();
                                document.getElementById('inputCodigoTabelaPrecos').value = data['Codigo'];
                                document.getElementById('descriptionCodigoTabelaPrecos').innerHTML = data['Nome'];
                                validatorTabelaPrecos.update();
                                validatorTabelaPrecos.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#tablePrecosProduto table  tr').on('dblclick', function () {
                                var data = tableTabelaPrecosProduto.getSelectedData();
                                document.getElementById('inputCodigoTabelaPrecos').value = data['Codigo'];
                                document.getElementById('descriptionCodigoTabelaPrecos').innerHTML = data['Nome'];
                                validatorTabelaPrecos.update();
                                validatorTabelaPrecos.validate();
                                $('#modalTabPrecosProduto').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalTabelaPrecos = document.getElementById('linkButtonModalTabelaPrecos');
                    var inputTabelaPrecos = document.getElementById('inputCodigoTabelaPrecos');
                    var modalTabelasPrecosProdutos = new Modal('Tabelas Preços Produtos', linkButtonModalTabelaPrecos, inputTabelaPrecos, tableTabelaPrecosProduto);
                    modalTabelasPrecosProdutos.listen();

                    // cfop item
                    var validatorCfopItem = new Validator({
                        field: 'CodigoCfopItem',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informada a CFOP do item.',
                        route: 'Comercial/F4CfopItemPedido/GetCfop',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorFilial, validatorCliente],
                        onValid: function (data) {
                            document.getElementById('inputCodigoCfopItem').value = data.Classificacao;
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = data.Nome;
                            validateIntegracaoCfopFinanceiro(data.EfetuarLancamentoFinanceiro);
                            setPermissions();
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(1);
                            self.clear({ warning: true, focus: true });
                            validateIntegracaoCfopFinanceiro(true);
                            setPermissions();
                        },
                        onEmpty: function () {
                            setPermissions();
                            validateIntegracaoCfopFinanceiro(true);
                        }
                    });
                    validatorCfopItem.listen();
                    validatorCfopItem.update();

                    var tableCfopItem = new Table({
                        id: 'tableCfopItem',
                        msgDialog: true,
                        route: window.baseUrl + 'Comercial/F4CfopItemPedido/GetCfopsItemPedidoProxy',
                        GuidProxy: GuidProxy.getValue(),
                        showFilter: true,
                        columns: [
                            { title: 'Classificação', field: 'Classificacao', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Nome', field: 'Nome', width: 275, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Filial', field: 'NomeFilial', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } }
                        ],
                        columnsLegend: { Classificacao: "Ex: 1.101" },
                        params: [validatorFilial, validatorCliente],
                        onParams: function () {
                            u.alterTab(0);
                        },
                        onChange: function () {
                            'use strict';
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableCfopItem.getSelectedData();
                                document.getElementById('inputCodigoCfopItem').value = data.Classificacao;
                                document.getElementById('descriptionCodigoCfopItem').innerHTML = data.Nome;
                                validatorCfopItem.update();
                                validatorCfopItem.validate();
                            };
                        },
                        onDataBound: function () {
                            $('#tableCfopItem table tr').on('dblclick', function () {
                                var data = tableCfopItem.getSelectedData();
                                document.getElementById('inputCodigoCfopItem').value = data.Classificacao;
                                document.getElementById('descriptionCodigoCfopItem').innerHTML = data.Nome;
                                validatorCfopItem.update();
                                validatorCfopItem.validate();
                                $('#modalCfopItem').modal('hide');
                            });
                        },
                        dataSourceType: 'Mixed'
                    });
                    var linkButtonModalCfopItem = document.getElementById('linkButtonModalCfopItem');
                    var inputCfopItem = document.getElementById('inputCodigoCfopItem');
                    var modalCfopItem = new Modal('CFOP Item', linkButtonModalCfopItem, inputCfopItem, tableCfopItem);
                    modalCfopItem.listen();

                    // produto
                    var validatorProdutos = new Validator({
                        field: 'CodigoProduto',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código do produto.",
                        route: 'Comercial/F4ProdutoPedido/GetProdutoProxy',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorTabelaPrecos, validatorFilial],
                        onValid: function (data) {
                            validatorProdutos.setChange(true);
                            var selected = gridItens.getSelectedData();

                            if (selected) {
                                if (selected.CodProduto != data['Codigo']) {
                                    validatorGrade1.disable();
                                    validatorGrade2.disable();
                                    validatorGrade3.disable();
                                    u.disable('inputQuantidade');
                                    u.disable('inputValorUnitario');
                                    u.disable('inputDescontoUnitario');
                                    u.disable('spanPercentualOuMoeda');
                                    $('#spanPercentualOuMoeda').css('cursor', 'default');
                                    u.disable('buttonAlterarItem');
                                    u.disable('buttonRemoverInvalidarItem');
                                    u.enable('buttonAdicionarItem');
                                    gridItens.clearSelectedData();
                                }
                            }

                            clearCurrentItem(false);

                            document.getElementById('inputCodigoProduto').value = data['Codigo'];
                            document.getElementById('descriptionCodigoProduto').innerHTML = data['Nome'];
                            document.getElementById('inputValorUnitario').value = data['ValorUnitario'];
                            document.getElementById('inputValorAliquotaIcms').value = data['ValorAliquotaIcms'].toCasasDecimais(2);
                            document.getElementById('inputValorAliquotaIpi').value = data['ValorAliquotaIPI'].toCasasDecimais(2);
                            document.getElementById('inputValorAliquotaIcmsSt').value = data['ValorAliquotaIcmsSt'].toCasasDecimais(2);

                            if (data['HaveGrade3'])
                                validatorGrade3.enable();
                            else
                                validatorGrade3.disable();

                            if (data['HaveGrade2'])
                                validatorGrade2.enable();
                            else
                                validatorGrade2.disable();

                            if (data['HaveGrade1'])
                                validatorGrade1.enable();
                            else
                                validatorGrade1.disable();

                            validatorGrade1.update();
                            validatorGrade2.update();
                            validatorGrade3.update();

                            u.enable('inputQuantidade');
                            u.enable('inputValorUnitario');
                            u.enable('inputDescontoUnitario');
                            u.enable('spanPercentualOuMoeda');
                            $('#spanPercentualOuMoeda').css('cursor', 'pointer');

                            $("#inputValorUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                            $("#inputDescontoUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                            $("#inputQuantidade")[0].setAttribute("radarmask", "radar-valor-8-" + data['CasasDecimaisQuantidade'] + "-R");
                            alterControlGroupBehavior('inputValorUnitario', controlGroupBehavior.normal);
                            setMask();
                            setPermissions();

                            // sugere OC nos itens
                            if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                            else 
                                $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                        },
                        onInvalid: function () {
                            validatorProdutos.setChange(true);
                            validatorGrade1.disable();
                            validatorGrade2.disable();
                            validatorGrade3.disable();

                            u.disable('inputQuantidade');
                            u.disable('inputValorUnitario');
                            u.disable('inputDescontoUnitario');
                            u.disable('spanPercentualOuMoeda');
                            $('#spanPercentualOuMoeda').css('cursor', 'default');

                            var self = this;
                            u.alterTab(1);
                            self.focus();
                            self.value = "";
                            self.input.value = "";

                            // sugere OC nos itens
                            if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                            else
                                $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                        },
                        onEmpty: function () {
                            validatorProdutos.setChange(true);
                            validatorGrade1.disable();
                            validatorGrade2.disable();
                            validatorGrade3.disable();

                            u.disable('inputQuantidade');
                            u.disable('inputValorUnitario');
                            u.disable('inputDescontoUnitario');
                            u.disable('spanPercentualOuMoeda');
                            $('#spanPercentualOuMoeda').css('cursor', 'default');
                            u.disable('buttonAlterarItem');
                            u.disable('buttonRemoverInvalidarItem');
                            u.enable('buttonAdicionarItem');

                            clearCurrentItem(false);
                            gridItens.clearSelectedData();

                            // sugere OC nos itens
                            if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                            else
                                $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                        }
                    });
                    validatorProdutos.listen();

                    var tableProdutos = new Table({
                        'id': 'tableProdutos',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4ProdutoPedido/GetProdutos',
                        'showFilter': true,
                        'columns': [
                            { title: 'Código', field: 'Codigo', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Nome', field: 'Nome', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Unidade', field: 'Unidade', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Preço', field: 'ValorUnitario', width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                            { title: 'Classificação', field: 'Classificacao', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        'columnsLegend': { Classificacao: "Ex: 1.101" },
                        'params': [validatorFilial, validatorTabelaPrecos],
                        onParams: function (validator) {
                            if (validator.field === "CodigoFilial")
                                u.alterTab(0);
                        },
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                validatorProdutos.setChange(true);
                                var data = tableProdutos.getSelectedData(),
                                    search = {};

                                search['CodigoProduto'] = data['Codigo'];
                                search['CodigoTabelaPrecos'] = document.getElementById('inputCodigoTabelaPrecos').value;
                                GuidProxy.addParam(search);

                                getJsonFromRoute('Comercial/F4ProdutoPedido/GetProdutoProxy', search).done(function (produto) {
                                    if (data.IsAlert)
                                        throw new Error(data.Message);

                                    document.getElementById('inputCodigoProduto').value = produto['Codigo'];
                                    document.getElementById('descriptionCodigoProduto').innerHTML = produto['Nome'];
                                    document.getElementById('inputValorUnitario').value = produto['ValorUnitario'];
                                    document.getElementById('inputValorAliquotaIcms').value = produto['ValorAliquotaIcms'].toCasasDecimais(2);
                                    document.getElementById('inputValorAliquotaIpi').value = produto['ValorAliquotaIPI'].toCasasDecimais(2);
                                    document.getElementById('inputValorAliquotaIcmsSt').value = produto['ValorAliquotaIcmsSt'].toCasasDecimais(2);

                                    data['HaveGrade1'] ? validatorGrade1.enable() : validatorGrade1.disable();
                                    data['HaveGrade2'] ? validatorGrade2.enable() : validatorGrade2.disable();
                                    data['HaveGrade3'] ? validatorGrade3.enable() : validatorGrade3.disable();

                                    u.enable('inputQuantidade');
                                    u.enable('inputValorUnitario');
                                    u.enable('inputDescontoUnitario');
                                    u.enable('spanPercentualOuMoeda');
                                    $('#spanPercentualOuMoeda').css('cursor', 'pointer');

                                    $("#inputValorUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                    $("#inputDescontoUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                    $("#inputQuantidade")[0].setAttribute("radarmask", "radar-valor-8-" + data['CasasDecimaisQuantidade'] + "-R");

                                    setMask();
                                    validatorProdutos.update();
                                    validatorProdutos.validate();
                                    setPermissions();

                                    // sugere OC nos itens
                                    if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                        $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                                    else
                                        $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                                });
                            };
                        },
                        'onDataBound': function () {
                            $('#tableProdutos table  tr').on('dblclick', function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                validatorProdutos.setChange(true);
                                var data = tableProdutos.getSelectedData(),
                                    search = {};

                                search['CodigoProduto'] = data['Codigo'];
                                search['CodigoTabelaPrecos'] = document.getElementById('inputCodigoTabelaPrecos').value;
                                GuidProxy.addParam(search);

                                getJsonFromRoute('Comercial/F4ProdutoPedido/GetProdutoProxy', search).done(function (produto) {
                                    if (data.IsAlert)
                                        throw new Error(data.Message);

                                    document.getElementById('inputCodigoProduto').value = produto['Codigo'];
                                    document.getElementById('descriptionCodigoProduto').innerHTML = produto['Nome'];
                                    document.getElementById('inputValorUnitario').value = produto['ValorUnitario'];
                                    document.getElementById('inputValorAliquotaIcms').value = produto['ValorAliquotaIcms'].toCasasDecimais(2);
                                    document.getElementById('inputValorAliquotaIpi').value = produto['ValorAliquotaIPI'].toCasasDecimais(2);
                                    document.getElementById('inputValorAliquotaIcmsSt').value = produto['ValorAliquotaIcmsSt'].toCasasDecimais(2);

                                    data['HaveGrade1'] ? validatorGrade1.enable() : validatorGrade1.disable();
                                    data['HaveGrade2'] ? validatorGrade2.enable() : validatorGrade2.disable();
                                    data['HaveGrade3'] ? validatorGrade3.enable() : validatorGrade3.disable();

                                    u.enable('inputQuantidade');
                                    u.enable('inputValorUnitario');
                                    u.enable('inputDescontoUnitario');
                                    u.enable('spanPercentualOuMoeda');
                                    $('#spanPercentualOuMoeda').css('cursor', 'pointer');

                                    $("#inputValorUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                    $("#inputDescontoUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + data['CasasDecimaisValorUnitario'] + "-R");
                                    $("#inputQuantidade")[0].setAttribute("radarmask", "radar-valor-8-" + data['CasasDecimaisQuantidade'] + "-R");

                                    setMask();
                                    validatorProdutos.update();
                                    validatorProdutos.validate();
                                    setPermissions();

                                    // sugere OC nos itens
                                    if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                        $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                                    else
                                        $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                                });

                                $('#modalProdutos').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalProdutos = document.getElementById('linkButtonModalProdutos');
                    var inputProdutos = document.getElementById('inputCodigoProduto');

                    // hierarquia
                    var options = {
                        showOpcaoExibir: true,
                        urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                        exibirHierarquiaParams: {
                            ClassificacaoNoPai: "",
                            CodigoTabelaPrecos: validatorTabelaPrecos.value
                        },
                        onDblClickGetItem: function (event, dados) {
                            // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                            validatorProdutos.setChange(true);
                            var data = dados,
                                search = {};

                            search['CodigoProduto'] = data['Codigo'];
                            search['CodigoTabelaPrecos'] = document.getElementById('inputCodigoTabelaPrecos').value;
                            GuidProxy.addParam(search);

                            getJsonFromRoute('Comercial/F4ProdutoPedido/GetProdutoProxy', search).done(function (produto) {
                                if (produto.IsAlert)
                                    throw new Error(produto.Message);

                                document.getElementById('inputCodigoProduto').value = produto['Codigo'];
                                document.getElementById('descriptionCodigoProduto').innerHTML = produto['Nome'];
                                document.getElementById('inputValorUnitario').value = produto['ValorUnitario'];
                                document.getElementById('inputValorAliquotaIcms').value = produto['ValorAliquotaIcms'].toCasasDecimais(2);
                                document.getElementById('inputValorAliquotaIpi').value = produto['ValorAliquotaIPI'].toCasasDecimais(2);
                                document.getElementById('inputValorAliquotaIcmsSt').value = produto['ValorAliquotaIcmsSt'].toCasasDecimais(2);

                                produto['HaveGrade1'] ? validatorGrade1.enable() : validatorGrade1.disable();
                                produto['HaveGrade2'] ? validatorGrade2.enable() : validatorGrade2.disable();
                                produto['HaveGrade3'] ? validatorGrade3.enable() : validatorGrade3.disable();

                                u.enable('inputQuantidade');
                                u.enable('inputValorUnitario');
                                u.enable('inputDescontoUnitario');
                                u.enable('spanPercentualOuMoeda');
                                $('#spanPercentualOuMoeda').css('cursor', 'pointer');

                                $("#inputValorUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + produto['CasasDecimaisValorUnitario'] + "-R");
                                $("#inputDescontoUnitario")[0].setAttribute("radarmask", "radar-valor-16-" + produto['CasasDecimaisValorUnitario'] + "-R");
                                $("#inputQuantidade")[0].setAttribute("radarmask", "radar-valor-8-" + produto['CasasDecimaisQuantidade'] + "-R");

                                setMask();
                                validatorProdutos.update();
                                validatorProdutos.validate();
                                setPermissions();

                                // sugere OC nos itens
                                if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled"))
                                    $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                                else
                                    $("#inputNumeroOc").val($("#inputNumeroOc").attr("valorBkp"));
                            });

                            $('#modalProdutos').modal('hide');
                        }
                    };

                    var modalProdutos = new Modal('Produtos', linkButtonModalProdutos, inputProdutos, tableProdutos, null, options);
                    modalProdutos.listen();

                    // F4 Grades
                    var columnsGrade = [
                        { title: 'Código', field: 'Codigo', width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        { title: 'Descrição', field: 'Descricao', width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                    ];

                    // grade1
                    var validatorGrade1 = new Validator({
                        field: 'CodigoGrade1',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informada a grade 1.",
                        route: 'Comercial/F4ProdutoPedido/GetItemGrade1',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorProdutos, validatorTabelaPrecos],
                        onValid: function (data) {
                            validatorGrade1.setChange(true);
                            document.getElementById('inputCodigoGrade1').value = data['Codigo'];
                            document.getElementById('descriptionCodigoGrade1').innerHTML = ' - ' + data['Descricao'];

                            if (data['ValorUnitarioAtualizadoDoProduto'] !== "")
                                document.getElementById('inputValorUnitario').value = data['ValorUnitarioAtualizadoDoProduto'];
                        },
                        onInvalid: function () {
                            validatorGrade1.setChange(true);
                            var self = this;
                            u.alterTab(1);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorGrade1.listen();

                    var tableGrade1 = new Table({
                        'id': 'tableGrade1',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4ProdutoPedido/List1',
                        'showFilter': true,
                        'columns': columnsGrade,
                        'params': [validatorProdutos, validatorTabelaPrecos],
                        "fieldDepende": validatorProdutos,
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                validatorGrade1.setChange(true);
                                var data = tableGrade1.getSelectedData();
                                document.getElementById('inputCodigoGrade1').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade1').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade1.update();
                                validatorGrade1.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#' + this.id + ' table  tr').on('dblclick', function () {
                                validatorGrade1.setChange(true);
                                var data = tableGrade1.getSelectedData();
                                document.getElementById('inputCodigoGrade1').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade1').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade1.update();
                                validatorGrade1.validate();

                                $('#modalGrade1').modal('hide');
                            });
                        },
                        'dataSourceType': "Parameter"
                    });

                    // grade2
                    var validatorGrade2 = new Validator({
                        field: 'CodigoGrade2',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informada a grade 2.",
                        route: 'Comercial/F4ProdutoPedido/GetItemGrade2',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorGrade1, validatorProdutos, validatorTabelaPrecos],
                        onValid: function (data) {
                            validatorGrade2.setChange(true);
                            document.getElementById('inputCodigoGrade2').value = data['Codigo'];
                            document.getElementById('descriptionCodigoGrade2').innerHTML = ' - ' + data['Descricao'];

                            if (data['ValorUnitarioAtualizadoDoProduto'] !== "")
                                document.getElementById('inputValorUnitario').value = data['ValorUnitarioAtualizadoDoProduto'];
                        },
                        onInvalid: function () {
                            validatorGrade2.setChange(true);
                            var self = this;
                            u.alterTab(1);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorGrade2.listen();

                    var tableGrade2 = new Table({
                        'id': 'tableGrade2',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4ProdutoPedido/List2',
                        'showFilter': true,
                        'columns': columnsGrade,
                        'params': [validatorGrade1, validatorProdutos, validatorTabelaPrecos],
                        "fieldDepende": validatorGrade1,
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                validatorGrade2.setChange(true);
                                var data = tableGrade2.getSelectedData();
                                document.getElementById('inputCodigoGrade2').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade2').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade2.update();
                                validatorGrade2.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#' + this.id + ' table  tr').on('dblclick', function () {
                                validatorGrade2.setChange(true);
                                var data = tableGrade2.getSelectedData();
                                document.getElementById('inputCodigoGrade2').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade2').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade2.update();
                                validatorGrade2.validate();

                                $('#modalGrade2').modal('hide');
                            });
                        },
                        'dataSourceType': "Parameter"
                    });

                    // grade3
                    var validatorGrade3 = new Validator({
                        field: 'CodigoGrade3',
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informada a grade 3.",
                        route: 'Comercial/F4ProdutoPedido/GetItemGrade3',
                        GuidProxy: GuidProxy.getValue(),
                        pendency: [validatorGrade2, validatorGrade1, validatorProdutos, validatorTabelaPrecos],
                        onValid: function (data) {
                            validatorGrade3.setChange(true);
                            document.getElementById('inputCodigoGrade3').value = data['Codigo'];
                            document.getElementById('descriptionCodigoGrade3').innerHTML = ' - ' + data['Descricao'];

                            if (data['ValorUnitarioAtualizadoDoProduto'] !== "")
                                document.getElementById('inputValorUnitario').value = data['ValorUnitarioAtualizadoDoProduto'];
                        },
                        onInvalid: function () {
                            validatorGrade3.setChange(true);
                            var self = this;
                            u.alterTab(1);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorGrade3.listen();

                    var tableGrade3 = new Table({
                        'id': 'tableGrade3',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Comercial/F4ProdutoPedido/List3',
                        'showFilter': true,
                        'columns': columnsGrade,
                        'params': [validatorGrade2, validatorGrade1, validatorProdutos, validatorTabelaPrecos],
                        'fieldDepende': validatorGrade2,
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                validatorGrade3.setChange(true);
                                var data = tableGrade2.getSelectedData();
                                document.getElementById('inputCodigoGrade3').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade3').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade3.update();
                                validatorGrade3.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#' + this.id + ' table  tr').on('dblclick', function () {
                                validatorGrade3.setChange(true);
                                var data = tableGrade3.getSelectedData();
                                document.getElementById('inputCodigoGrade3').value = data['Codigo'];
                                document.getElementById('descriptionCodigoGrade3').innerHTML = ' - ' + data['Descricao'];
                                validatorGrade3.update();
                                validatorGrade3.validate();

                                $('#modalGrade3').modal('hide');
                            });
                        },
                        'dataSourceType': "Parameter"
                    });

                    // listens produto
                    var linkButtonModalGrade1 = document.getElementById('linkButtonModalGrade1');
                    var linkButtonModalGrade2 = document.getElementById('linkButtonModalGrade2');
                    var linkButtonModalGrade3 = document.getElementById('linkButtonModalGrade3');

                    var inputGrade1 = document.getElementById('inputCodigoGrade1');
                    var inputGrade2 = document.getElementById('inputCodigoGrade2');
                    var inputGrade3 = document.getElementById('inputCodigoGrade3');

                    var modalGrade1 = new Modal('Grade', linkButtonModalGrade1, inputGrade1, tableGrade1);
                    var modalGrade2 = new Modal('Grade', linkButtonModalGrade2, inputGrade2, tableGrade2);
                    var modalGrade3 = new Modal('Grade', linkButtonModalGrade3, inputGrade3, tableGrade3);

                    modalGrade1.listen();
                    modalGrade2.listen();
                    modalGrade3.listen();

                    listenToggleProdutoGradesF4();

                    // quantidade
                    $('#inputQuantidade').on('change', checkQuantidade);
                    function checkQuantidade() {
                        "use strict";

                        if (validatorTabelaPrecos.invalid) {
                            u.alterTab(1);
                            u.dialogOk(validatorTabelaPrecos.onPendencyMessage, null, true, function () {
                                validatorTabelaPrecos.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            throw new Error(validatorTabelaPrecos.onPendencyMessage);
                        }

                        if (validatorProdutos.invalid) {
                            u.alterTab(1);
                            u.dialogOk(validatorProdutos.onPendencyMessage, null, true, function () {
                                validatorProdutos.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            throw new Error(validatorProdutos.onPendencyMessage);
                        }

                        var search = {};
                        search['Quantidade'] = byId("inputQuantidade").value.replace(/\./g, '').replace(/\,/g, '.');
                        search['CodigoTabelaPreco'] = validatorTabelaPrecos.value;
                        search['CodigoProduto'] = validatorProdutos.value;
                        GuidProxy.addParam(search);
                        getJsonFromRoute("Comercial/F4ProdutoPedido/CheckQuantidade", search).done(function (data) {
                            if (data.IsAlert) {
                                if (data.Level == alertLevel.error) {
                                    u.dialogOk(data.Message, null, true, function () {
                                        alterControlGroupBehavior("inputQuantidade", controlGroupBehavior.warning);
                                        $("#inputQuantidade").focus();
                                    }, alertBehavior.warning);
                                    throw new Error(data.Message);
                                }
                                if (data.Level == alertLevel.normal) {
                                    u.dialogOk(data.Message, null, true, function () {
                                        alterControlGroupBehavior("inputQuantidade", controlGroupBehavior.normal);
                                        $("#inputValorUnitario").focus();
                                    }, alertBehavior.warning);
                                }
                            }
                            alterControlGroupBehavior("inputQuantidade", controlGroupBehavior.normal);
                        });
                    }

                    // valor unitario
                    $('#inputValorUnitario').on('blur', function () {
                        "use strict";
                        var cmp = this.value.toFloat().compare(0);
                        if (cmp == 'greater') {
                            alterControlGroupBehavior(this.id, controlGroupBehavior.normal);
                        }
                    });

                    // valor desconto
                    $('#inputDescontoUnitario').on('blur', function () {
                        var arrMask = $('#inputDescontoUnitario')[0].getAttribute('radarmask').split('-');
                        var casasDecimais = arrMask[arrMask.length - 2].toInt();
                        var desconto = document.getElementById('inputDescontoUnitario').value.toFloat().toFixed(casasDecimais).toFloat();

                        if (isDescontoEmPercentual()) {
                            var cem = new Number(100).toFixed(casasDecimais).toFloat();

                            if (desconto > cem) {
                                u.dialogOk(
                                    'Desconto percentual não pode ultrapassar 100%.',
                                    null,
                                    true,
                                    function () {
                                        document.getElementById('inputDescontoUnitario').focus();
                                    },
                                    alertBehavior.warning
                                );
                            }
                        } else {
                            var valor = document.getElementById('inputValorUnitario').value.toFloat().toFixed(casasDecimais).toFloat();

                            if (desconto > valor) {
                                u.dialogOk(
                                    'Desconto unitário  deve ser menor ou igual ao valor unitário.',
                                    null,
                                    true,
                                    function () {
                                        document.getElementById('inputDescontoUnitario').focus();
                                    },
                                    alertBehavior.warning
                                );
                            }
                        }
                    });

                    // sugere OC nos itens, quando altera OC do pedido
                    $("#fieldNumeroOrdemCompraCliente").on("change", function () {
                        if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled")) {
                            $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                        }
                    });

                    // data entrega
                    var inputDataEntregaValidator = new DateValidator({
                        id: "inputDataEntrega",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker('#' + this.id);
                        },
                        isEmptyValid: true,
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                            validateDate('inputDataEntrega', 1);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalidDialog(validator, function () {
                                u.alterTab(1);
                                inputDataEntregaValidator.clear();
                                inputDataEntregaValidator.focus(alertBehavior.warning);
                            });
                        }
                    });

                    // proxima aba
                    $('#buttonAdicionarItem').on('keydown', function (ev) {
                        var key = ev.which || ev.keyCode;
                        if (key == 9) {
                            u.alterTab(2);
                            $('#fieldValorTotalDesconto').focus();
                        }
                    });

                    // buttons
                    $('#buttonAdicionarItem').on('click', adicionarItem);
                    $('#buttonAlterarItem').on('click', alterarItem);
                    $('#spanPercentualOuMoeda').on('click', toggleDescontoUnitario);
                    $('#buttonRemoverInvalidarItem').on('click', function () {
                        if (params.Pedido.IsAlteracao)
                            invalidarItem();
                        else
                            removerItem();
                    });

                    //
                    // functions itens
                    //

                    function calcDescontoUnitario(deMoedaParaPercentual) {
                        var arrMask = $('#inputDescontoUnitario')[0].getAttribute('radarmask').split('-');
                        var casasDecimais = arrMask[arrMask.length - 2].toInt();

                        if (document.getElementById('inputDescontoUnitario').value === "")
                            return new Number(0).toFixed(casasDecimais);

                        var desconto = document.getElementById('inputDescontoUnitario').value.toFloat().toFixed(casasDecimais);
                        var valor = document.getElementById('inputValorUnitario').value.toFloat().toFixed(casasDecimais);
                        var cem = new Number(100).toFixed(casasDecimais);

                        if (deMoedaParaPercentual)
                            return new Number(desconto * cem / valor).toFixed(casasDecimais);
                        else
                            return new Number(desconto * valor / cem).toFixed(casasDecimais);
                    }

                    function isDescontoEmPercentual() {
                        return document.getElementById('spanPercentualOuMoeda').innerHTML === '%';
                    }

                    function toggleDescontoUnitario() {
                        if (isFieldEnabled('spanPercentualOuMoeda')) {
                            if (isDescontoEmPercentual()) { //em modo percentual
                                document.getElementById('spanPercentualOuMoeda').innerHTML = '$';
                                document.getElementById('inputDescontoUnitario').value = calcDescontoUnitario(false).toString().replace('.', ',');
                            } else { //em modo moeda
                                document.getElementById('spanPercentualOuMoeda').innerHTML = '%';
                                document.getElementById('inputDescontoUnitario').value = calcDescontoUnitario(true).toString().replace('.', ',');
                            }
                        }
                    }

                    function clearCurrentItem(sugerirCfop) {
                        if (sugerirCfop) {
                            document.getElementById('inputCodigoCfopItem').value = document.getElementById('inputCodigoCfop').value;
                            document.getElementById('descriptionCodigoCfopItem').innerHTML = document.getElementById('descriptionCodigoCfop').innerHTML;
                        }

                        document.getElementById('inputCodigoProduto').value = "";
                        document.getElementById('descriptionCodigoProduto').innerHTML = "";
                        document.getElementById('inputCodigoGrade1').value = "";
                        document.getElementById('descriptionCodigoGrade1').innerHTML = "";
                        document.getElementById('inputCodigoGrade2').value = "";
                        document.getElementById('descriptionCodigoGrade2').innerHTML = "";
                        document.getElementById('inputCodigoGrade3').value = "";
                        document.getElementById('descriptionCodigoGrade3').innerHTML = "";
                        document.getElementById('fieldItemComplemento').value = ""; // TODO: alterar para o padrão
                        document.getElementById('inputQuantidade').value = "";
                        document.getElementById('inputValorUnitario').value = "";
                        document.getElementById('inputDescontoUnitario').value = "";
                        document.getElementById('spanPercentualOuMoeda').innerHTML = "$";
                        document.getElementById('inputValorAliquotaIcms').value = "";
                        document.getElementById('inputValorAliquotaIpi').value = "";
                        document.getElementById('inputValorAliquotaIcmsSt').value = "";
                        document.getElementById('inputNumeroOc').value = "";
                        document.getElementById('inputItemPed').value = "";
                        document.getElementById('inputDataEntrega').value = document.getElementById('inputPrincipalDataEntrega').value;
                        document.getElementById('inputLivreCobranca').value = "";

                        u.disable('inputQuantidade');
                        u.disable('inputValorUnitario');
                        u.disable('inputDescontoUnitario');
                        u.disable('spanPercentualOuMoeda');
                        $('#spanPercentualOuMoeda').css('cursor', 'default');
                        u.disable('inputCodigoGrade1');
                        u.disable('inputCodigoGrade2');
                        u.disable('inputCodigoGrade3');

                        setMask();
                    }

                    function getCurrentItem() {
                        "use strict";
                        var item = {};

                        validateDate('inputDataEntrega', 1);

                        if (validatorTabelaPrecos.invalid) {
                            u.alterTab(1);
                            u.dialogOk(validatorTabelaPrecos.onPendencyMessage, null, true, function () {
                                validatorTabelaPrecos.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            msgWait.hide();
                            throw new Error(validatorTabelaPrecos.onPendencyMessage);
                        }

                        if (validatorProdutos.invalid) {
                            u.alterTab(1);
                            u.dialogOk(validatorProdutos.onPendencyMessage, null, true, function () {
                                validatorProdutos.focus(controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            msgWait.hide();
                            throw new Error(validatorProdutos.onPendencyMessage);
                        }

                        item['CodTabelaPrecos'] = document.getElementById('inputCodigoTabelaPrecos').value;
                        item['CodCfop'] = document.getElementById('inputCodigoCfopItem').value;
                        item['CodProduto'] = document.getElementById('inputCodigoProduto').value;
                        item['CodItemGrade1'] = document.getElementById('inputCodigoGrade1').value || 0;
                        item['CodItemGrade2'] = document.getElementById('inputCodigoGrade2').value || 0;
                        item['CodItemGrade3'] = document.getElementById('inputCodigoGrade3').value || 0;
                        item['Complemento'] = document.getElementById('fieldItemComplemento').value; //TODO: alterar nome para padrão

                        var inputQuantidade = document.getElementById('inputQuantidade');
                        if (inputQuantidade.value.replace(/\./g, '').replace(/\,/g, '') == 0) {
                            u.alterTab(1);
                            var msgErroquantidade = '"Quantidade" deve ser informada.';
                            u.dialogOk(msgErroquantidade, null, true, function () {
                                inputQuantidade.focus();
                                alterControlGroupBehavior('inputQuantidade', controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            msgWait.hide();
                            throw new Error(msgErroquantidade);
                        } else {
                            alterControlGroupBehavior('inputQuantidade', controlGroupBehavior.normal);
                            item['Quantidade'] = inputQuantidade.value.replace(/\./g, '').replace(/\,/g, '.');
                        }

                        item['ValorUnitarioLiquido'] = document.getElementById('inputValorUnitario').value;

                        var inputValorUnitario = document.getElementById('inputValorUnitario');
                        if (inputValorUnitario.value.replace(/\./g, '').replace(/\,/g, '') == 0) {
                            u.alterTab(1);
                            var msgErroValor = '"Vlr. Unitário" deve ser informado.';
                            u.dialogOk(msgErroValor, null, true, function () {
                                inputValorUnitario.focus();
                                alterControlGroupBehavior('inputValorUnitario', controlGroupBehavior.warning);
                            }, alertBehavior.warning);
                            msgWait.hide();
                            throw new Error(msgErroValor);
                        } else {
                            alterControlGroupBehavior('inputValorUnitario', controlGroupBehavior.normal);
                            item['ValorUnitario'] = inputValorUnitario.value.replace(/\./g, '').replace(/\,/g, '.');
                        }

                        item['AliquotaIcms'] = document.getElementById('inputValorAliquotaIcms').value.replace(/\,/g, '.');
                        item['AliquotaIpi'] = document.getElementById('inputValorAliquotaIpi').value.replace(/\,/g, '.');
                        item['AliquotaIcmsSt'] = document.getElementById('inputValorAliquotaIcmsSt').value.replace(/\,/g, '.');
                        item['NumeroOrdemCompra'] = document.getElementById('inputNumeroOc').value;
                        item['ItemPed'] = document.getElementById('inputItemPed').value;
                        item['DataEntrega'] = document.getElementById('inputDataEntrega').value;
                        item['LivreCobranca'] = document.getElementById('inputLivreCobranca').checked;
                        
                        if (isFieldEnabled('inputDescontoUnitario')) {
                            if (isDescontoEmPercentual()) {
                                item['ValorDescontoUnitario'] = calcDescontoUnitario(false).toString().replace('.', ',');
                                item['PercentualDescontoUnitario'] = document.getElementById('inputDescontoUnitario').value.replace(/\./g, '').replace(/\,/g, '.');
                                item['DescontoEmPercentual'] = true;
                            } else {
                                item['ValorDescontoUnitario'] = document.getElementById('inputDescontoUnitario').value.replace(/\./g, '').replace(/\,/g, '.');
                                item['PercentualDescontoUnitario'] = calcDescontoUnitario(true).toString().replace('.', ',');
                                item['DescontoEmPercentual'] = false;
                            }
                        }

                        GuidProxy.addParam(item);

                        return item;
                    }

                    function afterItem() {
                        clearCurrentItem(true);
                        defaultSetIdCondicaoPagamento();
                        updateCondicoesPagamento();
                        defaultSetIdTipoCobranca();
                        gridItens.refresh();
                        updateFatura();
                        document.getElementById('inputCodigoTabelaPrecos').focus();

                        // sugere OC nos itens
                        $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                        $("#inputNumeroOc").data("podesugerir", true);
                        $("#inputNumeroOc").attr("valorBkp", "");

                        enableFieldSelectCondicaoPagamento();
                    }

                    function adicionarItem() {
                        "use strict";

                        alterouCampo = true;
                        var item = getCurrentItem();
                        item['Index'] = -1;

                        msgWait.show();
                        postJsonToRoute('Comercial/ItensPedido/AddItem', JSON.stringify(item)).done(function (data) {
                            msgWait.hide();
                            atualizaPesos(data.Pesos);

                            if (data.IsAlert) {
                                u.dialogOk(
                                    data.Message,
                                    null,
                                    true,
                                    function () {
                                        if (data.IsWrongQuantity) {
                                            alterControlGroupBehavior("inputQuantidade", u.getControlGroupBehavior(data.Level));
                                            $("#inputQuantidade").focus();
                                        }

                                        if (data.Level == alertLevel.warning)
                                            afterItem();
                                    },
                                    alertBehavior.warning
                                );

                                throw new Error(data.Message);
                            } else {
                                afterItem();
                            }
                        });
                    }

                    function alterarItem() {
                        "use strict";
                        alterouCampo = true;
                        var param = {};
                        param = getCurrentItem();
                        param['Index'] = gridItens.getSelectedData()['Sequencial'];
                        msgWait.show();

                        postJsonToRoute('Comercial/ItensPedido/ChangeItem', JSON.stringify(param)).done(function (data) {
                            msgWait.hide();
                            atualizaPesos(data.Pesos);

                            if (data.IsAlert) {
                                u.dialogOk(
                                    data.Message,
                                    null,
                                    true,
                                    function () {
                                        if (data.IsWrongQuantity) {
                                            alterControlGroupBehavior("inputQuantidade", u.getControlGroupBehavior(data.Level));
                                            $("#inputQuantidade").focus();
                                        }

                                        if (data.Level == alertLevel.warning) {
                                            afterItem();

                                            u.disable('buttonAlterarItem');
                                            u.disable('buttonRemoverInvalidarItem');
                                            u.enable('buttonAdicionarItem');
                                        }
                                    },
                                    alertBehavior.warning
                                );

                                throw new Error(data.Message);
                            } else {
                                afterItem();
                            }

                            u.disable('buttonAlterarItem');
                            u.disable('buttonRemoverInvalidarItem');
                            u.enable('buttonAdicionarItem');
                        });
                    }

                    function invalidarItem() {
                        "use strict";
                        var param = {};
                        param.Index = gridItens.getSelectedData()['Sequencial'];
                        GuidProxy.addParam(param);
                        msgWait.show();

                        postJsonToRoute('Comercial/ItensPedido/InvalidateItem', JSON.stringify(param)).done(
                            function (data) {
                                msgWait.hide();
                                atualizaPesos(data.Pesos);

                                if (data.IsAlert) {
                                    u.dialogOk(
                                        data.Message,
                                        null,
                                        true,
                                        function () {
                                            if (data.IsWrongQuantity) {
                                                alterControlGroupBehavior("inputQuantidade", u.getControlGroupBehavior(data.Level));
                                                $("#inputQuantidade").focus();
                                            }

                                            if (data.Level == alertLevel.warning) {
                                                afterItem();

                                                u.disable('buttonAlterarItem');
                                                u.disable('buttonRemoverInvalidarItem');
                                                u.enable('buttonAdicionarItem');
                                            }
                                        },
                                        alertBehavior.warning
                                    );

                                    throw new Error(data.Message);
                                } else {
                                    afterItem();
                                }

                                u.disable('buttonAlterarItem');
                                u.disable('buttonRemoverInvalidarItem');
                                u.enable('buttonAdicionarItem');
                            }
                        );
                    }

                    function removerItem() {
                        "use strict";

                        alterouCampo = true;
                        var param = {};
                        param.Index = gridItens.getSelectedData()['Sequencial'];
                        GuidProxy.addParam(param);
                        msgWait.show();

                        postJsonToRoute('Comercial/ItensPedido/DeleteItem', JSON.stringify(param)).done(function (data) {
                            msgWait.hide();
                            atualizaPesos(data.Pesos);

                            if (data.IsAlert) {
                                u.dialogOk(data.Message, null, true, null, data.Level);
                                throw new Error(data.Message);
                            }

                            clearCurrentItem(true);
                            u.disable('buttonAlterarItem');
                            u.disable('buttonRemoverInvalidarItem');
                            u.enable('buttonAdicionarItem');
                            defaultSetIdCondicaoPagamento();
                            updateCondicoesPagamento();
                            defaultSetIdTipoCobranca();
                            gridItens.refresh();
                            updateFatura();

                            // sugere OC nos itens
                            $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                            $("#inputNumeroOc").data("podesugerir", true);
                            $("#inputNumeroOc").attr("valorBkp", "");

                            enableFieldSelectCondicaoPagamento();
                        });
                    }

                    function atualizaPesos(pesos) {
                        if (pesos != undefined) {
                            $("#fieldPesoBruto").val(pesos.PesoBrutoTotal);
                            $("#fieldPesoLiquido").val(pesos.PesoLiquidoTotal);
                        }
                    }

                    function clearProdutoBeforeInsert() {
                        document.getElementById('inputCodigoProduto').value = "";
                        document.getElementById('inputCodigoGrade1').value = "";
                        document.getElementById('inputCodigoGrade2').value = "";
                        document.getElementById('inputCodigoGrade3').value = "";
                        document.getElementById('descriptionCodigoProduto').innerHTML = "";
                        document.getElementById('descriptionCodigoGrade1').innerHTML = "";
                        document.getElementById('descriptionCodigoGrade2').innerHTML = "";
                        document.getElementById('descriptionCodigoGrade3').innerHTML = "";
                        document.getElementById('fieldItemComplemento').value = "";

                        if (document.getElementById('inputQuantidade').value !== "0,0000")
                            document.getElementById('inputQuantidade').value = "";

                        if (document.getElementById('inputValorUnitario').value !== "0,00")
                            document.getElementById('inputValorUnitario').value = "";

                        if (document.getElementById('inputDescontoUnitario').value !== "0,00")
                            document.getElementById('inputDescontoUnitario').value = "";

                        if (document.getElementById('inputValorAliquotaIcms').value !== "0,00")
                            document.getElementById('inputValorAliquotaIcms').value = "";

                        if (document.getElementById('inputValorAliquotaIpi').value !== "0,00")
                            document.getElementById('inputValorAliquotaIpi').value = "";

                        if (document.getElementById('inputValorAliquotaIcmsSt').value !== "0,00")
                            document.getElementById('inputValorAliquotaIcmsSt').value = "";

                        document.getElementById('inputNumeroOc').value = "";
                        document.getElementById('inputItemPed').value = "";
                        document.getElementById('spanPercentualOuMoeda').innerHTML = "$";

                        if (document.getElementById('inputDataEntrega').value !== "00/00/0000")
                            document.getElementById('inputDataEntrega').value = "";
                    }

                    function validateIntegracaoCfopFinanceiro(efetuarLancamentoFinanceiro) {
                        if (params.Pedido.Permissoes.PodeAtivarCheckLivreCobranca) {
                            if (!efetuarLancamentoFinanceiro) {
                                document.getElementById('inputLivreCobranca').checked = true;
                                u.disable('inputLivreCobranca');
                            } else {
                                document.getElementById('inputLivreCobranca').checked = false;
                                u.enable('inputLivreCobranca');
                            }
                        }
                    }

                    //
                    // aba faturamento
                    //

                    $("#fieldValorTotalDesconto").on('blur', function () {
                        var param = {};
                        param.Value = document.getElementById('fieldValorTotalDesconto').value.replace('.', '').replace(',', '.');
                        GuidProxy.addParam(param);
                        postJsonToRoute('Comercial/ParcelasPedido/SetDescontoPedido', JSON.stringify(param)).done(
                            function () {
                                updateFatura();
                            }
                        );
                    });

                    // tipo cobranca
                    var dropDownTipoCobranca = new DropDown({
                        id: 'fieldSelectTiposCobrancas',
                        route: 'Comercial/CombosPedido/GetTiposCobranca',
                        onChange: function () {
                            var param = {};
                            param['Value'] = document.getElementById('fieldSelectTiposCobrancas').value;
                            GuidProxy.addParam(param);
                            postJsonToRoute("Comercial/ParcelasPedido/SetIdTipoCobranca", JSON.stringify(param));
                        }
                    });
                    dropDownTipoCobranca.make();

                    // condicao pagamento
                    var dropDownCondicoesPagamento = new DropDown({
                        id: 'fieldSelectCondicaoPagamento',
                        route: 'Comercial/CombosPedido/GetCondicoesPagamento',
                        onChange: function () {
                            updateCondicoesPagamento();
                        }
                    });
                    dropDownCondicoesPagamento.make();

                    // grid parcelas
                    var gridParcelas = new Table({
                        id: 'gridParcelas',
                        msgDialog: true,
                        GuidProxy: GuidProxy.getValue(),
                        route: window.baseUrl + 'Comercial/ParcelasPedido/GetParcelas',
                        columns: [
                            { field: "Parcela", title: "Parcela", width: 90, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "DataVencimento", title: "Data Vencimento", width: 90, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "Valor", title: "Valor", width: 100, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { field: "FormaPagamento", title: "Forma de Pagamento", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "Observacao", title: "Observações", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }
                        ],
                        onChange: function () {
                            "use strict";
                            var data = gridParcelas.getSelectedData();
                            document.getElementById('inputFaturamentoParcela').value = data['Numero'];
                            document.getElementById('inputDataVencimento').value = data['DataVencimento'];
                            document.getElementById('inputFaturamentoValor').value = data['Valor'];
                            document.getElementById('inputObservacao').value = data['Observacao'];
                            dropDownFormasPagamento.set(data.IdFormaPagamento);

                            if (enableFieldSelectCondicaoPagamento()) {
                                enableFieldsParcela();
                            }

                            setPermissions();
                        },
                        onDataBound: function () {
                            var el = $('.k-grid-content');
                            el[0].style.height = "118px";
                            el[1].style.height = "108px";
                            enableFieldSelectCondicaoPagamento();
                        },
                        dataSourceType: "Filtered"
                    });
                    gridParcelas.make();

                    // forma pagamento
                    var dropDownFormasPagamento = new DropDown({
                        id: 'selectFormaPagamento',
                        route: 'Comercial/CombosPedido/GetFormasPagamento'
                    });
                    dropDownFormasPagamento.make();

                    // data vencimento
                    var inputDataVencimentoValidator = new DateValidator({
                        id: "inputDataVencimento",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker('#' + this.id);
                        },
                        isEmptyValid: true,
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalidDialog(validator, function () {
                                u.alterTab(2);
                                inputDataVencimentoValidator.clear();
                                inputDataVencimentoValidator.focus(alertBehavior.warning);
                            });
                        }
                    });

                    var compareEmissaoVecto = new DateComparer({
                        idA: "inputDataEmissao",
                        idB: "inputDataVencimento",
                        verb: "less",
                        v2: true,
                        onInvalid: function (data) {
                            if (!inputDataVencimentoValidator.isValid) {
                                var message = "Data de Vencimento é obrigatória.";
                                u.dialogOk(message, null, true, function () {
                                    inputDataVencimentoValidator.focus(controlGroupBehavior.warning);
                                    inputDataVencimentoValidator.clear();
                                }, alertBehavior.warning);
                            }
                            else {
                                u.dialogOk("Data de vencimento da parcela inválida.", null, true, function () {
                                    inputDataVencimentoValidator.focus(controlGroupBehavior.warning);
                                    inputDataVencimentoValidator.clear();
                                }, alertBehavior.warning);
                            }
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior("inputDataVencimento", controlGroupBehavior.normal);
                        }
                    });

                    // proxima aba
                    $('#fieldValorTotalAPagar').on('keydown', function (ev) {
                        var key = ev.which || ev.keyCode;
                        if (key == 9) {
                            u.alterTab(3);
                            $('#inputCodigoTransportadora').focus();
                        }
                    });

                    // buttons
                    $('#buttonAlteraParcela').on('click', alteraParcela);

                    //
                    // functions faturamento
                    //

                    // condicao pagamento

                    function defaultSetIdCondicaoPagamento() {
                        setInProxy("fieldSelectCondicaoPagamento", "Comercial/ParcelasPedido/SetIdCondicaoPagamento");
                    }

                    function enableFieldValorTotalDesconto(ValorTotalProdutos) {
                        if (parseFloat(ValorTotalProdutos) === 0)
                            u.disable('fieldValorTotalDesconto');
                        else {
                            var input = document.getElementById('fieldValorTotalDesconto');
                            if (input.hasAttribute('datapermission')) {
                                if (input.getAttribute('datapermission') == 'False') {
                                    u.disable('fieldValorTotalDesconto');
                                } else {
                                    u.enable('fieldValorTotalDesconto');
                                }
                            }
                        }
                    }

                    function updateFaturaDesconto(param) {
                        getJsonFromRoute("Comercial/ParcelasPedido/UpdateFatura", GuidProxy.getObj()).done(function (data) {
                            if (data.IsAlert) {
                                u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                throw new Error(data.Message);
                            }

                            enableFieldValorTotalDesconto(data.ValorTotalProdutos);

                            byId("fieldValorTotalProdutos").value = data.ValorTotalProdutos;
                            byId("fieldValorTotalDesconto").value = data.ValorTotalDesconto;
                            byId("fieldValorTotalIpi").value = data.ValorTotalIpi;
                            byId("fieldValorTotalAPagar").value = data.ValorTotalAPagar;
                            gridParcelas.refresh();

                            postJsonToRoute('Comercial/ParcelasPedido/SetDescontoPedido', JSON.stringify(param)).done(
                                function () {
                                    clearCurrentParcela();
                                    gridParcelas.refresh();
                                }
                            );
                        });

                        setMask();
                        setPermissions();
                    }

                    function updateCondicoesPagamento() {
                        var desconto = document.getElementById('fieldValorTotalDesconto').value.replace('.', '').replace(',', '.');
                        var param = {};
                        param['Value'] = document.getElementById("fieldSelectCondicaoPagamento").value;
                        GuidProxy.addParam(param);

                        postJsonToRoute("Comercial/ParcelasPedido/SetIdCondicaoPagamento", JSON.stringify(param)).done(
                            function (data) {
                                if (data.Level == alertLevel.error) {
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                    throw new Error(data.Message);
                                } else {
                                    updateValorAcrescimoOuDescontoCondicaoPagamento(data);
                                }

                                param['Value'] = desconto;
                                updateFaturaDesconto(param);
                            }
                        );
                    }

                    function updateValorAcrescimoOuDescontoCondicaoPagamento(data) {
                        var tipo = data['TipoCondicao'];
                        var valor = data['ValorAcrescimoOuDesconto'];

                        if (tipo === 0) { //nenhum
                            $("#idFaturamentoValorAcrescimoOuDesconto").hide();
                            document.getElementById('labelFaturamentoValorAcrescimoOuDesconto').innerHTML = "";
                            document.getElementById('inputFaturamentoValorAcrescimoOuDesconto').value = "";
                        } else if (tipo === 1) { //acréscimo
                            $("#idFaturamentoValorAcrescimoOuDesconto").show();
                            document.getElementById('labelFaturamentoValorAcrescimoOuDesconto').innerHTML = "Valor Acréscimo:";
                            document.getElementById('inputFaturamentoValorAcrescimoOuDesconto').value = valor;
                        } else if (tipo === 2) { //desconto
                            $("#idFaturamentoValorAcrescimoOuDesconto").show();
                            document.getElementById('labelFaturamentoValorAcrescimoOuDesconto').innerHTML = "Valor Desconto:";
                            document.getElementById('inputFaturamentoValorAcrescimoOuDesconto').value = valor;
                        } else {
                            $("#idFaturamentoValorAcrescimoOuDesconto").hide();
                            document.getElementById('labelFaturamentoValorAcrescimoOuDesconto').innerHTML = "";
                            document.getElementById('inputFaturamentoValorAcrescimoOuDesconto').value = "";
                            throw new Error("Situação desconhecida retornada pelo servidor.");
                        }
                    }

                    // parcelas

                    function clearCurrentParcela() {
                        document.getElementById('inputFaturamentoParcela').value = "";
                        document.getElementById('inputDataVencimento').value = "";
                        document.getElementById('inputFaturamentoValor').value = "";
                        document.getElementById('inputObservacao').value = "";

                        u.disable('inputDataVencimento');
                        u.disable('inputFaturamentoValor');
                        dropDownFormasPagamento.disable();
                        u.disable('inputObservacao');

                        u.disable('buttonAlteraParcela');
                        setMask();
                    }

                    function enableFieldsParcela() {
                        u.enable('inputDataVencimento');
                        u.enable('inputFaturamentoValor');
                        dropDownFormasPagamento.enable();
                        u.enable('inputObservacao');

                        u.enable('buttonAlteraParcela');
                        setMask();
                    }

                    function getCurrentParcela() {
                        var fatura = {};
                        fatura['Numero'] = document.getElementById("inputFaturamentoParcela").value;
                        fatura['Parcela'] = "";
                        fatura['DataVencimento'] = document.getElementById("inputDataVencimento").value;
                        fatura['Valor'] = document.getElementById("inputFaturamentoValor").value;
                        fatura['IdFormaPagamento'] = document.getElementById("selectFormaPagamento").value;
                        fatura['Observacao'] = document.getElementById("inputObservacao").value;
                        fatura['IsIcmsSt'] = false;
                        fatura['IdTipoVencimento'] = 0;
                        fatura['TipoVencimento'] = "";
                        GuidProxy.addParam(fatura);
                        return fatura;
                    }

                    function alteraParcela() {
                        "use strict";

                        if (!inputDataVencimentoValidator.isValid || inputDataVencimentoValidator.getValue() === "" || inputDataVencimentoValidator.getValue() === "00/00/0000") {
                            var message = "Data de Vencimento é obrigatória.";
                            u.dialogOk(message, null, true, function () {
                                inputDataVencimentoValidator.focus(controlGroupBehavior.warning);
                                inputDataVencimentoValidator.clear();
                            }, alertBehavior.warning);
                            throw new Error(message);
                        }

                        if (!compareEmissaoVecto.isValid) {
                            u.dialogOk("Data de vencimento da parcela inválida.", null, true, function () {
                                inputDataVencimentoValidator.focus(controlGroupBehavior.warning);
                                inputDataVencimentoValidator.clear();
                            }, alertBehavior.warning);
                        }

                        if (compareEmissaoVecto.isValid) {
                            alterouCampo = true;
                            var desconto = document.getElementById('fieldValorTotalDesconto').value.replace('.', '').replace(',', '.');
                            var param = {};
                            param.Fatura = getCurrentParcela();
                            param.Index = $('#gridParcelas .k-grid-content table tbody .k-state-selected')[0].rowIndex;

                            msgWait.show();
                            postJsonToRoute('Comercial/ParcelasPedido/ChangeParcela', JSON.stringify(param)).done(
                                function (data) {
                                    msgWait.hide();
                                    if (data.IsAlert && data.Level == alertLevel.error) {
                                        u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        throw new Error(data.Message);
                                    }

                                    param['Value'] = "0.00"; //primeiro deve zerar o desconto
                                    msgWait.show();
                                    postJsonToRoute('Comercial/ParcelasPedido/SetDescontoPedido', JSON.stringify(param)).done(
                                        function () {
                                            getJsonFromRoute("Comercial/ParcelasPedido/UpdateFatura", GuidProxy.getObj()).done(function (data) {
                                                msgWait.hide();
                                                if (data.IsAlert) {
                                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                                    throw new Error(data.Message);
                                                } else {
                                                    param['Value'] = desconto;
                                                    postJsonToRoute('Comercial/ParcelasPedido/SetDescontoPedido', JSON.stringify(param)).done(
                                                        function () {
                                                            updateFatura();
                                                            clearCurrentParcela();
                                                            dropDownFormasPagamento.set("0");
                                                        }
                                                    );
                                                }
                                            });
                                        }
                                    );
                                }
                            );
                        }
                    }

                    function defaultSetIdTipoCobranca() {
                        setInProxy("fieldSelectTiposCobrancas", "Comercial/ParcelasPedido/SetIdTipoCobranca");
                    }

                    // diversos

                    // ativa/desativa campo condicoes pagamento,
                    // e verifica se pode alterar as parcelas
                    function enableFieldSelectCondicaoPagamento() {
                        var itens = $("#gridItens").data("kendoGrid").dataSource.data();
                        var enable = itens.length == 0;

                        for (var i = 0; i < itens.length && !enable; i = i + 1)
                            if (!itens[i].LivreCobranca)
                                enable = true;

                        // se não possuir nenhum item informado
                        // e possuir pelo menos um item livre de cobrança igual falso
                        // e PodeAlterarCondicaoPagamentoSugerida
                        if (enable) {
                            if (params.Pedido.Permissoes.PodeAlterarCondicaoPagamentoSugerida)
                                dropDownCondicoesPagamento.enable();
                            else
                                dropDownCondicoesPagamento.disable();
                        }

                        return enable;
                    }

                    function updateFatura() {
                        getJsonFromRoute("Comercial/ParcelasPedido/UpdateFatura", GuidProxy.getObj()).done(function (data) {
                            if (data.IsAlert) {
                                u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                throw new Error(data.Message);
                            }

                            enableFieldValorTotalDesconto(data.ValorTotalProdutos);

                            byId("fieldValorTotalProdutos").value = data.ValorTotalProdutos;
                            byId("fieldValorTotalDesconto").value = data.ValorTotalDesconto;
                            byId("fieldValorTotalIpi").value = data.ValorTotalIpi;
                            byId("fieldValorTotalAPagar").value = data.ValorTotalAPagar;
                            gridParcelas.refresh();
                            setMask();
                        });
                        setPermissions();
                    }

                    function setInProxy(fieldId, route, data) {
                        "use strict";
                        var param = {};
                        GuidProxy.addParam(param);

                        if (isFieldControlGroupInBehavior(fieldId, controlGroupBehavior.warning)) {

                        } else {
                            if (data)
                                param.Value = data;
                            else
                                param.Value = byId(fieldId).value;

                            if (param.Value === "") {

                            } else {
                                if (param.Value === '0') {
                                    var input = byId(fieldId);
                                    if (input.options) {
                                        param.Value = byId(fieldId).options[0].value;
                                    }
                                }

                                postJsonToRoute(route, JSON.stringify(param));
                            }
                        }
                    }

                    //
                    // aba transporte
                    //

                    // quem transporta
                    var dropDownQuemtransporta = new DropDown({
                        id: 'fieldSelectQuemTransporta',
                        route: 'Comercial/CombosPedido/GetQuemTransporta'
                    });
                    dropDownQuemtransporta.make();

                    // transportadora
                    var validatorTransportadora = new Validator({
                        field: 'CodigoTransportadora',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informada a transportadora.',
                        route: 'Empresarial/F4Transportadora/GetTransportadora',
                        onValid: function (data) {
                            document.getElementById('inputCodigoTransportadora').value = data.Codigo;
                            document.getElementById('descriptionCodigoTransportadora').innerHTML = data.Nome;

                            if (data['ValorUnitarioAtualizadoDoProduto'] !== "")
                                document.getElementById('inputValorUnitario').value = data['ValorUnitarioAtualizadoDoProduto'];
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(3);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorTransportadora.listen();

                    var tableTransportadoras = new Table({
                        'id': 'tableTransportadora',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Empresarial/F4Transportadora/GetTransportadoras',
                        'showFilter': true,
                        'columns': [
                             { title: 'Código', field: 'Codigo', width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                             { title: 'Nome', field: 'RazaoSocial', width: 120, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                             { title: 'CPF/CNPJ', field: 'CnpjCpf', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        ],
                        'columnsLegend': { CpfCnpj: 'Ex: 11.222.333/4444-55', Telefone: ' Ex: (0xx47) 33332222' },
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableTransportadoras.getSelectedData();
                                document.getElementById('inputCodigoTransportadora').value = data.Codigo;
                                document.getElementById('descriptionCodigoTransportadora').innerHTML = data.Nome;
                                validatorTransportadora.update();
                                validatorTransportadora.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableTransportadora table  tr').on('dblclick', function () {
                                var data = tableTransportadoras.getSelectedData();
                                document.getElementById('inputCodigoTransportadora').value = data.Codigo;
                                document.getElementById('descriptionCodigoTransportadora').innerHTML = data.Nome;
                                validatorTransportadora.update();
                                validatorTransportadora.validate();

                                $('#modalTransportadora').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalTransportadora = document.getElementById('linkButtonModalTransportadora');
                    var inputTransportadora = document.getElementById('inputCodigoTransportadora');
                    var modalTransportadora = new Modal('Transportadoras', linkButtonModalTransportadora, inputTransportadora, tableTransportadoras);
                    modalTransportadora.listen();

                    // via transporte
                    var dropDownViaTransporte = new DropDown({
                        id: 'fieldSelectViaTransporte',
                        route: 'Comercial/CombosPedido/GetviaTransporte'
                    });
                    dropDownViaTransporte.make();

                    // transportadora redespacho
                    var validatorTransportadoraRedespacho = new Validator({
                        field: 'CodigoTransportadoraRedespacho',
                        msgDialog: true,
                        onPendencyMessage: 'Deve ser informada a transportadora de redespacho.',
                        route: 'Empresarial/F4Transportadora/GetTransportadora',
                        onValid: function (data) {
                            document.getElementById('inputCodigoTransportadoraRedespacho').value = data.Codigo;
                            document.getElementById('descriptionCodigoTransportadoraRedespacho').innerHTML = data.Nome;
                        },
                        onInvalid: function () {
                            var self = this;
                            u.alterTab(3);
                            self.focus();
                            self.value = "";
                            self.input.value = "";
                        }
                    });
                    validatorTransportadoraRedespacho.listen();

                    var tableTransportadorasRedespacho = new Table({
                        'id': 'tableTransportadoraRedespacho',
                        'msgDialog': true,
                        'route': window.baseUrl + 'Empresarial/F4Transportadora/GetTransportadoras',
                        'showFilter': true,
                        'columns': [
                             { title: 'Código', field: 'Codigo', width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                             { title: 'Nome', field: 'RazaoSocial', width: 120, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                             { title: 'CPF/CNPJ', field: 'CnpjCpf', width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        ],
                        'onChange': function () {
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var data = tableTransportadorasRedespacho.getSelectedData();
                                document.getElementById('inputCodigoTransportadoraRedespacho').value = data.Codigo;
                                document.getElementById('descriptionCodigoTransportadoraRedespacho').innerHTML = data.Nome;
                                validatorTransportadoraRedespacho.update();
                                validatorTransportadoraRedespacho.validate();
                            };
                        },
                        'onDataBound': function () {
                            $('#tableTransportadoraRedespacho table  tr').on('dblclick', function () {
                                var data = tableTransportadorasRedespacho.getSelectedData();
                                document.getElementById('inputCodigoTransportadoraRedespacho').value = data.Codigo;
                                document.getElementById('descriptionCodigoTransportadoraRedespacho').innerHTML = data.Nome;
                                validatorTransportadoraRedespacho.update();
                                validatorTransportadoraRedespacho.validate();

                                $('#modalTransportadoraRedespacho').modal('hide');
                            });
                        },
                        'dataSourceType': "Filtered"
                    });
                    var linkButtonModalTransportadoraRedespacho = document.getElementById('linkButtonModalTransportadoraRedespacho');
                    var inputTransportadoraRedespacho = document.getElementById('inputCodigoTransportadoraRedespacho');
                    var modalTransportadoraRedespacho = new Modal('Transportadoras', linkButtonModalTransportadoraRedespacho, inputTransportadoraRedespacho, tableTransportadorasRedespacho);
                    modalTransportadoraRedespacho.listen();

                    //
                    // functions global
                    //

                    // salva id do campo com focus anterior
                    $.each($("input, textarea, a[role=button]"), function (index, value) {
                        if (value !== undefined && value !== null && value.id !== undefined && value.id !== null && value.id !== ""
                            && value.id !== "fieldItemSequencial"
                            && value.id !== "buttonSalvarPedido"
                            && value.id !== "buttonCancelarAlteracaoPedido"
                            && value.id !== "buttonGeneratePdfPedido"
                            && value.id !== "textAreaPordutoComplemento") {
                            $("#" + value.id).on("focus", function (evt) {
                                lastFieldFocus = evt.target.id;
                            });
                        }
                    });

                    //
                    // load
                    //

                    $('#inputCodigoFilial').focus();

                    // valor padrão
                    // seta como true no inicio, porque as rotinas de sugestões, só funcionam quando não tem valor informado manualmente, 
                    // a partir do momento que foi informado um valor manual, não será feito mais nenhuma sugestão
                    $("#inputNumeroOc").data("podesugerir", true);

                    // valor padrão
                    // sugere OC nos itens, se estiver alterando um pedido
                    if ($("#inputNumeroOc").data("podesugerir") && !$("#buttonAdicionarItem").attr("disabled")) {
                        $("#inputNumeroOc").val($("#fieldNumeroOrdemCompraCliente").val());
                    }

                    // valor padrão
                    document.getElementById('inputDataEntrega').value = document.getElementById('inputPrincipalDataEntrega').value;

                    kendo.culture("pt-BR");
                    setPermissions();
                    setMask();

                    var fieldValorTotalProdutos = parseFloat(params.Pedido.ValorTotalProdutos ? params.Pedido.ValorTotalProdutos.replace('.', '').replace(',', '.') : 0);
                    enableFieldValorTotalDesconto(fieldValorTotalProdutos);

                    clearCurrentParcela();

                    if (params.Pedido.IsAlert) {
                        // erro
                        $("#myTab > li > a").removeAttr("href").removeAttr("data-toggle");
                        $("a,input,i,textarea,select,checkbox,button").attr("disabled", "disabled");
                        $("#buttonNovoPedido").removeAttr("disabled");
                        $("#buttonCancelarAlteracaoPedido").removeAttr("disabled");

                        u.dialogOk(params.Pedido.Message, null, true, null, alertBehavior.warning);
                    }
                    else if (params.Pedido.IsAlteracao) {
                        // alteração de pedido
                        $("#buttonRemoverInvalidarItem").val("Invalidar");

                        if (params.Pedido.IsAlert && !params.Pedido.PodeSerAlterado && params.Pedido.Level === alertLevel.error)
                            disablePedido();
                    }
                })(params);
            },

            MovimentosAgendamentos: function (params) {
                return (function () {
                    msgWait.show();
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var gridAgendamentos = new Table({
                        id: "gridAgendamentos",
                        msgDialog: true,
                        route: window.baseUrl + "Comercial/MovimentosAgendamentos/GetAgendamentos",
                        dataSourceType: "Filtered",
                        initNotLoad: true,
                        columns: [
                            { field: "Numero", title: "Número", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Data", title: "Data", width: 80, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "Hora", title: "Hora", width: 50, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, format: "{0:dd/MM/yyyy}" },
                            { field: "Cliente", title: "Cliente", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "SituacaoVisita", title: "Situação Visita", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "SituacaoVenda", title: "Situação Venda", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "ValorVenda", title: "Valor Visita", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } }
                        ],
                        pageable: {
                            refresh: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        toolbar:
                            "<span style='float: left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Agendamentos de Visitas</span>" +
                            "</span>" +
                            "<span style='float: right' style='width: 60px;'>" +
                            "    <button id='buttonGridFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'></span> Filtro" +
                            "    </button>" +
                            "    <button id='buttonGridNew' type='button' class='btn btn-small btn-filtro' disabled>" +
                            "        <span class='k-icon k-i-plus'></span>Novo" +
                            "    </button>" +
                            "</span>",
                        onChange: function () {
                            "use strict";
                            var self = this;

                            var data = self.getSelectedData();
                            window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamento?id=" + data.Id;
                        },
                        onDataBound: function () {
                            "use strict";
                            var self = this;

                            msgWait.hide();
                        }
                    });
                    gridAgendamentos.make();
                    gridAgendamentos.listen();

                    if (params.IsIncluir) {
                        u.enable("buttonGridNew");
                        $("#buttonGridNew").addClass("btn-filtro");
                    } else {
                        u.disable("buttonGridNew");
                        $("#buttonGridNew").removeClass("btn-filtro");
                    }

                    $("#buttonGridFilter").click(function () {
                        $("#modalFilters").modal("show");
                        setDefaultFieldFocusFilters();
                    });

                    $("#buttonGridNew").click(function () {
                        window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamento";
                    });

                    //
                    // filter
                    //

                    // data inicial
                    var inputFilterDataInicial = new ValidatorDate({
                        idInput: "inputFilterDataInicial",
                        isEmptyValid: true,
                        idModalHideShow: "modalFilters",
                        onChange: function () {
                            if (inputFilterDataFinal.isEmpty)
                                inputFilterDataFinal.setValue(inputFilterDataInicial.getValue());
                        }
                    });

                    // data final
                    var inputFilterDataFinal = new ValidatorDate({
                        idInput: "inputFilterDataFinal",
                        compareGreater: "inputFilterDataInicial",
                        isEmptyValid: true,
                        idModalHideShow: "modalFilters"
                    });

                    // numero inicial
                    var inputFilterNumeroInicial = new ValidatorMask({
                        idInput: "inputFilterNumeroInicial",
                        mask: "chave",
                        onChange: function () {
                            if (inputFilterNumeroFinal.isEmpty())
                                inputFilterNumeroFinal.setValue(inputFilterNumeroInicial.getValue());
                        }
                    });

                    // numero final
                    var inputFilterNumeroFinal = new ValidatorMask({
                        idInput: "inputFilterNumeroFinal",
                        mask: "chave"
                    });

                    // valor inicial
                    var inputFilterValorInicial = new ValidatorMask({
                        idInput: "inputFilterValorInicial",
                        mask: "radar-valor-14-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true,
                        onChange: function () {
                            if (inputFilterValorFinal.getValueNumber() === 0)
                                inputFilterValorFinal.setValue(inputFilterValorInicial.getValue());
                        }
                    });

                    // valor final
                    var inputFilterValorFinal = new ValidatorMask({
                        idInput: "inputFilterValorFinal",
                        mask: "radar-valor-14-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true
                    });

                    // cliente
                    var inputFilterCodigoCliente = new ValidatorLookup({
                        abrev: "FilterCodigoCliente",
                        idModalHideShow: "modalFilters",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes"
                    });

                    // filters listen
                    $("#doFilter").click(function () {
                        if (checkFilters()) {
                            $("#modalFilters").modal("hide");
                            msgWait.show();
                            doFilter();
                        }
                    });

                    $("#removeFilter").click(function () {
                        setFiltersDefault(true);
                    });

                    $("#modalFilters").on("hidden", function () {
                    });

                    // filters functions
                    var idFilterSession = "filters_com_mov_agendamentos";

                    function checkFilters() {
                        return true;
                    }

                    function setDefaultFieldFocusFilters() {
                        inputFilterDataInicial.focus();
                    }

                    function loadFilters(loadData) {
                        var filter = JSON.parse(currentUser.getSessionData(idFilterSession));
                        if (filter !== null) {
                            setFiltersInFields(filter);

                            var dataSource = new kendo.data.DataSource(gridAgendamentos.getFilteredDataSource(filter));
                            gridAgendamentos.setDataSource(dataSource);
                        }
                        else {
                            setFiltersDefault();
                        }
                    }

                    function setFiltersInFields(filter) {
                        inputFilterDataInicial.setValue(filter.DataInicial);
                        inputFilterDataFinal.setValue(filter.DataFinal);
                        inputFilterNumeroInicial.setValue(filter.NumeroInicial);
                        inputFilterNumeroFinal.setValue(filter.NumeroFinal);
                        inputFilterValorInicial.setValue(filter.ValorInicial);
                        inputFilterValorFinal.setValue(filter.ValorFinal);

                        setChecked("inputFilterSituacaoVendaEfetuada", filter.SituacaoVendaEfetuada);
                        setChecked("inputFilterSituacaoVendaNaoEfetuada", filter.SituacaoVendaNaoEfetuada);

                        setChecked("inputFilterSituacaoVisitaEfetuada", filter.SituacaoVisitaEfetuada);
                        setChecked("inputFilterSituacaoVisitaCancelada", filter.SituacaoVisitaCancelada);
                        setChecked("inputFilterSituacaoVisitaNaoEfetuada", filter.SituacaoVisitaNaoEfetuada);
                        setChecked("inputFilterSituacaoVisitaReagendada", filter.SituacaoVisitaReagendada);

                        inputFilterCodigoCliente.setValue(filter.CodigoCliente);
                    }

                    function setFiltersDefault() {
                        var filter = {
                            DataInicial: "",
                            DataFinal: "",
                            NumeroInicial: "",
                            NumeroFinal: "",
                            ValorInicial: "",
                            ValorFinal: "",
                            
                            SituacaoVendaEfetuada: false,
                            SituacaoVendaNaoEfetuada: false,
                            
                            SituacaoVisitaEfetuada: false,
                            SituacaoVisitaCancelada: false,
                            SituacaoVisitaNaoEfetuada: false,
                            SituacaoVisitaReagendada: false,

                            CodigoCliente: ""
                        };

                        setFiltersInFields(filter);

                        var dataSource = new kendo.data.DataSource(gridAgendamentos.getFilteredDataSource(filter));
                        gridAgendamentos.setDataSource(dataSource);

                        currentUser.setSessionData(idFilterSession, JSON.stringify(filter));
                    }

                    function doFilter() {
                        var filter = {
                            DataInicial: inputFilterDataInicial.getValue(),
                            DataFinal: inputFilterDataFinal.getValue(),
                            NumeroInicial: inputFilterNumeroInicial.getValue(),
                            NumeroFinal: inputFilterNumeroFinal.getValue(),
                            ValorInicial: inputFilterValorInicial.getValue(),
                            ValorFinal: inputFilterValorFinal.getValue(),
                            
                            SituacaoVendaEfetuada: isChecked("inputFilterSituacaoVendaEfetuada"),
                            SituacaoVendaNaoEfetuada: isChecked("inputFilterSituacaoVendaNaoEfetuada"),
                            
                            SituacaoVisitaEfetuada: isChecked("inputFilterSituacaoVisitaEfetuada"),
                            SituacaoVisitaCancelada: isChecked("inputFilterSituacaoVisitaCancelada"),
                            SituacaoVisitaNaoEfetuada: isChecked("inputFilterSituacaoVisitaNaoEfetuada"),
                            SituacaoVisitaReagendada: isChecked("inputFilterSituacaoVisitaReagendada"),
                            
                            CodigoCliente: inputFilterCodigoCliente.getValue()
                        }

                        var dataSource = new kendo.data.DataSource(gridAgendamentos.getFilteredDataSource(filter));
                        gridAgendamentos.setDataSource(dataSource);

                        currentUser.setSessionData(idFilterSession, JSON.stringify(filter));
                    }

                    // carregar a grid com os filtros padrões ou selecionados anteriormente
                    loadFilters();

                }(params));
            },

            MovimentosAgendamento: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var perguntar = false;

                    var tabs = {
                        Agendamento: 0,
                        Visita: 1
                    };

                    // TODO: melhorar, sincronizar com radar desktop
                    var DiaDaVisitaEnum = {
                        NAO_CONSIDERAR_DIA_UTIL: 0,
                        ANTECIPA: 1,
                        POSTERGA: 2
                    }

                    var ValidadeDoCicloEnum = {
                        PRAZO_DE: 0,
                        PERIODO_DE_MOVIMENTACAO: 1
                    }

                    var SituacaoVisitaEnum = {
                        NAO_EFETUADA: 0,
                        EFETUADA: 1,
                        CANCELADA: 2,
                        REAGENDADA: 3
                    }

                    var RecalcularCiclosAlteracaoData = true;

                    var DataAgentamentoOriginal = null;

                    //
                    // aba agendamento
                    //

                    // numero agendamento
                    var inputAgendamentoNumero = new ValidatorMask({
                        idInput: "inputAgendamentoNumero",
                        mask: "chave",
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // data agendamento
                    var inputAgendamentoData= new ValidatorDate({
                        idInput: "inputAgendamentoData",
                        isEmptyValid: true,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // hora agendamento
                    var inputAgendamentoHora= new ValidatorMask({
                        idInput: "inputAgendamentoHora",
                        mask: "time",
                        defaultValue: "00:00",
                        isEmptyValid: false,
                        setDefaulValue: true,
                        onChange: function () {
                            var hora = inputAgendamentoHora.getValue().replace(":", "");
                            if (hora.length < 4 || (hora[0] === "2" && parseInt(hora[1]) > 3)) {
                                u.dialogOk("Hora inválida.", null, true, function () {
                                    u.changeTab(tabs.Agendamento);
                                    inputAgendamentoHora.clear();
                                    inputAgendamentoHora.focusError();
                                }, alertBehavior.warning);
                            }
                            perguntar = true;
                        }
                    });

                    // representante

                    // cliente
                    var inputAgendamentoCodigoCliente = new ValidatorLookup({
                        abrev: "ClienteCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes",
                        onValid: function (model) {
                            request2("Comercial/MovimentosAgendamentos/GetDadosCliente",
                                {
                                    CodigoCliente: model.Codigo
                                },
                                function (vm) {
                                    setVal("inputClienteCEP", vm.CEP);
                                    setVal("inputClienteCodigoMunicipio", vm.CodigoMunicipio);
                                    setHtml("descriptionClienteCodigoMunicipio", vm.DescricaoMunicipio);
                                    setVal("inputClienteUF", vm.UF);
                                    setVal("inputClienteEndereco", vm.Endereco);
                                    setVal("inputClienteTelefone", vm.Telefone);
                                    setVal("inputClienteEmail", vm.Email);
                                });
                        },
                        onInvalid: function () {
                            setVal("inputClienteCEP", "");
                            setVal("inputClienteCodigoMunicipio", "");
                            setHtml("descriptionClienteCodigoMunicipio", "");
                            setVal("inputClienteUF", "");
                            setVal("inputClienteEndereco", "");
                            setVal("inputClienteTelefone", "");
                            setVal("inputClienteEmail", "");
                        },
                        onEmpty: function () {
                            setVal("inputClienteCEP", "");
                            setVal("inputClienteCodigoMunicipio", "");
                            setHtml("descriptionClienteCodigoMunicipio", "");
                            setVal("inputClienteUF", "");
                            setVal("inputClienteEndereco", "");
                            setVal("inputClienteTelefone", "");
                            setVal("inputClienteEmail", "");
                        },
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // tipo periodo
                    var inputCicloDeVisitasTipoPeriodo = new ValidatorDropDown({
                        abrev: "CicloDeVisitasTipoPeriodo",
                        route: "/Comercial/CombosAgendamentos/GetTiposPeriodos",
                        width: 150,
                        onChange: function () {
                            if (inputCicloDeVisitasTipoPeriodo.getValue() === "0") {
                                setGrupoCicloDeVisitasDefault();
                            } else {
                                u.enable("inputDiaDaVisitaConsiderarDiaUtil");

                                u.enable("inputValidadeDoCicloPrazoDe");
                                inputValidadeDoCicloQtdDias.enable(true);
                                u.enable("inputValidadeDoCicloPeriodoMovimentacao");
                            }
                            perguntar = true;
                        }
                    });

                    // considerar dia útil
                    var inputDiaDaVisitaConsiderarDiaUtil = new ValidatorCheckbox({
                        idInput: "inputDiaDaVisitaConsiderarDiaUtil",
                        onChange: function () {
                            if (!inputDiaDaVisitaConsiderarDiaUtil.getValue()) {
                                setChecked("inputDiaDaVisitaAntecipa", true);
                                u.disable("inputDiaDaVisitaAntecipa");
                                u.disable("inputDiaDaVisitaPosterga");
                            }
                            else {
                                u.enable("inputDiaDaVisitaAntecipa");
                                u.enable("inputDiaDaVisitaPosterga");
                            }
                            perguntar = true;
                        }
                    });

                    // antecipa / posterga
                    $("#inputDiaDaVisitaAntecipa, #inputDiaDaVisitaPosterga").on("change", function () {
                        perguntar = true;
                    });

                    // prazo de / período de movimentação
                    $("#inputValidadeDoCicloPrazoDe, #inputValidadeDoCicloPeriodoMovimentacao").on("change", function () {
                        if (isChecked("inputValidadeDoCicloPrazoDe")) {
                            inputValidadeDoCicloQtdDias.enable(true);
                        }
                        else {
                            inputValidadeDoCicloQtdDias.setValue("0");
                            inputValidadeDoCicloQtdDias.enable(false);
                        }
                        perguntar = true;
                    });

                    // qtd dias
                    var inputValidadeDoCicloQtdDias = new ValidatorNumber({
                        idInput: "inputValidadeDoCicloQtdDias",
                        isEmptyValid: true,
                        maxLength: 3,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // observações
                    var inputAgendamentoObservacoes = new ValidatorMemo({
                        titleModal: "Observações",
                        idInput: "inputAgendamentoObservacoes",
                        idLink: "inputAgendamentoObservacoesLink",
                        css: { width: "780px" },
                        attr: { maxlength: 2000 },
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // proxima aba
                    $("#inputAgendamentoObservacoes").on("keydown", function (ev) {
                        var key = ev.which || ev.keyCode;
                        if (key == 9) {
                            u.changeTab(tabs.Visita);
                            inputVisitaSituacaoVisita.focus();
                        }
                    });

                    //
                    // visita
                    //

                    // situacao visita
                    var inputVisitaSituacaoVisita = new ValidatorDropDown({
                        abrev: "VisitaSituacaoVisita",
                        route: "/DropDown/GetDropDown?name=Empresarial.SituacaoVisita",
                        width: 150,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // atendido por
                    var inputVisitaAtendidoPor = new ValidatorAlphanumeric({
                        idInput: "inputVisitaAtendidoPor",
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // contato
                    var inputVisitaCodigoContato = new ValidatorLookup({
                        abrev: "VisitaCodigoContato",
                        fieldSearch: "CodigoContato",
                        msgPendencyMessagePartEnd: "do contato.",
                        pendency: [inputAgendamentoCodigoCliente],
                        params: [inputAgendamentoCodigoCliente],
                        paramsRequired: [true],
                        route: "Comercial/F4ContatoCfrt/GetContatoCfrt",
                        routeTable: "Comercial/F4ContatoCfrt/GetContatosCfrt",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Telefone", field: "Telefone", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "E-mail", field: "Email", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Função", field: "Funcao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Departamento", field: "Departamento", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Município", field: "Municipio", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "UF", field: "UF", width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Relação de Contatos",
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // reagendado para
                    var inputVisitaDataReagendaPara = new ValidatorDate({
                        idInput: "inputVisitaDataReagendaPara",
                        isEmptyValid: true,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // recalcular próximo agendamentos
                    var inputVisitaIsRecalcularProximosAgendamentos = new ValidatorCheckbox({
                        idInput: "inputVisitaIsRecalcularProximosAgendamentos",
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // situacao venda
                    var inputVisitaSituacaoVenda = new ValidatorDropDown({
                        abrev: "VisitaSituacaoVenda",
                        route: "/DropDown/GetDropDown?name=Empresarial.SituacaoVendaAgendamento",
                        width: 150,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // valor venda
                    var inputVisitaValorVenda = new ValidatorMask({
                        idInput: "inputVisitaValorVenda",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true,
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    // observações
                    var inputVisitaObservacoes = new ValidatorMemo({
                        titleModal: "Observações",
                        idInput: "inputVisitaObservacoes",
                        idLink: "inputVisitaObservacoesLink",
                        css: { width: "760px" },
                        attr: { maxlength: 2000 },
                        onChange: function () {
                            perguntar = true;
                        }
                    });

                    //
                    // buttons
                    //

                    byId("buttonOK").onclick = function () {
                        saveAgendamento();
                    }

                    byId("buttonCancelar").onclick = function () {
                        if (perguntar) {
                            u.dialog(
                                null,
                                "Deseja realmente abandonar as alterações?",
                                function () {
                                    setTimeout(function () { $('#waiting').show(); }, 100);
                                    window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamentos";
                                },
                                null,
                                null,
                                true
                            );
                        }
                        else {
                            setTimeout(function () { $('#waiting').show(); }, 100);
                            window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamentos";
                        }
                    }

                    byId("buttonNovo").onclick = function () {
                        if (perguntar) {
                            u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () { $('#waiting').show(); }, 100);
                                window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamento";
                            },
                            null,
                            null,
                            true
                            );
                        }
                        else {
                            setTimeout(function () { $('#waiting').show(); }, 100);
                            window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamento";
                        }
                    }

                    byId("buttonExcluir").onclick = function () {
                        u.dialog(
                            null,
                            "Confirma a exclusão do(s) agendamento(s)?",
                            function () {
                                deleteAgendamento();
                            },
                            null,
                            null,
                            true
                        );
                    }

                    //
                    // functions
                    //

                    function loadAgendamento() {
                        request2("Comercial/MovimentosAgendamentos/GetAgendamento/", { id: params.Id },
                            function (vm) {
                                setAgendamento(vm);
                            },
                            function () {
                                disableAgendamento(true, true);
                            }, null, null,
                            function () {
                                $("#buttonCancelar").focus();
                            });
                    }

                    function setAgendamento(vm) {
                        if (params.Id) {
                            // alteração
                            inputAgendamentoNumero.setValue(vm.Numero);
                            inputAgendamentoNumero.enable(false);

                            inputAgendamentoData.setValue(vm.Data);
                            DataAgentamentoOriginal = vm.Data;

                            inputAgendamentoHora.setValue(vm.Hora);
                            setVal("inputAgendamentoCodigoRepresentante", vm.CodigoRepresentante);
                            setHtml("descriptionAgendamentoCodigoRepresentante", vm.NomeRepresentante);

                            inputAgendamentoCodigoCliente.setValues(vm.CodigoCliente, vm.NomeCliente);
                            setVal("inputClienteCEP", vm.DadosCliente.CEP);
                            setVal("inputClienteCodigoMunicipio", vm.DadosCliente.CodigoMunicipio);
                            setHtml("descriptionClienteCodigoMunicipio", vm.DadosCliente.DescricaoMunicipio);
                            setVal("inputClienteUF", vm.DadosCliente.UF);
                            setVal("inputClienteEndereco", vm.DadosCliente.Endereco);
                            setVal("inputClienteTelefone", vm.DadosCliente.Telefone);
                            setVal("inputClienteEmail", vm.DadosCliente.Email);

                            inputCicloDeVisitasTipoPeriodo.setValue(vm.CodigoTipoPeriodo);
                            if (inputCicloDeVisitasTipoPeriodo.getValue() === "0") {
                                setGrupoCicloDeVisitasDefault();
                            }
                            else {
                                // dia da visita
                                if (vm.DiaDaVisita === DiaDaVisitaEnum.NAO_CONSIDERAR_DIA_UTIL) {
                                    inputDiaDaVisitaConsiderarDiaUtil.setValue(false);
                                    setChecked("inputDiaDaVisitaAntecipa", true);
                                    u.disable("inputDiaDaVisitaAntecipa");
                                    setChecked("inputDiaDaVisitaPosterga", false);
                                    u.disable("inputDiaDaVisitaPosterga");
                                }
                                else if (vm.DiaDaVisita === DiaDaVisitaEnum.ANTECIPA) {
                                    inputDiaDaVisitaConsiderarDiaUtil.setValue(true);
                                    setChecked("inputDiaDaVisitaAntecipa", true);
                                    u.enable("inputDiaDaVisitaAntecipa");
                                    setChecked("inputDiaDaVisitaPosterga", false);
                                    u.enable("inputDiaDaVisitaPosterga");
                                }
                                else if (vm.DiaDaVisita === DiaDaVisitaEnum.POSTERGA) {
                                    inputDiaDaVisitaConsiderarDiaUtil.setValue(true);
                                    setChecked("inputDiaDaVisitaAntecipa", false);
                                    u.enable("inputDiaDaVisitaAntecipa");
                                    setChecked("inputDiaDaVisitaPosterga", true);
                                    u.enable("inputDiaDaVisitaPosterga");
                                }

                                // validade do ciclo
                                if (vm.ValidadeDoCiclo !== ValidadeDoCicloEnum.PERIODO_DE_MOVIMENTACAO) {
                                    setChecked("inputValidadeDoCicloPrazoDe", true);
                                    u.enable("inputValidadeDoCicloPrazoDe");
                                    // TODO: vm.QtdDias > 999 bug do agendamento desktop quando alterar data do agendamento, corrigir futuramente
                                    inputValidadeDoCicloQtdDias.setValue(vm.QtdDias > 999 ? 0 : vm.QtdDias);
                                    inputValidadeDoCicloQtdDias.enable(true);
                                    setChecked("inputValidadeDoCicloPeriodoMovimentacao", false);
                                }
                                else {
                                    setChecked("inputValidadeDoCicloPrazoDe", false);
                                    inputValidadeDoCicloQtdDias.setValue("0");
                                    inputValidadeDoCicloQtdDias.enable(false);
                                    setChecked("inputValidadeDoCicloPeriodoMovimentacao", true);
                                    u.enable("inputValidadeDoCicloPeriodoMovimentacao");
                                }
                            }

                            inputAgendamentoObservacoes.set(vm.Observacoes);

                            inputVisitaSituacaoVisita.setValue(vm.SituacaoVisita);
                            inputVisitaAtendidoPor.setValue(vm.AtendidoPor);
                            inputVisitaCodigoContato.setValues(vm.CodigoContato, vm.NomeContato);
                            inputVisitaDataReagendaPara.setValue(vm.DataReagendamento);
                            inputVisitaIsRecalcularProximosAgendamentos.setValue(vm.IsRecalcularProximosAgendamentos);
                            inputVisitaSituacaoVenda.setValue(vm.SituacaoVenda);
                            inputVisitaValorVenda.setValue(vm.ValorVenda);
                            inputVisitaObservacoes.set(vm.ObservacoesVisita);

                            perguntar = false;
                            if ((vm.Permissoes.IsIncluir && !params.Id) || (vm.Permissoes.IsAlterar && params.Id)) u.enable("buttonOK"); else u.disable("buttonOK");
                            if (vm.Permissoes.IsIncluir) u.enable("buttonNovo"); else u.disable("buttonNovo");
                            if (vm.Permissoes.IsExcluir && vm.SituacaoVisita === SituacaoVisitaEnum.NAO_EFETUADA) u.enable("buttonExcluir"); else u.disable("buttonExcluir");

                            // se for uma alteração, deixa visualizar os campos, mas não pode alterar
                            if (!vm.Permissoes.IsAlterar && params.Id) disableAgendamento(false, false);

                            // se "Situação da Visita" igual "Reagendada", deixa visualizar os campos, mas não pode alterar
                            if (vm.SituacaoVisita === SituacaoVisitaEnum.REAGENDADA) disableAgendamento(false, true);
                        } else {
                            // inclusão
                            inputAgendamentoNumero.setValue("0000-000000");
                            inputAgendamentoNumero.enable(false);

                            inputAgendamentoData.setValue(vm.Data);
                            setVal("inputAgendamentoCodigoRepresentante", vm.CodigoRepresentante);
                            setHtml("descriptionAgendamentoCodigoRepresentante", vm.NomeRepresentante);

                            setGrupoCicloDeVisitasDefault();

                            perguntar = false;
                            u.disable("buttonNovo");
                            u.disable("buttonExcluir");
                        }
                    }

                    function setGrupoCicloDeVisitasDefault() {
                        inputDiaDaVisitaConsiderarDiaUtil.setValue(false);
                        inputDiaDaVisitaConsiderarDiaUtil.disable();

                        setChecked("inputDiaDaVisitaAntecipa", true);
                        u.disable("inputDiaDaVisitaAntecipa");
                        u.disable("inputDiaDaVisitaPosterga");

                        setChecked("inputValidadeDoCicloPrazoDe", true);
                        u.disable("inputValidadeDoCicloPrazoDe");
                        inputValidadeDoCicloQtdDias.setValue("0");
                        inputValidadeDoCicloQtdDias.enable(false);
                        u.disable("inputValidadeDoCicloPeriodoMovimentacao");
                    }

                    function disableAgendamento(disableAba, disableButtons) {
                        perguntar = false;

                        inputAgendamentoNumero.enable(false);
                        inputAgendamentoData.enable(false);
                        inputAgendamentoHora.enable(false);
                        inputAgendamentoCodigoCliente.enable2(false);
                        inputCicloDeVisitasTipoPeriodo.enable2(false);
                        setGrupoCicloDeVisitasDefault();
                        inputAgendamentoObservacoes.enable(false);

                        // disabled abas
                        if (disableAba) $("#tabs > li > a").removeAttr("href").removeAttr("data-toggle");

                        inputVisitaSituacaoVisita.enable2(false);
                        inputVisitaAtendidoPor.enable(false);
                        inputVisitaCodigoContato.enable2(false);
                        inputVisitaDataReagendaPara.enable(false);
                        inputVisitaIsRecalcularProximosAgendamentos.enable2(false);
                        inputVisitaSituacaoVenda.enable2(false);
                        inputVisitaValorVenda.enable(false);
                        inputVisitaObservacoes.enable(false);

                        if (disableButtons) {
                            u.disable("buttonOK");
                            u.disable("buttonNovo");
                            u.disable("buttonExcluir");
                        }
                    }

                    function saveAgendamento() {
                        if (!checkAgendamento())
                            return;

                        // se for alteração, e alterou a data do agendamento, pergunta
                        if (params.Id && inputAgendamentoData.getValue() !== DataAgentamentoOriginal) {
                            u.dialog(null, "A data do agendamento foi alterada. Deseja recalcular o ciclo de visitas?",
                                function () {
                                    saveAgendamento_request();
                                },
                                function () {
                                    RecalcularCiclosAlteracaoData = false;
                                    saveAgendamento_request();
                                }, null, true);
                        }
                        else {
                            saveAgendamento_request()
                        }
                    }

                    // TODO: melhorar
                    function saveAgendamento_request() {
                        request2(
                            "Comercial/MovimentosAgendamentos/SaveAgendamento",
                            getObjAgendamento(),
                            function (vm) {
                                u.dialogOk(
                                    "Agendamento salvo com sucesso.",
                                    null,
                                    true,
                                    function () {
                                        setTimeout(function () { $('#waiting').show(); }, 100);
                                        window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamento?Id={0}".format(vm.Id);
                                    },
                                    alertBehavior.success
                                );
                            }
                        );
                    }

                    function checkAgendamento() {
                        if (inputAgendamentoData.isEmpty) {
                            u.dialogOk("O campo \"Data Agendamento\" da aba \"Agendamento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Agendamento);
                                inputAgendamentoData.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputAgendamentoCodigoCliente.isEmpty()) {
                            u.dialogOk("O campo \"Cliente\" da aba \"Agendamento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Agendamento);
                                inputAgendamentoCodigoCliente.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        return true;
                    }

                    function getObjAgendamento() {
                        var obj = {};

                        obj.Id = params.Id;

                        obj.Numero = inputAgendamentoNumero.getValue();
                        obj.Data = inputAgendamentoData.getValue();
                        obj.Hora = inputAgendamentoHora.getValue();
                        obj.CodigoCliente = inputAgendamentoCodigoCliente.getValue();
                        obj.CodigoTipoPeriodo = inputCicloDeVisitasTipoPeriodo.getValue();
                        obj.CodigoDiaDaVisita = !isChecked("inputDiaDaVisitaConsiderarDiaUtil") ? DiaDaVisitaEnum.NAO_CONSIDERAR_DIA_UTIL : isChecked("inputDiaDaVisitaAntecipa") ? DiaDaVisitaEnum.ANTECIPA : DiaDaVisitaEnum.POSTERGA;
                        obj.CodigoValidadeDoCiclo = isChecked("inputValidadeDoCicloPrazoDe") ? ValidadeDoCicloEnum.PRAZO_DE : ValidadeDoCicloEnum.PERIODO_DE_MOVIMENTACAO;
                        obj.QtdDias = inputValidadeDoCicloQtdDias.getValue();
                        obj.Observacoes = inputAgendamentoObservacoes.get();

                        obj.CodigoSituacaoVisita = inputVisitaSituacaoVisita.getValue();
                        obj.AtendidoPor = inputVisitaAtendidoPor.getValue();
                        obj.CodigoContato = inputVisitaCodigoContato.getValue();
                        obj.DataReagendamento = inputVisitaDataReagendaPara.getValue();
                        obj.IsRecalcularProximosAgendamentos = inputVisitaIsRecalcularProximosAgendamentos.getValue();
                        obj.CodigoSituacaoVenda = inputVisitaSituacaoVenda.getValue();
                        obj.ValorVenda = inputVisitaValorVenda.getValue();
                        obj.ObservacoesVisita = inputVisitaObservacoes.get();

                        obj.RecalcularCiclosAlteracaoData = RecalcularCiclosAlteracaoData;

                        return obj;
                    }

                    function deleteAgendamento() {
                        request2("Comercial/MovimentosAgendamentos/DeleteAgendamento/", { id: params.Id },
                            function (vm) {
                                setTimeout(function () { $('#waiting').show(); }, 100);
                                window.location.href = window.baseUrl + "Comercial/MovimentosAgendamentos/Agendamentos";
                            });
                    }

                    //
                    // load
                    //

                    loadAgendamento();

                }(params));
            },

            ConsultasHistoricoClientes: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            getHistoricoDeClientes();
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);

                            getHistoricoDeClientes();
                        },
                        onEmpty: function () {
                            getHistoricoDeClientes();
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);

                            getHistoricoDeClientes();
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);

                            getHistoricoDeClientes();
                        },
                        onEmpty: function () {
                            getHistoricoDeClientes();
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var validatorCliente = new Validator({
                        field: "CodigoCliente",
                        onPendencyMessage: "Deve ser informado o código do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        v2: true,
                        onValid: function (data) {
                            $("#inputCodigoCliente").val(data.Codigo);
                            $("#descriptionCodigoCliente").html(data.RazaoSocial);
                            validatorCliente.update();

                            getHistoricoDeClientes();
                        },
                        onInvalid: function (data) {
                            validatorCliente.clear({ error: true });
                            validatorCliente.update();
                            validatorCliente.focus();

                            getHistoricoDeClientes();
                        },
                        onEmpty: function () {
                            validatorCliente.clear();
                            validatorCliente.update();

                            getHistoricoDeClientes();
                        }
                    });
                    validatorCliente.listen();

                    var tableClientes = new Table({
                        "id": "tableCliente",
                        "route": window.baseUrl + "Empresarial/F4Cliente/GetClientes",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "columnsLegend": { CnpjCpf: "Ex: 11.222.333/4444-55" },
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                $("#modalCliente").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalCliente").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableCliente table tr").on("dblclick", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                $("#modalCliente").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalCliente").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var modalClientes = new Modal("Clientes", byId("linkButtonModalClientes"), byId("inputCodigoCliente"), tableClientes).listen();

                    function getHistoricoDeClientes() {
                        if (validatorCliente.invalid || !inputPeriodoInicial.isValid || !inputPeriodoFinal.isValid || !comparePeriodoInicialComFinal.isValid) {
                            $("#buttonDadosClienteAnotacoesGerais").attr("disabled", "disabled");

                            setVal("DadosCliente.CpfCnpj", "");
                            setVal("DadosCliente.InscricaoEstadual", "");
                            setVal("DadosCliente.DataClienteDesde", "");

                            setVal("DadosCliente.Endereco", "");

                            setVal("DadosCliente.Contato", "");
                            setVal("DadosCliente.Telefone", "");
                            setVal("DadosCliente.Email", "");

                            setHtml("DadosCliente.Categoria1Legenda", "Categoria 1:");
                            setVal("DadosCliente.Categoria1Descricao", "");
                            setHtml("DadosCliente.Categoria2Legenda", "Categoria 2:");
                            setVal("DadosCliente.Categoria2Descricao", "");
                            setHtml("DadosCliente.Categoria3Legenda", "Categoria 3:");
                            setVal("DadosCliente.Categoria3Descricao", "");

                            // - informacoes comerciais
                            setHtml("InformacoesComerciais.ValorPedidos", "");
                            setHtml("InformacoesComerciais.ValorVendas", "");
                            setHtml("InformacoesComerciais.ValorDevolucoes", "");
                            setHtml("InformacoesComerciais.ValorProdutoMaisComprado", "");
                            setVal("InformacoesComerciais.DescricaoProdutoMaisCompradoValor", "");

                            setHtml("InformacoesComerciais.CondicoesPagamento", "");
                            setHtml("InformacoesComerciais.TabelaPrecos", "");
                            setHtml("InformacoesComerciais.FrequenciaMediaCompra", "");
                            setHtml("InformacoesComerciais.QuantidadeProdutoMaisComprado", "");
                            setVal("InformacoesComerciais.DescricaoProdutoMaisCompradoQuantidade", "");

                            // - informacoes financeiras
                            setHtml("InformacoesFinanceiras.ValorLimite", "");
                            setHtml("InformacoesFinanceiras.DataLimite", "");
                            setHtml("InformacoesFinanceiras.ValorCreditoUtilizado", "");
                            setHtml("InformacoesFinanceiras.ValorAdiantamento", "");
                            setHtml("InformacoesFinanceiras.ValorChequesPreDatados", "");
                            setHtml("InformacoesFinanceiras.ValorCreditoDisponivel", "");
                            setHtml("InformacoesFinanceiras.LiberacaoVenda", "");
                            setHtml("InformacoesFinanceiras.ValorSaldoVencido", "");
                            setHtml("InformacoesFinanceiras.ValorSaldoAVencer", "");
                            setHtml("InformacoesFinanceiras.MediaAtrasoEmDias", "");
                            setHtml("InformacoesFinanceiras.ValorChequesDevolvidos", "");
                            setHtml("InformacoesFinanceiras.ValorMaiorAtraso", "");
                            setHtml("InformacoesFinanceiras.BaixasInadimplencia", "");
                            setHtml("InformacoesFinanceiras.ValorBaixasInadimplencia", "");

                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridUltimasCompras").data("kendoGrid").setDataSource(data);
                        }
                        else {
                            request(
                                "Comercial/Consultas/GetHistoricoDeClientes",
                                {
                                    codCliente: getVal("inputCodigoCliente"),
                                    dataInicial: getVal("inputPeriodoInicial"),
                                    dataFinal: getVal("inputPeriodoFinal")
                                },
                                function (model) {
                                    // - periodo pesquisa
                                    //setVal("inputPeriodoInicial", );
                                    //setVal("inputPeriodoFinal", );

                                    // - dados do cliente
                                    //setVal("inputCodigoCliente", );
                                    //setHtml("descriptionCodigoCliente", );
                                    $("#buttonDadosClienteAnotacoesGerais").removeAttr("disabled")

                                    setVal("DadosCliente.CpfCnpj", model.DadosCliente.CpfCnpj);
                                    setVal("DadosCliente.InscricaoEstadual", model.DadosCliente.InscricaoEstadual);
                                    setVal("DadosCliente.DataClienteDesde", getDateJsonMSStringDDMMYYYY(model.DadosCliente.DataClienteDesde));

                                    setVal("DadosCliente.Endereco", model.DadosCliente.Endereco);

                                    setVal("DadosCliente.Contato", model.DadosCliente.Contato);
                                    setVal("DadosCliente.Telefone", model.DadosCliente.Telefone);
                                    setVal("DadosCliente.Email", model.DadosCliente.Email);

                                    setHtml("DadosCliente.Categoria1Legenda", model.DadosCliente.Categoria1Legenda);
                                    setVal("DadosCliente.Categoria1Descricao", model.DadosCliente.Categoria1Descricao);
                                    setHtml("DadosCliente.Categoria2Legenda", model.DadosCliente.Categoria2Legenda);
                                    setVal("DadosCliente.Categoria2Descricao", model.DadosCliente.Categoria2Descricao);
                                    setHtml("DadosCliente.Categoria3Legenda", model.DadosCliente.Categoria3Legenda);
                                    setVal("DadosCliente.Categoria3Descricao", model.DadosCliente.Categoria3Descricao);

                                    // - informacoes comerciais
                                    setHtml("InformacoesComerciais.ValorPedidos", formatDecimalPtBr(model.InformacoesComerciais.ValorPedidos));
                                    setHtml("InformacoesComerciais.ValorVendas", formatDecimalPtBr(model.InformacoesComerciais.ValorVendas));
                                    setHtml("InformacoesComerciais.ValorDevolucoes", formatDecimalPtBr(model.InformacoesComerciais.ValorDevolucoes));
                                    setHtml("InformacoesComerciais.ValorProdutoMaisComprado", formatDecimalPtBr(model.InformacoesComerciais.ValorProdutoMaisComprado));
                                    setVal("InformacoesComerciais.DescricaoProdutoMaisCompradoValor", model.InformacoesComerciais.DescricaoProdutoMaisCompradoValor);

                                    setHtml("InformacoesComerciais.CondicoesPagamento", model.InformacoesComerciais.CondicoesPagamento);
                                    setHtml("InformacoesComerciais.TabelaPrecos", model.InformacoesComerciais.TabelaPrecos);
                                    setHtml("InformacoesComerciais.FrequenciaMediaCompra", model.InformacoesComerciais.FrequenciaMediaCompra);
                                    setHtml("InformacoesComerciais.QuantidadeProdutoMaisComprado", formatDecimalPtBr(model.InformacoesComerciais.QuantidadeProdutoMaisComprado));
                                    setVal("InformacoesComerciais.DescricaoProdutoMaisCompradoQuantidade", model.InformacoesComerciais.DescricaoProdutoMaisCompradoQuantidade);

                                    if (model.MostrarInformacoesFinanceiras) {
                                        // - informacoes financeiras
                                        setHtml("InformacoesFinanceiras.ValorLimite", formatDecimalPtBr(model.InformacoesFinanceiras.ValorLimite));
                                        setHtml("InformacoesFinanceiras.DataLimite", getDateJsonMSStringDDMMYYYY(model.InformacoesFinanceiras.DataLimite));
                                        setHtml("InformacoesFinanceiras.ValorCreditoUtilizado", formatDecimalPtBr(model.InformacoesFinanceiras.ValorCreditoUtilizado));
                                        setHtml("InformacoesFinanceiras.ValorAdiantamento", formatDecimalPtBr(model.InformacoesFinanceiras.ValorAdiantamento));
                                        setHtml("InformacoesFinanceiras.ValorChequesPreDatados", formatDecimalPtBr(model.InformacoesFinanceiras.ValorChequesPreDatados));
                                        setHtml("InformacoesFinanceiras.ValorCreditoDisponivel", formatDecimalPtBr(model.InformacoesFinanceiras.ValorCreditoDisponivel));

                                        setHtml("InformacoesFinanceiras.LiberacaoVenda", model.InformacoesFinanceiras.LiberacaoVenda);
                                        if (model.InformacoesFinanceiras.LiberacaoVenda === 'BLOQUEADA')
                                            $(document.getElementById("InformacoesFinanceiras.LiberacaoVenda")).css({ "color": "red", "font-weight": "800" });
                                        else
                                            $(document.getElementById("InformacoesFinanceiras.LiberacaoVenda")).css({ "color": "green", "font-weight": "800" });

                                        setHtml("InformacoesFinanceiras.ValorSaldoVencido", formatDecimalPtBr(model.InformacoesFinanceiras.ValorSaldoVencido));
                                        setHtml("InformacoesFinanceiras.ValorSaldoAVencer", formatDecimalPtBr(model.InformacoesFinanceiras.ValorSaldoAVencer));
                                        setHtml("InformacoesFinanceiras.MediaAtrasoEmDias", model.InformacoesFinanceiras.MediaAtrasoEmDias);
                                        setHtml("InformacoesFinanceiras.ValorChequesDevolvidos", formatDecimalPtBr(model.InformacoesFinanceiras.ValorChequesDevolvidos));
                                        setHtml("InformacoesFinanceiras.ValorMaiorAtraso", formatDecimalPtBr(model.InformacoesFinanceiras.ValorMaiorAtraso));
                                        setHtml("InformacoesFinanceiras.BaixasInadimplencia", model.InformacoesFinanceiras.BaixasInadimplencia);
                                        setHtml("InformacoesFinanceiras.ValorBaixasInadimplencia", formatDecimalPtBr(model.InformacoesFinanceiras.ValorBaixasInadimplencia));
                                    }

                                    var data = new kendo.data.DataSource({ data: [] });
                                    for (var atual in model.ListaUltimasCompras) {
                                        data.options.data.push({
                                            TipoMovimentacao: model.ListaUltimasCompras[atual].TipoMovimentacao,
                                            Documento: model.ListaUltimasCompras[atual].Documento,
                                            Filial: model.ListaUltimasCompras[atual].Filial,
                                            DataEmissao: getDateJsonMSStringDDMMYYYY(model.ListaUltimasCompras[atual].DataEmissao),
                                            DataSaida: getDateJsonMSStringDDMMYYYY(model.ListaUltimasCompras[atual].DataSaida),
                                            ValorVenda: model.ListaUltimasCompras[atual].ValorVenda,
                                            ValorDesconto: model.ListaUltimasCompras[atual].ValorDesconto,
                                            Vendedor: model.ListaUltimasCompras[atual].Vendedor,
                                            Representante: model.ListaUltimasCompras[atual].Representante
                                        });
                                    }
                                    $("#gridUltimasCompras").data("kendoGrid").setDataSource(data);
                                }
                            );
                        }
                    }

                    $("#buttonDadosClienteAnotacoesGerais").on("click", function () {
                        request("Comercial/Consultas/GetHistoricoDeClientes_AnotacoesGerais",
                            {
                                codCliente: getVal("inputCodigoCliente"),
                            },
                            function (result) {
                                setVal("DadosCliente.AnotacoesGerais", result);
                            }
                        );
                    });

                    $("#buttonOK_AnotacoesGerais").on("click", function () {
                        request("Comercial/Consultas/SalveHistoricoDeClientes_AnotacoesGerais",
                            {
                                codCliente: getVal("inputCodigoCliente"),
                                anotacoesGerais: getVal("DadosCliente.AnotacoesGerais")
                            }
                        );
                    });

                    var gridUltimasCompras = new Table({
                        "toolbar": "<span id='toolbarUltimasCompras'>&nbsp&nbsp&nbspÚltimas Compras do Cliente </span>",
                        "id": "gridUltimasCompras",
                        "pageable": false,
                        "columns": [
                            { field: "TipoMovimentacao", title: "Tipo Movimentação", width: 60, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "Documento", title: "Documento", width: 60, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "Filial", title: "Filial", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "DataEmissao", title: "Data Emissão", width: 90, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "DataSaida", title: "Data Saída", width: 90, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "ValorVenda", title: "Vlr Venda", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorDesconto", title: "Vlr Desconto", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "Vendedor", title: "Vendedor", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "Representante", title: "Representante", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }
                        ],
                        "dataSourceType": "Object"
                    });
                    gridUltimasCompras.make();

                    // formata o titulo da grid
                    var selector_Titulo = ".container-historico-clientes > fieldset > legend";
                    var cssGridUltimasCompras_Titulo = {
                        "font-family": $(selector_Titulo).css("font-family"),
                        "font-size": $(selector_Titulo).css("font-size"),
                        "font-weight": $(selector_Titulo).css("font-weight"),
                        "color": $(selector_Titulo).css("color"),
                        "background": $(selector_Titulo).css("background"),
                        "line-height": "20px"
                    }
                    $("#toolbarUltimasCompras").css(cssGridUltimasCompras_Titulo);

                    // formata os heads da grid
                    var selector_Header = ".container-historico-clientes > fieldset > .radar-row > .radar-control > .control-group > .controls > label";
                    var cssGridUltimasCompras_Header = {
                        "font-family": $(selector_Header).css("font-family"),
                        "font-size": $(selector_Header).css("font-size"),
                        "font-weight": $(selector_Header).css("font-weight"),
                        "color": $(selector_Header).css("color"),
                    }
                    $("#gridUltimasCompras > .k-grid-header > .k-grid-header-wrap > table > thead > tr > th > .k-link ").css(cssGridUltimasCompras_Header);

                    // seta a altura do grid
                    $("#gridUltimasCompras .k-grid-content").height(140);

                    $("#inputCodigoCliente").focus();

                }(params));
            },

            ConsultasSaldoProdutoNoEstoque: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // produto
                    var validatorProdutos = new Validator({
                        field: "CodigoProduto",
                        onPendencyMessage: "Deve ser informado o código do produto.",
                        route: "Empresarial/F4Produto/GetProduto",
                        v2: true,
                        onValid: function (data) {
                            validatorProdutos.setChange(true);
                            setVal("inputCodigoProduto", data["Codigo"]);
                            setHtml("descriptionCodigoProduto", data["Nome"]);
                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });

                            if (data["HaveGrade1"]) {
                                validatorGrade1.enable();
                                validatorGrade1.focus();
                            } else {
                                $("#linkButtonModalProdutos").focus();
                            }

                            if (data["HaveGrade2"])
                                validatorGrade2.enable();

                            if (data["HaveGrade3"])
                                validatorGrade3.enable();

                            getSaldoProduto();
                        },
                        onInvalid: function (data) {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear({ error: true });
                            validatorProdutos.focus();
                            validatorGrade1.clear({ error: true, disable: true });
                            validatorGrade2.clear({ error: true, disable: true });
                            validatorGrade3.clear({ error: true, disable: true });
                            getSaldoProduto();
                            $("#linkButtonModalFotos").hide();
                        },
                        onEmpty: function () {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear();
                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });
                            $("#linkButtonModalProdutos").focus();
                            getSaldoProduto();
                            $("#linkButtonModalFotos").hide();
                        }
                    });
                    validatorProdutos.listen();

                    var tableProdutos = new Table({
                        id: "tableProdutos",
                        route: window.baseUrl + "Empresarial/F4Produto/GetProdutos",
                        showFilter: true,
                        columns: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Unidade", field: "Unidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Preço", field: "ValorUnitario", width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                            { title: "Classificação", field: "Classificacao", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        onChange: function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                            };
                        },
                        onDataBound: function () {
                            $("#tableProdutos table  tr").on("dblclick", function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                                $("#modalProdutos").modal("hide");
                            });
                        },
                        dataSourceType: "Filtered"
                    });
                    var linkButtonModalProdutos = document.getElementById("linkButtonModalProdutos");
                    var inputProdutos = document.getElementById("inputCodigoProduto");

                    // showOpcaoExibir, exibirHierarquiaLista
                    var options = {
                        urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                        showOpcaoExibir: true,
                        onDblClickGetItem: function (event, dados) {
                            // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                            var data = dados,
                                search = {};
                            search["CodigoProduto"] = data["Codigo"];
                            getJsonFromRoute("Empresarial/F4Produto/GetProduto", search).done(function (data) {
                                validatorProdutos.onValid(data);
                                validatorProdutos.update();
                            });
                            $("#modalProdutos").modal("hide");
                        }
                    };

                    var modalProdutos = new Modal("Produtos", linkButtonModalProdutos, inputProdutos, tableProdutos, null, options);
                    modalProdutos.listen();

                    // grades
                    var columnsGrade = [
                        { title: "Código", field: "Codigo", width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        { title: "Descrição", field: "Descricao", width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                    ];

                    // grade1
                    var validatorGrade1 = new Validator({
                        field: "CodigoGrade1",
                        onPendencyMessage: "Deve ser informada a grade 1.",
                        route: "Empresarial/F4Produto/GetItemGrade1",
                        pendency: [validatorProdutos],
                        v2: true,
                        onValid: function (data) {
                            validatorGrade1.setChange(true);
                            setVal("inputCodigoGrade1", data["Codigo"]);
                            setHtml("descriptionCodigoGrade1", " - " + data["Descricao"]);
                            getSaldoProduto();
                        },
                        onInvalid: function (data) {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear({ error: true });
                            validatorGrade1.focus();
                            getSaldoProduto();
                        },
                        onEmpty: function () {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear();
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                            getSaldoProduto();
                        }
                    });
                    validatorGrade1.listen();

                    var optionsGrade1 = {
                        "id": "tableGrade1",
                        "route": window.baseUrl + "Empresarial/F4Produto/List1",
                        "showFilter": true,
                        "columns": columnsGrade,
                        "params": [validatorProdutos],
                        "fieldDepende": validatorProdutos,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            var cancelar = document.getElementById("inputF4ModalCancelar");
                            ok.onclick = function () {
                                var data = tableGrade1.getSelectedData();
                                validatorGrade1.onValid(data);
                                validatorGrade1.update();
                                $("#filtroPedidosModal").modal("show");
                            };
                            cancelar.onclick = function () {
                                $("#filtroPedidosModal").modal("show");
                            };
                        },
                        "onDataBound": onDataBoundGrade1,
                        "dataSourceType": "Parameter"
                    };

                    function onDataBoundGrade1() {
                        $("#filtroPedidosModal").modal("hide");
                        $("#" + this.id + " table  tr").on("dblclick", function () {
                            var data = tableGrade1.getSelectedData();
                            validatorGrade1.onValid(data);
                            validatorGrade1.update();
                            $("#modalGrade1").modal("hide");
                            $("#filtroPedidosModal").modal("show");
                        });
                        var cancelar = document.getElementById("inputF4ModalCancelar");
                        cancelar.onclick = function () {
                            $("#filtroPedidosModal").modal("show");
                        };
                        $("#filtroPedidosModal").modal("hide");
                    }

                    var tableGrade1 = new Table(optionsGrade1);
                    var linkButtonModalGrade1 = document.getElementById("linkButtonModalGrade1");
                    $(linkButtonModalGrade1).on("click", function () {
                        $("#filtroPedidosModal").modal("hide");
                    });
                    var inputGrade1 = document.getElementById("inputCodigoGrade1");
                    var modalGrade1 = new Modal("Grade", linkButtonModalGrade1, inputGrade1, tableGrade1);
                    modalGrade1.listen();

                    // grade2
                    var validatorGrade2 = new Validator({
                        field: "CodigoGrade2",
                        onPendencyMessage: "Deve ser informada a grade 2.",
                        route: "Empresarial/F4Produto/GetItemGrade2",
                        pendency: [validatorGrade1, validatorProdutos],
                        v2: true,
                        onValid: function (data) {
                            validatorGrade2.setChange(true);
                            setVal("inputCodigoGrade2", data["Codigo"]);
                            setHtml("descriptionCodigoGrade2", " - " + data["Descricao"]);
                            getSaldoProduto();
                        },
                        onInvalid: function (data) {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear({ error: true });
                            validatorGrade2.focus();
                            getSaldoProduto();
                        },
                        onEmpty: function () {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                            getSaldoProduto();
                        }
                    });
                    validatorGrade2.listen();

                    var optionsGrade2 = {
                        "id": "tableGrade2",
                        "route": window.baseUrl + "Empresarial/F4Produto/List2",
                        "showFilter": true,
                        "columns": columnsGrade,
                        "params": [validatorGrade1, validatorProdutos],
                        "fieldDepende": validatorGrade1,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            var cancelar = document.getElementById("inputF4ModalCancelar");
                            ok.onclick = function () {
                                var data = tableGrade2.getSelectedData();
                                validatorGrade2.onValid(data);
                                validatorGrade2.update();
                                $("#filtroPedidosModal").modal("show");
                            };
                            cancelar.onclick = function () {
                                $("#filtroPedidosModal").modal("show");
                            };
                        },
                        "onDataBound": onDataBoundGrade2,
                        "dataSourceType": "Parameter"
                    };

                    function onDataBoundGrade2() {
                        $("#filtroPedidosModal").modal("hide");
                        $("#" + this.id + " table  tr").on("dblclick", function () {
                            var data = tableGrade2.getSelectedData();
                            validatorGrade2.onValid(data);
                            validatorGrade2.update();
                            $("#modalGrade2").modal("hide");
                            $("#filtroPedidosModal").modal("show");
                        });
                        var cancelar = document.getElementById("inputF4ModalCancelar");
                        cancelar.onclick = function () {
                            $("#filtroPedidosModal").modal("show");
                        };
                    }

                    var tableGrade2 = new Table(optionsGrade2);
                    var linkButtonModalGrade2 = document.getElementById("linkButtonModalGrade2");
                    $(linkButtonModalGrade2).on("click", function () {
                        $("#filtroPedidosModal").modal("hide");
                    });
                    var inputGrade2 = document.getElementById("inputCodigoGrade2");
                    var modalGrade2 = new Modal("Grade", linkButtonModalGrade2, inputGrade2, tableGrade2);
                    modalGrade2.listen();

                    // grade3
                    var validatorGrade3 = new Validator({
                        field: "CodigoGrade3",
                        onPendencyMessage: "Deve ser informada a grade 3.",
                        route: "Empresarial/F4Produto/GetItemGrade3",
                        pendency: [validatorGrade2, validatorGrade1, validatorProdutos],
                        v2: true,
                        onValid: function (data) {
                            validatorGrade3.setChange(true);
                            setVal("inputCodigoGrade3", data["Codigo"]);
                            setHtml("descriptionCodigoGrade3", " - " + data["Descricao"]);
                            getSaldoProduto();
                        },
                        onInvalid: function (data) {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear({ error: true });
                            validatorGrade3.focus();
                            getSaldoProduto();
                        },
                        onEmpty: function () {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear();
                            getSaldoProduto();
                        }
                    });
                    validatorGrade3.listen();

                    var optionsGrade3 = {
                        "id": "tableGrade3",
                        "route": window.baseUrl + "Empresarial/F4Produto/List3",
                        "showFilter": true,
                        "columns": columnsGrade,
                        "params": [validatorGrade2, validatorGrade1, validatorProdutos],
                        "fieldDepende": validatorGrade2,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            var cancelar = document.getElementById("inputF4ModalCancelar");
                            ok.onclick = function () {
                                var data = tableGrade3.getSelectedData();
                                validatorGrade3.onValid(data);
                                validatorGrade3.update();
                                $("#filtroPedidosModal").modal("show");
                            };
                            cancelar.onclick = function () {
                                $("#filtroPedidosModal").modal("show");
                            };
                        },
                        "onDataBound": onDataBoundGrade3,
                        "dataSourceType": "Parameter"
                    };

                    function onDataBoundGrade3() {
                        $("#filtroPedidosModal").modal("hide");
                        $("#" + this.id + " table  tr").on("dblclick", function () {
                            var data = tableGrade3.getSelectedData();
                            validatorGrade3.onValid(data);
                            validatorGrade3.update();
                            $("#modalGrade3").modal("hide");
                            $("#filtroPedidosModal").modal("show");
                        });
                        var cancelar = document.getElementById("inputF4ModalCancelar");
                        cancelar.onclick = function () {
                            $("#filtroPedidosModal").modal("show");
                        };
                        $("#filtroPedidosModal").modal("hide");
                    }

                    var tableGrade3 = new Table(optionsGrade3);
                    var linkButtonModalGrade3 = document.getElementById("linkButtonModalGrade3");
                    $(linkButtonModalGrade3).on("click", function () {
                        $("#filtroPedidosModal").modal("hide");
                    });
                    var inputGrade3 = document.getElementById("inputCodigoGrade3");
                    var modalGrade3 = new Modal("Grade", linkButtonModalGrade3, inputGrade3, tableGrade3);
                    modalGrade3.listen();

                    // fotos
                    var gridFotos = new Grid({
                        id: "gridFotos",
                        columns: [
                            { field: "Nome", title: "Arquivo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        onChange: function () {
                            "use strict";
                            var self = this;
                            carregaFoto();
                        }
                    });

                    $("#modalFotos").focusout(function () {
                        apagaFotos();
                    });

                    $("#linkButtonModalFotos").on("click", function () {
                        getJsonFromRoute(
                            "Empresarial/Imagens/GetFotosProduto",
                            { codProduto : $("#inputCodigoProduto").val() }
                        ).done(
                            function (listaFotos) {
                                if (listaFotos.IsAlert)
                                    u.alert(listaFotos.Message, alertBehavior.warning);
                                else
                                    carregaGridFotos(listaFotos);
                            }
                        );
                    });

                    function carregaFoto() {
                        var foto = gridFotos.getSelectedData();
                        var src = window.baseUrl + "Empresarial/Imagens/LoadFotoProduto?&PathRemoto=" + foto.PathRemoto + "&PathLocal=" + foto.PathLocal + "&Nome=" + foto.Nome;
                        $("#fotoProduto").attr("src", src);
                        $("#fotoProduto").attr("alt", foto.Nome);

                        $("#fotoProduto").on("load", function () {
                            var fotoProduto = document.getElementById("fotoProduto");
                            var maxWidth = fotoProduto.style.maxWidth.asInt();
                            var maxHeight = fotoProduto.style.maxHeight.asInt();
                            var width = $("#fotoProduto").width();
                            var height = $("#fotoProduto").height();

                            if (height >= width) {
                                fotoProduto.style.top = Math.round(height / 2) + "px";
                                fotoProduto.style.left = "50%";
                                fotoProduto.style.marginLeft = Math.round(width / 2) + "px";
                            } else {
                                fotoProduto.style.top = Math.round((maxHeight - height) / 2) + "px";
                                fotoProduto.style.left = "50%";
                                fotoProduto.style.marginLeft = Math.round((maxWidth - width) / 2) + "px";
                            }
                        });
                    }

                    function zeraFoto() {
                        $("#fotoProduto").removeAttr("src");
                        $("#fotoProduto").removeAttr("alt");
                        $("#fotoProduto").removeAttr("style");
                        document.getElementById("fotoProduto").style.maxWidth = "600px";
                        document.getElementById("fotoProduto").style.maxHeight = "400px";
                    }

                    function apagaFotos() {
                        var fotos = $("#gridFotos").data("kendoGrid").dataSource.data();
                        var listaFotos = "";

                        for (var i = 0; i < fotos.length; i = i + 1)
                            listaFotos += fotos[i].PathLocal + ",";

                        getJsonFromRoute(
                            "Empresarial/Imagens/DeleteFotoProduto",
                            { listaFotos: listaFotos }
                        ).done(
                            function (data) {
                                if (data.IsAlert)
                                    u.alert(data.Message, alertBehavior.warning);
                            }
                        );
                    }

                    function carregaGridFotos(listaFotos) {
                        gridFotos.setValue(listaFotos, function (foto) {
                            return {
                                Nome: foto.Nome,
                                PathRemoto: foto.PathRemoto,
                                PathLocal: foto.PathLocal,
                            }
                        });
                    }

                    // filial
                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                            getSaldoProduto();
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ error: true });
                            validatorFilial.focus();
                            getSaldoProduto();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                            getSaldoProduto();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        "id": "tableFilial",
                        "route": window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $("#modalFilial").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    // tab. preços
                    var validatorTabelaPrecos = new Validator({
                        field: "CodigoTabelaPrecos",
                        onPendencyMessage: "Deve ser informado o código da tabela de preços.",
                        route: "Empresarial/F4TabelaPrecoProdutos/GetTabPreco",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoTabelaPrecos", data["Codigo"]);
                            setHtml("descriptionCodigoTabelaPrecos", data["Nome"]);
                            getSaldoProduto();
                        },
                        onInvalid: function () {
                            validatorTabelaPrecos.clear({ error: true });
                            validatorTabelaPrecos.focus();
                            getSaldoProduto();
                        },
                        onEmpty: function () {
                            validatorTabelaPrecos.clear();
                            getSaldoProduto();
                        }
                    });
                    validatorTabelaPrecos.listen();

                    function setDefault() {
                        getJsonFromRoute('Empresarial/F4Filial/GetFilialPadrao').done(
                            function (data) {
                                if (data.IsAlert)
                                    throw new Error(data.Message);

                                validatorFilial.setValues(data.Codigo, data.Nome);

                                if (data.CpfCnpj === "")
                                    validatorFilial.enable();
                                else
                                    validatorFilial.disable();
                            }
                        );

                        getJsonFromRoute('Empresarial/F4TabelaPrecoProdutos/GetTabelaPadrao').done(
                            function (data) {
                                if (data.IsAlert)
                                    throw new Error(data.Message);

                                validatorTabelaPrecos.setValues(data.Codigo, data.Nome);
                            }
                        );
                    };

                    var tableTabelaPrecosProduto = new Table({
                        "id": "tablePrecosProduto",
                        "route": window.baseUrl + "Empresarial/F4TabelaPrecoProdutos/GetTabPrecos",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Validade", field: "DataValidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableTabelaPrecosProduto.getSelectedData();
                                validatorTabelaPrecos.onValid(data);
                                validatorTabelaPrecos.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tablePrecosProduto table  tr").on("dblclick", function () {
                                var data = tableTabelaPrecosProduto.getSelectedData();
                                validatorTabelaPrecos.onValid(data);
                                validatorTabelaPrecos.update();
                                $("#modalTabPrecosProduto").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkButtonModalTabelaPrecos = document.getElementById("linkButtonModalTabelaPrecos");
                    var inputTabelaPrecos = document.getElementById("inputCodigoTabelaPrecos");
                    var modalTabelasPrecosProdutos = new Modal("Tabelas de Preços de Produtos", linkButtonModalTabelaPrecos, inputTabelaPrecos, tableTabelaPrecosProduto);
                    modalTabelasPrecosProdutos.listen();

                    // grid produtos
                    var gridProdutos = new Table({
                        id: "gridProdutos",
                        pageable: false,
                        columnMenu: true,
                        sortable: true,
                        columns: [
                            { field: "CodFilial", title: "Cód.", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "NomeFilial", title: "Filial", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "CodProduto", title: "Cód.", width: 40, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "NomeProduto", title: "Produto", width: 100, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "ItemGrade1", title: "Grade 1", width: 80, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "ItemGrade2", title: "Grade 2", width: 80, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "ItemGrade3", title: "Grade 3", width: 80, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "QuantidadeTotal", title: "Total", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;", format: "{0:c0}" } },
                            { field: "QuantidadeReservada", title: "Reservada", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;", format: "{0:c0}" } },
                            { field: "QuantidadePreBaixa", title: "Pré-Baixa", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;", format: "{0:c0}" } },
                            { field: "QuantidadeDisponivel", title: "Disponível", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;", format: "{0:c0}" } },
                            { field: "Preco", title: "Preço", width: 80, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: right;", format: "{0:c0}" } }
                        ],
                        dataSourceType: "Object"
                    });
                    gridProdutos.make();

                    // formata os heads da grid
                    var selector_Header = ".containerSaldoProdutoNoEstoque > fieldset > .radar-row > .radar-control > .control-group > label";
                    var cssGridProdutos_Header = {
                        "font-family": $(selector_Header).css("font-family"),
                        "font-size": $(selector_Header).css("font-size"),
                        "font-weight": $(selector_Header).css("font-weight"),
                        "color": $(selector_Header).css("color"),
                    }
                    $("#gridProdutos > .k-grid-header > .k-grid-header-wrap > table > thead > tr > th > .k-link ").css(cssGridProdutos_Header);

                    // seta a altura do grid
                    $("#gridProdutos .k-grid-content").height(140);

                    // saldo produto
                    $("#EstoqueProprio, #EstoqueEmPoderDeTerceiros, #EstoqueDeTerceirosEmPoderDaEmpresa, #MostrarProdutosComSaldoIgualZero").on(
                        "change",
                        function () {
                            getSaldoProduto();
                        }
                    );

                    var getSaldoProduto = (function () {
                        if (getVal("inputCodigoProduto") === "") {
                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridProdutos").data("kendoGrid").setDataSource(data);
                        } else {
                            request("Comercial/Consultas/GetSaldoProdutoNoEstoque", {
                                CodProduto: getVal("inputCodigoProduto"),
                                CodGrade1: getVal("inputCodigoGrade1"),
                                CodGrade2: getVal("inputCodigoGrade2"),
                                CodGrade3: getVal("inputCodigoGrade3"),
                                CodFilial: getVal("inputCodigoFilial"),
                                CodTabPrecos: getVal("inputCodigoTabelaPrecos"),
                                EstoqueProprio: isChecked("EstoqueProprio"),
                                EstoqueEmPoderDeTerceiros: isChecked("EstoqueEmPoderDeTerceiros"),
                                EstoqueDeTerceirosEmPoderDaEmpresa: isChecked("EstoqueDeTerceirosEmPoderDaEmpresa"),
                                MostrarProdutosComSaldoIgualZero: isChecked("MostrarProdutosComSaldoIgualZero")
                            },
                                function (model) {
                                    var data = new kendo.data.DataSource({ data: [] });

                                    for (var atual in model.saldos) {
                                        data.options.data.push({
                                            CodFilial: model.saldos[atual].CodFilial,
                                            NomeFilial: model.saldos[atual].NomeFilial,
                                            CodProduto: model.saldos[atual].CodProduto,
                                            NomeProduto: model.saldos[atual].NomeProduto,
                                            ItemGrade1: model.saldos[atual].ItemGrade1,
                                            ItemGrade2: model.saldos[atual].ItemGrade2,
                                            ItemGrade3: model.saldos[atual].ItemGrade3,
                                            QuantidadeTotal: model.saldos[atual].QuantidadeTotal,
                                            QuantidadeReservada: model.saldos[atual].QuantidadeReservada,
                                            QuantidadePreBaixa: model.saldos[atual].QuantidadePreBaixa,
                                            QuantidadeDisponivel: model.saldos[atual].QuantidadeDisponivel,
                                            Preco: model.saldos[atual].Preco,
                                        });
                                    }

                                    $("#gridProdutos").data("kendoGrid").setDataSource(data);

                                    if (model.temFotos)
                                        $("#linkButtonModalFotos").show();
                                    else
                                        $("#linkButtonModalFotos").hide();
                                }
                            );
                        }
                    });

                    $("#EstoqueDeTerceirosEmPoderDaEmpresa").on("click", function () {
                        if (isChecked("EstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#EstoqueProprio").attr("checked", false);
                            $("#EstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#EstoqueProprio").attr("disabled", "disabled");
                            $("#EstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#EstoqueProprio").removeAttr("disabled");
                            $("#EstoqueEmPoderDeTerceiros").removeAttr("disabled");
                        }
                    });
                    setDefault();
                    $("#inputCodigoProduto").focus();
                }(params));
            },

            RelatoriosRelacaoDePedidos: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var validatorCliente = new Validator({
                        field: "CodigoCliente",
                        onPendencyMessage: "Deve ser informado o código do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        v2: true,
                        onValid: function (data) {
                            $("#inputCodigoCliente").val(data.Codigo);
                            $("#descriptionCodigoCliente").html(data.RazaoSocial);
                        },
                        onInvalid: function (data) {
                            validatorCliente.clear({ error: true });
                            validatorCliente.focus();
                        },
                        onEmpty: function () {
                            validatorCliente.clear();
                        }
                    });
                    validatorCliente.listen();

                    var tableClientes = new Table({
                        "id": "tableCliente",
                        "route": window.baseUrl + "Empresarial/F4Cliente/GetClientes",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "columnsLegend": { CnpjCpf: "Ex: 11.222.333/4444-55" },
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                validatorCliente.update();
                                $("#modalCliente").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalCliente").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableCliente table tr").on("dblclick", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                validatorCliente.update();
                                $("#modalCliente").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalCliente").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var modalClientes = new Modal("Clientes", byId("linkButtonModalClientes"), byId("inputCodigoCliente"), tableClientes).listen();

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Comercial/Relatorios/GetModelosRelacaoPedidosReport"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("com_rel_relacaodepedidos");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        validatorCliente.setValue(inputs.Cliente);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            Cliente: validatorCliente.getValue()
                        }
                        currentUser.setCustomData("com_rel_relacaodepedidos", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Comercial/Relatorios/GeraRelatorioRelacaoDePedidos?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&Cliente=" + getVal("inputCodigoCliente")
                        );
                    });
                }(params));
            },

            RelatoriosComissoesAPagar: function (params) {
                return (function () {
                    var u = new Util();

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Comercial/Relatorios/GetModelosComissoesReport"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("com_rel_comissoes");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue()
                        }
                        currentUser.setCustomData("com_rel_comissoes", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Comercial/Relatorios/GeraRelatorioComissoesAPagar?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                        );
                    });
                }(params));
            },

            RelatoriosMovimentos: function (params) {
                return (function () {
                    var u = new Util();

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        },
                        onEmpty: function () {
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var inputData = $("#inputData").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Emissão" },
                            { Value: "1", Text: "Saída" },
                            { Value: "2", Text: "Inclusão" },
                            { Value: "3", Text: "Vencimento" },
                            { Value: "4", Text: "Recebimento" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0"
                    });

                    var inputSituacao = $("#inputSituacao").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Recebidos" },
                            { Value: "1", Text: "Abertos" },
                            { Value: "2", Text: "Vencidos" },
                            { Value: "3", Text: "Recebidos parcialmente" },
                            { Value: "4", Text: "Todos" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0"
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Comercial/Relatorios/GetModelosContasReceberMovimentosReport"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("com_rel_movimentos");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        inputData.data().kendoDropDownList.select(inputs.Data.toInt());
                        inputSituacao.data().kendoDropDownList.select(inputs.Situacao.toInt());
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            Data: inputData.val(),
                            Situacao: inputSituacao.val()
                        }
                        currentUser.setCustomData("com_rel_movimentos", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Comercial/Relatorios/GeraRelatorioMovimentos?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&PorData=" + getVal("inputData")
                            + "&Situacao=" + getVal("inputSituacao")
                        );
                    });
                }(params));
            }
        }
    })();

    Gerenciador.Manager = (function () {
        return {
            MovimentosAtendimentosTecnicos: function (params) {
                return (function () {
                    var u = new Util();

                    // grid atendimentos
                    var atendimentosTable = new Table({
                        'id': 'gridAtendimentos',
                        'msgDialog': true,
                        'idModalHideShow': "filtroAtendimentosModal",
                        'route': window.baseUrl + 'Gerenciador/Movimentos/GetAtendimentosTecnicos/',
                        'showFilter': false,
                        'columns': [
                            { title: 'Nº', field: 'Numero', width: 50, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { title: 'Cliente', field: 'Cliente', width: 160, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Emissão', field: 'DataEmissao', width: 75, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { title: 'Faturamento', field: 'DataFaturamento', width: 75, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { title: 'Vencimento', field: 'DataVencimento', width: 75, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { title: 'Situação', field: 'Situacao', width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: 'Filial', field: 'IdFilial', width: 50, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } }
                        ],
                        'toolbar':
                            "<span style='float:left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Atendimentos Técnicos</span>" +
                            "</span>" +
                            "<span style='float:right'>" +
                            "    <button id='inputFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'>Atualiza</span>Filtro" +
                            "    </button>" +
                            "    <button id='buttonNovoAtendimentoTecnico' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-plus'>Atualiza</span>Novo" +
                            "    </button>" +
                            "</span>",
                        'dataSourceType': "Filtered",
                        'pageable': {
                            refresh: true,
                            numeric: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        'onChange': function () {
                            "use strict";
                            var self = this;
                            var $data = self.getSelectedData();
                            window.location = window.baseUrl + 'Gerenciador/Movimentos/AtendimentoTecnico?Id=' + $data.Id + "&DataEmissao=" + $data.DataEmissao;
                        },
                        'onDataBound': function () {
                            "use strict";
                            var self = this;
                            $('#' + self.id + ' table tr').on('dblclick',
                                function () {
                                    var data = self.getSelectedData();
                                }
                            );
                            var el = $('#' + self.id + ' .k-grid-content');
                            el[0].style.height = "auto";
                        }
                    });
                    atendimentosTable.make();
                    atendimentosTable.listen();

                    // button ok
                    $('#inputFilter').on('click', function () {
                        $("#filtroAtendimentosModal").modal('show');
                    });

                    // button novo atendimento
                    $("#buttonNovoAtendimentoTecnico").click(function () {
                        window.location = window.baseUrl + 'Gerenciador/Movimentos/AtendimentoTecnico/';
                    });

                    // data inicial emissao
                    var inputFilterDataInicial = new ValidatorDate({
                        idInput: "inputEmissaoInicial",
                        isEmptyValid: true,
                        idModalHideShow: "filtroAtendimentosModal"
                    });

                    // data final emissao
                    var inputFilterDataFinal = new ValidatorDate({
                        idInput: "inputEmissaoFinal",
                        compareGreater: "inputEmissaoInicial",
                        isEmptyValid: true,
                        idModalHideShow: "filtroAtendimentosModal"
                    });

                    // data inicial faturamento
                    var inputFilterDataInicial = new ValidatorDate({
                        idInput: "inputFaturamentoInicial",
                        isEmptyValid: true,
                        idModalHideShow: "filtroAtendimentosModal"
                    });

                    // data final faturamento
                    var inputFilterDataFinal = new ValidatorDate({
                        idInput: "inputFaturamentoFinal",
                        compareGreater: "inputFaturamentoInicial",
                        isEmptyValid: true,
                        idModalHideShow: "filtroAtendimentosModal"
                    });

                    // situacao - pendente/realizado

                    // filial
                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        msgDialog: true,
                        idModalHideShow: "filtroAtendimentosModal",
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ warning: true });
                            validatorFilial.focus();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        "id": "tableFilial",
                        "msgDialog": true,
                        "idModalHideShow": "filtroAtendimentosModal",
                        "route": window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $.when($("#modalFilial").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            };
                        },
                        "onDataBound": function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $.when($("#modalFilial").modal("hide"))
								.done(function () {
								    $("#filtroAtendimentosModal").modal('show');
								});
                            });
                            listenF4ModalCancelar("#modalFilial");
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais, function () {
                        $("#filtroAtendimentosModal").modal("hide");
                    }, {
                        onHidden: function () {
                            $("#filtroAtendimentosModal").modal("show");
                        }
                    });
                    modalFiliais.listen();

                    // numero atendimento

                    // cliente
                    var validatorCliente = new Validator({
                        field: "CodigoCliente",
                        msgDialog: true,
                        idModalHideShow: "filtroAtendimentosModal",
                        onPendencyMessage: "Deve ser informado o código do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        onValid: function (data) {
                            setVal("inputCodigoCliente", data["Codigo"]);
                            setHtml("descriptionCodigoCliente", data["RazaoSocial"]);
                        },
                        onInvalid: function () {
                            validatorCliente.clear({ warning: true });
                            validatorCliente.focus();
                        },
                        onEmpty: function () {
                            validatorCliente.clear();
                        }
                    });
                    validatorCliente.listen();

                    var tableClientes = new Table({
                        "id": "tableCliente",
                        "msgDialog": true,
                        "idModalHideShow": "filtroAtendimentosModal",
                        "route": window.baseUrl + "Empresarial/F4Cliente/GetClientes",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "columnsLegend": { CnpjCpf: "Ex: 11.222.333/4444-55" },
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                validatorCliente.update();
                                $.when($("#modalCliente").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $.when($("#modalCliente").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            });
                        },
                        "onDataBound": function () {
                            $("#tableCliente table tr").on("dblclick", function () {
                                var data = tableClientes.getSelectedData();
                                validatorCliente.onValid(data);
                                validatorCliente.update();
                                $.when($("#modalCliente").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            });
                            listenF4ModalCancelar("#modalCliente");
                        },
                        "dataSourceType": "Filtered"
                    });
                    var modalClientes = new Modal("Clientes", byId("linkButtonModalClientes"), byId("inputCodigoCliente"), tableClientes, function () {
                        $("#filtroAtendimentosModal").modal("hide");
                    }, {
                        onHidden: function () {
                            $("#filtroAtendimentosModal").modal("show");
                        }
                    }).listen();

                    // servico
                    var validatorServico = new Validator({
                        field: "CodigoServico",
                        msgDialog: true,
                        idModalHideShow: "filtroAtendimentosModal",
                        onPendencyMessage: "Deve ser informado o código do serviço.",
                        route: "Empresarial/F4Servico/GetServico",
                        onValid: function (data) {
                            setVal("inputCodigoServico", data["Codigo"]);
                            setHtml("descriptionCodigoServico", data["Nome"]);
                            //setVal("inputServicosValor", data["Valor"]);
                        },
                        onInvalid: function () {
                            validatorServico.clear({ warning: true });
                            validatorServico.focus();
                        },
                        onEmpty: function () {
                            validatorServico.clear();
                        }
                    });
                    validatorServico.listen();

                    var tableServicos = new Table({
                        "id": "tableServico",
                        "msgDialog": true,
                        "idModalHideShow": "filtroAtendimentosModal",
                        "route": window.baseUrl + "Empresarial/F4Servico/GetServicos",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Un. Serviço", field: "UnidadeMedida.Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableServicos.getSelectedData();
                                validatorServico.onValid(data);
                                validatorServico.update();
                                $.when($("#modalServico").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            });
                        },
                        "onDataBound": function () {
                            $("#tableServico table tr").on("dblclick", function () {
                                var data = tableServicos.getSelectedData();
                                validatorServico.onValid(data);
                                validatorServico.update();
                                $.when($("#modalServico").modal("hide"))
									.done(function () {
									    $("#filtroAtendimentosModal").modal('show');
									});
                            });
                            listenF4ModalCancelar("#modalServico");
                        },
                        "dataSourceType": "Filtered"
                    });
                    var modalServicos = new Modal("Serviços", byId("linkButtonModalServicos"), byId("inputCodigoServico"), tableServicos, function () {
                        $("#filtroAtendimentosModal").modal("hide");
                    }, {
                        onHidden: function () {
                            $("#filtroAtendimentosModal").modal("show");
                        }
                    }).listen();

                    // button filter
                    $('#doFilter').on('click', function () {
                        var filter = $('filtro-viewmodel').viewModel();
                        filter.CodFilial = validatorFilial.getValue();
                        filter.CodCliente = validatorCliente.getValue();
                        filter.CodServico = validatorServico.getValue();

                        var dataSource = new kendo.data.DataSource(atendimentosTable.getFilteredDataSource(filter));
                        atendimentosTable.setDataSource(dataSource);
                    });

                    // button remove
                    $('#removeFilter').on('click', function () {
                        var filtroDefault = {
                            "FaturamentoInicial": "",
                            "FaturamentoFinal": "",
                            "EmissaoInicial": "",
                            "EmissaoFinal": "",
                            "SituacaoPendente": true,
                            "SituacaoRealizado": true,
                            "CodigoFilial": "",
                            "NumeroAtendimento": "",
                            "CodigoCliente": "",
                            "CodigoServico": ""
                        };
                        $(filtroDefault).viewModel('filtro-viewmodel');

                        validatorFilial.setValue(filtroDefault.CodigoFilial);
                        document.getElementById('descriptionCodigoFilial').innerHTML = "";

                        validatorCliente.setValue(filtroDefault.CodigoCliente);
                        document.getElementById('descriptionCodigoCliente').innerHTML = "";

                        validatorServico.setValue(filtroDefault.CodigoServico);
                        document.getElementById('descriptionCodigoServico').innerHTML = "";

                        setChecked("check-filter-situacao-pendente", false);
                        setChecked("check-filter-situacao-realizado", false);

                        var dataSource = new kendo.data.DataSource(atendimentosTable.getFilteredDataSource());
                        atendimentosTable.setDataSource(dataSource);
                    });

                    // functions
                    function listenF4ModalCancelar(modalSelector) {
                        $(modalSelector + " #inputF4ModalCancelar").on("click", function () {
                            $.when($(modalSelector).modal('hide'))
                                .done(function () {
                                    $("#filtroAtendimentosModal").modal("show");
                                });
                        });
                    }

                })(params);
            },

            MovimentosAtendimentoTecnico: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);
                    GuidProxy = params.GuidProxy;

                    var tabs = {
                        Principal: 0,
                        Servicos: 1,
                        Despesas: 2,
                    };

                    var idAtendimentoTecnico;

                    //
                    // aba principal
                    //

                    // filial
                    var validatorPrincipalFilial = new ValidatorLookup({
                        abrev: "PrincipalCodigoFilial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        routeTable: "Empresarial/F4Filial/GetFiliais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais"
                    });

                    // numero atendimento
                    var validatorPrincipalNumeroAtendimento = new ValidatorMask({
                        idInput: "inputPrincipalNumeroAtendimento",
                        mask: "radar-valor-6"
                    });

                    // cliente
                    var validatorPrincipalCliente = new ValidatorLookup({
                        abrev: "PrincipalCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes",
                        onValid: function (data) {
                            var params = {
                                CodigoCliente: validatorPrincipalCliente.getValue(),
                            };
                            postJsonToRoute("Gerenciador/Movimentos/ValidateCliente", JSON.stringify(params)).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    $("#waiting").hide();
                                }
                            });
                        }
                    });

                    var validatorPrincipalDataEmissao = new ValidatorDate({
                        idInput: "inputPrincipalDataEmissao",
                        isEmptyValid: true
                    });

                    var validatorPrincipalDataFaturamento = new ValidatorDate({
                        idInput: "inputPrincipalDataFaturamento",
                        isEmptyValid: true
                    });

                    var validatorPrincipalDataVencimento = new ValidatorDate({
                        idInput: "inputPrincipalDataVencimento",
                        isEmptyValid: true
                    });

                    // comentarios
                    var inputPrincipalComentarios = new ValidatorMemo({
                        titleModal: "Comentários",
                        idInput: "inputPrincipalComentarios",
                        idLink: "inputPrincipalComentariosLink",
                        css: { width: "780px" },
                        attr: { maxlength: 300 }
                    });

                    // rotinas principal
                    function getPrincipal() {
                        return {
                            Id: idAtendimentoTecnico,
                            CodigoFilial: validatorPrincipalFilial.getValue(),
                            NumeroAtendimento: validatorPrincipalNumeroAtendimento.getValue(),

                            CodigoCliente: validatorPrincipalCliente.getValue(),

                            Contato: getVal("inputPrincipalContato"),
                            CargoSetor: getVal("inputPrincipalCargoSetor"),

                            DataEmissao: validatorPrincipalDataEmissao.getValue(),
                            DataFaturamento: validatorPrincipalDataFaturamento.getValue(),
                            DataVencimento: validatorPrincipalDataVencimento.getValue(),

                            Comentarios: getVal("inputPrincipalComentarios")
                        }
                    }

                    //
                    // aba servicos
                    //

                    var gridServicos = new Grid({
                        id: "divGridServicos",
                        columns: [
                            { field: "Codigo", title: "Código", width: 30, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Servico", title: "Serviço", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Situacao", title: "Situação", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Executor", title: "Executor", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Valor", title: "Valor", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "Cobrar", title: "Cobrar", width: 40, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } }
                        ],
                        onChange: function (data) {
                            setServicos(data);
                        },
                        height: 142
                    });

                    // tabela precos
                    var validatorServicosTabelaPrecoServico = new ValidatorLookup({
                        abrev: "ServicosCodigoTabelaPrecoServico",
                        fieldSearch: "CodigoTabelaPrecos",
                        msgPendencyMessagePartEnd: "da tabela de preços.",
                        route: "Empresarial/F4TabelaPrecoServicos/GetTabelaPrecoServicos",
                        routeTable: "Empresarial/F4TabelaPrecoServicos/GetTabelasPrecosServicos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Validade", field: "Validade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Tabelas de Preços de Serviços"
                    });

                    // servico
                    var validatorServicosServico = new ValidatorLookup({
                        abrev: "ServicosCodigoServico",
                        fieldSearch: "CodigoServico",
                        msgPendencyMessagePartEnd: "do serviço.",
                        route: "Empresarial/F4Servico/GetServico",
                        pendency: [validatorServicosTabelaPrecoServico],
                        routeTable: "Empresarial/F4Servico/GetServicos",
                        params: [validatorServicosTabelaPrecoServico],
                        paramsRequired: [false],
                        paramsDefault: [1],
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Un. Serviço", field: "UnidadeMedida.Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        ],
                        titleModal: "Clientes",
                        defaultValue: {
                            Codigo: "",
                            UnidadeMedida: {
                                ConsiderarFormatoHorario: false,
                                CasasDecimais: "2"
                            }
                        },
                        setDefaultValueInOldValueWhereCreateValidator: true,
                        onValid: function (dados) {
                            validatorServicosServico.PropertiesSpecifyField = dados;
                            setVal("inputServicosValor", dados["Valor"]);

                            if (!validatorServicosServico.oldValue.UnidadeMedida.ConsiderarFormatoHorario && dados.UnidadeMedida.ConsiderarFormatoHorario) {
                                var params = {
                                    TotalHorasQuantidade: validatorServicosQuantidade.getValue(),
                                    CodigoServico: validatorServicosServico.getValue()
                                };
                                postJsonToRoute("Gerenciador/Movimentos/ToggleHoraQuantidade", JSON.stringify(params)).done(function (data) {
                                    if (data.IsAlert) {
                                        $("#waiting").hide();
                                        u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                    }
                                    else {
                                        validatorServicosTotalHoras.setValue(data);
                                        updateTotalServico(validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.ConsiderarFormatoHorario, validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.CasasDecimais);
                                        $("#waiting").hide();
                                    }
                                });
                            }
                            else {
                                if (validatorServicosServico.oldValue.UnidadeMedida.ConsiderarFormatoHorario && !dados.UnidadeMedida.ConsiderarFormatoHorario) {
                                    var params = {
                                        TotalHorasQuantidade: validatorServicosQuantidade.getValue(),
                                        CodigoServico: validatorServicosServico.getValue()
                                    };
                                    postJsonToRoute("Gerenciador/Movimentos/ToggleHoraQuantidade", JSON.stringify(params)).done(function (data) {
                                        if (data.IsAlert) {
                                            $("#waiting").hide();
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        }
                                        else {
                                            validatorServicosQuantidade.setValue(data);
                                            updateTotalServico(validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.ConsiderarFormatoHorario, validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.CasasDecimais);
                                            $("#waiting").hide();
                                        }
                                    });
                                }
                                else {
                                    var params = {
                                        QuantidadeOrigem: validatorServicosQuantidade.getValue(),
                                        NumeroCasasDecimaisDestino: dados.UnidadeMedida.CasasDecimais
                                    };
                                    postJsonToRoute("Gerenciador/Movimentos/ConvertQuantidadeNToQuantidadeN", JSON.stringify(params)).done(function (data) {
                                        if (data.IsAlert) {
                                            $("#waiting").hide();
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        }
                                        else {
                                            validatorServicosQuantidade.setValue(data);
                                            updateTotalServico(validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.ConsiderarFormatoHorario, validatorServicosServico.PropertiesSpecifyField.UnidadeMedida.CasasDecimais);
                                            $("#waiting").hide();
                                        }
                                    });
                                }
                            }

                            setTotalHorasOuQuantidade(dados.UnidadeMedida.ConsiderarFormatoHorario, dados.UnidadeMedida.CasasDecimais);
                            validatorServicosServico.oldValue = dados;
                        },
                        onInvalid: function (data) {
                            validatorServicosServico.PropertiesSpecifyField = {};
                            setTotalHorasOuQuantidade(false, validatorServicosServico.defaultValue.UnidadeMedida.CasasDecimais);
                            validatorServicosServico.oldValue = validatorServicosServico.defaultValue;
                        },
                        onEmpty: function () {
                            validatorServicosServico.PropertiesSpecifyField = {};
                            setTotalHorasOuQuantidade(false, validatorServicosServico.defaultValue.UnidadeMedida.CasasDecimais);
                            validatorServicosServico.oldValue = validatorServicosServico.defaultValue;
                        }
                    });

                    // executor
                    var validatorServicosExecutor = new ValidatorLookup({
                        abrev: "ServicosCodigoExecutor",
                        fieldSearch: "Apelido",
                        msgPendencyMessage: "Usuário não cadastrado.",
                        onValidOnly: function (validator, data) {
                            validator.setValue(data["Apelido"]);
                        },
                        route: "Empresarial/F4Usuario/GetUsuario",
                        routeTable: "Empresarial/F4Usuario/GetUsuarios",
                        columnsTable: [
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Apelido", field: "Apelido", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "IsSupervisor", field: "Supervisor", width: 30, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Usuários"
                    });

                    // comentarios
                    var inputServicosComentarios = new ValidatorMemo({
                        titleModal: "Comentários",
                        idInput: "inputServicosComentarios",
                        idLink: "inputServicosComentariosLink",
                        css: { width: "610px" },
                        attr: { maxlength: 1000 }
                    });

                    // resultado
                    var inputServicosResultado = new ValidatorMemo({
                        titleModal: "Resultado",
                        idInput: "inputServicosResultado",
                        idLink: "inputServicosResultadoLink",
                        css: { width: "610px" },
                        attr: { maxlength: 300 }
                    });

                    // data saida
                    var validatorServicosDataSaida = new ValidatorDate({
                        idInput: "inputServicosDataSaida",
                        isEmptyValid: true
                    });

                    // data retorno
                    var validatorServicosDataRetorno = new ValidatorDate({
                        idInput: "inputServicosDataRetorno",
                        compareGreater: "inputServicosDataSaida",
                        compareGreaterMsg: "Data de retorno deve ser igual ou posterior à data de saída.",
                        isEmptyValid: true
                    });

                    // totalhoras
                    var validatorServicosTotalHoras = new ValidatorMask({
                        idInput: "inputServicosTotalHoras",
                        mask: "time-servico",
                        onChange: function () {
                            updateTotalServico(true);
                        }
                    });
                    $("#linkButtonModalServicosQuantidade").click(function () {
                        $("#waiting").show();

                        var indexServico = validatorServicosServico.isEmpty() ? -1 : gridServicos.getSelectedDataIndex();
                        postJsonToRoute("Gerenciador/Movimentos/GetSessoes", JSON.stringify({ IndexServico: indexServico })).done(function (data) {
                            if (data.IsAlert) {
                                $("#waiting").hide();
                                u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                            }
                            else {
                                loadGridSessoes(data);
                                $("#waiting").hide();
                            }
                        });

                        if (!permissoes.PodeAlterarAttecOutrem) {
                            $("#buttonSessoesAdicionar").attr("disabled", "disabled");
                            $("#buttonSessoesRemover").attr("disabled", "disabled");
                            $("#buttonSessoesAlterar").attr("disabled", "disabled");
                            $("#buttonSessoesOk").attr("disabled", "disabled");
                        }
                    });

                    // quantidade
                    var validatorServicosQuantidade = new ValidatorMask({
                        idInput: "inputServicosQuantidade",
                        mask: "radar-valor-14-2-R",
                        onChange: function () {
                            updateTotalServico(false);
                        }
                    });

                    // valor
                    var validatorServicosValor = new ValidatorMask({
                        idInput: "inputServicosValor",
                        mask: "radar-valor-14-2-R",
                        onChange: function () {
                            updateTotalServico(validatorServicosServico.oldValue.UnidadeMedida.ConsiderarFormatoHorario);
                        }
                    });

                    // total
                    var validatorServicosTotal = new ValidatorMask({
                        idInput: "inputServicosTotal",
                        mask: "radar-valor-16-2-R"
                    });

                    // botoes servico
                    function loadGridServicos(dados) {
                        gridServicos.setValue(dados, function (reg) {
                            return {
                                Codigo: reg.CodigoServico,
                                Servico: reg.NomeCodigoServico,
                                Situacao: reg.Pendente ? "Pendente" : "Realizado",
                                Executor: reg.CodigoExecutor,
                                Valor: reg.Valor,
                                Cobrar: reg.Cobrar ? "x" : "",
                                DadosVM: reg
                            }
                        });
                    }

                    function updateTotalServico(ConsiderarFormatoHorario) {
                        if (ConsiderarFormatoHorario) {
                            var params = {
                                ConsiderarFormatoHorario: ConsiderarFormatoHorario,
                                TotalHorasQuantidade: validatorServicosTotalHoras.getValue(),
                                Valor: validatorServicosValor.getValue()
                            };
                            postJsonToRoute("Gerenciador/Movimentos/UpdateTotalServico", JSON.stringify(params)).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    validatorServicosTotal.setValue(data);
                                    $("#waiting").hide();
                                }
                            });
                        }
                        else {
                            var params = {
                                ConsiderarFormatoHorario: ConsiderarFormatoHorario,
                                TotalHorasQuantidade: validatorServicosQuantidade.getValue(),
                                Valor: validatorServicosValor.getValue()
                            };
                            postJsonToRoute("Gerenciador/Movimentos/UpdateTotalServico", JSON.stringify(params)).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    validatorServicosTotal.setValue(data);
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    function setDefaultServicos() {
                        if (config.CodigoTabelaPrecoServicoDefault) {
                            validatorServicosTabelaPrecoServico.setValues(config.CodigoTabelaPrecoServicoDefault, config.NomeCodigoTabelaPrecoServicoDefault);
                        }

                        validatorServicosExecutor.setValue(params.User.Nome);

                        validatorServicosTotalHoras.setValue("000:00");
                        validatorServicosQuantidade.setValue("0,00");
                        validatorServicosValor.setValue("0,00");
                        validatorServicosTotal.setValue("0,00");
                    }

                    function checkServicos() {
                        if (validatorServicosServico.invalid) {
                            u.dialogOk("Campo \"Serviço\" é obrigatório.", null, true, function () {
                                validatorServicosServico.focus();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (isChecked("inputServicosCobrar") && isChecked("inputServicosRealizado") && validatorServicosValor.isEmptyOrZeros()) {
                            u.dialogOk("Campo \"Valor\" é obrigatório.", null, true, function () {
                                validatorServicosValor.focus();
                            }, alertBehavior.warning);
                            return false;
                        }

                        return true;
                    }

                    function setTotalHorasOuQuantidade(ConsiderarFormatoHorario, NumeroCasasDecimaisQuantidade) {
                        if (ConsiderarFormatoHorario) {
                            $("#inputServicosTotalHoras").css("display", "inline-block");
                            $("#inputServicosQuantidade").css("display", "none");
                            $("#spanTotalHorasQuantidade").html("Total Horas:");
                            $("#linkButtonModalServicosQuantidade").css("display", "inline-block");
                            validatorServicosQuantidade.changeMask("radar-valor-14-" + NumeroCasasDecimaisQuantidade + "-R");
                        }
                        else {
                            $("#inputServicosTotalHoras").css("display", "none");
                            $("#inputServicosQuantidade").css("display", "inline-block");
                            $("#spanTotalHorasQuantidade").html("Quant.:");
                            $("#linkButtonModalServicosQuantidade").css("display", "none");
                            validatorServicosQuantidade.changeMask("radar-valor-14-" + NumeroCasasDecimaisQuantidade + "-R");
                        }
                    }

                    function setServicos(data) {
                        validatorServicosTabelaPrecoServico.setValues(data.DadosVM.CodigoTabelaPrecoServico, data.DadosVM.NomeCodigoTabelaPrecoServico);

                        validatorServicosServico.setValues(data.DadosVM.CodigoServico, data.DadosVM.NomeCodigoServico);
                        validatorServicosServico.oldValue = {
                            Codigo: validatorServicosServico.getValue(),
                            UnidadeMedida: {
                                ConsiderarFormatoHorario: data.DadosVM.ConsiderarFormatoHorario,
                                CasasDecimais: data.DadosVM.NumeroCasasDecimaisQuantidade
                            }
                        };

                        setVal("inputServicosDescricao", data.DadosVM.Descricao);

                        validatorServicosDataSaida.setValueNoValidate(data.DadosVM.DataSaida);
                        validatorServicosDataRetorno.setValueNoValidate(data.DadosVM.DataRetorno);
                        validatorServicosExecutor.setValue(data.DadosVM.CodigoExecutor);

                        setVal("inputServicosComentarios", data.DadosVM.Comentarios);
                        setVal("inputServicosResultado", data.DadosVM.Resultado);

                        setTotalHorasOuQuantidade(data.DadosVM.ConsiderarFormatoHorario, data.DadosVM.NumeroCasasDecimaisQuantidade);
                        validatorServicosTotalHoras.setValue(data.DadosVM.TotalHoras);
                        if (data.DadosVM.TemSessoes)
                            validatorServicosTotalHoras.enable(false);
                        else
                            validatorServicosTotalHoras.enable(true);
                        validatorServicosQuantidade.setValue(data.DadosVM.Quantidade);
                        validatorServicosValor.setValue(data.DadosVM.Valor);
                        validatorServicosTotal.setValue(data.DadosVM.Total);

                        setChecked("inputServicosCobrar", data.DadosVM.Cobrar);
                        setChecked("inputServicosPendente", data.DadosVM.Pendente);
                        setChecked("inputServicosRealizado", data.DadosVM.Realizado);

                        if (permissoes.PodeAlterarAttecOutrem) {
                            $("#buttonServicosAdicionar").attr("disabled", "disabled");
                            $("#buttonServicosAlterar").removeAttr("disabled");
                            $("#buttonServicosRemover").removeAttr("disabled");
                        } else {
                            $("#buttonServicosAdicionar").attr("disabled", "disabled");
                            $("#buttonServicosAlterar").attr("disabled", "disabled");
                            $("#buttonServicosRemover").attr("disabled", "disabled");
                            validatorServicosTotalHoras.enable(false);
                            validatorServicosQuantidade.enable(false);
                        }
                    }

                    function getObjServico(alt) {
                        var index = alt ? gridServicos.getSelectedDataIndex() : -1;
                        return {
                            Index: index,
                            CodigoTabelaPrecoServico: validatorServicosTabelaPrecoServico.value,
                            CodigoServico: validatorServicosServico.value,

                            Descricao: getVal("inputServicosDescricao"),

                            DataSaida: validatorServicosDataSaida.getValue(),
                            DataRetorno: validatorServicosDataRetorno.getValue(),
                            CodigoExecutor: validatorServicosExecutor.value,

                            Comentarios: getVal("inputServicosComentarios"),
                            Resultado: getVal("inputServicosResultado"),

                            ConsiderarFormatoHorario: validatorServicosServico.oldValue.UnidadeMedida.ConsiderarFormatoHorario,
                            TotalHoras: validatorServicosTotalHoras.getValue(),
                            Quantidade: validatorServicosQuantidade.getValue(),
                            Valor: validatorServicosValor.getValue(),
                            Total: validatorServicosTotal.getValue(),

                            Cobrar: isChecked("inputServicosCobrar"),
                            Pendente: isChecked("inputServicosPendente"),
                            Realizado: isChecked("inputServicosRealizado")
                        }
                    }

                    function clearServicos() {
                        validatorServicosTabelaPrecoServico.setValues("", "");
                        validatorServicosServico.setValues("", "");

                        setVal("inputServicosDescricao", "");

                        validatorServicosDataSaida.setValueNoValidate("");
                        validatorServicosDataRetorno.setValueNoValidate("");
                        validatorServicosExecutor.setValues("", "");

                        setVal("inputServicosComentarios", "");
                        setVal("inputServicosResultado", "");

                        validatorServicosTotalHoras.setValue("000:00");
                        validatorServicosQuantidade.setValue("0,00");
                        validatorServicosValor.setValue("0,00");
                        validatorServicosTotal.setValue("0,00");

                        setChecked("inputServicosCobrar", false);
                        setChecked("inputServicosPendente", true);

                        $("#buttonServicosAdicionar").removeAttr("disabled");
                        $("#buttonServicosAlterar").attr("disabled", "disabled");
                        $("#buttonServicosRemover").attr("disabled", "disabled");
                    }

                    // botoes servico
                    byId("buttonServicosAdicionar").onclick = function () {
                        if (!$("#buttonServicosAdicionar").attr("disabled")) {
                            $("#waiting").show();

                            if (!checkServicos()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/AddServico", JSON.stringify(getObjServico(false))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridServicos(data);
                                    clearServicos();
                                    setDefaultServicos();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonServicosAlterar").onclick = function () {
                        if (!$("#buttonServicosAlterar").attr("disabled")) {
                            $("#waiting").show();

                            if (!checkServicos()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/UpdateServico", JSON.stringify(getObjServico(true))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridServicos(data);
                                    clearServicos();
                                    setDefaultServicos();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonServicosRemover").onclick = function () {
                        if (!$("#buttonServicosRemover").attr("disabled")) {
                            $("#waiting").show();

                            postJsonToRoute("Gerenciador/Movimentos/DeleteServico", JSON.stringify({ Index: gridServicos.getSelectedDataIndex() })).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridServicos(data);
                                    clearServicos();
                                    setDefaultServicos();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    //
                    // aba sessoes
                    //

                    var gridSessoes = new Grid({
                        id: "divGridSessoes",
                        columns: [
                            { field: "HoraInicial", title: "H. Inicial", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "HoraFinal", title: "H. Final", width: 60, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } }
                        ],
                        onChange: function (data) {
                            setSessoes(data);
                        },
                        height: 142
                    });

                    // hora inicial
                    var validatorSessoesHoraInicial = new ValidatorMask({
                        idInput: "inputSessoesHoraInicial",
                        mask: "time-sessoes",
                        onChange: function () {
                            var hora = parseInt(validatorSessoesHoraInicial.getValue().substr(0, 2));
                            if (hora > 23) {
                                $("#modalServicosQuantidade").modal("hide");
                                u.dialogOk("Hora Inválida.", null, true, function () {
                                    $("#modalServicosQuantidade").modal("show");
                                    validatorSessoesHoraInicial.setValue("00:00");
                                    validatorSessoesHoraInicial.focus();
                                }, alertBehavior.warning);
                            }
                        }
                    });

                    // hora final
                    var validatorSessoesHoraFinal = new ValidatorMask({
                        idInput: "inputSessoesHoraFinal",
                        mask: "time-sessoes",
                        onChange: function () {
                            var hora = parseInt(validatorSessoesHoraFinal.getValue().substr(0, 2));
                            if (hora > 23) {
                                $("#modalServicosQuantidade").modal("hide");
                                u.dialogOk("Hora Inválida.", null, true, function () {
                                    $("#modalServicosQuantidade").modal("show");
                                    validatorSessoesHoraFinal.setValue("00:00");
                                    validatorSessoesHoraFinal.focus();
                                }, alertBehavior.warning);
                            }
                        }
                    });

                    // rotinas sessoes
                    function loadGridSessoes(data) {
                        gridSessoes.setValue(data, function (reg) {
                            return {
                                HoraInicial: reg.HoraInicial,
                                HoraFinal: reg.HoraFinal,
                                DadosVM: reg
                            }
                        });
                        validatorSessoesHoraInicial.focus();
                    }

                    function checkSessoes() {
                        if (validatorSessoesHoraInicial.getValue() === "00:00" && validatorSessoesHoraFinal.getValue() === "00:00") {
                            $("#modalServicosQuantidade").modal("hide");
                            u.dialogOk("Informar Hora.", null, true, function () {
                                $("#modalServicosQuantidade").modal("show");
                                validatorSessoesHoraInicial.focus();
                            }, alertBehavior.warning);
                            return false;
                        }
                        else if (validatorSessoesHoraInicial.getValue() === validatorSessoesHoraFinal.getValue()) {
                            $("#modalServicosQuantidade").modal("hide");
                            u.dialogOk("Informar hora final diferente da hora inicial.", null, true, function () {
                                $("#modalServicosQuantidade").modal("show");
                                validatorSessoesHoraFinal.focus();
                            }, alertBehavior.warning);
                            return false;
                        }
                        return true;
                    }

                    function setSessoes(data) {
                        validatorSessoesHoraInicial.setValue(data.HoraInicial);
                        validatorSessoesHoraFinal.setValue(data.HoraFinal);

                        if (permissoes.PodeAlterarAttecOutrem) {
                            validatorSessoesHoraInicial.focus();
                            $("#buttonSessoesAlterar").removeAttr("disabled");
                            $("#buttonSessoesRemover").removeAttr("disabled");
                        } else {
                            $("#buttonSessoesAdicionar").attr("disabled", "disabled");
                            $("#buttonSessoesRemover").attr("disabled", "disabled");
                            $("#buttonSessoesAlterar").attr("disabled", "disabled");
                            $("#buttonSessoesOk").attr("disabled", "disabled");
                        }
                    }

                    function getObjSessao(alt) {
                        var indexServico = validatorServicosServico.isEmpty() ? -1 : gridServicos.getSelectedDataIndex();
                        var index = alt ? gridSessoes.getSelectedDataIndex() : -1;
                        return {
                            IndexServico: indexServico,
                            Index: index,
                            HoraInicial: validatorSessoesHoraInicial.getValue(),
                            HoraFinal: validatorSessoesHoraFinal.getValue()
                        }
                    }

                    function getObjSessoes() {
                        return gridSessoes.getDadosVM();
                    }

                    function clearSessoes() {
                        validatorSessoesHoraInicial.setValue("00:00");
                        validatorSessoesHoraFinal.setValue("00:00");

                        $("#buttonSessoesAlterar").attr("disabled", "disabled");
                        $("#buttonSessoesRemover").attr("disabled", "disabled");
                    }

                    // botoes sessoes
                    byId("buttonSessoesAdicionar").onclick = function () {
                        if (!$("#buttonSessoesAdicionar").attr("disabled")) {
                            $("#waiting").show();
                            if (!checkSessoes()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/AddSessao", JSON.stringify(getObjSessao(false))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridSessoes(data);
                                    clearSessoes();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonSessoesAlterar").onclick = function () {
                        if (!$("#buttonSessoesAlterar").attr("disabled")) {
                            $("#waiting").show();
                            if (!checkSessoes()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/UpdateSessao", JSON.stringify(getObjSessao(true))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridSessoes(data);
                                    clearSessoes();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonSessoesRemover").onclick = function () {
                        if (!$("#buttonSessoesRemover").attr("disabled")) {
                            $("#waiting").show();

                            postJsonToRoute("Gerenciador/Movimentos/DeleteSessao", JSON.stringify(getObjSessao(true))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridSessoes(data);
                                    clearSessoes();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonSessoesOK").onclick = function () {
                        $("#waiting").show();

                        postJsonToRoute("Gerenciador/Movimentos/SumSessoes", JSON.stringify(getObjSessoes())).done(function (data) {
                            if (data.IsAlert) {
                                $("#waiting").hide();
                                u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                            }
                            else {
                                if (data.TemSessoes) {
                                    validatorServicosTotalHoras.setValue(data.Result);
                                    validatorServicosTotalHoras.enable(false);
                                }
                                else {
                                    validatorServicosTotalHoras.setValue("000:00");
                                    validatorServicosTotalHoras.enable(true);
                                }
                                updateTotalServico(true);
                                $("#waiting").hide();
                            }
                        });
                    }

                    //
                    // aba despesas
                    //

                    var gridDespesas = new Grid({
                        id: "divGridDespesas",
                        columns: [
                            { field: "Descricao", title: "Descrição", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Valor", title: "Valor", width: 100, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" }
                        ],
                        onChange: function (data) {
                            setDespesas(data);
                        },
                        height: 142
                    });

                    // valor
                    var validatorDespesasValor = new ValidatorMask({
                        idInput: "inputDespesasValor",
                        mask: "radar-valor-14-2-R"
                    });

                    // comentarios
                    var inputDespesasComentarios = new ValidatorMemo({
                        titleModal: "Comentários",
                        idInput: "inputDespesasComentarios",
                        idLink: "inputDespesasComentariosLink",
                        css: { width: "740px" },
                        attr: { maxlength: 300 }
                    });

                    // rotinas despesa
                    function loadGridDespesas(dados) {
                        gridDespesas.setValue(dados, function (reg) {
                            return {
                                Descricao: reg.Descricao,
                                Valor: reg.Valor,
                                Comentarios: reg.Comentarios,
                                DadosVM: reg
                            }
                        });
                    }

                    function checkDespesas() {
                        if (getVal("inputDespesasDescricao") === "") {
                            u.dialogOk("Informe uma descrição.", null, true, function () {
                                $("#inputDespesasDescricao").focus();
                            }, alertBehavior.warning);
                            return false;
                        }
                        return true;
                    }

                    function setDespesas(data) {
                        setVal("inputDespesasDescricao", data.Descricao);
                        validatorDespesasValor.setValue(data.Valor);
                        setVal("inputDespesasComentarios", data.Comentarios);

                        if (permissoes.PodeAlterarAttecOutrem) {
                            $("#buttonDespesasAdicionar").attr("disabled", "disabled");
                            $("#buttonDespesasAlterar").removeAttr("disabled");
                            $("#buttonDespesasRemover").removeAttr("disabled");
                        } else {
                            $("#buttonDespesasAdicionar").attr("disabled", "disabled");
                            $("#buttonDespesasAlterar").attr("disabled", "disabled");
                            $("#buttonDespesasRemover").attr("disabled", "disabled");
                        }
                    }

                    function getObjDespesa(alt) {
                        var index = alt ? gridDespesas.getSelectedDataIndex() : -1;
                        return {
                            Index: index,
                            Descricao: getVal("inputDespesasDescricao"),
                            Valor: validatorDespesasValor.getValue(),
                            Comentarios: getVal("inputDespesasComentarios")
                        }
                    }

                    function setDefaultDespesas() {
                        validatorDespesasValor.setValue("0,00");
                    }

                    function clearDespesas() {
                        setVal("inputDespesasDescricao", "");
                        validatorDespesasValor.setValue("0,00");
                        setVal("inputDespesasComentarios", "");

                        $("#buttonDespesasAdicionar").removeAttr("disabled");
                        $("#buttonDespesasAlterar").attr("disabled", "disabled");
                        $("#buttonDespesasRemover").attr("disabled", "disabled");
                    }

                    // botoes despesa
                    byId("buttonDespesasAdicionar").onclick = function () {
                        if (!$("#buttonDespesasAdicionar").attr("disabled")) {
                            $("#waiting").show();
                            if (!checkDespesas()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/AddDespesa", JSON.stringify(getObjDespesa(false))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridDespesas(data);
                                    clearDespesas();
                                    setDefaultDespesas();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonDespesasAlterar").onclick = function () {
                        if (!$("#buttonDespesasAlterar").attr("disabled")) {
                            $("#waiting").show();
                            if (!checkDespesas()) {
                                $("#waiting").hide();
                                return;
                            }

                            postJsonToRoute("Gerenciador/Movimentos/UpdateDespesa", JSON.stringify(getObjDespesa(true))).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridDespesas(data);
                                    clearDespesas();
                                    setDefaultDespesas();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    byId("buttonDespesasRemover").onclick = function () {
                        if (!$("#buttonDespesasRemover").attr("disabled")) {
                            $("#waiting").show();

                            postJsonToRoute("Gerenciador/Movimentos/DeleteDespesa", JSON.stringify({ Index: gridDespesas.getSelectedDataIndex() })).done(function (data) {
                                if (data.IsAlert) {
                                    $("#waiting").hide();
                                    u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                }
                                else {
                                    loadGridDespesas(data);
                                    clearDespesas();
                                    setDefaultDespesas();
                                    $("#waiting").hide();
                                }
                            });
                        }
                    }

                    //
                    // functions - regras inclusao/alteracao tela
                    //

                    var dados = params.GetAtendimentoTecnicoViewModel;
                    var config = params.GetAtendimentoTecnicoViewModel.Configuracoes;
                    var permissoes = params.GetAtendimentoTecnicoViewModel.Permissoes;

                    // load atendimento tecnico
                    if (dados.IsAlert) {
                        u.dialogOk(dados.Message, null, true, null, alertBehavior.warning);
                    } else {
                        validatorPrincipalNumeroAtendimento.enable(config.AlterarNumeroAtendimentoTecnico);

                        if (!dados.IsAlteracao) {
                            // principal
                            idAtendimentoTecnico = 0; // 0 = inclusao
                            setFilialDefault(validatorPrincipalFilial);

                            if (!config.AlterarNumeroAtendimentoTecnico)
                                validatorPrincipalNumeroAtendimento.setValue("");
                            else
                                validatorPrincipalNumeroAtendimento.setValue(dados.Principal.NumeroAtendimento);

                            validatorPrincipalDataEmissao.enable(config.AlterarDataEmissao);
                            validatorPrincipalDataEmissao.setValue(dados.Principal.DataEmissao);
                            setDefaultServicos();
                            setDefaultDespesas();

                            $("#buttonGerarPDF").attr("disabled", "disabled");
                            $("#buttonCopiar").attr("disabled", "disabled");

                            if (!permissoes.PodeGravarAttec)
                                $("#buttonOK").attr("disabled", "disabled");
                        } else {
                            // principal
                            idAtendimentoTecnico = dados.Principal.Id;
                            $("#buttonGerarPDF").removeAttr("disabled");
                            $("#buttonCopiar").removeAttr("disabled", "disabled");

                            if (permissoes.PodeVisualizarAttecOutrem) {
                                validatorPrincipalFilial.setValues(dados.Principal.CodigoFilial, dados.Principal.NomeCodigoFilial);
                                validatorPrincipalNumeroAtendimento.setValue(dados.Principal.NumeroAtendimento);
                                validatorPrincipalCliente.setValues(dados.Principal.CodigoCliente, dados.Principal.NomeCodigoCliente);
                                setVal("inputPrincipalContato", dados.Principal.Contato);
                                setVal("inputPrincipalCargoSetor", dados.Principal.CargoSetor);
                                validatorPrincipalDataEmissao.enable(config.AlterarDataEmissao);

                                if (dados.Principal.DataEmissao)
                                    validatorPrincipalDataEmissao.setValue(dados.Principal.DataEmissao);
                                if (dados.Principal.DataFaturamento)
                                    validatorPrincipalDataFaturamento.setValue(dados.Principal.DataFaturamento);
                                if (dados.Principal.DataVencimento)
                                    validatorPrincipalDataVencimento.setValue(dados.Principal.DataVencimento);

                                setVal("inputPrincipalComentarios", dados.Principal.Comentarios);

                                // servicos
                                loadGridServicos(dados.Servicos);
                                setDefaultServicos();
                                setDefaultDespesas();

                                // depesas
                                loadGridDespesas(dados.Despesas);
                            } else {
                                u.dialogOk("Atendimento bloqueado para visualização.", null, true, null, alertBehavior.warning);

                                validatorPrincipalFilial.setValues("", "");
                                validatorPrincipalNumeroAtendimento.setValue("");
                                validatorPrincipalCliente.setValues("", "");
                                validatorPrincipalDataEmissao.setValue("");
                                validatorPrincipalDataFaturamento.setValue("");
                                validatorPrincipalDataVencimento.setValue("");
                                setVal("inputPrincipalComentarios", "");
                                setVal("inputPrincipalContato", "");
                                setVal("inputPrincipalCargoSetor", "");
                                validatorPrincipalDataEmissao.enable(false);

                                clearDespesas();
                                clearServicos();
                                disableAllInputs();

                                $("#buttonOK").attr("disabled", "disabled");
                            }

                            if (!permissoes.PodeAlterarAttecOutrem) {
                                u.dialogOk("Atendimento bloqueado para alteração.", null, true, null, alertBehavior.warning);
                                disableAllInputs();
                                $("#buttonGerarPDF").attr("disabled", "disabled");
                                $("#buttonOK").attr("disabled", "disabled");
                                $("#buttonServicosAdicionar").attr("disabled", "disabled");
                                $("#buttonDespesasAdicionar").attr("disabled", "disabled");
                            }
                        }

                        if (config.PodeIncluirNovoAtendimento)
                            $("#buttonNovo").removeAttr("disabled");
                    }

                    // rotinas tela
                    function checkAtendimentoTecnico() {
                        var temCobrar = false;
                        $.each(gridServicos.getDadosVM(), function (i, el) {
                            if (el.Cobrar) {
                                temCobrar = true;
                                return false;
                            }
                        });

                        if (temCobrar && validatorPrincipalDataFaturamento.isEmpty) {
                            u.dialogOk("O campo \"Faturamento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                validatorPrincipalDataFaturamento.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (temCobrar && validatorPrincipalDataVencimento.isEmpty) {
                            u.dialogOk("O campo \"Vencimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                validatorPrincipalDataVencimento.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (!validatorPrincipalDataEmissao.isEmpty && !validatorPrincipalDataFaturamento.isEmpty) {
                            var $result = validatorPrincipalDataEmissao.getValue().toDate().compare(validatorPrincipalDataFaturamento.getValue().toDate());
                            if ($result !== "less" && $result !== "equal") {
                                u.dialogOk("Data de faturamento deve ser posterior à data de emissão.", null, true, function () {
                                    validatorPrincipalDataFaturamento.focusError();
                                    validatorPrincipalDataFaturamento.alterBehavior(controlGroupBehavior.warning);
                                }, alertBehavior.warning);
                                return false;
                            }
                        }

                        if (!validatorPrincipalDataFaturamento.isEmpty && !validatorPrincipalDataVencimento.isEmpty) {
                            var $result = validatorPrincipalDataFaturamento.getValue().toDate().compare(validatorPrincipalDataVencimento.getValue().toDate());
                            if ($result !== "less" && $result !== "equal") {
                                u.dialogOk("Data de vencimento deve ser posterior à data de faturamento.", null, true, function () {
                                    validatorPrincipalDataVencimento.focusError();
                                    validatorPrincipalDataVencimento.alterBehavior(controlGroupBehavior.warning);
                                }, alertBehavior.warning);
                                return false;
                            }
                        }

                        return true;
                    }

                    function salveAtendimentoTecnico() {
                        $("#waiting").show();
                        postJsonToRoute("Gerenciador/Movimentos/SaveAtendimentoTecnico", JSON.stringify({ Principal: getPrincipal() })).done(function (data) {
                            if (data.IsAlert) {
                                $("#waiting").hide();
                                u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                            } else {
                                $("#waiting").hide();
                                u.dialogOk("Atendimento técnico salvo com sucesso.", function () {
                                        window.location.href = window.baseUrl + "Gerenciador/Movimentos/AtendimentoTecnico?id=" + data.Principal.Id + "&DataEmissao=" + data.Principal.DataEmissao;
                                    },
                                    true, null, alertBehavior.success);
                            }
                        });
                    }

                    // botoes tela
                    byId("buttonOK").onclick = function () {
                        if (!$("#buttonOK").attr("disabled")) {
                            $("#waiting").show();

                            if (!checkAtendimentoTecnico()) {
                                $("#waiting").hide();
                                return;
                            }

                            var params = {
                                CodigoCliente: validatorPrincipalCliente.getValue()
                            };
                            requestNoAsync(window.baseUrl + "Gerenciador/Movimentos/ValidateTitulosEmAtraso", params,
                                function (data) {
                                    $("#waiting").hide();
                                    if (data.IsAlert) {
                                        if (data.Level === alertLevel.warning) {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        } else if (data.Level === alertLevel.question) {
                                            u.dialog(
                                                null,
                                                data.Message.replace("\n", "<br />"),
                                                function () {
                                                    salveAtendimentoTecnico();
                                                }, null, null, true
                                            );
                                        } else {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        }
                                    } else {
                                        salveAtendimentoTecnico();
                                    }
                                },
                                function (data) {
                                    $("#waiting").hide();
                                }, true
                            );
                        }
                    }

                    byId("buttonCancelar").onclick = function () {
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                window.location.href = window.baseUrl + "Gerenciador/Movimentos/AtendimentosTecnicos";
                            }
                        );
                    }

                    byId("buttonNovo").onclick = function () {
                        if (!$("#buttonNovo").attr("disabled")) {
                            u.dialog(
                                null,
                                "Deseja realmente abandonar as alterações?",
                                function () {
                                    window.location.href = window.baseUrl + "Gerenciador/Movimentos/AtendimentoTecnico";
                                }
                            );
                        }
                    }

                    byId("buttonCopiar").onclick = function () {
                        if (!$("#buttonCopiar").attr("disabled")) {
                            u.dialog(
                                null,
                                "Deseja realmente abandonar as alterações?",
                                function () {
                                    setTimeout(function () { $('#waiting').show(); }, 200);
                                    window.location.href = window.baseUrl + "Gerenciador/Movimentos/CopyAtendimentoTecnico?GuidProxy=" + GuidProxy;
                                },
                                null,
                                null
                            );
                        }
                    }

                    // relatorio

                    byId("buttonGerarPDF").onclick = function () {
                        if (!$("#buttonGerarPDF").attr("disabled")) {
                            window.open(window.baseUrl + "Gerenciador/Relatorios/GeraRelatorioAtendimentoTecnico?"
                                + "AtendimentoTecnico=" + idAtendimentoTecnico
                                + "&DataEmissao=" + validatorPrincipalDataEmissao.getValue()
                                + "&LayoutAtendimento=" + getHtml("inputLayoutAtendimento_option_selected")
                            );
                        }
                    }

                    var inputLayoutAtendimento = new ValidatorDropDown({
                        idInputCodigo: "inputLayoutAtendimento",
                        dataSource: config.LayoutsAtendimento,
                        value: config.LayoutAtendimentoDefault,
                    });
                })(params);
            }
        };
    })();

    Executivo.Manager = (function () {
        return {
            Dashboard: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputRelatorio = new DropDown({
                        id: "inputRelatorio",
                        route: "Executivo/Relatorios/GetRelatoriosDashboard",
                        onDataBound: function () {
                            if (byId("inputRelatorio").value === "")
                                u.disable("buttonOK");
                            else
                                u.enable("buttonOK");
                        }
                    });
                    inputRelatorio.make();

                    $("#buttonOK").on("click", function () {
                        window.open(window.baseUrl + "BI/" + inputRelatorio.dropDown.dataItem().Text + ".htm");
                    });
                })(params);
            }
        };
    })();

    Ged.Manager = (function () {
        return {
            Busca: function (params) {
                return (function () {
                    var u = new Util();
                    var isInsideGrid = false;
                    var lastMouseX = 0;
                    var lastMouseY = 0;

                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    //
                    // principal
                    //

                    $("#inputPesquisa").on("keydown", function (ev) {
                        var evCodeKey = (ev.keyCode || ev.which);
                        // enter
                        if (evCodeKey == 13) {
                            doBusca('DoBuscaRapida', $("#inputPesquisa").val());
                        }
                    });

                    byId("buttonOK").onclick = function () {
                        doBusca('DoBuscaRapida', $("#inputPesquisa").val());
                    }

                    var gridResultadoBusca = new Table({
                        id: "gridResultadoBusca",
                        pageable: true,
                        pageSize: 1,
                        dataSourceType: "Object",
                        columns: [
                            { field: "TipoDoc", title: "Tipo Documento", width: 65, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Id", title: "Código", width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Descricao", title: "Descrição", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "NomeDoc", title: "Nome Documento", width: 85, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "DataEmissao", title: "Emissão", width: 55, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } }
                        ],
                        onChange: function () {
                            "use strict";
                            var self = this;
                            var data = self.getSelectedData();

                            if (data.IsSomenteDownload)
                                doDownload(data);
                            else
                                doVisualizacao(data);
                        },
                        onDataBound: function () {
                            "use strict";
                            var self = this;

                            var el = $("#" + self.id + " .k-grid-content");
                            el[0].style.height = "auto";
                        }
                    });
                    gridResultadoBusca.make();
                    var gridResultadoBuscaHeight = 140;
                    $("#gridResultadoBusca .k-grid-content").height(gridResultadoBuscaHeight + "px");
                    $("#gridResultadoBusca .k-grid-pager").html("&nbsp");

                    function doVisualizacao(data) {
                        var carregando = "<img src=\"" + window.baseUrl + "Content/TreeviewAjaxNode/Images/loading.gif\" />" +
                                         "<label style=\"display: inline; margin-left: 5px\">Carregando...</label>";
                        $("#thumbnail").html(carregando);

                        var src = window.baseUrl + "Ged/Consultas/GetThumbnail?idDocumento=" + data.Id + "&nomeArquivo=" + data.NomeDoc;
                        $("#thumbnailView").attr("src", src);
                        $("#thumbnailView").attr("alt", data.NomeDoc);

                        $("#thumbnailView").on("load", function (ev) {
                            var thumbnailView = document.getElementById("thumbnailView");
                            var maxWidth = thumbnailView.style.maxWidth.asInt();
                            var maxHeight = thumbnailView.style.maxHeight.asInt();
                            var width = $("#thumbnailView").width();
                            var height = $("#thumbnailView").height();

                            if (height >= width) {
                                thumbnailView.style.top = Math.round(height / 2) + "px";
                                thumbnailView.style.left = "50%";
                                thumbnailView.style.marginLeft = Math.round(width / 2) + "px";
                            } else {
                                thumbnailView.style.top = Math.round((maxHeight - height) / 2) + "px";
                                thumbnailView.style.left = "50%";
                                thumbnailView.style.marginLeft = Math.round((maxWidth - width) / 2) + "px";
                            }

                            $("#thumbnail").css("display", "block");
                            $("#thumbnail").css("left", lastMouseX + "px");
                            $("#thumbnail").css("top", lastMouseY + "px");
                            $("#thumbnail").html($("#thumbnail-content").html());

                            byId("thumbnailView").onclick = function () {
                                doDownload(data);
                            }
                        });
                    }

                    function limpaThumb() {
                        $("#thumbnailView").removeAttr("src");
                        $("#thumbnailView").removeAttr("alt");
                        $("#thumbnail").css("display", "none");
                    }

                    function doDownload(data) {
                        limpaThumb();
                        var location = window.baseUrl + "Ged/Consultas/DownloadArquivo?idDocumento=" + data.Id + "&nomeArquivo=" + data.NomeDoc;
                        window.open(location);
                    }

                    function doBusca(action, query) {
                        msgWait.show();
                        getJsonFromRoute('Ged/Consultas/' + action, { query: query }).done(
                            function (result) {
                                if (result.IsAlert) {
                                    msgWait.hide();
                                    u.alert(result.Message, getAlertBehavior(result.Level));
                                    throw new Error(result.Message);
                                } else {
                                    var data = new kendo.data.DataSource({ data: [] });

                                    for (var atual in result) {
                                        data.options.data.push({
                                            TipoDoc: result[atual].TipoDocumento.Nome,
                                            Descricao: result[atual].Descricao,
                                            NomeDoc: result[atual].NomeArquivo,
                                            DataEmissao: result[atual].DataEmissao,
                                            Id: result[atual].Id,
                                            IsSomenteDownload: result[atual].IsSomenteDownload
                                        });
                                    }

                                    gridResultadoBusca.setDataSource(data);
                                    if ($("#gridResultadoBusca .k-grid-content").height() < gridResultadoBuscaHeight)
                                        $("#gridResultadoBusca .k-grid-content").height(gridResultadoBuscaHeight + "px");

                                    var qtd = gridResultadoBusca.length();
                                    if (qtd === 0)
                                        $("#gridResultadoBusca .k-grid-pager").html("Nenhum registro encontrado.");
                                    else if (qtd === 1)
                                        $("#gridResultadoBusca .k-grid-pager").html("1 registro encontrado.");
                                    else if (qtd > 1)
                                        $("#gridResultadoBusca .k-grid-pager").html(qtd + " registros encontrados.");

                                    msgWait.hide();
                                }
                            }
                        );
                    }

                    //
                    // thumbnailView
                    //

                    $(document).on("keydown", function (ev) {
                        var evCodeKey = (ev.keyCode || ev.which);

                        // ESC
                        if (evCodeKey == 27)
                            limpaThumb();
                    });                    

                    $(document).on("click", function (ev) {
                        if (isInsideGrid)
                            isInsideGrid = false
                        else 
                            limpaThumb();
                    });

                    $("#gridResultadoBusca").on("click", function (ev) {
                        lastMouseX = ev.clientX;
                        lastMouseY = ev.clientY;
                        isInsideGrid = true;
                    });

                    //
                    // load
                    //

                    if (params.idGed !== "")
                        doBusca('DoBuscaDistribuicao', params.idGed);

                    $("#inputPesquisa").focus();

                })(params);
            }
        };
    })();

    Financeiro.Manager = (function () {
        return {
            MovimentosAutorizacaoPagamento: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // grid
                    var grid = new Table({
                        id: "gridTitulos",
                        dataSourceType: "Object",
                        route: window.baseUrl + "Financeiro/Movimentos/GetListaTitulos",
                        showFilter: false,
                        height: "400px",
                        columns: [
                            {
                                field: "Selecionado",
                                title: " ",
                                width: 20,
                                sortable: false,
                                headerAttributes: { style: "color: black; text-align: center;" },
                                headerTemplate: "<input type='checkbox' id='checkAll' />",
                                attributes: { style: "text-align: center;" },
                                template: "<input type=\"checkbox\" #= Selecionado ? checked='checked' : '' # #= !PodeSerAlterado ? disabled='disabled' : 'ativado' # class=\"check_row\" />"
                            },
                            {
                                field: "GetTitulo",
                                title: " ",
                                sortable: false,
                                width: 14,
                                headerAttributes: { style: "color: black; text-align: center;" },
                                attributes: { style: "text-align: center;" },
                                template: "<span class=\"getitulo\"><i class=\"icon-list-alt\"></i><input type=\"hidden\" value=\"#= GetTitulo #\" /></span>"
                            },
                            { field: "Status", title: " ", width: 15, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "Codigo", title: "Código", width: 70, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Fornecedor", title: "Fornecedor", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Vencimento", title: "Vencimento", width: 65, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, format: "{0:dd/MM/yyyy}" },
                            { field: "Documento", title: "Documento", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Valor", title: "Valor", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" }
                        ],
                        pageable: false,
                        toolbar:
                            "<span style='float: left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Títulos</span>" +
                            "</span>" +
                            "<span style='float: right' style='width: 60px;'>" +
                            "    <button id='inputFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'>Filtro</span>&nbsp&nbspFiltro" +
                            "    </button>" +
                            "</span>",
                        onChange: function (el) {
                            "use strict";
                            var self = this;
                        },
                        onDataBound: function () {
                            "use strict";
                            var self = this;

                            // seleciona todos os titulos
                            $("#checkAll").unbind("click");
                            $("#checkAll").bind("change", function (e) {
                                $("#waiting").show();
                                var $cb = $(this);
                                var checked = $cb.is(":checked");
                                var grid = $("#gridTitulos").data("kendoGrid");
                                grid.table.find("tr").find("input[ativado]").attr("checked", checked);

                                var items = $("#gridTitulos").data("kendoGrid").dataSource.data();
                                for (var i = 0; i < items.length; i++) {
                                    if (items[i].PodeSerAlterado)
                                        items[i].Selecionado = checked;
                                }
                                $("#waiting").hide();
                            });

                            // seleciona titulo
                            $(".check_row").unbind("click");
                            $(".check_row").bind("click", function (e) {
                                $("#waiting").show();
                                var $cb = $(this);
                                var checked = $cb.is(":checked");

                                var grid = $("#gridTitulos").data("kendoGrid");
                                // pega a linha(s) e seta no datasource como selecionado
                                var selectedItems = grid.select();
                                selectedItems.each(function (index, row) {
                                    var selectedItem = grid.dataItem(row);
                                    selectedItem.set("Selecionado", checked);
                                });
                                $("#waiting").hide();
                            });

                            // busca titulo
                            $(".getitulo").unbind("mouseover");
                            $(".getitulo").bind("mouseover", function (el) {
                                var hintWait = "<img src=\"" + window.baseUrl + "Content/TreeviewAjaxNode/Images/loading.gif\" />" +
                                               "<label style=\"display: inline; margin-left: 5px\">Carregando...</label>";
                                $("#hint").html(hintWait);

                                $("#hint").css("display", "block");
                                $("#hint").css("left", (20 + el.clientX) + "px");
                                $("#hint").css("top", el.clientY + "px");

                                var dados = $(el.target).parent().find("input").val().split(",");

                                request("Financeiro/Movimentos/GetTitulo",
                                    {
                                        Id: dados[0],
                                        DataEmissao: dados[1]
                                    },
                                    function (model) {
                                        try {
                                            if (model.IsAlert) {
                                                var hintWait = "<img src=\"" + window.baseUrl + "Content/TreeviewAjaxNode/Images/error.gif\" />" +
                                                               "<label style=\"display: inline; margin-left: 5px\">Erro: " + model.Message + "</label>";
                                                $("#hint").html(hintWait);
                                            } else {
                                                setHtml("spanCodigo", model.Codigo);
                                                setHtml("spanFilial", model.Filial);
                                                setHtml("spanEmissao", model.DataEmissao);
                                                setHtml("spanVencimento", model.DataVencimento);
                                                setHtml("spanVencimentoEfetivo", model.DataVencimentoEfetivo);
                                                setHtml("spanFornecedor", model.Fornecedor);
                                                setHtml("spanDocumento", model.Documento);
                                                setHtml("spanClassificacao", model.Classificacao);
                                                setHtml("spanGerencial", model.Gerencial);
                                                setHtml("spanHistorico", model.Historico);
                                                setHtml("spanValor", model.Valor);
                                                setHtml("spanDesconto", model.ValorDesconto);
                                                setHtml("spanTerminoDesconto", model.DataTerminoDesconto);
                                                setHtml("spanJurosDiario", model.ValorDiarioJuros);
                                                setHtml("spanMulta", model.ValorMulta);
                                                setHtml("spanInicioMulta", model.DataInicioMulta);
                                                setHtml("spanCobrancaApresentada", model.CobrancaApresentada);
                                                setHtml("spanPortador", model.Portador);
                                                setHtml("spanTipoCobranca", model.TipoCobranca);
                                                setHtml("spanFormaPagamento", model.FormaPagamento);
                                                $("#hint").html($("#hint-content").html());

                                                // TODO: melhorar o calculo de posicionamento do hint
                                                // pois a coluna pode mudar de lugar, de largura,
                                                // a tela pode mudar de lugar e altura
                                                var posY = el.clientY;
                                                if (el.clientY > (window.innerHeight / 2))
                                                    posY = el.clientY - parseFloat($("#hint").css("height").replace("px", ""));
                                                $("#hint").css("top", posY + "px");
                                            }
                                        }
                                        catch (err) {
                                            var hintWait = "<img src=\"" + window.baseUrl + "Content/TreeviewAjaxNode/Images/error.gif\" />" +
                                                           "<label style=\"display: inline; margin-left: 5px\">" + err.message + "</label>";
                                            $("#hint").html(hintWait);
                                        }
                                    },
                                    function (result) {
                                        if (result.jqxhr.responseText.indexOf('<input type="hidden" value="TelaLogin" />') > -1) {
                                            window.location = window.baseUrl + "User/Login/?ReturnUrl=" + window.baseUrl + "/Financeiro/Movimentos/AutorizacaoPagamento";
                                        }
                                        else {
                                            var hintWait = "<img src=\"" + window.baseUrl + "Content/TreeviewAjaxNode/Images/error.gif\" />" +
                                                           "<label style=\"display: inline; margin-left: 5px\">" + result.jqxhr.status + "-" + result.jqxhr.statusText + "</label>";
                                            $("#hint").html(hintWait);
                                        }
                                    },
                                    false
                                );
                            });

                            $(".getitulo").unbind("mouseout");
                            $(".getitulo").bind("mouseout", function (el) {
                                $("#hint").css("display", "none");
                            });
                        }
                    });
                    grid.make();

                    // acao
                    var inputAcao = new DropDown({
                        id: "inputAcao",
                        route: "DropDown/GetDropDownAutorizacaoPagamento",
                        defaultValue: 1,
                        onChange: function () {
                            if (byId("inputAcao").value === "3") // AUTORIZAR_NA_DATA_INFORMADA
                                $("#inputDataAutorizacao").css("display", "inline-block");
                            else
                                $("#inputDataAutorizacao").css("display", "none");
                        }
                    });
                    inputAcao.make();

                    // data autorizacao
                    var inputDataAutorizacao = new ValidatorDate({
                        idInput: "inputDataAutorizacao",
                        isEmptyValid: false,
                        onValid: function (validator) {
                        },
                        onInvalid: function (validator) {
                        },
                        onEmpty: function () {
                        }
                    });

                    // buttonok
                    $("#buttonOK").on("click", function () {
                        if (!$("#buttonOK").attr("disabled")) {
                            doAutorizacao();
                        }
                    });

                    // filters

                    // data inicial
                    var inputFilterDataInicial = new DateValidator({
                        id: "inputFilterDataInicial",
                        v2: true,
                        forceToStayFieldWhereErro: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            validator.focus();
                        },
                        onEmpty: function () {
                        }
                    });

                    // data final
                    var inputFilterDataFinal = new DateValidator({
                        id: "inputFilterDataFinal",
                        v2: true,
                        forceToStayFieldWhereErro: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            validator.focus();
                        },
                        onEmpty: function () {
                        }
                    });

                    var compareFilterDataInicial_FilterDataFinal = new DateComparer({
                        idA: "inputFilterDataInicial",
                        idB: "inputFilterDataFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // cedente
                    var inputFilterCedente = new ValidatorLookup({
                        abrev: "FilterCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        msgPendencyMessagePartEnd: "do Cedente.",
                        route: "Empresarial/F4ContaCendete/GetContaContabil",
                        routeTable: "Empresarial/F4ContaCendete/GetContasContabeis",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Cedente",
                        idModalHideShow: "modalFilters"
                    });

                    // tipo titulo
                    function getDefaultTipoTitulo() {
                        return 85;
                    }

                    function getTipoTitulo() {
                        if (isChecked("inputAutorizados"))
                            return 65;
                        if (isChecked("inputPendentes"))
                            return 80;
                        if (isChecked("inputVetados"))
                            return 86;
                        return 85;
                    }

                    function setTipoTitulo(tipo) {
                        if (tipo === 65)
                            setChecked("inputAutorizados", true);
                        else if (tipo === 80)
                            setChecked("inputPendentes", true);
                        else if (tipo === 86)
                            setChecked("inputVetados", true);
                        else
                            setChecked("inputMinhaAutorizacao", true);
                    }

                    // filters listen
                    $("#inputFilter").click(function () {
                        loadFilters(false);
                        $("#modalFilters").modal("show");
                        setDefaultFieldFocusFilters();
                    });

                    $("#doFilter").click(function () {
                        saveFilters();
                        $("#modalFilters").modal("hide");
                    });

                    $("#removeFilter").click(function () {
                        setFiltersDefault(true);
                    });

                    $("#modalFilters").on("hidden", function () {
                        // TODO:
                        // quando o campo data esta com um valor invalido, ele fica em vermelho,
                        // se precionar a tecla "esc" para sair da tela do filtro, se voltar para o
                        // filtro logo em seguida, o campo continua vermelho e vazio, o comando
                        // abaixo forca o campo a ficar normal
                        if (!inputFilterDataInicial.isValid) {
                            inputFilterDataInicial.setValue("");
                        }
                        if (!inputFilterDataFinal.isValid) {
                            inputFilterDataFinal.setValue("");
                        }

                        // TODO:
                        // se precionar a tecla "esc" para sair da tela do filtro, e o campo data
                        // estiver com o foco, esconde a tela do filtro e o calendario do campo
                        // data continua na tela, o comando abaixo forca o calendario a sumir
                        $("#datepicker").css("display", "none");
                    });

                    // filters functions
                    function setDefaultFieldFocusFilters() {
                    }

                    function loadFilters(loadData) {
                        var filter = JSON.parse(currentUser.getSessionData("filters_fin_con_autorizacao_pagamento"));
                        if (filter !== null)
                            setFiltersInFields(filter);
                        else
                            setFiltersDefault();

                        if (loadData)
                            getData();
                    }

                    function setFiltersInFields(filter) {
                        inputFilterDataInicial.setValue(filter.inputFilterDataInicial);
                        inputFilterDataFinal.setValue(filter.inputFilterDataFinal);
                        setTipoTitulo(filter.inputFilterTipoTitulo);
                        inputFilterCedente.setValueValidate(filter.inputFilterCedente);
                    }

                    function setFiltersDefault() {
                        var FiltersDefault = {
                            inputFilterDataInicial: "",
                            inputFilterDataFinal: "",
                            inputFilterTipoTitulo: getDefaultTipoTitulo(),
                            inputFilterCedente: ""
                        };
                        setFiltersInFields(FiltersDefault);
                    }

                    function saveFilters() {
                        var filter = {};
                        filter.inputFilterDataInicial = inputFilterDataInicial.getValue();
                        filter.inputFilterDataFinal = inputFilterDataFinal.getValue();
                        filter.inputFilterTipoTitulo = getTipoTitulo();
                        filter.inputFilterCedente = inputFilterCedente.getValue();

                        getData();

                        currentUser.setSessionData("filters_fin_con_autorizacao_pagamento", JSON.stringify(filter));
                    }

                    function getData() {
                        if (inputFilterDataInicial.isValid && inputFilterDataFinal.isValid) {
                            msgWait.show();
                            getJsonFromRoute("Financeiro/Movimentos/GetListaTitulos", {
                                DataInicial: inputFilterDataInicial.getValue(),
                                DataFinal: inputFilterDataFinal.getValue(),
                                TipoTituloPagar: getTipoTitulo(),
                                Cedente: inputFilterCedente.getValue()
                            }).done(
                                function (model) {
                                    if (model.IsAlert) {
                                        u.alert(model.Message, alertBehavior.warning);
                                    } else {
                                        if (model.length > 0) {
                                            var data = new kendo.data.DataSource({ data: [] });

                                            for (var atual in model) {
                                                data.options.data.push({
                                                    Selecionado: false,
                                                    GetTitulo: model[atual].Id + "," + model[atual].DataEmissao,
                                                    PodeSerAlterado: model[atual].PodeSerAlterado,
                                                    Id: model[atual].Id,
                                                    DataEmissao: model[atual].DataEmissao,
                                                    Status: model[atual].Status,
                                                    Codigo: model[atual].Codigo,
                                                    Fornecedor: model[atual].Fornecedor,
                                                    Vencimento: convertDateStringDDMMYYYYToDate(model[atual].Vencimento),
                                                    Documento: model[atual].Documento,
                                                    Valor: parseFloat(model[atual].Valor.replace(".", "").replace(",", ".")) // TODO: ver questao de cultura e precisao
                                                });
                                            }

                                            $("#gridTitulos").data("kendoGrid").setDataSource(data);
                                            inputAcao.dropDown.enable(true);
                                            u.enable("buttonOK");
                                        }
                                        else {
                                            $("#gridTitulos").data("kendoGrid").setDataSource(new kendo.data.DataSource({ data: [] }));
                                            inputAcao.dropDown.enable(false);
                                            u.disable("buttonOK");
                                        }
                                    }
                                    msgWait.hide();
                                }
                            );
                        }
                    }

                    function doAutorizacao() {
                        var registros = grid.getDataSource().data();
                        var selecionados = "";
                        $.each(registros, function (atual) {
                            if (registros[atual].Selecionado) {
                                selecionados += registros[atual].Id + ";" + registros[atual].DataEmissao + ";" + convertDateToStringDDMMYYYY(registros[atual].Vencimento) + ",";
                            }
                        });
                        if (selecionados === "") {
                            u.dialogOk("Selecione ao menos um registro", null, true, null, alertBehavior.warning);
                            return;
                        }
                        else {
                            request("Financeiro/Movimentos/DoAutorizacaoPagamento",
                                {
                                    Titulos: selecionados,
                                    AutorizacaoPagamento: byId("inputAcao").value,
                                    DataAutorizacao: inputDataAutorizacao.getValue()
                                },
                                function (data) {
                                    if (data.IsAlert) {
                                        u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                    } else {
                                        u.dialogOk("Operação executada com sucesso", null, true, function () {
                                            loadFilters(true);
                                        }, alertBehavior.success);
                                    }
                                },
                                function (data) {
                                }, true
                            );
                        }
                    }

                    // para carregar a grid com os dados ja filtrados
                    loadFilters(true);
                })(params);
            },

            ConsultasPosicaoFinanceiraClientesFornecedores: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // data inicial
                    var inputDataInicial = new ValidatorDate({
                        idInput: "inputDataInicial",
                        isEmptyValid: true,
                        onValid: function (validator) {
                            executaConsulta();
                        },
                        onInvalid: function (validator) {
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    // data final
                    var inputDataFinal = new ValidatorDate({
                        idInput: "inputDataFinal",
                        isEmptyValid: true,
                        onValid: function () {
                            executaConsulta();
                        },
                        onInvalid: function () {
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var compareDataInicial_DataFinal = new DateComparer({
                        idA: "inputDataInicial",
                        idB: "inputDataFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                            zeraCampos();
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // cliente
                    var inputCliente = new ValidatorLookup({
                        abrev: "CodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes",
                        onValid: function () {
                            executaConsulta();
                        },
                        onInvalid: function () {
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    $("#inputConsiderarAsFiliaisDaEmpresa, #inputConsiderarAsEmpresasDoGrupo, #inputConsiderarTitulosSubstituidos, #inputConsiderarADataDeBaixaParaCalculoDoAtraso").on("change", function () {
                        executaConsulta();
                    });

                    // listen anotacoes gerais

                    $("#buttonDadosClienteAnotacoesGerais").on("click", function () {
                        request("Financeiro/Consultas/GetPosicaoFinanceiraClientesFornecedores_AnotacoesGerais",
                            {
                                codCliente: getVal("inputCodigoCliente"),
                            },
                            function (result) {
                                setVal("DadosCliente.AnotacoesGerais", result);
                            }
                        );
                    });

                    $("#buttonOK_AnotacoesGerais").on("click", function () {
                        request("Comercial/Consultas/SalveHistoricoDeClientes_AnotacoesGerais",
                            {
                                codCliente: getVal("inputCodigoCliente"),
                                anotacoesGerais: getVal("DadosCliente.AnotacoesGerais")
                            }
                        );
                    });

                    // functions

                    var inputs = currentUser.getCustomData("fin_con_PosicaoFinanceirasClientesFornecedores");
                    if (inputs === null || inputs === "") {
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputDataInicial.setValue(inputs.inputDataInicial);
                        inputDataFinal.setValue(inputs.inputDataInicial);
                        inputCliente.setValueValidate(inputs.inputCodigoCliente);
                        setChecked("inputConsiderarAsFiliaisDaEmpresa", inputs.inputConsiderarAsFiliaisDaEmpresa);
                        setChecked("inputConsiderarAsEmpresasDoGrupo", inputs.inputConsiderarAsEmpresasDoGrupo);
                        setChecked("inputConsiderarTitulosSubstituidos", inputs.inputConsiderarTitulosSubstituidos);
                        setChecked("inputConsiderarADataDeBaixaParaCalculoDoAtraso", inputs.inputConsiderarADataDeBaixaParaCalculoDoAtraso);
                    }

                    function zeraCampos() {
                        if (!inputDataInicial.isValid || !inputDataFinal.isValid || inputCliente.invalid) {
                            $("#buttonDadosClienteAnotacoesGerais").attr("disabled", "disabled");

                            setVal("inputCNPJCPF", "");
                            setVal("inputInscricaoEstadual", "");
                            setVal("inputEndereco", "");
                            setVal("inputContato", "");
                            setVal("inputTelefone", "");
                            setVal("inputEmail", "");

                            setVal("inputCategoria1Legenda", "");
                            $("#inputCategoria1Legenda").attr("title", "");
                            setVal("inputCategoria1Descricao", "");
                            setVal("inputCategoria2Legenda", "");
                            $("#inputCategoria2Legenda").attr("title", "");
                            setVal("inputCategoria2Descricao", "");
                            setVal("inputCategoria3Legenda", "");
                            $("#inputCategoria3Legenda").attr("title", "");
                            setVal("inputCategoria3Descricao", "");

                            setVal("inputRepresentante", "");

                            // credito
                            setHtml("inputValorLimite", "");
                            setHtml("inputDataLimite", "");

                            setHtml("inputValorCreditoUtilizado", "");
                            setHtml("inputValorAdiantamentos", "");
                            setHtml("inputValorPedidos", "");
                            setHtml("inputValorChequesPreDatados", "");
                            setHtml("inputValorCreditoDisponivel", "");
                            setHtml("inputVenda", "");
                            setHtml("inputValorSaldoAVencer", "");

                            setHtml("inputValorMaiorAcumulo", "");
                            setHtml("inputDataMaiorAcumulo", "");

                            setHtml("inputPrazoMedioFaturamento", "");
                            setHtml("inputPrazoMedioFaturamentoDias", "");

                            setHtml("inputValorSaldoVencido", "");

                            setHtml("inputMediaAtraso", "");
                            setHtml("inputMediaAtrasoDias", "");

                            setHtml("inputMediaAtrasoPonderada", "");
                            setHtml("inputMediaAtrasoPonderadaDias", "");

                            setHtml("inputValorIndiceAtrasoPonderado", "");
                            setHtml("inputValorIndiceAtrasoPonderadoPorcento", "");

                            setHtml("inputValorMaiorAtraso", "");
                            setHtml("inputMaiorAtraso", "");
                            setHtml("inputMaiorAtrasoDias", "");

                            setHtml("inputValorChequesDevolvidos", "");

                            setHtml("inputBaixasPorInadimplencia", "");
                            setHtml("inputValorBaixasPorInadimplencia", "");

                            setHtml("inputValorLimiteSerasa", "");

                            // historico
                            setHtml("inputDataClienteDesde", "");

                            setHtml("inputSituacao", "");
                            setHtml("inputDataSituacao", "");

                            setHtml("inputValorMaiorFatura", "");
                            setHtml("inputDataMaiorFatura", "");

                            setHtml("inputValorUltimaFatura", "");
                            setHtml("inputDataUltimaFatura", "");

                            setHtml("inputFrequenciaMediaCompra", "");
                            setHtml("inputFrequenciaMediaCompraDias", "");

                            setHtml("inputValorMedioDeCompra", "");

                            setHtml("inputValorTotalDeCompras", "");
                            setHtml("inputDataTotalDeCompras", "");

                            setHtml("inputValorMaiorRisco", "");
                            setHtml("inputDataMaiorRisco", "");

                            setHtml("inputValorAcumuloCompras180Dias", "");
                            setHtml("inputValorComprasNoMes", "");
                        }
                    }

                    function executaConsulta() {
                        if (inputDataInicial.isValid && inputDataFinal.isValid && !inputCliente.invalid) {
                            inputs = {
                                inputDataInicial: inputDataInicial.getValue(),
                                inputDataFinal: inputDataFinal.getValue(),
                                inputCodigoCliente: inputCliente.getValue(),
                                inputConsiderarAsFiliaisDaEmpresa: isChecked("inputConsiderarAsFiliaisDaEmpresa"),
                                inputConsiderarAsEmpresasDoGrupo: isChecked("inputConsiderarAsEmpresasDoGrupo"),
                                inputConsiderarTitulosSubstituidos: isChecked("inputConsiderarTitulosSubstituidos"),
                                inputConsiderarADataDeBaixaParaCalculoDoAtraso: isChecked("inputConsiderarADataDeBaixaParaCalculoDoAtraso")
                            }
                            currentUser.setCustomData("fin_con_PosicaoFinanceirasClientesFornecedores", JSON.stringify(inputs));

                            request(
                                "Financeiro/Consultas/GetPosicaoFinanceiraClientesFornecedores", {
                                    inputDataInicial: getVal("inputDataInicial"),
                                    inputDataFinal: getVal("inputDataFinal"),
                                    inputCodigoCliente: inputCliente.getValue(),
                                    inputConsiderarAsFiliaisDaEmpresa: isChecked("inputConsiderarAsFiliaisDaEmpresa"),
                                    inputConsiderarAsEmpresasDoGrupo: isChecked("inputConsiderarAsEmpresasDoGrupo"),
                                    inputConsiderarTitulosSubstituidos: isChecked("inputConsiderarTitulosSubstituidos"),
                                    inputConsiderarADataDeBaixaParaCalculoDoAtraso: isChecked("inputConsiderarADataDeBaixaParaCalculoDoAtraso")
                                },
                                function (model) {
                                    if (model.IsAlert) {
                                        u.alert(model.Message, alertBehavior.warning);
                                        zeraCampos();
                                    } else {
                                        $("#buttonDadosClienteAnotacoesGerais").removeAttr("disabled");

                                        // dados
                                        setVal("inputCNPJCPF", model.CnpjCpf);
                                        setVal("inputInscricaoEstadual", model.InscricaoEstadual);
                                        setVal("inputEndereco", model.Endereco);
                                        setVal("inputContato", model.Contato);
                                        setVal("inputTelefone", model.Telefone);
                                        setVal("inputEmail", model.Email);

                                        setHtml("inputCategoria1Legenda", model.Categoria1Legenda + ":");
                                        $("#inputCategoria1Legenda").attr("title", model.Categoria1Legenda);
                                        setVal("inputCategoria1Descricao", model.Categoria1Descricao);
                                        setHtml("inputCategoria2Legenda", model.Categoria2Legenda + ":");
                                        $("#inputCategoria2Legenda").attr("title", model.Categoria2Legenda);
                                        setVal("inputCategoria2Descricao", model.Categoria2Descricao);
                                        setHtml("inputCategoria3Legenda", model.Categoria3Legenda + ":");
                                        $("#inputCategoria3Legenda").attr("title", model.Categoria3Legenda);
                                        setVal("inputCategoria3Descricao", model.Categoria3Descricao);

                                        setVal("inputRepresentante", model.Representante);

                                        // credito
                                        setHtml("inputValorLimite", model.ValorLimite);
                                        setHtml("inputDataLimite", model.DataLimite);

                                        setHtml("inputValorCreditoUtilizado", model.ValorCreditoUtilizado);
                                        setHtml("inputValorAdiantamentos", model.ValorAdiantamentos);
                                        setHtml("inputValorPedidos", model.ValorPedidos);
                                        setHtml("inputValorChequesPreDatados", model.ValorChequesPreDatados);
                                        setHtml("inputValorCreditoDisponivel", model.ValorCreditoDisponivel);
                                        setHtml("inputVenda", model.Venda);
                                        setHtml("inputValorSaldoAVencer", model.ValorSaldoAVencer);

                                        setHtml("inputValorMaiorAcumulo", model.ValorMaiorAcumulo);
                                        setHtml("inputDataMaiorAcumulo", model.DataMaiorAcumulo);

                                        setHtml("inputPrazoMedioFaturamento", model.PrazoMedioFaturamento);
                                        setHtml("inputPrazoMedioFaturamentoDias", "dias");

                                        setHtml("inputValorSaldoVencido", model.ValorSaldoVencido);

                                        setHtml("inputMediaAtraso", model.MediaAtraso);
                                        setHtml("inputMediaAtrasoDias", "dias");

                                        setHtml("inputMediaAtrasoPonderada", model.MediaAtrasoPonderada);
                                        setHtml("inputMediaAtrasoPonderadaDias", "dias");

                                        setHtml("inputValorIndiceAtrasoPonderado", model.ValorIndiceAtrasoPonderado);
                                        setHtml("inputValorIndiceAtrasoPonderadoPorcento", "%");

                                        setHtml("inputValorMaiorAtraso", model.ValorMaiorAtraso);
                                        setHtml("inputMaiorAtraso", model.QtdeMaiorAtraso);
                                        setHtml("inputMaiorAtrasoDias", "dias");

                                        setHtml("inputValorChequesDevolvidos", model.ValorChequesDevolvidos);

                                        setHtml("inputBaixasPorInadimplencia", model.QtdeBaixasPorInadimplencia);
                                        setHtml("inputValorBaixasPorInadimplencia", model.ValorBaixasPorInadimplencia);

                                        setHtml("inputValorLimiteSerasa", model.ValorLimiteSerasa);

                                        // historico
                                        setHtml("inputDataClienteDesde", model.DataClienteDesde);

                                        setHtml("inputSituacao", model.DescricaoSituacao);
                                        setHtml("inputDataSituacao", model.DataSituacao);

                                        setHtml("inputValorMaiorFatura", model.ValorMaiorFatura);
                                        setHtml("inputDataMaiorFatura", model.DataMaiorFatura);

                                        setHtml("inputValorUltimaFatura", model.ValorUltimaFatura);
                                        setHtml("inputDataUltimaFatura", model.DataUltimaFatura);

                                        setHtml("inputFrequenciaMediaCompra", model.FrequenciaMediaCompra);
                                        setHtml("inputFrequenciaMediaCompraDias", "dias");

                                        setHtml("inputValorMedioDeCompra", model.ValorMedioDeCompra);

                                        setHtml("inputValorTotalDeCompras", model.ValorTotalDeCompras);
                                        setHtml("inputDataTotalDeCompras", model.DataTotalDeCompras);

                                        setHtml("inputValorMaiorRisco", model.ValorMaiorRisco);
                                        setHtml("inputDataMaiorRisco", model.DataMaiorRisco);

                                        setHtml("inputValorAcumuloCompras180Dias", model.ValorAcumuloCompras180Dias);
                                        setHtml("inputValorComprasNoMes", model.ValorComprasNoMes);
                                    }
                                },
                                function (erro) {
                                    u.alert(erro.jqxhr.status + " - " + erro.jqxhr.statusText, alertBehavior.warning);
                                    zeraCampos();
                                }
                            );
                        }
                    }

                    executaConsulta();

                })(params);
            },

            ConsultasSaldoDeContasBancarias: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // periodo
                    var inputPeriodoInicial = new DateValidator({
                        id: "inputPeriodoInicial",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                            executaConsulta();
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var inputPeriodoFinal = new DateValidator({
                        id: "inputPeriodoFinal",
                        v2: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                            executaConsulta();
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                            zeraCampos();
                        },
                        onEmpty: function () {
                            zeraCampos();
                        }
                    });

                    var comparePeriodoInicialComFinal = new DateComparer({
                        idA: "inputPeriodoInicial",
                        idB: "inputPeriodoFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior a data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // IncluirContasInativas
                    $("#inputIncluirContasInativas").on("change", function () {
                        if (inputPeriodoInicial.isValid && inputPeriodoFinal.isValid)
                            executaConsulta();
                    });

                    // grid

                    var style = document.createElement("style");
                    style.type = "text/css";
                    style.innerHTML = "\
                    /* remove a linhas das colunas */\
                    #divResulta .k-grid td {\
                        border-style: none;\
                    }\
                    /* remove o zebrado das colunas */\
                    #divResulta .k-alt {\
                        background-color: #fff;\
                    }\
                    ";
                    document.getElementsByTagName("head")[0].appendChild(style);

                    var gridResultado = new Table({
                        "id": "gridResultado",
                        "pageable": false,
                        "showFilter": false,
                        "sortable": false,
                        "columnMenu": false,
                        "resizable": true,
                        "columns": [
                            { field: "Codigo", title: "Código", width: 40, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } },
                            { field: "ContaCorrente", title: "Conta Corrente", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "SaldoInicial", title: "Saldo Inicial", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Entrada", title: "Entrada", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Saida", title: "Saída", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "SaldoDisponivel", title: "Saldo Disponível", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "SaldoTotal", title: "Saldo Total", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } },
                            { field: "Limite", title: "Limite", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: right;" } }
                        ],
                        "dataSourceType": "Object"
                    });
                    gridResultado.make();

                    // valores padroes / ultimos filtros usados
                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("fin_con_SaldoDeContasBancarias");
                    if (inputs === null || inputs === "") {
                        requestNoAsync(window.baseUrl + "Financeiro/Consultas/GetDataInferiorMovimentacao", {},
                            function (result) {
                                inputPeriodoInicial.setValue(result.DataInferiorMovimentacao);
                            }
                        );

                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        setChecked("inputIncluirContasInativas", inputs.IncluirContasInativas);
                    }

                    function zeraCampos() {
                        if (!inputPeriodoInicial.isValid || !inputPeriodoFinal.isValid) {
                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridResultado").data("kendoGrid").setDataSource(data);
                        }
                    }

                    function executaConsulta() {
                        if (inputPeriodoInicial.isValid && inputPeriodoFinal.isValid) {
                            inputs = {
                                PeriodoInicial: inputPeriodoInicial.getValue(),
                                PeriodoFinal: inputPeriodoFinal.getValue(),
                                IncluirContasInativas: isChecked("inputIncluirContasInativas")
                            }
                            currentUser.setCustomData("fin_con_SaldoDeContasBancarias", JSON.stringify(inputs));

                            request(
                                "Financeiro/Consultas/GetSaldoDeContasBancarias", {
                                    DataInicial: getVal("inputPeriodoInicial"),
                                    DataFinal: getVal("inputPeriodoFinal"),
                                    IncluirContasInativas: isChecked("inputIncluirContasInativas")
                                },
                                function (model) {
                                    if (model.IsAlert) {
                                        zeraCampos();
                                        u.alert(model.Message, alertBehavior.warning);
                                    } else {
                                        var data = new kendo.data.DataSource({ data: [] });
                                        for (var atual in model) {
                                            data.options.data.push({
                                                Codigo: model[atual].Codigo,
                                                ContaCorrente: model[atual].ContaCorrente,
                                                SaldoInicial: model[atual].SaldoInicial,
                                                Entrada: model[atual].Entrada,
                                                Saida: model[atual].Saida,
                                                SaldoDisponivel: model[atual].SaldoDisponivel,
                                                SaldoTotal: model[atual].SaldoTotal,
                                                Limite: model[atual].Limite
                                            });
                                        }
                                        $("#gridResultado").data("kendoGrid").setDataSource(data);

                                        // para as linhas em branco:
                                        // tem que colocar um &nbsp em alguma coluna, senão a linha não fica com a altura padrão
                                        // mesmo se viesse &nbsp em alguma coluna por padrão, o kendo fazer encode dos dados por segurança
                                        $("#divResulta tbody > tr > td:first-child").each(function (i, el) {
                                            if (el.innerText === "")
                                                el.innerHTML = "&nbsp;";
                                        });
                                    }
                                },
                                function (erro) {
                                    u.alert(erro.jqxhr.status + " - " + erro.jqxhr.statusText, alertBehavior.warning);
                                }
                            );
                        }
                    }

                })(params);
            },

            RelatoriosFluxoDeCaixa: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    var inputDataInicial = new DateValidator({
                        id: "inputDataInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        }
                    });

                    var inputDataFinal = new DateValidator({
                        id: "inputDataFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        }
                    });

                    var compareDataInicial_DataFinal = new DateComparer({
                        idA: "inputDataInicial",
                        idB: "inputDataFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    var dropDownTipoTotalizacao = new DropDown({
                        'id': 'inputTipoTotalizacao',
                        'route': 'DropDown/GetDropDownTipoTotalizacao'
                    });
                    dropDownTipoTotalizacao.make();

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaCaixaBanco/GetContaContabil",
                        v2: "v3",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var validatorContaContabil = new Validator({
                        field: "inputCodigoContaContabil",
                        fieldDescriptionId: "descriptionCodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        onPendencyMessage: "Deve ser informado o código da conta contábil.",
                        route: "Empresarial/F4ContaCaixaBanco/GetContaContabil",
                        v2: "v3",
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "Nome",
                        linkButton: "linkButtonModalContaContabil",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasContaContabil",
                        onValid: function (data) {
                            $("#inputCodigoContaContabil").val(data.Codigo);
                            $("#descriptionCodigoContaContabil").html(data.Nome);
                        },
                        onInvalid: function (data) {
                            validatorContaContabil.clear({ error: true });
                            validatorContaContabil.focus();
                        },
                        onEmpty: function () {
                            validatorContaContabil.clear();
                        }
                    });
                    validatorContaContabil.listen();

                    var tableContaContabil = new Table({
                        "id": "tableContaContabil",
                        "route": window.baseUrl + "Empresarial/F4ContaCaixaBanco/GetContasContabeis",
                        "showFilter": true,
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "onChange": function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "onDataBound": function () {
                            $("#tableContaContabil table tr").on("dblclick", function () {
                                var data = tableContaContabil.getSelectedData();
                                validatorContaContabil.onValid(data);
                                validatorContaContabil.update();
                                $("#modalContaContabil").modal("hide");
                            });
                            $("#inputF4ModalCancelar").on("click", function () {
                                $("#modalContaContabil").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });

                    var modalContaContabil = new Modal("Conta Contábil",
                        byId("linkButtonModalContaContabil"),
                        byId("inputCodigoContaContabil"),
                        tableContaContabil,
                        null, {
                            validatorInput: validatorContaContabil,
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaCaixaBanco/GetClassesPai",
                            onHidden: function () {
                            }
                        }
                     ).listen();

                    var modalGrupoContasContaContabil = new ModalGrupoContas({
                        id: "ContaContabil",
                        validatorInput: validatorContaContabil,
                        validatorConta: {
                            fieldSearch: "CodigoContaContabil",
                            onPendencyMessage: "Deve ser informado o código da conta contábil.",
                            route: "Empresarial/F4ContaCaixaBanco/GetContaContabil",
                            v2: "v3",
                            fieldNome: "Nome"
                        },
                        tableConta: {
                            route: window.baseUrl + "Empresarial/F4ContaCaixaBanco/GetContasContabeis",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        },
                        modalConta: {
                            useClassePai: true,
                            ClassePaiURL: "Empresarial/F4ContaCaixaBanco/GetClassesPai",
                        },
                        onShow: function () {
                        },
                        onHidden: function () {
                        }
                    });

                    function getSituacao() {
                        if (isChecked("inputTitulosRecebidosPagos"))
                            return 2;

                        if (isChecked("inputTitulosAbertos"))
                            return 1;

                        return 0;
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = { DataInicial: inputDataInicial.getValue(), DataFinal: inputDataFinal.getValue() }
                        currentUser.setCustomData("fin_rel_FluxoDeCaixa", JSON.stringify(inputs));
                        window.open(window.baseUrl + "Financeiro/Relatorios/GeraRelatorioFluxoDeCaixa"
		                    + "?DataInicial=" + getVal("inputDataInicial")
		                    + "&DataFinal=" + getVal("inputDataFinal")
		                    + "&TotalizacaoRelatorio=" + document.getElementById("inputTipoTotalizacao").value
		                    + "&SituacaoTitulo=" + getSituacao()
		                    + "&IsSimplificado=" + isChecked("inputTipoSimplificado")
		                    + "&OcultTransf=" + isChecked("inputOcultarTransf")
		                    + "&OcultTransfEntreFiliais=" + isChecked("inputOcultarTransfEntreFiliais")
		                    + "&OcultAplicResg=" + isChecked("inputOcultarAplicacao")
		                    + "&OcultTransfContaCorrente=" + isChecked("inputOcultarTransfCC")
		                    + "&OcultTransfContaVinculada=" + isChecked("inputOcultarTransfCV")
		                    + "&IncluirPrevisoes=" + isChecked("inputIncluirPrevisoes")
		                    + "&IncluirTitulosRec=" + isChecked("inputTitulosRec")
		                    + "&IncluirTitulosPag=" + isChecked("inputTitulosPag")
		                    + "&NaoConsidMovTes=" + isChecked("inputNaoConsidMovTes")
		                    + "&ListarMovApenasContasConsid=" + isChecked("inputListarMovApenasContas")
		                    + "&ListarTodaMovExcetoContasConsid=" + isChecked("inputTodaMovExcetoContas")
		                    + "&ConsidApenasSeguintesContas=" + isChecked("inputConsiderarSomente")
		                    + "&CodigosContas=" + (validatorContaContabil.getVarios()
                                                ? validatorContaContabil.getGrupoContasString()
                                                : getVal("inputCodigoContaContabil"))
                        );
                    });

                    $("#inputListarMovApenasContas").on("click", function () {
                        if (isChecked("inputListarMovApenasContas")) {
                            setChecked("inputTodaMovExcetoContas", false);
                            u.disable("inputTodaMovExcetoContas");
                        } else {
                            u.enable("inputTodaMovExcetoContas");
                        }
                    });

                    $("#inputTodaMovExcetoContas").on("click", function () {
                        if (isChecked("inputTodaMovExcetoContas")) {
                            setChecked("inputListarMovApenasContas", false);
                            u.disable("inputListarMovApenasContas");
                        } else {
                            u.enable("inputListarMovApenasContas");
                        }
                    });

                    var inputs = currentUser.getCustomData("fin_rel_FluxoDeCaixa");
                    if (inputs === null || inputs === "") {

                    } else {
                        inputs = JSON.parse(inputs);
                        inputDataInicial.setValue(inputs.DataInicial);
                        inputDataFinal.setValue(inputs.DataFinal);
                    }
                })(params);
            },

            RelatoriosTesourariaMovimentos: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // data inicial
                    var inputDataInicial = new DateValidator({
                        id: "inputDataInicial",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        }
                    });

                    // data final
                    var inputDataFinal = new DateValidator({
                        id: "inputDataFinal",
                        v2: true,
                        isEmptyValid: true,
                        constructInjection: function () {
                            makeDatePicker("#" + this.id);
                        },
                        onValid: function (validator) {
                            dateValidatorOnValid(validator);
                        },
                        onInvalid: function (validator) {
                            dateValidatorOnInvalid(validator);
                        }
                    });

                    var compareDataInicial_DataFinal = new DateComparer({
                        idA: "inputDataInicial",
                        idB: "inputDataFinal",
                        verb: "less",
                        onInvalid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.warning);
                            u.alert("Data inicial deve ser anterior à data final.", alertBehavior.warning);
                        },
                        onValid: function (data) {
                            alterControlGroupBehavior(data.idA, controlGroupBehavior.normal);
                        }
                    });

                    // tipo data
                    var inputTipoDeData = new DropDown({
                        id: "inputTipoDeData",
                        route: "DropDown/GetDropDownTipoDataEx"
                    });
                    inputTipoDeData.make();

                    // tipo lancamento
                    var inputTipoDeLancamento = new DropDown({
                        id: "inputTipoDeLancamento",
                        route: "DropDown/GetDropDownTipoLancamento"
                    });
                    inputTipoDeLancamento.make();

                    // historico
                    var inputCodigoHistorico = new ValidatorLookup({
                        abrev: "CodigoHistorico",
                        fieldSearch: "CodigoHistorico",
                        fieldCode: "Codigo",
                        msgPendencyMessagePartEnd: "do Histórico.",
                        route: "Empresarial/F4Historico/GetHistorico",
                        routeTable: "Empresarial/F4Historico/GetHistoricos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Descrição", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Relação de Históricos"
                    });

                    // formas pagamento
                    var inputFormasDePagamento = new DropDown({
                        id: "inputFormasDePagamento",
                        route: "Financeiro/Relatorios/GetFormasPagamento"
                    });
                    inputFormasDePagamento.make();

                    // indice
                    var inputIndice = new DropDown({
                        id: "inputIndice",
                        route: "Financeiro/Relatorios/GetIndices"
                    });
                    inputIndice.make();

                    // conta
                    var inputCodigoContaContabil = new ValidatorLookup({
                        abrev: "CodigoContaContabil",
                        fieldSearch: "CodigoContaContabil",
                        msgPendencyMessagePartEnd: "da Conta Contábil.",
                        route: "Empresarial/F4ContaCaixaBanco/GetContaContabil",
                        routeTable: "Empresarial/F4ContaCaixaBanco/GetContasContabeis",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Tipo", field: "Tipo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Plano Empresarial",
                        ModalGrupoContas: true
                    });

                    // transacao
                    var inputTransacao = new ValidatorDropDown({
                        abrev: "Transacao",
                        route: "DropDown/GetDropDownTransacao",
                        ModalGrupoContas: true,
                        nameFieldDescription: "Descricao",
                        columnsModalGrupoContas: [
                            { field: "id", title: "Código", width: 50, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } },
                            { field: "Descricao", title: "Descrição", width: 150, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }
                        ]
                    });

                    // relatorio
                    var inputRelatorio = new DropDown({
                        id: "inputRelatorio",
                        route: "Financeiro/Relatorios/GetModelosTesourariaMovimentos"
                    });
                    inputRelatorio.make();

                    // botao ok
                    $("#buttonOK").on("click", function () {
                        inputs = {
                            DataInicial: inputDataInicial.getValue(),
                            DataFinal: inputDataFinal.getValue(),

                            TipoDeData: inputTipoDeData.dropDown.dataItem().Value,
                            TipoDeLancamento: inputTipoDeLancamento.dropDown.dataItem().Value,

                            LancamentoClassificacao: isChecked("inputLancamento"),
                            CodigoHistorico: inputCodigoHistorico.getValue(),
                            Complemento: getVal("inputComplemento"),

                            FormaPagamento: inputFormasDePagamento.dropDown.dataItem().Value,
                            Indice: inputIndice.dropDown.dataItem().Value,

                            ConsolidarMovimentacaoPorFormaDePagamento: isChecked("inputConsolidarMovimentacaoPorFormaDePagamento"),
                            DetalharChequesDeTerceiros: isChecked("inputDetalharChequesDeTerceiros"),

                            CodigoContaContabil: inputCodigoContaContabil.getGrupoContasOuConta(),
                            Transacao: inputTransacao.getGrupoContas(),

                            Relatorio: inputRelatorio.get()
                        }
                        currentUser.setCustomData("fin_rel_TesourariaMovimentos", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Financeiro/Relatorios/GeraRelatorioTesourariaMovimentos"
                            + "?DataInicial=" + inputDataInicial.getValue()
                            + "&DataFinal=" + inputDataFinal.getValue()
                            + "&TipoDeData=" + inputTipoDeData.dropDown.dataItem().Value
                            + "&TipoDeLancamento=" + inputTipoDeLancamento.dropDown.dataItem().Value
                            + "&LancamentoClassificacao=" + isChecked("inputLancamento")
                            + "&CodigoHistorico=" + inputCodigoHistorico.getValue()
                            + "&Complemento=" + getVal("inputComplemento")
                            + "&FormaPagamento=" + inputFormasDePagamento.dropDown.dataItem().Value
                            + "&Indice=" + inputIndice.dropDown.dataItem().Value
                            + "&ConsolidarMovimentacaoPorFormaDePagamento=" + isChecked("inputConsolidarMovimentacaoPorFormaDePagamento")
                            + "&DetalharChequesDeTerceiros=" + isChecked("inputDetalharChequesDeTerceiros")
                            + "&CodigoContaContabil=" + inputCodigoContaContabil.getGrupoContasStringOuConta()
                            + "&CodigoTransacao=" + inputTransacao.getGrupoContasString()
                            + "&Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                        );
                    });

                    // functions
                    var inputs = currentUser.getCustomData("fin_rel_TesourariaMovimentos");
                    if (inputs === null || inputs === "") {
                    } else {
                        inputs = JSON.parse(inputs);

                        inputDataInicial.setValue(inputs.DataInicial);
                        inputDataFinal.setValue(inputs.DataFinal);

                        inputTipoDeData.set(inputs.TipoDeData);
                        inputTipoDeLancamento.set(inputs.TipoDeLancamento);

                        if (inputs.LancamentoClassificacao) $("#inputLancamento").attr("checked", "checked")
                        else $("#inputClassificacao").attr("checked", "checked");
                        inputCodigoHistorico.setValue(inputs.CodigoHistorico);
                        setVal("inputComplemento", inputs.Complemento);

                        inputFormasDePagamento.set(inputs.FormaPagamento);
                        inputIndice.set(inputs.Indice);

                        setChecked("inputConsolidarMovimentacaoPorFormaDePagamento", inputs.ConsolidarMovimentacaoPorFormaDePagamento);
                        setChecked("inputDetalharChequesDeTerceiros", inputs.DetalharChequesDeTerceiros);

                        inputCodigoContaContabil.setGrupoContasOuConta(inputs.CodigoContaContabil);
                        inputTransacao.setGrupoContas(inputs.Transacao);

                        inputRelatorio.set(inputs.Relatorio);
                    }
                })(params);
            }
        };
    })();

    Estoque.Manager = (function () {
        return {
            RelatoriosInventario: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new ValidatorDate({
                        idInput: "inputPeriodoInicial",
                        isEmptyValid: true
                    });

                    var inputPeriodoFinal = new ValidatorDate({
                        idInput: "inputPeriodoFinal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial deve ser anterior a data final.",
                        isEmptyValid: true
                    });

                    // filial
                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ error: true });
                            validatorFilial.focus();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        "id": "tableFilial",
                        "msgDialog": true,
                        "route": window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $("#modalFilial").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    // ClasseProduto
                    var validatorClasseProduto = new Validator({
                        field: "CodigoClasseProduto",
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da classe de produto.",
                        route: "Empresarial/F4ClasseProduto/GetClasseProduto",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoClasseProduto", data["Codigo"]);
                            setHtml("descriptionCodigoClasseProduto", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorClasseProduto.clear({ error: true });
                            validatorClasseProduto.focus();
                        },
                        onEmpty: function () {
                            validatorClasseProduto.clear();
                        }
                    });
                    validatorClasseProduto.listen();

                    var tableClasseProduto = new Table({
                        "id": "tableClasseProduto",
                        "msgDialog": true,
                        "route": window.baseUrl + "Empresarial/F4ClasseProduto/GetClassesProdutos",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableClasseProduto.getSelectedData();
                                validatorClasseProduto.onValid(data);
                                validatorClasseProduto.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tableClasseProduto table tr").on("dblclick", function () {
                                var data = tableClasseProduto.getSelectedData();
                                validatorClasseProduto.onValid(data);
                                validatorClasseProduto.update();
                                $("#modalClasseProduto").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkClasseProduto = document.getElementById("linkButtonModalClasseProduto");
                    var inputClasseProduto = document.getElementById("inputCodigoClasseProduto");
                    var modalClasseProduto = new Modal("ClasseProduto", linkClasseProduto, inputClasseProduto, tableClasseProduto);
                    modalClasseProduto.listen();

                    var inputTipoDeInventario = $("#inputTipoDeInventario").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Normal" },
                            { Value: "1", Text: "Separar Estoque de Terceiros em Poder da Empresa" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0"
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Estoque/Relatorios/GetModelosInventario"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("est_rel_inventario");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                        setFilialDefault(validatorFilial, true);
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        validatorFilial.setValue(inputs.Filial);
                        setFilialDefault(validatorFilial, false);
                        validatorClasseProduto.setValue(inputs.ClasseProduto);
                        inputTipoDeInventario.data().kendoDropDownList.select(inputs.TipoDeInventario.toInt());
                        setChecked("inputListarEstoqueDeTerceirosEmPoderDaEmpresa", inputs.ListarEstoqueDeTerceirosEmPoderDaEmpresa);
                        setChecked("inputIgnorarProdutosInativosNaImpressao", inputs.IgnorarProdutosInativosNaImpressao);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            Filial: getVal("inputCodigoFilial"),
                            ClasseProduto: getVal("inputCodigoClasseProduto"),
                            TipoDeInventario: inputTipoDeInventario.val(),
                            ListarEstoqueDeTerceirosEmPoderDaEmpresa: isChecked("inputListarEstoqueDeTerceirosEmPoderDaEmpresa"),
                            IgnorarProdutosInativosNaImpressao: isChecked("inputIgnorarProdutosInativosNaImpressao")
                        }
                        currentUser.setCustomData("est_rel_inventario", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Estoque/Relatorios/GeraRelatorioInventario?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&Filial=" + getVal("inputCodigoFilial")
                            + "&ClasseProduto=" + getVal("inputCodigoClasseProduto")
                            + "&TipoDeInventario=" + getVal("inputTipoDeInventario")
                            + "&ListarEstoqueDeTerceirosEmPoderDaEmpresa=" + isChecked("inputCodigoClasseProduto")
                            + "&IgnorarProdutosInativosNaImpressao=" + isChecked("inputCodigoClasseProduto")
                        );
                    });
                })(params);
            },

            RelatoriosMovimentos: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new ValidatorDate({
                        idInput: "inputPeriodoInicial",
                        isEmptyValid: true
                    });

                    var inputPeriodoFinal = new ValidatorDate({
                        idInput: "inputPeriodoFinal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial deve ser anterior a data final.",
                        isEmptyValid: true
                    });

                    // produto
                    var validatorProdutos = new Validator({
                        field: "inputCodigoProduto",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoProduto",
                        fieldSearch: "CodigoProduto",
                        v2: "v3",
                        linkButton: "linkButtonModalProdutos",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasProduto",
                        onPendencyMessage: "Deve ser informado o código do produto.",
                        route: "Empresarial/F4Produto/GetProdutoClasse",
                        onValid: function (data) {
                            validatorProdutos.setChange(true);
                            validatorProdutos.setValues(data["Codigo"], data["Nome"]);
                            validatorProdutos.PropertiesSpecifyField = {
                                Classificacao: data.Classificacao,
                                HaveGrade1: data.HaveGrade1,
                                HaveGrade2: data.HaveGrade2,
                                HaveGrade3: data.HaveGrade3
                            };

                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade1) {
                                validatorGrade1.enable();
                                validatorGrade1.focus();
                            } else {
                                $("#linkButtonModalProdutos").focus();
                            }

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade2)
                                validatorGrade2.enable();

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade3)
                                validatorGrade3.enable();
                        },
                        onInvalid: function (data) {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear({ error: true });
                            validatorProdutos.focus();
                            validatorGrade1.clear({ error: true, disable: true });
                            validatorGrade2.clear({ error: true, disable: true });
                            validatorGrade3.clear({ error: true, disable: true });
                            validatorProdutos.PropertiesSpecifyField = {};
                        },
                        onEmpty: function () {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear();
                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });
                            validatorProdutos.PropertiesSpecifyField = {};
                            $("#linkButtonModalProdutos").focus();
                        }
                    });
                    validatorProdutos.listen();

                    var tableProdutos = new Table({
                        id: "tableProdutos",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/GetProdutos",
                        showFilter: true,
                        columns: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Unidade", field: "Unidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Preço", field: "ValorUnitario", width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                            { title: "Classificação", field: "Classificacao", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                                $("#modalProdutos").modal("hide");
                            });
                        },
                        dataSourceType: "Filtered"
                    });

                    var modalProdutos = new Modal(
                        "Produtos",
                        byId("linkButtonModalProdutos"),
                        byId("inputCodigoProduto"),
                        tableProdutos,
                        null,
                        {
                            urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                            validatorInput: validatorProdutos, // o objeto modal precisa para depois setar a instancia dele, na propriedade "modal" do validator
                            showOpcaoExibir: true,
                            selectClass: true,
                            onDblClickGetItem: function (event, dados) {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = dados,
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                                $("#modalProdutos").modal("hide");
                            }
                        }).listen();

                    // grades
                    var columnsGrade = [
                        { title: "Código", field: "Codigo", width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        { title: "Descrição", field: "Descricao", width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                    ];

                    // grade1
                    var validatorGrade1 = new Validator({
                        field: "inputCodigoGrade1",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade1",
                        fieldSearch: "CodigoGrade1",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 1.",
                        route: "Empresarial/F4Produto/GetItemGrade1",
                        pendency: [validatorProdutos],
                        onValid: function (data) {
                            validatorGrade1.setChange(true);
                            validatorGrade1.setValues(data["Codigo"], " - " + data["Descricao"]);

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade2) {
                                validatorGrade2.focus();
                            }
                        },
                        onInvalid: function (data) {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear({ error: true });
                            validatorGrade1.focus();
                        },
                        onEmpty: function () {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear();
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade1.listen();

                    var tableGrade1 = new Table({
                        id: "tableGrade1",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List1",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorProdutos],
                        fieldDepende: validatorProdutos,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade1.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade1.onValid(data);
                                    validatorGrade1.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade1.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade1.onValid(data);
                                    validatorGrade1.update();
                                });
                                $("#modalGrade1").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade1 = new Modal("Grade",
                        byId("linkButtonModalGrade1"),
                        byId("inputCodigoGrade1"),
                        tableGrade1
                    ).listen();

                    // grade2
                    var validatorGrade2 = new Validator({
                        field: "inputCodigoGrade2",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade2",
                        fieldSearch: "CodigoGrade2",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 2.",
                        route: "Empresarial/F4Produto/GetItemGrade2",
                        pendency: [validatorGrade1, validatorProdutos],
                        onValid: function (data) {
                            validatorGrade2.setChange(true);
                            validatorGrade2.setValues(data["Codigo"], " - " + data["Descricao"]);

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade3) {
                                validatorGrade3.focus();
                            }
                        },
                        onInvalid: function (data) {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear({ error: true });
                            validatorGrade2.focus();
                        },
                        onEmpty: function () {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade2.listen();

                    var tableGrade2 = new Table({
                        id: "tableGrade2",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List2",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorGrade1, validatorProdutos],
                        fieldDepende: validatorGrade1,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade2.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade2.onValid(data);
                                    validatorGrade2.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade2.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade2.onValid(data);
                                    validatorGrade2.update();
                                });
                                $("#modalGrade2").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade2 = new Modal("Grade",
                        byId("linkButtonModalGrade2"),
                        byId("inputCodigoGrade2"),
                        tableGrade2
                    ).listen();

                    // grade3
                    var validatorGrade3 = new Validator({
                        field: "inputCodigoGrade3",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade3",
                        fieldSearch: "CodigoGrade3",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 3.",
                        route: "Empresarial/F4Produto/GetItemGrade3",
                        pendency: [validatorGrade2, validatorGrade1, validatorProdutos],
                        onValid: function (data) {
                            validatorGrade3.setChange(true);
                            validatorGrade3.setValues(data["Codigo"], " - " + data["Descricao"]);
                        },
                        onInvalid: function (data) {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear({ error: true });
                            validatorGrade3.focus();
                        },
                        onEmpty: function () {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade3.listen();

                    var tableGrade3 = new Table({
                        id: "tableGrade3",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List3",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorGrade2, validatorGrade1, validatorProdutos],
                        fieldDepende: validatorGrade2,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade3.getSelectedData();
                                validatorGrade3.onValid(data);
                                validatorGrade3.update();
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade3.getSelectedData();
                                validatorGrade3.onValid(data);
                                validatorGrade3.update();
                                $("#modalGrade3").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade3 = new Modal("Grade",
                        byId("linkButtonModalGrade3"),
                        byId("inputCodigoGrade3"),
                        tableGrade3
                    ).listen();

                    listenToggleProdutoGradesF4();

                    // o modalGrupoContasProduto tem que criar por ultimo porque é passado os validator grades como parametro
                    var modalGrupoContasProduto = new ModalGrupoContas({
                        id: "Produto",
                        tipo: "Produto",
                        validatorInput: [validatorProdutos, validatorGrade1, validatorGrade2, validatorGrade3],
                    });

                    // tipo de local
                    $("#inputTipoLocalEstoqueProprio").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", true);
                        }
                    });

                    $("#inputTipoLocalEstoqueEmPoderDeTerceiros").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueProprio")) {
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", true);
                        }
                    });

                    $("#inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa").on("click", function () {
                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                            setChecked("inputTipoLocalEstoqueProprio", true);
                        }
                    });

                    var inputNomesDosLocais = $("#inputNomesDosLocais").kendoDropDownList({
                        dataSource: [
                            { Value: "1", Text: "Estocagem" },
                            { Value: "2", Text: "Armazenagem" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "1"
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Estoque/Relatorios/GetModelosMovimentos"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("est_rel_movimentos");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                        setChecked("inputTipoLocalEstoqueProprio", true);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", false);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", false);
                    } else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);

                        validatorProdutos.setGrupoContas(inputs.GrupoContasProdutos);
                        if (inputs.GrupoContasProdutos.length > 1) {
                            validatorProdutos.setVarios(true, "Produto");
                        }
                        else {
                            validatorProdutos.setVarios(false, "Produto", [validatorGrade1, validatorGrade2, validatorGrade3]);
                        }

                        setChecked("inputListarSubordinados", inputs.ListarSubordinados);
                        setChecked("inputTipoLocalEstoqueProprio", inputs.TipoLocalEstoqueProprio);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", inputs.TipoLocalEstoqueEmPoderDeTerceiros);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", inputs.TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa);
                        inputNomesDosLocais.data().kendoDropDownList.select(inputs.NomesDosLocais.toInt());
                    }

                    $("#buttonOK").on("click", function () {
                        var grupoContasProdutosSalva = [];
                        if (validatorProdutos.getVarios()) {
                            grupoContasProdutosSalva = validatorProdutos.getGrupoContas();
                        }
                        else {
                            var produto = {
                                Classificacao: validatorProdutos.PropertiesSpecifyField.Classificacao,
                                Codigo: validatorProdutos.getValue(),
                                Nome: validatorProdutos.getDescription(),
                                HaveGrade1: validatorProdutos.PropertiesSpecifyField.HaveGrade1,
                                HaveGrade2: validatorProdutos.PropertiesSpecifyField.HaveGrade2,
                                HaveGrade3: validatorProdutos.PropertiesSpecifyField.HaveGrade3,
                                CodigoGrade1: validatorGrade1.getValue(),
                                CodigoGrade2: validatorGrade2.getValue(),
                                CodigoGrade3: validatorGrade3.getValue(),
                                Grade1: validatorGrade1.getDescription().replace(" - ", ""),
                                Grade2: validatorGrade2.getDescription().replace(" - ", ""),
                                Grade3: validatorGrade3.getDescription().replace(" - ", "")
                            };
                            grupoContasProdutosSalva.push(produto);
                        }

                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            GrupoContasProdutos: grupoContasProdutosSalva,
                            ListarSubordinados: isChecked("inputListarSubordinados"),
                            TipoLocalEstoqueProprio: isChecked("inputTipoLocalEstoqueProprio"),
                            TipoLocalEstoqueEmPoderDeTerceiros: isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"),
                            TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa: isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa"),
                            NomesDosLocais: inputNomesDosLocais.val()
                        }
                        currentUser.setCustomData("est_rel_movimentos", JSON.stringify(inputs));

                        var grupoContasProdutosEnvia = [];
                        if (validatorProdutos.getVarios()) {
                            var lista = validatorProdutos.getGrupoContas()
                            for (var produtoAtual in lista) {
                                var produto = {
                                    Codigo: lista[produtoAtual].Codigo,
                                    CodigoGrade1: lista[produtoAtual].CodigoGrade1,
                                    CodigoGrade2: lista[produtoAtual].CodigoGrade2,
                                    CodigoGrade3: lista[produtoAtual].CodigoGrade3
                                };
                                grupoContasProdutosEnvia.push(produto);
                            }
                        }
                        else {
                            var produto = {
                                Codigo: validatorProdutos.getValue(),
                                CodigoGrade1: validatorGrade1.getValue(),
                                CodigoGrade2: validatorGrade2.getValue(),
                                CodigoGrade3: validatorGrade3.getValue()
                            };
                            grupoContasProdutosEnvia.push(produto);
                        }

                        window.open(window.baseUrl + "Estoque/Relatorios/GeraRelatorioMovimentos?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&GrupoContasProdutos=" + JSON.stringify(grupoContasProdutosEnvia)
                            + "&ListarSubordinados=" + isChecked("inputListarSubordinados")
                            + "&TipoLocalEstoqueProprio=" + isChecked("inputTipoLocalEstoqueProprio")
                            + "&TipoLocalEstoqueEmPoderDeTerceiros=" + isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros")
                            + "&TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa=" + isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")
                            + "&NomesDosLocais=" + getVal("inputNomesDosLocais")
                        );
                    });
                })(params);
            },

            RelatoriosPontoDeReposicao: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    // filial
                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ error: true });
                            validatorFilial.focus();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        "id": "tableFilial",
                        "msgDialog": true,
                        "route": window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $("#modalFilial").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Estoque/Relatorios/GetModelosPontoDeReposicao"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("est_rel_pontodefeposicao");
                    if (inputs === null || inputs === "") {
                        setFilialDefault(validatorFilial, true);
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        setVal("inputCodigoFilial", inputs.Filial);
                        setFilialDefault(validatorFilial, false);
                    }

                    $("#buttonOK").on("click", function () {
                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            Filial: getVal("inputCodigoFilial")
                        }
                        currentUser.setCustomData("est_rel_pontodefeposicao", JSON.stringify(inputs));

                        window.open(window.baseUrl + "Estoque/Relatorios/GeraRelatorioPontoDeReposicao?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&Filial=" + getVal("inputCodigoFilial")
                        );
                    });
                })(params);
            },

            RelatoriosRegistroEstoque: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");

                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputPeriodoInicial = new ValidatorDate({
                        idInput: "inputPeriodoInicial",
                        isEmptyValid: true
                    });

                    var inputPeriodoFinal = new ValidatorDate({
                        idInput: "inputPeriodoFinal",
                        compareGreater: "inputPeriodoInicial",
                        compareGreaterMsg: "Data inicial deve ser anterior a data final.",
                        isEmptyValid: true
                    });

                    // filial
                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ error: true });
                            validatorFilial.focus();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        "id": "tableFilial",
                        "msgDialog": true,
                        "route": window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        "columns": [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        "showFilter": true,
                        "onChange": function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                            };
                        },
                        "onDataBound": function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $("#modalFilial").modal("hide");
                            });
                        },
                        "dataSourceType": "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    // produto
                    var validatorProdutos = new Validator({
                        field: "inputCodigoProduto",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoProduto",
                        fieldSearch: "CodigoProduto",
                        v2: "v3",
                        linkButton: "linkButtonModalProdutos",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasProduto",
                        onPendencyMessage: "Deve ser informado o código do produto.",
                        route: "Empresarial/F4Produto/GetProdutoClasse",
                        onValid: function (data) {
                            validatorProdutos.setChange(true);
                            validatorProdutos.setValues(data["Codigo"], data["Nome"]);
                            validatorProdutos.PropertiesSpecifyField = {
                                Classificacao: data.Classificacao,
                                HaveGrade1: data.HaveGrade1,
                                HaveGrade2: data.HaveGrade2,
                                HaveGrade3: data.HaveGrade3
                            };

                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade1) {
                                validatorGrade1.enable();
                                validatorGrade1.focus();
                            } else {
                                $("#linkButtonModalProdutos").focus();
                            }

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade2)
                                validatorGrade2.enable();

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade3)
                                validatorGrade3.enable();
                        },
                        onInvalid: function (data) {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear({ error: true });
                            validatorProdutos.focus();
                            validatorGrade1.clear({ error: true, disable: true });
                            validatorGrade2.clear({ error: true, disable: true });
                            validatorGrade3.clear({ error: true, disable: true });
                            validatorProdutos.PropertiesSpecifyField = {};
                        },
                        onEmpty: function () {
                            validatorProdutos.setChange(true);
                            validatorProdutos.clear();
                            validatorGrade1.clear({ disable: true });
                            validatorGrade2.clear({ disable: true });
                            validatorGrade3.clear({ disable: true });
                            validatorProdutos.PropertiesSpecifyField = {};
                            $("#linkButtonModalProdutos").focus();
                        }
                    });
                    validatorProdutos.listen();

                    var tableProdutos = new Table({
                        id: "tableProdutos",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/GetProdutos",
                        showFilter: true,
                        columns: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Unidade", field: "Unidade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Preço", field: "ValorUnitario", width: 60, headerAttributes: { style: "color: black; text-align: rigtht;" }, attributes: { style: "text-align: rigtht;" } },
                            { title: "Classificação", field: "Classificacao", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = tableProdutos.getSelectedData(),
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                                $("#modalProdutos").modal("hide");
                            });
                        },
                        dataSourceType: "Filtered"
                    });

                    var modalProdutos = new Modal(
                        "Produtos",
                        byId("linkButtonModalProdutos"),
                        byId("inputCodigoProduto"),
                        tableProdutos,
                        null,
                        {
                            urlBuscaHierarquia: "Empresarial/F4Produto/GetProdutosHierarquia",
                            validatorInput: validatorProdutos, // o objeto modal precisa para depois setar a instancia dele, na propriedade "modal" do validator
                            showOpcaoExibir: true,
                            selectClass: true,
                            onDblClickGetItem: function (event, dados) {
                                // TODO: refatorar e colocar em uma rotina, pois sao 3 lugares para alterar: onclick-table, dblclick-table e dblclick-hierarquia
                                var data = dados,
                                    search = {};
                                search["CodigoProduto"] = data["Codigo"];
                                getJsonFromRoute("Empresarial/F4Produto/GetProdutoClasse", search).done(function (data) {
                                    validatorProdutos.onValid(data);
                                    validatorProdutos.update();
                                });
                                $("#modalProdutos").modal("hide");
                            }
                        }).listen();

                    // grades
                    var columnsGrade = [
                        { title: "Código", field: "Codigo", width: 45, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        { title: "Descrição", field: "Descricao", width: 64, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                    ];

                    // grade1
                    var validatorGrade1 = new Validator({
                        field: "inputCodigoGrade1",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade1",
                        fieldSearch: "CodigoGrade1",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 1.",
                        route: "Empresarial/F4Produto/GetItemGrade1",
                        pendency: [validatorProdutos],
                        onValid: function (data) {
                            validatorGrade1.setChange(true);
                            validatorGrade1.setValues(data["Codigo"], " - " + data["Descricao"]);

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade2) {
                                validatorGrade2.focus();
                            }
                        },
                        onInvalid: function (data) {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear({ error: true });
                            validatorGrade1.focus();
                        },
                        onEmpty: function () {
                            validatorGrade1.setChange(true);
                            validatorGrade1.clear();
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade1.listen();

                    var tableGrade1 = new Table({
                        id: "tableGrade1",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List1",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorProdutos],
                        fieldDepende: validatorProdutos,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade1.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade1.onValid(data);
                                    validatorGrade1.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade1.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade1.onValid(data);
                                    validatorGrade1.update();
                                });
                                $("#modalGrade1").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade1 = new Modal("Grade",
                        byId("linkButtonModalGrade1"),
                        byId("inputCodigoGrade1"),
                        tableGrade1
                    ).listen();

                    // grade2
                    var validatorGrade2 = new Validator({
                        field: "inputCodigoGrade2",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade2",
                        fieldSearch: "CodigoGrade2",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 2.",
                        route: "Empresarial/F4Produto/GetItemGrade2",
                        pendency: [validatorGrade1, validatorProdutos],
                        onValid: function (data) {
                            validatorGrade2.setChange(true);
                            validatorGrade2.setValues(data["Codigo"], " - " + data["Descricao"]);

                            if (validatorProdutos.PropertiesSpecifyField.HaveGrade3) {
                                validatorGrade3.focus();
                            }
                        },
                        onInvalid: function (data) {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear({ error: true });
                            validatorGrade2.focus();
                        },
                        onEmpty: function () {
                            validatorGrade2.setChange(true);
                            validatorGrade2.clear();
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade2.listen();

                    var tableGrade2 = new Table({
                        id: "tableGrade2",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List2",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorGrade1, validatorProdutos],
                        fieldDepende: validatorGrade1,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade2.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade2.onValid(data);
                                    validatorGrade2.update();
                                });
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade2.getSelectedData();
                                requestLeg(function () {
                                    validatorGrade2.onValid(data);
                                    validatorGrade2.update();
                                });
                                $("#modalGrade2").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade2 = new Modal("Grade",
                        byId("linkButtonModalGrade2"),
                        byId("inputCodigoGrade2"),
                        tableGrade2
                    ).listen();

                    // grade3
                    var validatorGrade3 = new Validator({
                        field: "inputCodigoGrade3",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoGrade3",
                        fieldSearch: "CodigoGrade3",
                        v2: "v3",
                        onPendencyMessage: "Deve ser informada a grade 3.",
                        route: "Empresarial/F4Produto/GetItemGrade3",
                        pendency: [validatorGrade2, validatorGrade1, validatorProdutos],
                        onValid: function (data) {
                            validatorGrade3.setChange(true);
                            validatorGrade3.setValues(data["Codigo"], " - " + data["Descricao"]);
                        },
                        onInvalid: function (data) {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear({ error: true });
                            validatorGrade3.focus();
                        },
                        onEmpty: function () {
                            validatorGrade3.setChange(true);
                            validatorGrade3.clear();
                        }
                    });
                    validatorGrade3.listen();

                    var tableGrade3 = new Table({
                        id: "tableGrade3",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Produto/List3",
                        showFilter: true,
                        columns: columnsGrade,
                        params: [validatorGrade2, validatorGrade1, validatorProdutos],
                        fieldDepende: validatorGrade2,
                        onChange: function () {
                            $("#inputF4ModalOk" + this.id).on("click", function () {
                                var data = tableGrade3.getSelectedData();
                                validatorGrade3.onValid(data);
                                validatorGrade3.update();
                            });
                        },
                        onDataBound: function () {
                            $("#" + this.id + " table  tr").on("dblclick", function () {
                                var data = tableGrade3.getSelectedData();
                                validatorGrade3.onValid(data);
                                validatorGrade3.update();
                                $("#modalGrade3").modal("hide");
                            });
                        },
                        dataSourceType: "Parameter"
                    });

                    var modalGrade3 = new Modal("Grade",
                        byId("linkButtonModalGrade3"),
                        byId("inputCodigoGrade3"),
                        tableGrade3
                    ).listen();

                    listenToggleProdutoGradesF4();

                    // o modalGrupoContasProduto tem que criar por ultimo porque é passado os validator grades como parametro
                    var modalGrupoContasProduto = new ModalGrupoContas({
                        id: "Produto",
                        tipo: "Produto",
                        validatorInput: [validatorProdutos, validatorGrade1, validatorGrade2, validatorGrade3],
                    });

                    // tipo operacao
                    var validatorTipoOperacao = new ValidatorDropDown({
                        abrev: "TipoOperacao",
                        route: "Estoque/Relatorios/GetListTipoOperacao",
                        ModalGrupoContas: true,
                        nameFieldDescription: "TipoOperacao",
                        columnsModalGrupoContas: [{ field: "TipoOperacao", title: "Tipo de Operação", width: 150, headerAttributes: { style: "color: black; text-align: Left;" }, attributes: { style: "text-align: Left;" } }]
                    });

                    // tipo de local
                    $("#inputTipoLocalEstoqueProprio").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", true);
                        }
                    });

                    $("#inputTipoLocalEstoqueEmPoderDeTerceiros").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueProprio")) {
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", true);
                        }
                    });

                    $("#inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa").on("click", function () {
                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                            setChecked("inputTipoLocalEstoqueProprio", true);
                        }
                    });

                    // tipo de relatorio
                    var inputTipoDeRelatorio = $("#inputTipoDeRelatorio").kendoDropDownList({
                        dataSource: [
                            { Value: "0", Text: "Sintético" },
                            { Value: "1", Text: "Analítico" }
                        ],
                        dataTextField: "Text",
                        dataValueField: "Value",
                        value: "0"
                    });

                    var inputRelatorio = new DropDown({
                        "id": "inputRelatorio",
                        "route": "Estoque/Relatorios/GetModelosRegistroEstoque"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);

                    var inputs = currentUser.getCustomData("est_rel_registroestoque");
                    if (inputs === null || inputs === "") {
                        inputPeriodoInicial.setValue(getDateNowDDMMYYYY());
                        inputPeriodoFinal.setValue(getDateNowDDMMYYYY());
                        setFilialDefault(validatorFilial, true);
                        setChecked("inputTipoLocalEstoqueProprio", true);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", false);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", false);
                    }
                    else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        inputPeriodoInicial.setValue(inputs.PeriodoInicial);
                        inputPeriodoFinal.setValue(inputs.PeriodoFinal);
                        validatorFilial.setValue(inputs.Filial);
                        setFilialDefault(validatorFilial, false);

                        validatorProdutos.setGrupoContas(inputs.GrupoContasProdutos);
                        if (inputs.GrupoContasProdutos.length > 1) {
                            validatorProdutos.setVarios(true, "Produto");
                        }
                        else {
                            validatorProdutos.setVarios(false, "Produto", [validatorGrade1, validatorGrade2, validatorGrade3]);
                        }

                        setChecked("inputConsolidarGradesDoProduto", inputs.ConsolidarGradesDoProduto);

                        validatorTipoOperacao.setGrupoContas(inputs.TipoOperacao);
                        if (inputs.TipoOperacao.length > 1) {
                            validatorTipoOperacao.setVarios(true);
                        }
                        else {
                            validatorTipoOperacao.setVarios(false);
                        }

                        setChecked("inputTipoLocalEstoqueProprio", inputs.TipoLocalEstoqueProprio);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", inputs.TipoLocalEstoqueEmPoderDeTerceiros);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", inputs.TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa);
                        inputTipoDeRelatorio.data().kendoDropDownList.select(inputs.TipoDeRelatorio.toInt());
                    }

                    $("#buttonOK").on("click", function () {
                        var grupoContasProdutosSalva = [];
                        if (validatorProdutos.getVarios()) {
                            grupoContasProdutosSalva = validatorProdutos.getGrupoContas();
                        }
                        else {
                            var produto = {
                                Classificacao: validatorProdutos.PropertiesSpecifyField.Classificacao,
                                Codigo: validatorProdutos.getValue(),
                                Nome: validatorProdutos.getDescription(),
                                HaveGrade1: validatorProdutos.PropertiesSpecifyField.HaveGrade1,
                                HaveGrade2: validatorProdutos.PropertiesSpecifyField.HaveGrade2,
                                HaveGrade3: validatorProdutos.PropertiesSpecifyField.HaveGrade3,
                                CodigoGrade1: validatorGrade1.getValue(),
                                CodigoGrade2: validatorGrade2.getValue(),
                                CodigoGrade3: validatorGrade3.getValue(),
                                Grade1: validatorGrade1.getDescription().replace(" - ", ""),
                                Grade2: validatorGrade2.getDescription().replace(" - ", ""),
                                Grade3: validatorGrade3.getDescription().replace(" - ", "")
                            };
                            grupoContasProdutosSalva.push(produto);
                        }

                        var grupoContasTipoOperacaoSalva = [];
                        if (validatorTipoOperacao.getVarios()) {
                            grupoContasTipoOperacaoSalva = validatorTipoOperacao.getGrupoContas();
                        }
                        else {
                            var tipoOperacao = {
                                id: validatorTipoOperacao.getValue(),
                            };
                            grupoContasTipoOperacaoSalva.push(tipoOperacao);
                        }

                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            PeriodoInicial: inputPeriodoInicial.getValue(),
                            PeriodoFinal: inputPeriodoFinal.getValue(),
                            Filial: getVal("inputCodigoFilial"),
                            GrupoContasProdutos: grupoContasProdutosSalva,
                            ConsolidarGradesDoProduto: isChecked("inputConsolidarGradesDoProduto"),
                            TipoOperacao: grupoContasTipoOperacaoSalva,
                            TipoLocalEstoqueProprio: isChecked("inputTipoLocalEstoqueProprio"),
                            TipoLocalEstoqueEmPoderDeTerceiros: isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"),
                            TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa: isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa"),
                            TipoDeRelatorio: inputTipoDeRelatorio.val()
                        }
                        currentUser.setCustomData("est_rel_registroestoque", JSON.stringify(inputs));

                        var grupoContasProdutosEnvia = [];
                        if (validatorProdutos.getVarios()) {
                            var lista = validatorProdutos.getGrupoContas()
                            for (var produtoAtual in lista) {
                                var produto = {
                                    Codigo: lista[produtoAtual].Codigo,
                                    CodigoGrade1: lista[produtoAtual].CodigoGrade1,
                                    CodigoGrade2: lista[produtoAtual].CodigoGrade2,
                                    CodigoGrade3: lista[produtoAtual].CodigoGrade3
                                };
                                grupoContasProdutosEnvia.push(produto);
                            }
                        }
                        else {
                            var produto = {
                                Codigo: validatorProdutos.getValue(),
                                CodigoGrade1: validatorGrade1.getValue(),
                                CodigoGrade2: validatorGrade2.getValue(),
                                CodigoGrade3: validatorGrade3.getValue()
                            };
                            grupoContasProdutosEnvia.push(produto);
                        }

                        var grupoContasTipoOperacaoEnvia = "";
                        if (validatorTipoOperacao.getVarios()) {
                            grupoContasTipoOperacaoEnvia = validatorTipoOperacao.getGrupoContasString();
                        }
                        else {
                            grupoContasTipoOperacaoEnvia = validatorTipoOperacao.getValue();
                        }

                        window.open(window.baseUrl + "Estoque/Relatorios/GeraRelatorioRegistroEstoque?"
                            + "Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataInicial=" + getVal("inputPeriodoInicial")
                            + "&DataFinal=" + getVal("inputPeriodoFinal")
                            + "&Filial=" + getVal("inputCodigoFilial")
                            + "&GrupoContasProdutos=" + JSON.stringify(grupoContasProdutosEnvia)
                            + "&ConsolidarGradesDoProduto=" + isChecked("inputConsolidarGradesDoProduto")
                            + "&TipoOperacao=" + grupoContasTipoOperacaoEnvia
                            + "&TipoLocalEstoqueProprio=" + isChecked("inputTipoLocalEstoqueProprio")
                            + "&TipoLocalEstoqueEmPoderDeTerceiros=" + isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros")
                            + "&TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa=" + isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")
                            + "&TipoDeRelatorio=" + getVal("inputTipoDeRelatorio")
                        );
                    });
                })(params);
            },

            RelatoriosSaldoDoEstoque: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    var inputDataFinal = new ValidatorDate({
                        idInput: "inputDataFinal",
                        isEmptyValid: false
                    });

                    var validatorFilial = new Validator({
                        field: "CodigoFilial",
                        msgDialog: true,
                        onPendencyMessage: "Deve ser informado o código da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        v2: true,
                        onValid: function (data) {
                            setVal("inputCodigoFilial", data["Codigo"]);
                            setHtml("descriptionCodigoFilial", data["Nome"]);
                        },
                        onInvalid: function () {
                            validatorFilial.clear({ error: true });
                            validatorFilial.focus();
                        },
                        onEmpty: function () {
                            validatorFilial.clear();
                        }
                    });
                    validatorFilial.listen();

                    var tableFiliais = new Table({
                        id: "tableFilial",
                        msgDialog: true,
                        route: window.baseUrl + "Empresarial/F4Filial/GetFiliais",
                        columns: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        showFilter: true,
                        onChange: function () {
                            var ok = document.getElementById("inputF4ModalOk" + this.id);
                            ok.onclick = function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                            };
                        },
                        onDataBound: function () {
                            $("#tableFilial table tr").on("dblclick", function () {
                                var data = tableFiliais.getSelectedData();
                                validatorFilial.onValid(data);
                                validatorFilial.update();
                                $("#modalFilial").modal("hide");
                            });
                        },
                        dataSourceType: "Filtered"
                    });
                    var linkFiliais = document.getElementById("linkButtonModalFiliais");
                    var inputFiliais = document.getElementById("inputCodigoFilial");
                    var modalFiliais = new Modal("Filiais", linkFiliais, inputFiliais, tableFiliais);
                    modalFiliais.listen();

                    var validatorLocais = new Validator({
                        field: "inputCodigoLocal",
                        msgDialog: true,
                        fieldDescriptionId: "descriptionCodigoLocal",
                        fieldSearch: "CodigoLocal",
                        v2: true,
                        ModalGrupoContas: true,
                        grupoContasFieldNome: "Local",
                        linkButton: "linkButtonModalLocais",
                        linkButtonModalGrupoContas: "linkButtonModalGrupoContasLocais",
                        onPendencyMessage: 'Deve ser informado o código do local de armazenagem.',
                        route: 'Estoque/F4LocalArmazenagem/GetLocalArmazenagem',
                        onValid: function (data) {
                            validatorLocais.PropertiesSpecifyField = data;
                            document.getElementById("inputCodigoLocal").value = data.Codigo;
                            document.getElementById("descriptionCodigoLocal").innerHTML = data.Nome;
                        },
                        onInvalid: function (data) {
                            validatorLocais.PropertiesSpecifyField = {};
                            validatorLocais.clear();
                            validatorLocais.focusError();
                        },
                        onEmpty: function () {
                            validatorLocais.PropertiesSpecifyField = {};
                            validatorLocais.clear();
                        }
                    });
                    validatorLocais.listen();

                    var tableLocais = new Table({
                        id: 'tableLocal',
                        msgDialog: true,
                        idModalHideShow: "filtroPedidosModal",
                        route: window.baseUrl + "Estoque/F4LocalArmazenagem/GetLocaisArmazenagem",
                        showFilter: true,
                        columns: [
                            { title: "Código", field: "Codigo", width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Local", field: "Nome", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Id", field: "Id", hidden: true }
                        ],
                        onChange: function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var local = tableLocais.getSelectedData();
                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocais.PropertiesSpecifyField = local;
                                $('#modalLocal').modal('hide');
                            };
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalLocal').modal('hide');
                            };
                        },
                        onDataBound: function () {
                            $('#tableLocal table tr').on('dblclick', function () {
                                var local = tableLocais.getSelectedData();
                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocais.update();
                                validatorLocais.PropertiesSpecifyField = local;
                                $('#modalLocal').modal('hide');
                            });
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalLocal').modal('hide');
                            };
                        },
                        dataSourceType: "Filtered"
                    });
                    var linkButtonModalLocais = document.getElementById('linkButtonModalLocais');
                    var inputLocais = document.getElementById('inputCodigoLocal');

                    var options = {
                        urlBuscaHierarquia: "Estoque/F4LocalArmazenagem/GetLocaisArmazenagem",
                        showOpcaoExibir: true,
                        allowContaTitulo: true,
                        exibirHierarquiaParams: {
                            ClassificacaoNoPai: "",
                            CodFilial: getVal("inputCodigoFilial"),
                            BuscaPorHierarquia: true
                        },
                        onDblClickGetItem: function (event, dados) {
                            validatorLocais.setChange(true);

                            getJsonFromRoute('Estoque/F4LocalArmazenagem/GetLocalArmazenagem', { CodigoLocal: dados['Codigo'] }).done(function (local) {
                                if (local.IsAlert)
                                    throw new Error(local.Message);

                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocais.update();
                                validatorLocais.PropertiesSpecifyField = local;
                            });

                            $('#modalLocal').modal('hide');
                        },
                        validatorInput: validatorLocais
                    };

                    var modalLocais = new Modal('Locais', linkButtonModalLocais, inputLocais, tableLocais, null, options);
                    modalLocais.listen();

                    var modalGrupoContasLocais = new ModalGrupoContas({
                        id: "Locais",
                        modalHierarquia: modalLocais,
                        validatorInput: validatorLocais,
                        validatorConta: {
                            fieldSearch: "CodigoLocal",
                            onPendencyMessage: "Deve ser informado o código do local.",
                            route: "Estoque/F4LocalArmazenagem/GetLocalArmazenagem",
                            fieldNome: "Nome"
                        },
                        tableConta: {
                            route: window.baseUrl + "Estoque/F4LocalArmazenagem/GetLocaisArmazenagem",
                            showFilter: true,
                            columns: [
                                { title: "Código", field: "Codigo", width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Classificação", field: "Classificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Local", field: "Nome", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Id", field: "Id", hidden: true }
                            ],
                        },
                    });

                    $("#inputTipoLocalEstoqueProprio").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"))
                            $("#inputTipoLocalEstoqueProprio").attr("checked", true);
                    });

                    $("#inputTipoLocalEstoqueEmPoderDeTerceiros").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueProprio"))
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", true);
                    });

                    $("#inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa").on("click", function () {
                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                            setChecked("inputTipoLocalEstoqueProprio", true);
                        }
                    });

                    var inputRelatorio = new DropDown({
                        id: "inputRelatorio",
                        route: "Estoque/Relatorios/GetModelosSaldoDoEstoque"
                    });
                    inputRelatorio.make();

                    currentUser.update(params.User);
                    var inputs = currentUser.getCustomData("est_rel_saldodoestoque");

                    if (inputs === null || inputs === "") {
                        inputDataFinal.setValue(getDateNowDDMMYYYY());
                        setFilialDefault(validatorFilial, true);
                        setChecked("inputTipoLocalEstoqueProprio", true);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", false);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", false);

                        $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                        $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                        setChecked("inputTipoLocalEstoqueProprio", true);
                    } else {
                        inputs = JSON.parse(inputs);
                        inputRelatorio.set(inputs.Relatorio);
                        if (inputs.DataFinal) inputDataFinal.setValue(inputs.DataFinal);
                        validatorFilial.setValue(inputs.Filial);
                        setFilialDefault(validatorFilial, false);
                        validatorLocais.setGrupoContasOuConta(inputs.LocaisArmazenagem);

                        setChecked("inputTipoLocalEstoqueProprio", inputs.TipoLocalEstoqueProprio);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", inputs.TipoLocalEstoqueEmPoderDeTerceiros);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", inputs.TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa);

                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                            setChecked("inputTipoLocalEstoqueProprio", true);
                        }
                    }

                    $("#buttonOK").on("click", function () {
                        if (inputDataFinal.isEmpty) {
                            u.dialogOk("O campo \"Data Final\" deve ser informado.", null, true, function () {
                                inputDataFinal.focusError();
                            }, alertBehavior.warning);
                            return;
                        }

                        inputs = {
                            Relatorio: inputRelatorio.get(),
                            DataFinal: inputDataFinal.getValue(),
                            Filial: getVal("inputCodigoFilial"),
                            LocaisArmazenagem: validatorLocais.getGrupoContasOuConta(),
                            TipoLocalEstoqueProprio: isChecked("inputTipoLocalEstoqueProprio"),
                            TipoLocalEstoqueEmPoderDeTerceiros: isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"),
                            TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa: isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")
                        }

                        currentUser.setCustomData("est_rel_saldodoestoque", JSON.stringify(inputs));

                        window.open(
                            window.baseUrl
                            + "Estoque/Relatorios/GeraRelatorioSaldoDoEstoque"
                            + "?Relatorio=" + inputRelatorio.dropDown.dataItem().Text
                            + "&DataFinal=" + getVal("inputDataFinal")
                            + "&CodigoFilial=" + getVal("inputCodigoFilial")
                            + "&LocaisArmazenagem=" + validatorLocais.getGrupoContasOuConta()
                            + "&TipoLocalEstoqueProprio=" + isChecked("inputTipoLocalEstoqueProprio")
                            + "&TipoLocalEstoqueEmPoderDeTerceiros=" + isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros")
                            + "&TipoLocalEstoqueDeTerceirosEmPoderDaEmpresa=" + isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")
                        );
                    });
                })(params);
            },

            ConsultasSaldoPorLocal: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    // filial
                    var validatorLookupFilial = new ValidatorLookup({
                        abrev: "CodigoFilial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        routeTable: "Empresarial/F4Filial/GetFiliais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais",
                        maxLength: 5
                    });

                    // local
                    var validatorLocal = new Validator({
                        field: 'CodigoLocal',
                        v2: true,
                        onPendencyMessage: 'Deve ser informado o código do local de armazenagem.',
                        route: 'Estoque/F4LocalArmazenagem/GetLocalArmazenagem',
                        onValid: function (data) {
                            validatorLocal.PropertiesSpecifyField = data;
                            document.getElementById("inputCodigoLocal").value = data.Codigo;
                            document.getElementById("descriptionCodigoLocal").innerHTML = data.Nome;
                            doConsulta();
                        },
                        onInvalid: function (data) {
                            validatorLocal.PropertiesSpecifyField = {};
                            validatorLocal.clear();
                            validatorLocal.focusError();
                        },
                        onEmpty: function () {
                            validatorLocal.PropertiesSpecifyField = {};
                            validatorLocal.clear();

                            if (isFieldEnabled("inputCodigoFilial"))
                                validatorLookupFilial.clear();

                            validatorLookupProduto.clear();

                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridSaldoPorLocal").data("kendoGrid").setDataSource(data);
                        }
                    });
                    validatorLocal.listen();

                    var tableLocais = new Table({
                        id: 'tableLocal',
                        route: window.baseUrl + "Estoque/F4LocalArmazenagem/GetLocaisArmazenagem",
                        showFilter: true,
                        columns: [
                            { title: "Código", field: "Codigo", width: 50, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Local", field: "Nome", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Id", field: "Id", hidden: true }
                        ],
                        onChange: function () {
                            "use strict";
                            var ok = document.getElementById('inputF4ModalOk' + this.id);
                            ok.onclick = function () {
                                var local = tableLocais.getSelectedData();
                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocal.PropertiesSpecifyField = local;
                                $('#modalLocal').modal('hide');
                                doConsulta();
                            };
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalLocal').modal('hide');
                            };
                        },
                        onDataBound: function () {
                            $('#tableLocal table tr').on('dblclick', function () {
                                var local = tableLocais.getSelectedData();
                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocal.update();
                                validatorLocal.PropertiesSpecifyField = local;
                                $('#modalLocal').modal('hide');
                                doConsulta();
                            });
                            var cancelar = document.getElementById('inputF4ModalCancelar');
                            cancelar.onclick = function () {
                                $('#modalLocal').modal('hide');
                            };
                        },
                        dataSourceType: "Filtered"
                    });
                    var linkButtonModalLocais = document.getElementById('linkButtonModalLocais');
                    var inputLocais = document.getElementById('inputCodigoLocal');

                    var options = {
                        urlBuscaHierarquia: "Estoque/F4LocalArmazenagem/GetLocaisArmazenagem",
                        showOpcaoExibir: true,
                        allowContaTitulo: true,
                        exibirHierarquiaParams: {
                            ClassificacaoNoPai: "",
                            CodFilial: getVal("inputCodigoFilial"),
                            BuscaPorHierarquia: true
                        },
                        onDblClickGetItem: function (event, dados) {
                            validatorLocal.setChange(true);

                            getJsonFromRoute('Estoque/F4LocalArmazenagem/GetLocalArmazenagem', { CodigoLocal: dados['Codigo'] }).done(function (local) {
                                if (local.IsAlert)
                                    throw new Error(local.Message);

                                document.getElementById("inputCodigoLocal").value = local.Codigo;
                                document.getElementById("descriptionCodigoLocal").innerHTML = local.Nome;
                                validatorLocal.update();
                                validatorLocal.PropertiesSpecifyField = local;
                                doConsulta();
                            });

                            $('#modalLocal').modal('hide');
                        },
                        validatorInput: validatorLocal
                    };

                    var modalLocais = new Modal('Locais', linkButtonModalLocais, inputLocais, tableLocais, null, options);
                    modalLocais.listen();

                    // produto
                    var validatorLookupProduto = new ValidatorLookupProduto({
                        abrev: "",
                        allowContaTitulo: true,
                        onValid: function (data) {
                            doConsulta();
                        },
                        onInvalid: function () {
                            validatorLookupProduto.clear();
                            validatorLookupProduto.focusError();
                        },
                        onEmpty: function () {
                            validatorLookupProduto.focusError();
                            doConsulta();
                        }
                    });

                    // estoque proprio
                    $("#inputTipoLocalEstoqueProprio").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"))
                            $("#inputTipoLocalEstoqueProprio").attr("checked", true);

                        doConsulta();
                    });

                    // estoque em poder de terceiros
                    $("#inputTipoLocalEstoqueEmPoderDeTerceiros").on("click", function () {
                        if (!isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa") && !isChecked("inputTipoLocalEstoqueProprio"))
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", true);

                        doConsulta();
                    });

                    // estoque de terceiros em poder da empresa
                    $("#inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa").on("click", function () {
                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                            setChecked("inputTipoLocalEstoqueProprio", true);
                        }

                        doConsulta();
                    });

                    // motrar protudos com saldo igual a zero
                    $("#inputMostrarProdutosSaldoZero").on("click", function () {
                        doConsulta();
                    });

                    // grid
                    var gridSaldoPorLocal = new Table({
                        id: "gridSaldoPorLocal",
                        pageable: false,
                        sortable: false,
                        columns: [
                            { field: "Local.Codigo", title: "Cód. Local", width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Local.Classificacao", title: "Class. Local", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Local.Nome", title: "Nome Local", width: 125, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "CodigoProduto", title: "Cód. Produto", width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "ClassificacaoProduto", title: "Class. Produto", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "NomeProduto", title: "Nome Produto", width: 125, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "QuantidadeTotal", title: "Qtde. Total", width: 75, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } }
                        ],
                        dataSourceType: "Object"
                    });
                    gridSaldoPorLocal.make();
                    $("#gridSaldoPorLocal .k-grid-content").height(300);

                    // seta filial padrao
                    function setFilialDefault() {
                        request(
                            "Empresarial/F4Filial/GetFilialPadrao",
                            null,
                            function (data) {
                                validatorLookupFilial.setValues(data.Codigo, data.Nome);

                                if (data.CpfCnpj === "")
                                    validatorLookupFilial.enable();
                                else
                                    validatorLookupFilial.disable();
                            },
                            function () {
                                clearAll();
                            }
                        );
                    }

                    // limpa campos
                    function clearAll() {
                        if (isFieldEnabled("inputCodigoFilial"))
                            validatorLookupFilial.clear();

                        validatorLocal.clear();
                        validatorLookupProduto.clear();

                        setChecked("inputTipoLocalEstoqueProprio", true);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", false);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", false);

                        $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                        $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                        $("#inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa").removeAttr("disabled");

                        var data = new kendo.data.DataSource({ data: [] });
                        $("#gridSaldoPorLocal").data("kendoGrid").setDataSource(data);
                        setHtml("spanDataConsulta", "");
                    }

                    // consulta
                    function doConsulta() {
                        if (getVal("inputCodigoLocal") === "" && getVal("inputCodigoProduto") === "") {
                            var data = new kendo.data.DataSource({ data: [] });
                            $("#gridSaldoPorLocal").data("kendoGrid").setDataSource(data);
                            setHtml("spanDataConsulta", "");
                        } else {
                            var search = {
                                CodigoFilial: getVal("inputCodigoFilial"),
                                CodigoLocal: getVal("inputCodigoLocal"),
                                CodigoProduto: getVal("inputCodigoProduto"),
                                CodigoItemGrade1: getVal("inputCodigoGrade1"),
                                CodigoItemGrade2: getVal("inputCodigoGrade2"),
                                CodigoItemGrade3: getVal("inputCodigoGrade3"),
                                IsEp: isChecked("inputTipoLocalEstoqueProprio"),
                                IsEpt: isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"),
                                IsEtpe: isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa"),
                                MostrarProdutosSaldoZero: isChecked("inputMostrarProdutosSaldoZero")
                            };
                            request2(
                                "Estoque/Consultas/GetSaldoPorLocal",
                                search,
                                function (listaSaldos) {
                                    var data = new kendo.data.DataSource({ data: [] });

                                    for (var atual in listaSaldos) {
                                        var local = {
                                            Codigo: listaSaldos[atual].Local.Codigo,
                                            Classificacao: listaSaldos[atual].Local.Classificacao,
                                            Nome: listaSaldos[atual].Local.Nome
                                        };

                                        data.options.data.push({
                                            Local: local,
                                            CodigoProduto: listaSaldos[atual].CodigoProduto,
                                            ClassificacaoProduto: listaSaldos[atual].ClassificacaoProduto,
                                            NomeProduto: listaSaldos[atual].NomeProduto,
                                            QuantidadeTotal: listaSaldos[atual].QuantidadeTotal
                                        });
                                    }

                                    $("#gridSaldoPorLocal").data("kendoGrid").setDataSource(data);
                                    setHtml("spanDataConsulta", getCurrentDateHour());

                                    inputs = {
                                        Filial: validatorLookupFilial.getValue(),
                                        FilialDesc: validatorLookupFilial.getDescription(),
                                        Local: validatorLocal.getValue(),
                                        LocalDesc: validatorLocal.getDescription(),
                                        Produto: validatorLookupProduto.getProdutoGrades(),
                                        IsEp: isChecked("inputTipoLocalEstoqueProprio"),
                                        IsEpt: isChecked("inputTipoLocalEstoqueEmPoderDeTerceiros"),
                                        IsEtpe: isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa"),
                                        MostrarProdutosSaldoZero: isChecked("inputMostrarProdutosSaldoZero")
                                    };
                                    currentUser.setCustomData("est_con_saldo_local", JSON.stringify(inputs));
                                },
                                null,
                                true
                            );
                        }
                    }

                    // load
                    clearAll();
                    setFilialDefault();

                    var inputs = currentUser.getCustomData("est_con_saldo_local");
                    if (inputs === null || inputs === "") {
                        $("#inputCodigoLocal").focus();
                    } else {
                        inputs = JSON.parse(inputs);
                        validatorLookupFilial.setValues(inputs.Filial, inputs.FilialDesc);
                        validatorLocal.setValues(inputs.Local, inputs.LocalDesc);
                        validatorLookupProduto.setProdutoGrades(inputs.Produto);
                        setChecked("inputTipoLocalEstoqueProprio", inputs.IsEp);
                        setChecked("inputTipoLocalEstoqueEmPoderDeTerceiros", inputs.IsEpt);
                        setChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa", inputs.IsEtpe);
                        setChecked("inputMostrarProdutosSaldoZero", inputs.MostrarProdutosSaldoZero);

                        if (isChecked("inputTipoLocalEstoqueDeTerceirosEmPoderDaEmpresa")) {
                            $("#inputTipoLocalEstoqueProprio").attr("checked", false);
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("checked", false);
                            $("#inputTipoLocalEstoqueProprio").attr("disabled", "disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").attr("disabled", "disabled");
                        } else {
                            $("#inputTipoLocalEstoqueProprio").removeAttr("disabled");
                            $("#inputTipoLocalEstoqueEmPoderDeTerceiros").removeAttr("disabled");
                        }

                        doConsulta();
                    }

                })(params);
            }
        };
    })();

    Assistec.Manager = (function () {
        return {
            MovimentosAssistenciasTecnicas: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    var gridAssistenciasTecnicas = new Table({
                        id: "gridAssistenciasTecnicas",
                        msgDialog: true,
                        route: window.baseUrl + "Assistec/Movimentos/GetAssistenciasTecnicas",
                        dataSourceType: "Filtered",
                        columns: [
                            { field: "Chave", title: "Chave", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Numero", title: "Número", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "DataAbertura", title: "Data Abertura", width: 80, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, format: "{0:dd/MM/yyyy}" },
                            { field: "Cliente", title: "Cliente", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Situacao", title: "Situação", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        pageable: {
                            refresh: true,
                            pageSizes: [10, 20, 30, 40, 50],
                            buttonCount: 5
                        },
                        toolbar:
                            "<span style='float: left; width: NaN;'>" +
                            "    <span style='font-size: large; font-weight: 800; text-align: center;' id='tableTitle'>Assistências Técnicas</span>" +
                            "</span>" +
                            "<span style='float: right' style='width: 60px;'>" +
                            "    <button id='buttonGridFilter' type='button' class='btn btn-small btn-filtro'>" +
                            "        <span class='k-icon k-i-funnel'></span> Fitro" +
                            "    </button>" +
                            "    <button id='buttonGridNew' type='button' class='btn btn-small btn-filtro' disabled>" +
                            "        <span class='k-icon k-i-plus'></span>Novo" +
                            "    </button>" +
                            "</span>",
                        onChange: function () {
                            "use strict";
                            var self = this;
                            var data = self.getSelectedData();
                            window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica?Id={0}&DataEmissao={1}".format(data.Id, data.DataAbertura);
                        }
                    });
                    gridAssistenciasTecnicas.make();
                    gridAssistenciasTecnicas.listen();

                    if (params.PodeIncluirNovaAssistencia) {
                        u.enable("buttonGridNew");
                        $("#buttonGridNew").addClass("btn-filtro");
                    }
                    else {
                        u.disable("buttonGridNew");
                        $("#buttonGridNew").removeClass("btn-filtro");
                    }

                    $("#buttonGridNew").click(function () {
                        window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica";
                    });

                    $("#buttonGridFilter").click(function () {
                        loadFilters(false);
                        $("#modalFilters").modal("show");
                        setDefaultFieldFocusFilters();
                    });

                    //
                    // filter
                    //

                    // chave inicial
                    var inputFilterChaveInicial = new ValidatorMask({
                        idInput: "inputFilterChaveInicial",
                        mask: "chave",
                        onChange: function () {
                            if (inputFilterChaveInicial.getValue() && !inputFilterChaveFinal.getValue()) {
                                inputFilterChaveFinal.setValue(inputFilterChaveInicial.getValue());
                            }
                        }
                    });

                    // chave final
                    var inputFilterChaveFinal = new ValidatorMask({
                        idInput: "inputFilterChaveFinal",
                        mask: "chave"
                    });

                    // data inicial
                    var inputFilterDataInicial = new ValidatorDate({
                        idInput: "inputFilterDataInicial",
                        isEmptyValid: true,
                        idModalHideShow: "modalFilters"
                    });

                    // data final
                    var inputFilterDataFinal = new ValidatorDate({
                        idInput: "inputFilterDataFinal",
                        compareGreater: "inputFilterDataInicial",
                        isEmptyValid: true,
                        idModalHideShow: "modalFilters"
                    });

                    // numero inicial
                    var inputFilterNumeroInicial = new ValidatorAlphanumeric({
                        idInput: "inputFilterNumeroInicial"
                    });

                    // numero final
                    var inputFilterNumeroFinal = new ValidatorAlphanumeric({
                        idInput: "inputFilterNumeroFinal"
                    });

                    // filial
                    var inputFilterCodigoFilial = new ValidatorLookup({
                        abrev: "FilterCodigoFilial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        routeTable: "Empresarial/F4Filial/GetFiliais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais",
                        idModalHideShow: "modalFilters"
                    });

                    // cliente
                    var inputFilterCodigoCliente = new ValidatorLookup({
                        abrev: "FilterCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes",
                        idModalHideShow: "modalFilters"
                    });

                    // situacao
                    var inputFilterSituacao = new ValidatorDropDown({
                        abrev: "FilterSituacao",
                        route: "/Assistec/Movimentos/GetListSituacaoFiltro"
                    });

                    // filters listen
                    $("#doFilter").click(function () {
                        if (checkFilters()) {
                            doFilter();
                            $("#modalFilters").modal("hide");
                        }
                    });

                    $("#removeFilter").click(function () {
                        setFiltersDefault(true);
                    });

                    $("#modalFilters").on("hidden", function () {
                    });

                    // filters functions
                    var idFilterSession = "filters_ast_mov_atendimentos_tecnicos";

                    function checkFilters() {
                        if (!inputFilterDataInicial.isValid) {
                            inputFilterDataInicial.forceExecuteValidate();
                            return false;
                        }

                        if (!inputFilterDataFinal.isValid) {
                            inputFilterDataFinal.forceExecuteValidate();
                            return false;
                        }

                        return true;
                    }

                    function setDefaultFieldFocusFilters() {
                    }

                    function loadFilters(loadData) {
                        var filter = JSON.parse(currentUser.getSessionData(idFilterSession));
                        if (filter !== null) {
                            setFiltersInFields(filter);

                            setFilialDefault(inputFilterCodigoFilial, false, true);
                            filter.CodigoFilial = inputFilterCodigoFilial.getValue();

                            var dataSource = new kendo.data.DataSource(gridAssistenciasTecnicas.getFilteredDataSource(filter));
                            gridAssistenciasTecnicas.setDataSource(dataSource);
                        }
                        else {
                            setFiltersDefault();
                        }
                    }

                    function setFiltersInFields(filter) {
                        inputFilterChaveInicial.setValue(filter.ChaveInicial);
                        inputFilterChaveFinal.setValue(filter.ChaveFinal);
                        inputFilterDataInicial.setValue(filter.DataInicial);
                        inputFilterDataFinal.setValue(filter.DataFinal);
                        inputFilterNumeroInicial.setValue(filter.NumeroInicial);
                        inputFilterNumeroFinal.setValue(filter.NumeroFinal);
                        inputFilterCodigoFilial.setValue(filter.CodigoFilial);
                        inputFilterCodigoCliente.setValue(filter.CodigoCliente);
                        inputFilterSituacao.setValue(filter.Situacao);
                    }

                    function setFiltersDefault() {
                        var filter = {
                            ChaveInicial: "",
                            ChaveFinal: "",
                            DataInicial: "",
                            DataFinal: "",
                            NumeroInicial: "",
                            NumeroFinal: "",
                            CodigoFilial: "",
                            CodigoCliente: "",
                            Situacao: 0
                        };

                        setFilialDefault(inputFilterCodigoFilial, false, true);
                        filter.CodigoFilial = inputFilterCodigoFilial.getValue();

                        setFiltersInFields(filter);

                        var dataSource = new kendo.data.DataSource(gridAssistenciasTecnicas.getFilteredDataSource(filter));
                        gridAssistenciasTecnicas.setDataSource(dataSource);

                        currentUser.setSessionData(idFilterSession, JSON.stringify(filter));
                    }

                    function doFilter() {
                        var filter = {
                            ChaveInicial: inputFilterChaveInicial.getValue(),
                            ChaveFinal: inputFilterChaveFinal.getValue(),
                            DataInicial: inputFilterDataInicial.getValue(),
                            DataFinal: inputFilterDataFinal.getValue(),
                            NumeroInicial: inputFilterNumeroInicial.getValue(),
                            NumeroFinal: inputFilterNumeroFinal.getValue(),
                            CodigoFilial: inputFilterCodigoFilial.getValue(),
                            CodigoCliente: inputFilterCodigoCliente.getValue(),
                            Situacao: inputFilterSituacao.getValue()
                        }

                        var dataSource = new kendo.data.DataSource(gridAssistenciasTecnicas.getFilteredDataSource(filter));
                        gridAssistenciasTecnicas.setDataSource(dataSource);

                        currentUser.setSessionData(idFilterSession, JSON.stringify(filter));
                    }

                    // para carregar a grid com os dados ja filtrados
                    loadFilters();
                }(params));
            },

            MovimentosAssistenciaTecnica: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");
                    currentUser.update(params.User);

                    var tabs = {
                        Principal: 0,
                        Atendimentos: 1
                    }

                    var globalConfigDefault = {
                        ServicoOrProduto: true
                    }

                    var globalAssistenciaTecnica = {
                    }

                    //
                    // principal
                    //

                    // chave
                    var inputPrincipalChave = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalChave"
                    });

                    // data abertura
                    var inputPrincipalDataAbertura = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalDataAbertura"
                    });

                    // hora
                    var inputPrincipalHora = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalHora"
                    });

                    // filial
                    var inputPrincipalCodigoFilial = new ValidatorLookup({
                        abrev: "PrincipalCodigoFilial",
                        fieldSearch: "CodigoFilial",
                        msgPendencyMessagePartEnd: "da filial.",
                        route: "Empresarial/F4Filial/GetFilialEx",
                        routeTable: "Empresarial/F4Filial/GetFiliais",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CNPJ/CPF", field: "CpfCnpj", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Filiais"
                    });

                    // situacao
                    var inputPrincipalSituacao = new ValidatorDropDown({
                        abrev: "PrincipalSituacao",
                        route: "/Assistec/Movimentos/GetListSituacaoCadastro",
                        width: 150
                    });

                    // numero
                    var inputPrincipalNumero = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalNumero",
                        maxLength: 50
                    });

                    // numero os fabricante
                    var inputPrincipalNumeroOSFabricante = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalNumeroOSFabricante",
                        maxLength: 50
                    });

                    // cliente
                    var inputPrincipalCodigoCliente = new ValidatorLookup({
                        abrev: "PrincipalCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes"
                    });

                    // cliente - cadastro click
                    byId("linkButtonModalCadastroPrincipalCodigoCliente").onclick = function () {
                        if (inputPrincipalCodigoCliente.getValue() === "") {
                            u.dialogOk("Cliente deve ser informado.", null, true, null, alertBehavior.warning);
                        }
                        else {
                            request2("Assistec/Movimentos/GetDadosCliente",
                                {
                                    Id: params.Id,
                                    DataEmissao: params.DataEmissao,

                                    CodigoCliente: inputPrincipalCodigoCliente.getValue()
                                },
                                function (model) {
                                    setVal("inputModalDadosClienteNome", model.Nome);
                                    setVal("inputModalDadosClienteRazaoSocial", model.RazaoSocial);

                                    setVal("inputModalDadosClienteEndereco", model.Endereco);
                                    setChecked("inputModalDadosClienteSN", model.SN);
                                    setVal("inputModalDadosClienteNr", model.Numero);

                                    setVal("inputModalDadosClienteComplemento", model.Complemento);
                                    setVal("inputModalDadosClienteBairro", model.Bairro);

                                    setVal("inputModalDadosClienteCEP", model.CEP);

                                    setVal("inputModalDadosClienteMunicipio", model.CodigoMunicipio);
                                    setHtml("descriptionModalDadosClienteMunicipio", model.NomeMunicipio);

                                    setVal("inputModalDadosClienteUF", model.SiglaUF);
                                    setHtml("descriptionModalDadosClienteUF", model.NomeUF);

                                    setVal("inputModalDadosClienteEmail", model.Email);

                                    setVal("inputModalDadosClienteTelefoneDDD", model.TelefoneDDD);
                                    setVal("inputModalDadosClienteTelefone", model.Telefone);

                                    setVal("inputModalDadosClienteContato", model.Contato);

                                    // localizacao
                                    if (model.LocalEquipamentoInstalado) {
                                        $("#grupoModalDadosClienteLocalEquipamento").css("display", "block");
                                        setVal("inputModalDadosClienteLocalEquipamentoEndereco", model.LocalEquipamentoInstalado.Endereco);
                                        setChecked("inputModalDadosClienteLocalEquipamentoSN", model.LocalEquipamentoInstalado.SN);
                                        setVal("inputModalDadosClienteLocalEquipamentoNr", model.LocalEquipamentoInstalado.Numero);

                                        setVal("inputModalDadosClienteLocalEquipamentoComplemento", model.LocalEquipamentoInstalado.Complemento);
                                        setVal("inputModalDadosClienteLocalEquipamentoBairro", model.LocalEquipamentoInstalado.Bairro);

                                        setVal("inputModalDadosClienteLocalEquipamentoCEP", model.LocalEquipamentoInstalado.CEP);

                                        setVal("inputModalDadosClienteLocalEquipamentoMunicipio", model.LocalEquipamentoInstalado.CodigoMunicipio);
                                        setHtml("descriptionModalDadosClienteLocalEquipamentoMunicipio", model.LocalEquipamentoInstalado.NomeMunicipio);
                                        setVal("inputModalDadosClienteLocalEquipamentoUF", model.LocalEquipamentoInstalado.SiglaUF);
                                        setHtml("descriptionModalDadosClienteLocalEquipamentoUF", model.LocalEquipamentoInstalado.NomeUF);

                                        setVal("inputModalDadosClienteLocalEquipamentoContato", model.LocalEquipamentoInstalado.Contato);
                                        inputModalDadosClienteLocalEquipamentoComentarios.set(model.LocalEquipamentoInstalado.Comentarios);
                                    }

                                    $("#modalDadosCliente").modal("show");
                                });
                        }
                    }

                    // cliente - dados do cliente - comentarios
                    var inputModalDadosClienteLocalEquipamentoComentarios = new ValidatorMemo({
                        titleModal: "Comentários",
                        idInput: "inputModalDadosClienteLocalEquipamentoComentarios",
                        idLink: "inputModalDadosClienteLocalEquipamentoComentariosLink",
                        idModalHideShow: "modalDadosCliente",
                        css: { width: "300px" },
                        attr: { maxlength: 1000, disabled: "disabled" }
                    });

                    // equipamento/produto
                    $("#inputRadioPrincipalEquipamento, #inputRadioPrincipalProduto").on("change", function () {
                        setEquipamentoOrProduto();
                    });

                    function setEquipamentoOrProduto() {
                        if (isChecked("inputRadioPrincipalEquipamento")) {
                            $("#inputPrincipalEquipamento").css("display", "block");
                            $("#inputControlPrincipalProduto").css("display", "none");

                            inputPrincipalCodigoEquipamento.clear();
                            inputPrincipalCodigoProduto.clear();
                            inputPrincipalCodigoMarca.clear();
                            inputPrincipalCodigoModelo.clear();
                            inputPrincipalCodigoTipo.clear();
                        }
                        else {
                            $("#inputPrincipalEquipamento").css("display", "none");
                            $("#inputControlPrincipalProduto").css("display", "block");

                            inputPrincipalCodigoEquipamento.clear();
                            inputPrincipalCodigoProduto.clear();
                            inputPrincipalCodigoMarca.clear();
                            inputPrincipalCodigoModelo.clear();
                            inputPrincipalCodigoTipo.clear();
                        }
                    }

                    // equipamento
                    var inputPrincipalCodigoEquipamento = new ValidatorLookup({
                        abrev: "PrincipalCodigoEquipamento",
                        fieldSearch: "Codigo",
                        msgPendencyMessagePartEnd: "do equipamento.",
                        route: "Assistec/F4Equipamento/GetEquipamento",
                        routeTable: "Assistec/F4Equipamento/GetEquipamentos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                        ],
                        titleModal: "Equipamentos",
                        maxLength: 8,
                        onValid: function (data) {
                            inputPrincipalCodigoMarca.setValues(data.CodigoMarca, data.NomeMarca);
                            inputPrincipalCodigoModelo.setValues(data.CodigoModelo, data.NomeModelo);
                            inputPrincipalCodigoTipo.setValues(data.CodigoTipo, data.NomeTipo);
                        },
                        onInvalid: function () {
                            inputPrincipalCodigoMarca.clear();
                            inputPrincipalCodigoModelo.clear();
                            inputPrincipalCodigoTipo.clear();
                        },
                        onEmpty: function () {
                            inputPrincipalCodigoMarca.clear();
                            inputPrincipalCodigoModelo.clear();
                            inputPrincipalCodigoTipo.clear();
                        }
                    });

                    // produto
                    var inputPrincipalCodigoProduto = new ValidatorLookupProduto({
                        abrev: "Principal"
                    });

                    // marca
                    var inputPrincipalCodigoMarca = new ValidatorLookup({
                        abrev: "PrincipalCodigoMarca",
                        fieldSearch: "Codigo",
                        msgPendencyMessagePartEnd: "da marca do equipamento.",
                        route: "Assistec/F4MarcaEquipamento/GetMarcaEquipamento",
                        routeTable: "Assistec/F4MarcaEquipamento/GetMarcasEquipamentos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Marcas",
                        maxLength: 8
                    });

                    // modelo
                    var inputPrincipalCodigoModelo = new ValidatorLookup({
                        abrev: "PrincipalCodigoModelo",
                        fieldSearch: "Codigo",
                        msgPendencyMessagePartEnd: "do modelo.",
                        route: "Assistec/F4ModeloEquipamento/GetModeloEquipamento",
                        routeTable: "Assistec/F4ModeloEquipamento/GetModelosEquipamentos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Modelos",
                        maxLength: 25
                    });

                    // tipo
                    var inputPrincipalCodigoTipo = new ValidatorLookup({
                        abrev: "PrincipalCodigoTipo",
                        fieldSearch: "Codigo",
                        msgPendencyMessagePartEnd: "do tipo.",
                        route: "Assistec/F4TipoEquipamento/GetTipoEquipamento",
                        routeTable: "Assistec/F4TipoEquipamento/GetTiposEquipamentos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Tipos",
                        maxLength: 8
                    });

                    // numero serie
                    var inputPrincipalNumeroSerie = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalNumeroSerie",
                        maxLength: 50
                    });

                    // numero patrimonial
                    var inputPrincipalNumeroPatrimonial = new ValidatorAlphanumeric({
                        idInput: "inputPrincipalNumeroPatrimonial",
                        maxLength: 20
                    });

                    // acessorios recebidos
                    var inputPrincipalAcessoriosRecebidos = new ValidatorMemo({
                        titleModal: "Acessórios Recebidos",
                        idInput: "inputPrincipalAcessoriosRecebidos",
                        idLink: "inputPrincipalAcessoriosRecebidosLink",
                        css: { width: "640px" },
                        attr: { maxlength: 500 }
                    });

                    // tipo defeito
                    var inputPrincipalCodigoTipoDefeito = new ValidatorLookup({
                        abrev: "PrincipalCodigoTipoDefeito",
                        fieldSearch: "Codigo",
                        msgPendencyMessagePartEnd: "do tipo de defeito.",
                        route: "Assistec/F4DefeitoEquipamento/GetDefeitoEquipamento",
                        routeTable: "Assistec/F4DefeitoEquipamento/GetDefeitosEquipamentos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 200, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Defeitos",
                        maxLength: 25,
                        onValid: function (data) {
                            buttonPrincipalVerSolucao.setValue(data.Solucao);
                            // ativa somente se tiver conteudo
                            buttonPrincipalVerSolucao.enable(data.Solucao);
                        },
                        onInvalid: function (data) {
                            buttonPrincipalVerSolucao.clear();
                            buttonPrincipalVerSolucao.enable(false);
                        },
                        onEmpty: function () {
                            buttonPrincipalVerSolucao.clear();
                            buttonPrincipalVerSolucao.enable(false);
                        }
                    });

                    // ver solucao
                    var buttonPrincipalVerSolucao = new ValidatorModalMemo({
                        idInput: "buttonPrincipalVerSolucao",
                        titleModal: "Sugestões de Possível Solução"
                    });

                    // defeito relatado cliente
                    var inputPrincipalDefeitoRelatadoCliente = new ValidatorMemo({
                        titleModal: "Defeito Relatado pelo Cliente",
                        idInput: "inputPrincipalDefeitoRelatadoCliente",
                        idLink: "inputPrincipalDefeitoRelatadoClienteLink",
                        css: { width: "640px" },
                        attr: { maxlength: 2000 }
                    });

                    // defeito detectado
                    var inputPrincipalDefeitoDetectado = new ValidatorMemo({
                        titleModal: "Defeito Detectado",
                        idInput: "inputPrincipalDefeitoDetectado",
                        idLink: "inputPrincipalDefeitoDetectadoLink",
                        css: { width: "640px" },
                        attr: { maxlength: 2000 }
                    });

                    // comentarios
                    var inputPrincipalComentarios = new ValidatorMemo({
                        titleModal: "Comentários",
                        idInput: "inputPrincipalComentarios",
                        idLink: "inputPrincipalComentariosLink",
                        css: { width: "640px" },
                        attr: { maxlength: 5000 }
                    });

                    // buttons

                    byId("buttonOK").onclick = function () {
                        saveAssistenciaTecnica();
                    }

                    byId("buttonCancelar").onclick = function () {
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () { $('#waiting').show(); }, 100);
                                window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciasTecnicas";
                            },
                            null,
                            null,
                            true
                        );
                    }

                    byId("buttonNovo").onclick = function () {
                        u.dialog(
                            null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () { $('#waiting').show(); }, 100);
                                window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica";
                            },
                            null,
                            null,
                            true
                        );
                    }

                    byId("buttonCopiar").onclick = function () {
                        u.dialog(null,
                            "Deseja realmente abandonar as alterações?",
                            function () {
                                setTimeout(function () { $('#waiting').show(); }, 100);
                                window.location.href = window.baseUrl + "Assistec/Movimentos/CopyAssistenciaTecnica?GuidProxy=" + params.GuidProxy;
                            },
                            null,
                            null,
                            true
                        );
                    }

                    byId("buttonGerarPDF").onclick = function () {
                        window.open(window.baseUrl + "Assistec/Relatorios/GeraRelatorioAssistenciaTecnica?"
                            + "&AssistenciaTecnica=" + params.Id
                            + "&DataEmissao=" + params.DataEmissao
                            + "&LayoutAssistenciaTecnica=" + getHtml("inputLayoutRelatorioAssistenciaTecnica_option_selected")
                        );
                    }

                    var inputLayoutRelatorioAssistenciaTecnica = new ValidatorDropDown({
                        abrev: "LayoutRelatorioAssistenciaTecnica",
                        dataSource: [],
                        width: 300
                    });

                    // functions

                    function disableAssistenciaTecnica() {
                        inputPrincipalCodigoFilial.disable();
                        inputPrincipalSituacao.setEnable(false);
                        inputPrincipalNumero.enable(false);
                        inputPrincipalNumeroOSFabricante.enable(false);
                        inputPrincipalCodigoCliente.enable2(false);
                    
                        u.disable("linkButtonModalCadastroPrincipalCodigoCliente");
                        u.disable("inputRadioPrincipalEquipamento");
                        u.disable("inputRadioPrincipalProduto");

                        inputPrincipalCodigoEquipamento.disable();
                        inputPrincipalCodigoProduto.enable();
                        inputPrincipalCodigoMarca.disable();
                        inputPrincipalCodigoModelo.disable();
                        inputPrincipalCodigoTipo.disable();

                        inputPrincipalNumeroSerie.enable(false);
                        inputPrincipalNumeroPatrimonial.enable(false);
                        inputPrincipalAcessoriosRecebidos.enable(false);
                        inputPrincipalCodigoTipoDefeito.disable();
                        buttonPrincipalVerSolucao.enable(false);
                        inputPrincipalDefeitoRelatadoCliente.enable(false);
                        inputPrincipalDefeitoDetectado.enable(false);
                        inputPrincipalComentarios.enable(false);

                        u.disable("buttonOK");
                        u.disable("buttonNovo");
                        u.disable("buttonCopiar");
                        u.disable("buttonGerarPDF");

                        // disabled abas
                        $("#tabs > li > a").removeAttr("href").removeAttr("data-toggle");
                    }

                    function setAssistenciaTecnica(model) {
                        globalAssistenciaTecnica = model;

                        if (!globalAssistenciaTecnica.IsAlteracao && !params.Copy) {
                            // inclusao - principal
                            inputPrincipalChave.setValue(model.Chave);
                            inputPrincipalDataAbertura.setValue(model.DataAbertura);
                            inputPrincipalHora.setValue(model.Hora);
                            inputPrincipalCodigoFilial.setValues(model.CodigoFilial, model.NomeFilial);
                            inputPrincipalCodigoFilial.enable2(globalAssistenciaTecnica.Configuracoes.QtdFiliaisAtivas > 1);

                            inputPrincipalSituacao.setValue(model.Situacao);
                            inputPrincipalNumero.setValue(model.Numero);
                            inputPrincipalNumero.enable(globalAssistenciaTecnica.Configuracoes.PodeAlterarNumero);
                            inputPrincipalNumeroOSFabricante.clear();

                            inputPrincipalCodigoCliente.clear();

                            if (globalAssistenciaTecnica.Configuracoes.IsCadastroEquipamento)
                                setChecked("inputRadioPrincipalEquipamento", true);
                            else
                                setChecked("inputRadioPrincipalEquipamento", false);
                            setEquipamentoOrProduto();
                            inputPrincipalCodigoEquipamento.clear();
                            inputPrincipalCodigoProduto.clear();

                            inputPrincipalCodigoMarca.clear();
                            inputPrincipalCodigoModelo.clear();
                            inputPrincipalCodigoTipo.clear();

                            inputPrincipalNumeroSerie.clear();
                            inputPrincipalNumeroPatrimonial.clear();

                            inputPrincipalAcessoriosRecebidos.clear();

                            inputPrincipalCodigoTipoDefeito.clear();
                            buttonPrincipalVerSolucao.clear();
                            buttonPrincipalVerSolucao.enable(false);

                            inputPrincipalDefeitoRelatadoCliente.clear();
                            inputPrincipalDefeitoDetectado.clear();
                            inputPrincipalComentarios.clear();

                            // atendimento
                            setAtendimentoDefault(model.Atendimentos);

                            globalAssistenciaTecnica.Configuracoes.AST_INCLUIR ? u.enable("buttonOK") : u.disable("buttonOK");
                            params.Copy ? u.enable("buttonNovo") : u.disable("buttonNovo");
                            u.disable("buttonCopiar");
                            u.disable("buttonGerarPDF");
                        } else {
                            // alteracao - principal
                            inputPrincipalChave.setValue(model.Chave);
                            inputPrincipalDataAbertura.setValue(model.DataAbertura);
                            inputPrincipalHora.setValue(model.Hora);

                            inputPrincipalCodigoFilial.setValues(model.CodigoFilial, model.NomeFilial);
                            inputPrincipalCodigoFilial.enable2(globalAssistenciaTecnica.Configuracoes.QtdFiliaisAtivas > 1);

                            inputPrincipalSituacao.setValue(model.Situacao);

                            inputPrincipalNumero.setValue(model.Numero);
                            inputPrincipalNumero.enable(globalAssistenciaTecnica.Configuracoes.PodeAlterarNumero);
                            inputPrincipalNumeroOSFabricante.setValue(model.NumeroOSFabricante);

                            inputPrincipalCodigoCliente.setValues(model.CodigoCliente, model.NomeCliente);

                            if (model.CodigoEquipamento) {
                                setChecked("inputRadioPrincipalEquipamento", true);
                                setEquipamentoOrProduto();

                                inputPrincipalCodigoEquipamento.setValues(model.CodigoEquipamento, model.NomeEquipamento);
                                inputPrincipalCodigoProduto.clear();
                            }
                            else {
                                setChecked("inputRadioPrincipalProduto", true);
                                setEquipamentoOrProduto();

                                inputPrincipalCodigoEquipamento.clear();
                                inputPrincipalCodigoProduto.setProdutoGrades({
                                    CodigoProduto: model.CodigoProduto,
                                    DescricaoProduto: model.DescricaoProduto,
                                    Classificacao: "",

                                    HaveGrade1: model.HaveGrade1,
                                    CodigoGrade1: model.CodigoGrade1,
                                    DescricaoGrade1: model.DescricaoGrade1,

                                    HaveGrade2: model.HaveGrade2,
                                    CodigoGrade2: model.CodigoGrade2,
                                    DescricaoGrade2: model.DescricaoGrade2,

                                    HaveGrade3: model.HaveGrade3,
                                    CodigoGrade3: model.CodigoGrade3,
                                    DescricaoGrade3: model.DescricaoGrade3
                                });
                            }

                            inputPrincipalCodigoMarca.setValues(model.CodigoMarca, model.NomeMarca);
                            inputPrincipalCodigoModelo.setValues(model.CodigoModelo, model.NomeModelo);
                            inputPrincipalCodigoTipo.setValues(model.CodigoTipo, model.NomeTipo);

                            inputPrincipalNumeroSerie.setValue(model.NumeroSerie);
                            inputPrincipalNumeroPatrimonial.setValue(model.NumeroPatrimonial);

                            inputPrincipalAcessoriosRecebidos.set(model.AcessoriosRecebido);

                            inputPrincipalCodigoTipoDefeito.setValues(model.CodigoTipoDefeito, model.NomeTipoDefeito);
                            if (model.VerSolucao) {
                                buttonPrincipalVerSolucao.setValue(model.VerSolucao);
                                buttonPrincipalVerSolucao.enable(true);
                            }

                            inputPrincipalDefeitoRelatadoCliente.set(model.DefeitoRelatadoCliente);
                            inputPrincipalDefeitoDetectado.set(model.DefeitoDetectado);
                            inputPrincipalComentarios.set(model.Comentarios);

                            // atendimento
                            setAtendimentoDefault(model.Atendimentos);

                            globalAssistenciaTecnica.Configuracoes.AST_ALTERAR ? u.enable("buttonOK") : u.disable("buttonOK");
                            globalAssistenciaTecnica.Configuracoes.AST_INCLUIR && !params.Copy ? u.enable("buttonNovo") : u.disable("buttonNovo");
                            globalAssistenciaTecnica.Configuracoes.AST_COPIAR && !params.Copy ? u.enable("buttonCopiar") : u.disable("buttonCopiar");
                            globalAssistenciaTecnica.Configuracoes.AST_VISUALIZAR && !params.Copy ? u.enable("buttonGerarPDF") : u.disable("buttonGerarPDF");

                            // TODO: transportar constantes/enuns junto com o view model, jah existe mapper para isso, ex: de "model.Situacao === 2" para "model.Situacao === vm.Situacoes.Concluida"
                            if (!globalAssistenciaTecnica.Configuracoes.AST_ALTERAR_CONCLUIDA && model.Situacao === 2/*concluída*/)
                                disableAssistenciaTecnica();
                        }

                        inputLayoutRelatorioAssistenciaTecnica.setDataSource(globalAssistenciaTecnica.Configuracoes.LayoutsAssistenciaTecnica);
                        inputLayoutRelatorioAssistenciaTecnica.setValue(globalAssistenciaTecnica.Configuracoes.LayoutAssistenciaTecnicaDefault);
                    }

                    function checkAssistenciaTecnica() {
                        if (inputPrincipalDataAbertura.isEmpty()) {
                            u.dialogOk("O campo \"Data Abertura\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                inputPrincipalDataAbertura.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputPrincipalHora.isEmpty()) {
                            u.dialogOk("O campo \"Hora\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                inputPrincipalHora.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputPrincipalCodigoFilial.isEmpty()) {
                            u.dialogOk("O campo \"Filial\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                inputPrincipalCodigoFilial.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputPrincipalNumero.isEmpty()) {
                            u.dialogOk("O campo \"Número\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                inputPrincipalNumero.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputPrincipalCodigoCliente.isEmpty()) {
                            u.dialogOk("O campo \"Cliente\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Principal);
                                inputPrincipalCodigoCliente.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (isChecked("inputRadioPrincipalEquipamento")) {
                            if (inputPrincipalCodigoEquipamento.isEmpty()) {
                                u.dialogOk("O campo \"Equipamento\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Principal);
                                    inputPrincipalCodigoEquipamento.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }
                        } else {
                            if (inputPrincipalCodigoProduto.isEmpty()) {
                                u.dialogOk("O campo \"Produto\" da aba \"Principal\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Principal);
                                    inputPrincipalCodigoProduto.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }
                        }

                        return true;
                    }

                    function getObjAssistenciaTecnica() {
                        var obj = {};

                        obj.Id = params.Id;
                        obj.DataEmissao = params.DataEmissao;

                        obj.Chave = inputPrincipalChave.getValue();
                        obj.DataAbertura = inputPrincipalDataAbertura.getValue();
                        obj.Hora = inputPrincipalHora.getValue();
                        obj.CodigoFilial = inputPrincipalCodigoFilial.getValue();
                        obj.Situacao = inputPrincipalSituacao.getValue();
                        obj.Numero = inputPrincipalNumero.getValue();
                        obj.NumeroOSFabricante = inputPrincipalNumeroOSFabricante.getValue();
                        obj.CodigoCliente = inputPrincipalCodigoCliente.getValue();

                        if (isChecked("inputRadioPrincipalEquipamento")) {
                            obj.CodigoEquipamento = inputPrincipalCodigoEquipamento.getValue();
                        } else {
                            var produtoGrades = inputPrincipalCodigoProduto.getProdutoGrades();
                            obj.CodigoProduto = produtoGrades.CodigoProduto;
                            obj.HaveGrade1 = produtoGrades.HaveGrade1;
                            obj.CodigoGrade1 = produtoGrades.CodigoGrade1;
                            obj.HaveGrade2 = produtoGrades.HaveGrade2;
                            obj.CodigoGrade2 = produtoGrades.CodigoGrade2;
                            obj.HaveGrade3 = produtoGrades.HaveGrade3;
                            obj.CodigoGrade3 = produtoGrades.CodigoGrade3;
                        }

                        obj.CodigoMarca = inputPrincipalCodigoMarca.getValue();
                        obj.CodigoModelo = inputPrincipalCodigoModelo.getValue();
                        obj.CodigoTipo = inputPrincipalCodigoTipo.getValue();

                        obj.NumeroSerie = inputPrincipalNumeroSerie.getValue();
                        obj.NumeroPatrimonial = inputPrincipalNumeroPatrimonial.getValue();
                        obj.AcessoriosRecebido = inputPrincipalAcessoriosRecebidos.get();
                        obj.CodigoTipoDefeito = inputPrincipalCodigoTipoDefeito.getValue();
                        obj.DefeitoRelatadoCliente = inputPrincipalDefeitoRelatadoCliente.get();
                        obj.DefeitoDetectado = inputPrincipalDefeitoDetectado.get();
                        obj.Comentarios = inputPrincipalComentarios.get();

                        obj.SalvarProdServNaoAdicionados = false;

                        //dados do último atendimento para o caso de usuário deixar algum produto ou serviço sem inserir.
                        obj.UltAtendimentoIndex = gridAtendimentosAtendimentos.getSelectedDataIndex();
                        obj.UltAtendimentoData = inputAtendimentosData.getValue();
                        obj.UltAtendimentoHora = inputAtendimentosHora.getValue();
                        obj.UltAtendimentoCodigoTecnico = inputAtendimentosCodigoTecnico.getValue();
                        obj.UltAtendimentoConcluido = inputAtendimentosConcluido.getValue();

                        return obj;
                    }

                    function saveAssistenciaTecnica() {
                        if (!checkAssistenciaTecnica())
                            return;

                        // tenta salvar assistencia tecnica
                        request2(
                            "Assistec/Movimentos/CheckProdServAndSaveAssistec",
                            getObjAssistenciaTecnica(),
                            function (model) {
                                u.dialogOk(
                                    "Assistência técnica salva com sucesso.",
                                    null,
                                    true,
                                    function () {
                                        setTimeout(function () { $('#waiting').show(); }, 100);
                                        window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica?Id={0}&DataEmissao={1}".format(model.Id, model.DataEmissao);
                                    },
                                    alertBehavior.success
                                );
                            },
                            null,
                            function (model) {
                                // se ocorrer o IsAlert e CodeError = ProdServNaoAdicionadoException
                                if (model.CodeError === 1) {
                                    // pergunta se salva assistencia com/sem servicos/produtos sem atendimento
                                    u.dialog(
                                        null,
                                        model.Message,
                                        function () {
                                            // salva assistencia com servicos/produtos com atendimento (cria o atendimento tambem)
                                            var save = getObjAssistenciaTecnica();
                                            save.SalvarProdServNaoAdicionados = true;

                                            request2(
                                                "Assistec/Movimentos/SaveAssistenciaTecnica",
                                                save,
                                                function (model) {
                                                    u.dialogOk(
                                                        "Assistência técnica salva com sucesso.",
                                                        null,
                                                        true,
                                                        function () {
                                                            setTimeout(function () { $('#waiting').show(); }, 100);
                                                            window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica?Id={0}&DataEmissao={1}".format(model.Id, model.DataEmissao);
                                                        },
                                                        alertBehavior.success
                                                    );
                                                }
                                            );
                                        },
                                        function () {
                                            // salva assistencia com servicos/produtos sem atendimento
                                            request2(
                                                "Assistec/Movimentos/SaveAssistenciaTecnica",
                                                getObjAssistenciaTecnica(),
                                                function (model) {
                                                    u.dialogOk(
                                                        "Assistência técnica salva com sucesso.",
                                                        null,
                                                        true,
                                                        function () {
                                                            setTimeout(function () { $('#waiting').show(); }, 100);
                                                            window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciaTecnica?Id={0}&DataEmissao={1}".format(model.Id, model.DataEmissao);
                                                        },
                                                        alertBehavior.success
                                                    );
                                                }
                                            );
                                        },
                                        null,
                                        true
                                    );
                                } else {
                                    // tratamento padrão para erro alert do servidor
                                    u.dialogOk(model.Message, null, true, null, alertBehavior.warning);
                                }
                            }
                        );
                    }

                    function loadAssistenciaTecnica() {
                        if (params.Copy) {
                            request2(
                                "Assistec/Movimentos/CopyAssistenciaTecnicaPost",
                                { Id: params.Id, DataEmissao: params.DataEmissao, GuidProxy: params.GuidProxy },
                                function (model) {
                                    setAssistenciaTecnica(model);
                                },
                                function () {
                                    disableAssistenciaTecnica();
                                }
                            );
                        } else {
                            request2(
                                "Assistec/Movimentos/GetAssistenciaTecnica",
                                { Id: params.Id, DataEmissao: params.DataEmissao, GuidProxy: params.GuidProxy },
                                function (model) {
                                    setAssistenciaTecnica(model);
                                },
                                function () {
                                    disableAssistenciaTecnica();
                                },
                                function (model) {
                                    if (model.CodeError === 1) { // gerou uma AssistenciaContemConjuntoException
                                        u.dialogOk(
                                            model.Message,
                                            null,
                                            true,
                                            function () {
                                                setTimeout(function () { $("#waiting").show(); }, 100);
                                                window.location.href = window.baseUrl + "Assistec/Movimentos/AssistenciasTecnicas"
                                            },
                                            getAlertBehavior(model.Level)
                                        );
                                    }
                                }
                            );
                        }
                    }

                    //
                    // atendimentos
                    //

                    // grid atendimentos
                    var gridAtendimentosAtendimentos = new Grid({
                        id: "gridAtendimentosAtendimentos",
                        columns: [
                            { field: "DataHora", title: "Data", width: 180, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "Tecnico", title: "Técnico", headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        onChange: function (data) {
                            getAtendimento();
                        },
                        height: 140
                    });

                    // data
                    var inputAtendimentosData = new ValidatorDate({
                        idInput: "inputAtendimentosData",
                        isEmptyValid: true
                    });

                    // hora
                    var inputAtendimentosHora = new ValidatorMask({
                        idInput: "inputAtendimentosHora",
                        mask: "time",
                        defaultValue: "00:00",
                        isEmptyValid: false,
                        setDefaulValue: true,
                        onChange: function () {
                            var hora = inputAtendimentosHora.getValue().replace(":", "");
                            if (hora.length < 4 || (hora[0] === "2" && parseInt(hora[1]) > 3)) {
                                u.dialogOk("Hora inválida.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputAtendimentosHora.clear();
                                    inputAtendimentosHora.focusError();
                                }, alertBehavior.warning);
                            }
                        }
                    });

                    // tecnico
                    var inputAtendimentosCodigoTecnico = new ValidatorLookup({
                        abrev: "AtendimentosCodigoTecnico",
                        fieldSearch: "Apelido",
                        msgPendencyMessage: "Usuário não cadastrado.",
                        onValidOnly: function (validator, data) {
                            validator.setValue(data["Apelido"]);
                        },
                        route: "Empresarial/F4Usuario/GetUsuario",
                        routeTable: "Empresarial/F4Usuario/GetUsuarios",
                        columnsTable: [
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Apelido", field: "Apelido", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "IsSupervisor", field: "Supervisor", width: 30, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Usuários"
                    });

                    // concluido
                    var inputAtendimentosConcluido = new ValidatorCheckbox({
                        idInput: "inputAtendimentosConcluido"
                    });

                    // total servicos/produtos
                    var inputAtendimentosTotalServicosProdutos = new ValidatorAlphanumeric({
                        idInput: "inputAtendimentosTotalServicosProdutos"
                    });

                    // buttons

                    byId("buttonAtendimentosAdicionar").onclick = function () {
                        addAtendimento();
                    }

                    byId("buttonAtendimentosAlterar").onclick = function () {
                        updateAtendimento();
                    }

                    byId("buttonAtendimentosRemover").onclick = function () {
                        deleteAtendimento();
                    }

                    // functions

                    function setAtendimentoDefault(atendimentos) {
                        gridAtendimentosAtendimentos.setValue(atendimentos);

                        inputAtendimentosData.setValue(globalAssistenciaTecnica.Configuracoes.Data);
                        inputAtendimentosHora.setValue(globalAssistenciaTecnica.Configuracoes.Hora);
                        inputAtendimentosCodigoTecnico.setValue(globalAssistenciaTecnica.Configuracoes.CodigoTecnico);

                        // servico/produto
                        // nao tem dados para grid servicos/produtos porque nao foi selecionado nenhum atendimento ainda
                        setServicosProdutosDefault(null);

                        inputAtendimentosConcluido.setValue(false);
                        inputAtendimentosTotalServicosProdutos.clear();

                        u.enable("buttonAtendimentosAdicionar");
                        u.disable("buttonAtendimentosAlterar");
                        u.disable("buttonAtendimentosRemover");
                    }

                    function setAtendimento(model) {
                        inputAtendimentosData.setValue(model.Data);
                        inputAtendimentosHora.setValue(model.Hora);
                        inputAtendimentosCodigoTecnico.setValue(model.CodigoTecnico);

                        // converte "List<ServicoProdutoGridViewModel>" para "ServicosProdutosGridViewModel",
                        // pois eh o ViewModel usado pelo "setServicosProdutosDefault"
                        setServicosProdutosDefault({
                            ServicosProdutos: model.ServicosProdutos,
                            ValorTotalServicosProdutos: model.ValorTotalServicosProdutos
                        });

                        inputAtendimentosConcluido.setValue(model.Concluido);
                        // nao precisa setar o campo "inputAtendimentosTotalServicosProdutos" pois o "setServicosProdutosDefault" ja faz isso

                        u.disable("buttonAtendimentosAdicionar");
                        u.enable("buttonAtendimentosAlterar");
                        u.enable("buttonAtendimentosRemover");
                    }

                    function checkAtendimento() {
                        if (inputAtendimentosData.isEmpty) {
                            u.dialogOk("O campo \"Data\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputAtendimentosData.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputAtendimentosHora.isEmpty()) {
                            u.dialogOk("O campo \"Hora\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputAtendimentosHora.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputAtendimentosCodigoTecnico.isEmpty()) {
                            u.dialogOk("O campo \"Técnico\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputAtendimentosCodigoTecnico.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        return true;
                    }

                    function getObjAtendimento() {
                        return {
                            Id: params.Id,
                            DataEmissao: params.DataEmissao,
                            IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex(),
                            Data: inputAtendimentosData.getValue(),
                            Hora: inputAtendimentosHora.getValue(),
                            CodigoTecnico: inputAtendimentosCodigoTecnico.getValue(),
                            Concluido: inputAtendimentosConcluido.getValue(),
                        }
                    }

                    function getAtendimento() {
                        request2("Assistec/Movimentos/GetAtendimento",
                            {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex()
                            },
                            function (model) {
                                setAtendimento(model);
                            });
                    }

                    function addAtendimento() {
                        if (!checkAtendimento()) {
                            return;
                        }

                        request2("Assistec/Movimentos/AddAtendimento",
                            getObjAtendimento(),
                            function (model) {
                                setAtendimentoDefault(model);
                            });
                    }

                    function updateAtendimento() {
                        if (!checkAtendimento()) {
                            return;
                        }

                        request2("Assistec/Movimentos/UpdateAtendimento",
                            getObjAtendimento(),
                            function (model) {
                                setAtendimentoDefault(model);
                            });
                    }

                    function deleteAtendimento() {
                        request2("Assistec/Movimentos/DeleteAtendimento",
                            {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex()
                            },
                            function (model) {
                                setAtendimentoDefault(model);
                            });
                    }

                    //
                    // atendimentos - produtos/servicos
                    //

                    // produtos/servicos
                    var gridServicosProdutos = new Grid({
                        id: "gridServicosProdutos",
                        columns: [
                            { field: "ServicoProduto", title: "Serviço/Produto", headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "DataGarantia", title: "Data Garantia", width: 100, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "Quantidade", title: "Quantidade", width: 100, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorUnitario", title: "Vlr. Unit.", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "DescontoUnitario", title: "Desc. Unit.", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorTotal", title: "Vlr. Total", width: 90, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "Cobrar", title: "Cobrar", width: 70, headerAttributes: { style: "color: black; text-align: center;" }, attributes: { style: "text-align: center;" } }
                        ],
                        onChange: function (data) {
                            getServicoProduto();
                        },
                        height: 140
                    });

                    // servico/produto
                    $("#inputServicoProdutoServico, #inputServicoProdutoProduto").on("change", function () {
                        setServicoOrProduto();
                    });

                    function setServicoOrProduto() {
                        if (isChecked("inputServicoProdutoServico")) {
                            $("#inputRowServicoProdutoTabelaPrecoServico").css("display", "block");
                            $("#inputRowServicoProdutoServico").css("display", "block");

                            $("#inputRowServicoProdutoTabelaPrecoProduto").css("display", "none");
                            $("#inputRowServicoProdutoProduto").css("display", "none");
                            $("#radarControlServicoProdutoCodigoLocal").css("visibility", "hidden");

                            inputServicoProdutoCodigoTabelaPrecoProduto.setValues(globalAssistenciaTecnica.Configuracoes.CodigoTabelaPrecoProdutoDefault, globalAssistenciaTecnica.Configuracoes.NomeTabelaPrecoProdutoDefault);
                            inputServicoProdutoCodigoTabelaPrecoProduto.enable2(globalAssistenciaTecnica.Configuracoes.QtdTabelaPrecoProduto > 1);
                            inputServicoProdutoCodigoProduto.clear();
                        }
                        else {
                            $("#inputRowServicoProdutoTabelaPrecoServico").css("display", "none");
                            $("#inputRowServicoProdutoServico").css("display", "none");

                            inputServicoProdutoCodigoTabelaPrecoServico.setValues(globalAssistenciaTecnica.Configuracoes.CodigoTabelaPrecoServicoDefault, globalAssistenciaTecnica.Configuracoes.NomeTabelaPrecoServicoDefault);
                            inputServicoProdutoCodigoTabelaPrecoServico.enable2(globalAssistenciaTecnica.Configuracoes.QtdTabelaPrecoServico > 1);
                            inputServicoProdutoCodigoServico.clear();

                            $("#inputRowServicoProdutoTabelaPrecoProduto").css("display", "block");
                            $("#inputRowServicoProdutoProduto").css("display", "block");
                            $("#radarControlServicoProdutoCodigoLocal").css("visibility", "visible");
                        }

                        setValoresServicosProdutosDefault();
                    }

                    function setValoresServicosProdutosDefault() {
                        inputServicoProdutoQuantidade.defaultValue = "0,00";
                        inputServicoProdutoQuantidade.changeMask("radar-valor-14-2-R");
                        inputServicoProdutoQuantidade.clear();

                        inputServicoProdutoValorUnitario.defaultValue = "0,00";
                        inputServicoProdutoValorUnitario.changeMask("radar-valor-14-2-R");
                        inputServicoProdutoValorUnitario.clear();

                        inputServicoProdutoValorDescontoUnitario.clear();

                        inputServicoProdutoValorTotal.clear();
                    }

                    // tabela precos servicos
                    var inputServicoProdutoCodigoTabelaPrecoServico = new ValidatorLookup({
                        abrev: "ServicoProdutoCodigoTabelaPrecoServico",
                        fieldSearch: "CodigoTabelaPrecos",
                        msgPendencyMessagePartEnd: "da tabela de preços.",
                        route: "Empresarial/F4TabelaPrecoServicos/GetTabelaPrecoServicos",
                        routeTable: "Empresarial/F4TabelaPrecoServicos/GetTabelasPrecosServicos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Validade", field: "Validade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Tabelas de Preços de Serviços",
                        maxLength: 10,
                        onValid: function (data) {
                            setValoresServicosProdutosDefault();
                        },
                        onInvalid: function () {
                            setValoresServicosProdutosDefault();
                        },
                        onEmpty: function () {
                            setValoresServicosProdutosDefault();
                        }
                    });

                    // servico
                    var inputServicoProdutoCodigoServico = new ValidatorLookup({
                        abrev: "ServicoProdutoCodigoServico",
                        fieldSearch: "CodigoServico",
                        msgPendencyMessagePartEnd: "do serviço.",
                        route: "Empresarial/F4Servico/GetServico",
                        routeTable: "Empresarial/F4Servico/GetServicos",
                        pendency: [inputServicoProdutoCodigoTabelaPrecoServico],
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Un. Serviço", field: "UnidadeMedida.Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Serviços",
                        maxLength: 60,
                        onValid: function (data) {
                            inputServicoProdutoCodigoUnidadeMedida.setValue(data.UnidadeMedida.Codigo);

                            // servico pode ser hora ou valor
                            if (data.UnidadeMedida.ConsiderarFormatoHorario) {
                                inputServicoProdutoQuantidade.isHora = true;
                                inputServicoProdutoQuantidade.defaultValue = "000:00";
                                inputServicoProdutoQuantidade.changeMask("time-servico");
                                inputServicoProdutoQuantidade.clear();
                            }
                            else {
                                inputServicoProdutoQuantidade.isHora = false;
                                inputServicoProdutoQuantidade.defaultValue = data.UnidadeMedida.CasasDecimais > 0 ? "0," + new Array(data.UnidadeMedida.CasasDecimais + 1).join("0") : "0";
                                inputServicoProdutoQuantidade.changeMask("radar-valor-14-" + data.UnidadeMedida.CasasDecimais + "-R");
                                inputServicoProdutoQuantidade.clear();
                            }

                            inputServicoProdutoValorUnitario.defaultValue = data.CasasDecimais > 0 ? "0," + new Array(data.CasasDecimais+ 1).join("0") : "0";
                            inputServicoProdutoValorUnitario.changeMask("radar-valor-14-" + data.CasasDecimais + "-R");
                            inputServicoProdutoValorUnitario.setValue(data.Valor);
                        },
                        onInvalid: function () {
                            inputServicoProdutoCodigoUnidadeMedida.clear();
                            setValoresServicosProdutosDefault();
                        },
                        onEmpty: function () {
                            inputServicoProdutoCodigoUnidadeMedida.clear();
                            setValoresServicosProdutosDefault();
                        }
                    });

                    // tabela precos produtos
                    var inputServicoProdutoCodigoTabelaPrecoProduto = new ValidatorLookup({
                        abrev: "ServicoProdutoCodigoTabelaPrecoProduto",
                        fieldSearch: "CodigoTabelaPrecos",
                        msgPendencyMessagePartEnd: "da tabela de preços.",
                        route: "Empresarial/F4TabelaPrecoProdutos/GetTabPreco",
                        routeTable: "Empresarial/F4TabelaPrecoProdutos/GetTabPrecos",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Nome", field: "Nome", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Validade", field: "Validade", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Tabelas de Preços de Produtos",
                        maxLength: 10,
                        onValid: function (data) {
                            setValoresServicosProdutosDefault();
                        },
                        onInvalid: function () {
                            setValoresServicosProdutosDefault();
                        },
                        onEmpty: function () {
                            setValoresServicosProdutosDefault();
                        }
                    });

                    // produto
                    var inputServicoProdutoCodigoProduto = new ValidatorLookupProduto({
                        abrev: "ServicoCodigo",
                        pendency: [inputServicoProdutoCodigoTabelaPrecoProduto],
                        onValid: function (data) {
                            inputServicoProdutoCodigoUnidadeMedida.setValue(data.Unidade);

                            inputServicoProdutoQuantidade.isHora = false;
                            inputServicoProdutoQuantidade.defaultValue = data.CasasDecimaisQuantidade > 0 ? "0," + new Array(data.CasasDecimaisQuantidade + 1).join("0") : "0";
                            inputServicoProdutoQuantidade.changeMask("radar-valor-14-" + data.CasasDecimaisQuantidade + "-R");
                            inputServicoProdutoQuantidade.clear();

                            inputServicoProdutoValorUnitario.defaultValue = data.CasasDecimaisValorUnitario > 0 ? "0," + new Array(data.CasasDecimaisValorUnitario + 1).join("0") : "0";
                            inputServicoProdutoValorUnitario.changeMask("radar-valor-14-" + data.CasasDecimaisValorUnitario + "-R");
                            inputServicoProdutoValorUnitario.setValue(data.ValorUnitario);

                            inputServicoProdutoValorDescontoUnitario.setValue(data.ValorDescontoSugerido);
                        },
                        onInvalid: function () {
                            inputServicoProdutoCodigoUnidadeMedida.clear();
                            setValoresServicosProdutosDefault();
                        },
                        onEmpty: function () {
                            inputServicoProdutoCodigoUnidadeMedida.clear();
                            setValoresServicosProdutosDefault();
                        }
                    });

                    // complemento
                    var inputServicoProdutoComplemento = new ValidatorMemo({
                        titleModal: "Complemento",
                        idInput: "inputServicoProdutoComplemento",
                        idLink: "inputServicoProdutoComplementoLink",
                        css: { width: "400px" },
                        attr: { maxlength: 1000 }
                    });

                    // unidade medida
                    var inputServicoProdutoCodigoUnidadeMedida = new ValidatorAlphanumeric({
                        idInput: "inputServicoProdutoCodigoUnidadeMedida"
                    });

                    // quantidade
                    var inputServicoProdutoQuantidade = new ValidatorMask({
                        idInput: "inputServicoProdutoQuantidade",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true,
                        mask: "radar-valor-14-2",
                        isHora: false,
                        onChange: function () {
                            computeValorTotal();
                        }
                    });

                    // valor unitario
                    var inputServicoProdutoValorUnitario = new ValidatorMask({
                        idInput: "inputServicoProdutoValorUnitario",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true,
                        onChange: function () {
                            if (!inputServicoProdutoValorDescontoUnitario.isEmptyOrZeros() && inputServicoProdutoValorDescontoUnitario.getValueNumber() >= inputServicoProdutoValorUnitario.getValueNumber()) {
                                u.dialogOk("Desconto inválido. Informe um valor menor que o valor unitário.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoValorDescontoUnitario.clear();
                                    inputServicoProdutoValorDescontoUnitario.focus();
                                    computeValorTotal();
                                }, alertBehavior.warning);
                            }
                            else {
                                computeValorTotal();
                            }
                        }
                    });

                    // valor desconto unitario
                    var inputServicoProdutoValorDescontoUnitario = new ValidatorMask({
                        idInput: "inputServicoProdutoValorDescontoUnitario",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        setDefaulValue: true,
                        onChange: function () {
                            if (!inputServicoProdutoValorDescontoUnitario.isEmptyOrZeros() && inputServicoProdutoValorDescontoUnitario.getValueNumber() >= inputServicoProdutoValorUnitario.getValueNumber()) {
                                u.dialogOk("Desconto inválido. Informe um valor menor que o valor unitário.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoValorDescontoUnitario.clear();
                                    inputServicoProdutoValorDescontoUnitario.focus();
                                    computeValorTotal();
                                }, alertBehavior.warning);
                            }
                            else {
                                computeValorTotal();
                            }
                        }
                    });

                    // valor total
                    var inputServicoProdutoValorTotal = new ValidatorMask({
                        idInput: "inputServicoProdutoValorTotal",
                        mask: "radar-valor-16-2",
                        isEmptyValid: true,
                        defaultValue: "0,00",
                        setDefaulValue: true
                    });

                    // local
                    var inputServicoProdutoCodigoLocal = new ValidatorLookup({
                        abrev: "ServicoProdutoCodigoLocal",
                        fieldSearch: "CodigoLocal",
                        msgPendencyMessagePartEnd: "do local de armazenagem.",
                        route: "Estoque/F4LocalArmazenagemAnalitico/GetLocalArmazenagem",
                        routeTable: "Estoque/F4LocalArmazenagemAnalitico/GetLocaisArmazenagem",
                        params: [inputPrincipalCodigoFilial],
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 80, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Classificação", field: "Classificacao", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Local", field: "Nome", width: 100, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Locais de Armazenagem",
                        maxLength: 10
                    });

                    // data garantia
                    var inputServicoProdutoDataGarantia = new ValidatorDate({
                        idInput: "inputServicoProdutoDataGarantia",
                        isEmptyValid: true
                    });

                    // cobrar
                    var inputServicoProdutoCobrar = new ValidatorCheckbox({
                        idInput: "inputServicoProdutoCobrar"
                    });

                    // buttons

                    byId("buttonServicoProdutoAdicionar").onclick = function () {
                        addServicoProduto();
                    }

                    byId("buttonServicoProdutoAlterar").onclick = function () {
                        updateServicoProduto();
                    }

                    byId("buttonServicoProdutoRemover").onclick = function () {
                        deleteServicoProduto();
                    }

                    // functions

                    function computeValorTotal() {
                        request2("Assistec/Movimentos/ComputeValorTotal",
                            {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                isHora: inputServicoProdutoQuantidade.isHora,
                                Quantidade: inputServicoProdutoQuantidade.getValue(),
                                ValorUnitario: inputServicoProdutoValorUnitario.getValue(),
                                ValorDescontoUnitario: inputServicoProdutoValorDescontoUnitario.getValue()
                            },
                            function (vlr) {
                                inputServicoProdutoValorTotal.setValue(vlr);
                            });
                    }

                    function setServicosProdutosDefault(servicosProdutos) {
                        servicosProdutos ? gridServicosProdutos.setValue(servicosProdutos.ServicosProdutos) : gridServicosProdutos.clear();

                        setChecked("inputServicoProdutoServico", globalConfigDefault.ServicoOrProduto);
                        setServicoOrProduto();

                        inputServicoProdutoCodigoTabelaPrecoServico.setValues(globalAssistenciaTecnica.Configuracoes.CodigoTabelaPrecoServicoDefault, globalAssistenciaTecnica.Configuracoes.NomeTabelaPrecoServicoDefault);
                        inputServicoProdutoCodigoTabelaPrecoServico.enable2(globalAssistenciaTecnica.Configuracoes.QtdTabelaPrecoServico > 1);
                        inputServicoProdutoCodigoServico.clear();

                        inputServicoProdutoCodigoTabelaPrecoProduto.setValues(globalAssistenciaTecnica.Configuracoes.CodigoTabelaPrecoProdutoDefault, globalAssistenciaTecnica.Configuracoes.NomeTabelaPrecoProdutoDefault);
                        inputServicoProdutoCodigoTabelaPrecoProduto.enable2(globalAssistenciaTecnica.Configuracoes.QtdTabelaPrecoProduto > 1);
                        inputServicoProdutoCodigoProduto.clear();

                        inputServicoProdutoComplemento.clear();
                        inputServicoProdutoCodigoUnidadeMedida.clear();

                        inputServicoProdutoQuantidade.clear();
                        inputServicoProdutoValorUnitario.clear();
                        inputServicoProdutoValorDescontoUnitario.clear();
                        inputServicoProdutoValorTotal.clear();

                        inputServicoProdutoCodigoLocal.clear();
                        inputServicoProdutoDataGarantia.setValue(globalAssistenciaTecnica.Configuracoes.DataGarantia);
                        inputServicoProdutoCobrar.setValue(true);

                        globalAssistenciaTecnica.Configuracoes.AST_ATENDIMENTO_INCLUIR ? u.enable("buttonServicoProdutoAdicionar") : false;
                        u.disable("buttonServicoProdutoAlterar");
                        u.disable("buttonServicoProdutoRemover");

                        // valor total produtos e servicos
                        servicosProdutos ? inputAtendimentosTotalServicosProdutos.setValue(servicosProdutos.ValorTotalServicosProdutos) : inputAtendimentosTotalServicosProdutos.clear();
                    }

                    function setServicosProdutos(model) {
                        model.IsServico ? setChecked("inputServicoProdutoServico", true) : setChecked("inputServicoProdutoProduto", true);
                        setServicoOrProduto();

                        if (model.IsServico) {
                            inputServicoProdutoCodigoTabelaPrecoServico.setValues(model.CodigoTabelaPreco, model.NomeTabelaPreco);

                            inputServicoProdutoCodigoServico.setValues(model.CodigoServicoProduto, model.DescricaoServicoProduto);
                        }
                        else {
                            inputServicoProdutoCodigoTabelaPrecoProduto.setValues(model.CodigoTabelaPreco, model.NomeTabelaPreco);

                            inputServicoProdutoCodigoProduto.setProdutoGrades({
                                CodigoProduto: model.CodigoServicoProduto,
                                DescricaoProduto: model.DescricaoServicoProduto,
                                Classificacao: "",

                                HaveGrade1: model.HaveGrade1,
                                CodigoGrade1: model.CodigoGrade1,
                                DescricaoGrade1: model.DescricaoGrade1,

                                HaveGrade2: model.HaveGrade2,
                                CodigoGrade2: model.CodigoGrade2,
                                DescricaoGrade2: model.DescricaoGrade2,

                                HaveGrade3: model.HaveGrade3,
                                CodigoGrade3: model.CodigoGrade3,
                                DescricaoGrade3: model.DescricaoGrade3
                            });
                        }

                        inputServicoProdutoComplemento.set(model.Complemento);
                        inputServicoProdutoCodigoUnidadeMedida.setValue(model.CodigoUnidadeMedida);

                        if (model.IsServico) {
                            if (model.IsHora) {
                                inputServicoProdutoQuantidade.isHora = true;
                                inputServicoProdutoQuantidade.defaultValue = "000:00";
                                inputServicoProdutoQuantidade.changeMask("time-servico");
                                inputServicoProdutoQuantidade.clear();
                            }
                            else {
                                inputServicoProdutoQuantidade.isHora = false;
                                inputServicoProdutoQuantidade.defaultValue = model.QuantidadeCasasDecimais > 0 ? "0," + new Array(model.QuantidadeCasasDecimais + 1).join("0") : "0";
                                inputServicoProdutoQuantidade.changeMask("radar-valor-14-" + model.QuantidadeCasasDecimais + "-R");
                                inputServicoProdutoQuantidade.clear();
                            }
                        }
                        else {
                            inputServicoProdutoQuantidade.isHora = false;
                            inputServicoProdutoQuantidade.defaultValue = model.QuantidadeCasasDecimais > 0 ? "0," + new Array(model.QuantidadeCasasDecimais + 1).join("0") : "0";
                            inputServicoProdutoQuantidade.changeMask("radar-valor-14-" + model.QuantidadeCasasDecimais + "-R");
                            inputServicoProdutoQuantidade.clear();
                        }
                        inputServicoProdutoValorUnitario.defaultValue = model.ValorUnitarioCasasDecimais > 0 ? "0," + new Array(model.ValorUnitarioCasasDecimais + 1).join("0") : "0";
                        inputServicoProdutoValorUnitario.changeMask("radar-valor-14-" + model.ValorUnitarioCasasDecimais + "-R");
                        inputServicoProdutoValorUnitario.clear();

                        inputServicoProdutoQuantidade.setValue(model.Quantidade);
                        inputServicoProdutoValorUnitario.setValue(model.ValorUnitario);
                        inputServicoProdutoValorDescontoUnitario.setValue(model.ValorDescontoUnitario);
                        inputServicoProdutoValorTotal.setValue(model.ValorTotal);

                        inputServicoProdutoCodigoLocal.setValues(model.CodigoLocal, model.NomeLocal);
                        inputServicoProdutoDataGarantia.setValue(model.DataGarantia);
                        inputServicoProdutoCobrar.setValue(model.Cobrar === "Sim" ? true : false);

                        u.disable("buttonServicoProdutoAdicionar");
                        globalAssistenciaTecnica.Configuracoes.AST_ATENDIMENTO_ALTERAR ? u.enable("buttonServicoProdutoAlterar") : false;
                        globalAssistenciaTecnica.Configuracoes.AST_ATENDIMENTO_REMOVER ? u.enable("buttonServicoProdutoRemover") : false;
                    }

                    function getServicoProduto() {
                        request2("Assistec/Movimentos/GetServicoProduto",
                            {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex(),
                                IndexServicoProduto: gridServicosProdutos.getSelectedDataIndex()
                            },
                            function (model) {
                                setServicosProdutos(model);
                            });
                    }

                    function getObjServicoProduto() {
                        if (isChecked("inputServicoProdutoServico")) {
                            return {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex(),
                                IndexServicoProduto: gridServicosProdutos.getSelectedDataIndex(),

                                IsServico: true,
                                CodigoTabelaPreco: inputServicoProdutoCodigoTabelaPrecoServico.getValue(),

                                CodigoServicoProduto: inputServicoProdutoCodigoServico.getValue(),
                                DescricaoServicoProduto: inputServicoProdutoCodigoServico.getDescription(),

                                Complemento: inputServicoProdutoComplemento.get(),

                                IsHora: inputServicoProdutoQuantidade.isHora,
                                Quantidade: inputServicoProdutoQuantidade.getValue(),
                                ValorUnitario: inputServicoProdutoValorUnitario.getValue(),
                                ValorDescontoUnitario: inputServicoProdutoValorDescontoUnitario.getValue(),

                                DataGarantia: inputServicoProdutoDataGarantia.getValue(),
                                Cobrar: inputServicoProdutoCobrar.getValue() ? "Sim" : "Não",
                            }
                        }
                        else {
                            var produtoGrades = inputServicoProdutoCodigoProduto.getProdutoGrades();
                            return {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex(),
                                IndexServicoProduto: gridServicosProdutos.getSelectedDataIndex(),

                                IsServico: false,
                                CodigoTabelaPreco: inputServicoProdutoCodigoTabelaPrecoProduto.getValue(),

                                CodigoServicoProduto: produtoGrades.CodigoProduto,
                                DescricaoServicoProduto: produtoGrades.DescricaoProduto,

                                HaveGrade1: produtoGrades.HaveGrade1,
                                CodigoGrade1: produtoGrades.CodigoGrade1,
                                DescricaoGrade1: produtoGrades.DescricaoGrade1,

                                HaveGrade2: produtoGrades.HaveGrade2,
                                CodigoGrade2: produtoGrades.CodigoGrade2,
                                DescricaoGrade2: produtoGrades.DescricaoGrade2,

                                HaveGrade3: produtoGrades.HaveGrade3,
                                CodigoGrade3: produtoGrades.CodigoGrade3,
                                DescricaoGrade3: produtoGrades.DescricaoGrade3,

                                Complemento: inputServicoProdutoComplemento.get(),

                                Quantidade: inputServicoProdutoQuantidade.getValue(),
                                ValorUnitario: inputServicoProdutoValorUnitario.getValue(),
                                ValorDescontoUnitario: inputServicoProdutoValorDescontoUnitario.getValue(),

                                CodigoLocal: inputServicoProdutoCodigoLocal.getValue(),
                                DataGarantia: inputServicoProdutoDataGarantia.getValue(),
                                Cobrar: inputServicoProdutoCobrar.getValue() ? "Sim" : "Não"
                            }
                        }
                    }

                    function checkServicoProduto() {
                        if (isChecked("inputServicoProdutoServico")) {
                            if (inputServicoProdutoCodigoTabelaPrecoServico.isEmpty()) {
                                u.dialogOk("O campo \"Tabela Preços\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoCodigoTabelaPrecoServico.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }

                            if (inputServicoProdutoCodigoServico.isEmpty()) {
                                u.dialogOk("O campo \"Serviço\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoCodigoServico.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }
                        }
                        else {
                            if (inputServicoProdutoCodigoTabelaPrecoProduto.isEmpty()) {
                                u.dialogOk("O campo \"Tabela Preços\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoCodigoTabelaPrecoProduto.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }

                            if (inputServicoProdutoCodigoProduto.isEmpty()) {
                                u.dialogOk("O campo \"Produto\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoCodigoProduto.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }

                            if (inputServicoProdutoCodigoLocal.isEmpty()) {
                                u.dialogOk("O campo \"Local\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                    u.changeTab(tabs.Atendimentos);
                                    inputServicoProdutoCodigoLocal.focusError();
                                }, alertBehavior.warning);
                                return false;
                            }
                        }

                        if (inputServicoProdutoQuantidade.isEmptyOrZeros()) {
                            u.dialogOk("O campo \"Quantidade\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputServicoProdutoQuantidade.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputServicoProdutoValorUnitario.isEmptyOrZeros()) {
                            u.dialogOk("O campo \"Valor Unitário\" da aba \"Atendimento\" deve ser informado.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputServicoProdutoValorUnitario.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (!inputServicoProdutoDataGarantia.isEmpty && inputServicoProdutoDataGarantia.getValueDate() < convertDateStringDDMMYYYYToDate(inputPrincipalDataAbertura.getValue())) {
                            u.dialogOk("A data de garantia deve ser igual ou superior a data de abertura.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputServicoProdutoDataGarantia.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (!inputServicoProdutoValorDescontoUnitario.isEmptyOrZeros() && inputServicoProdutoValorUnitario.getValueNumber() === inputServicoProdutoValorDescontoUnitario.getValueNumber()) {
                            u.dialogOk("Desconto inválido. Informe um valor menor que o valor unitário.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputServicoProdutoValorUnitario.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        if (inputServicoProdutoCobrar.getValue() && inputServicoProdutoValorTotal.isEmptyOrZeros()) {
                            u.dialogOk("Informe um valor para o serviço/produto.", null, true, function () {
                                u.changeTab(tabs.Atendimentos);
                                inputServicoProdutoValorUnitario.focusError();
                            }, alertBehavior.warning);
                            return false;
                        }

                        return true;
                    }

                    function addServicoProduto() {
                        if (!checkServicoProduto()) {
                            return;
                        }

                        request2("Assistec/Movimentos/AddServicoProduto",
                            getObjServicoProduto(),
                            function (model) {
                                // trazer opção "Serviços" como default, mas se o usuário adicionar um produto,
                                // manter opção "Produtos" marcada para ser utilizada nas inclusões seguintes
                                globalConfigDefault.ServicoOrProduto = isChecked("inputServicoProdutoServico");

                                setServicosProdutosDefault(model);
                            });
                    }

                    function updateServicoProduto() {
                        if (!checkServicoProduto()) {
                            return;
                        }

                        request2("Assistec/Movimentos/UpdateServicoProduto",
                            getObjServicoProduto(),
                            function (model) {
                                setServicosProdutosDefault(model);
                            });
                    }

                    function deleteServicoProduto() {
                        if (!checkServicoProduto()) {
                            return;
                        }

                        request2("Assistec/Movimentos/DeleteServicoProduto",
                            {
                                Id: params.Id,
                                DataEmissao: params.DataEmissao,
                                IndexAtendimento: gridAtendimentosAtendimentos.getSelectedDataIndex(),
                                IndexServicoProduto: gridServicosProdutos.getSelectedDataIndex()
                            },
                            function (model) {
                                setServicosProdutosDefault(model);
                            });
                    }

                    //
                    // load
                    //

                    loadAssistenciaTecnica();

                }(params));
            }
        }
    }());

    Compras.Manager = (function () {
        return {
            Cotacao: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial", true);
                    currentUser.update({ NomeBase: "Cotacao", Nome: "Cotacao" });
                    carregaLogoClienteCompras(params.CodigoGuid);
                    GuidProxy = params.GuidProxy;

                    //
                    // itens cotacao
                    //

                    // itens
                    var gridItens = new Grid({
                        id: "gridItens",
                        columns: [
                            { field: "Descricao", title: "Descrição", width: 150, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "UnidadeMedida", title: "Un. Medida", width: 60, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "Quantidade", title: "Quantidade", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" } },
                            { field: "ValorUnitario", title: "Vlr. Unitário", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorDescontoUnitario", title: "Desc. Unitário", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorTotal", title: "Total", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" }
                        ],
                        onChange: function (data) {
                            setVal("inputItensDescricao", data.Descricao);
                            setVal("inputItensUnidadeMedida", data.UnidadeMedida);
                            setVal("inputItensQuantidade", data.Quantidade);

                            inputItensValorUnitario.enable(true);
                            inputItensValorUnitario.setValue(data.ValorUnitario);

                            inputItensValorDescontoUnitario.enable(true);
                            inputItensValorDescontoUnitario.setValue(data.ValorDescontoUnitario);

                            inputItensValorTotal.setValue(data.ValorTotal);

                            if (data.IsProduto) {
                                inputAliqIPI.enable(true);
                                inputAliqIPI.setValue(data.AliqIPI);
                                inputAliqICMS.enable(true);
                                inputAliqICMS.setValue(data.AliqICMS);
                            }
                            else {
                                inputAliqIPI.enable(false);
                                inputAliqIPI.setValue("0,00");
                                inputAliqICMS.enable(false);
                                inputAliqICMS.setValue("0,00");
                            }

                            inputItensObservacao.enable(true);
                            inputItensObservacao.set(data.Observacao, false);
                        },
                        height: 142
                    });

                    // valor unitario
                    var inputItensValorUnitario = new ValidatorMask({
                        idInput: "inputItensValorUnitario",
                        mask: "radar-valor-8-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                            totalizaItem("ValorUnitario");
                        }
                    });

                    // valor desconto unitario
                    var inputItensValorDescontoUnitario = new ValidatorMask({
                        idInput: "inputItensValorDescontoUnitario",
                        mask: "radar-valor-7-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                            if (inputItensValorDescontoUnitario.getValueNumber() > inputItensValorUnitario.getValueNumber()) {
                                u.dialogOk("O desconto unitário deve ser menor que o valor unitário.", null, true, null, alertBehavior.warning);
                                inputItensValorDescontoUnitario.setValue("0,00");
                                totalizaItem("ValorDescontoUnitario");
                            }
                            else
                                totalizaItem("ValorDescontoUnitario");
                        }
                    });

                    // aliq ipi
                    var inputAliqIPI = new ValidatorMask({
                        idInput: "inputAliqIPI",
                        mask: "radar-valor-3-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                            if (getVal("inputAliqIPI").toFloat() > 100.00)
                                inputAliqIPI.setValue("100,00");

                            totalizaItem("AliqIPI");
                        }
                    });

                    // aliq icms
                    var inputAliqICMS = new ValidatorMask({
                        idInput: "inputAliqICMS",
                        mask: "radar-valor-3-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                            if (getVal("inputAliqICMS").toFloat() > 100.00)
                                inputAliqICMS.setValue("100,00");

                            totalizaItem("AliqICMS");
                        }
                    });

                    // valor total
                    var inputItensValorTotal = new ValidatorMask({
                        idInput: "inputItensValorTotal",
                        mask: "radar-valor-10-2"
                    });

                    // observacao
                    var inputItensObservacao = new ValidatorMemo({
                        idInput: "inputItensObservacao",
                        idLink: "inputItensObservacaoLink",
                        attr: { disabled: "disabled" },
                        css: { width: "792px" },
                        onChange: function () {
                            totalizaItem("Observacao");
                        }
                    });

                    function totalizaItem(fieldChange) {
                        var paramsResquest = {
                            CodigoGuid: params.CodigoGuid,
                            Item: getObjItem(),
                        }

                        var paramsTransfer = {
                            fieldChange: fieldChange
                        }

                        request("Compras/Movimentos/UpdateItem", paramsResquest,
                            function (data, paramsTransfer) {
                                try {
                                    if (data.IsAlert) {
                                        u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                    } else {
                                        if (paramsTransfer.fieldChange === "AliqIPI" || paramsTransfer.fieldChange === "AliqICMS") {
                                            gridItens.setValueColumnSelectInDatasource(paramsTransfer.fieldChange, convertStringDecimalPtBrToFloat(data.Item[paramsTransfer.fieldChange]));
                                        }

                                        if (paramsTransfer.fieldChange === "Observacao") {
                                            gridItens.setValueColumnSelectInDatasource(paramsTransfer.fieldChange, data.Item[paramsTransfer.fieldChange]);
                                        }

                                        if (paramsTransfer.fieldChange === "ValorUnitario" || paramsTransfer.fieldChange === "ValorDescontoUnitario" || paramsTransfer.fieldChange === "AliqIPI") {
                                            if (paramsTransfer.fieldChange)
                                                gridItens.setValueColumnSelect(paramsTransfer.fieldChange, convertStringDecimalPtBrToFloat(data.Item[paramsTransfer.fieldChange]));

                                            gridItens.setValueColumnSelect("ValorTotal", convertStringDecimalPtBrToFloat(data.Item.ValorTotal));
                                            inputItensValorTotal.setValue(convertStringDecimalPtBrToFloat(data.Item.ValorTotal));

                                            // totais/prazo proposta
                                            inputTotaisPrazoPropostaValorTotalBruto.setValue(convertStringDecimalPtBrToFloat(data.ValorTotalBrutoProposta));
                                            inputTotaisPrazoPropostaValorTotalDescontos.setValue(convertStringDecimalPtBrToFloat(data.ValorTotalDescontoProposta));
                                            inputTotaisPrazoPropostaValorTotalCotacao.setValue(convertStringDecimalPtBrToFloat(data.ValorTotalCotacaoProposta));
                                        }

                                        // se alterar qualquer campo dos itens da cotacao, tem que resetar as parcelas para calcular novamente
                                        // verifica se tem algum item com valor unitario informado
                                        var registros = gridItens.getDataSource();
                                        var temItemInformado = false;
                                        $.each(registros, function (atual) {
                                            if (registros[atual].ValorUnitario > 0) {
                                                temItemInformado = true;
                                                return false;
                                            }
                                        });

                                        // somente habilita os campos para gerar as pacelas, quando tiver ao menos um item com valor unitario informado
                                        // habilita/desabilita campos
                                        inputPagamentoCondicaoPagamento.setEnable(temItemInformado);
                                        if (!temItemInformado) inputPagamentoCondicaoPagamento.setValue(0);

                                        inputPagamentoNumeroParcelas.enable(temItemInformado);
                                        inputPagamentoNumeroParcelas.setValue(inputPagamentoNumeroParcelas.defaultValue);

                                        inputPagamentoDataPrimeiroVencimento.enable(temItemInformado);
                                        inputPagamentoTipoPeriodo.setEnable(temItemInformado);

                                        // grid
                                        gridParcelas.clear();

                                        // desabilita campos/button do grid
                                        inputPagamentoParcela.setValue("");
                                        inputPagamentoParcela.enable(false);
                                        inputPagamentoDataVencimento.setValue("");
                                        inputPagamentoDataVencimento.enable(false);
                                        inputPagamentoValorBrutoParcela.setValue("");
                                        inputPagamentoValorBrutoParcela.enable(false);
                                        u.disable("buttonPagamentoAlterar");

                                        // botao ok
                                        u.disable("buttonOK");
                                    }
                                }
                                catch (err) {
                                    u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                }
                            },
                            function (data) {
                                u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                            },
                            false,
                            paramsTransfer
                        );
                    }

                    function getObjItem() {
                        return {
                            IdProdServ: gridItens.getSelectedData().IdProdServ,
                            Indice: gridItens.getSelectedData().Indice,
                            IsProduto: gridItens.getSelectedData().IsProduto,
                            Descricao: getVal("inputItensDescricao"),
                            UnidadeMedida: getVal("inputItensUnidadeMedida"),
                            Quantidade: getVal("inputItensQuantidade"),
                            ValorUnitario: getVal("inputItensValorUnitario"),
                            ValorDescontoUnitario: getVal("inputItensValorDescontoUnitario"),
                            ValorTotal: getVal("inputItensValorTotal"),
                            AliqIPI: getVal("inputAliqIPI"),
                            AliqICMS: getVal("inputAliqICMS"),
                            Observacao: inputItensObservacao.get()
                        };
                    }

                    //
                    // informacoes frete/entrega
                    //

                    // prazo entrega
                    var inputFreteEntregaQtdDiasPrazoEntrega = new ValidatorMask({
                        idInput: "inputFreteEntregaQtdDiasPrazoEntrega",
                        mask: "radar-valor-4-0",
                        onChange: function () {
                            request("Compras/Movimentos/ComputeDataEntrega", { qtdDiasPrazoEntrega: inputFreteEntregaQtdDiasPrazoEntrega.getValueNumber() },
                                function (data) {
                                    try {
                                        if (data.IsAlert) {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        } else {
                                            inputFreteEntregaDataEntrega.setValueBkp(data);
                                        }
                                    }
                                    catch (err) {
                                        u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                    }
                                },
                                function (data) {
                                    u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                                },
                                false
                            );
                        }
                    });

                    // data entrega
                    var inputFreteEntregaDataEntrega = new ValidatorDate({
                        idInput: "inputFreteEntregaDataEntrega",
                        isEmptyValid: true,
                        onChange: function () {
                            if (inputFreteEntregaDataEntrega.isMinorDateNow()) {
                                u.dialogOk("Data de entrega deve ser igual ou superior a data de hoje", null, true, null, alertBehavior.warning);
                                inputFreteEntregaDataEntrega.setValue("");
                            }
                            inputFreteEntregaQtdDiasPrazoEntrega.setValue("");
                        }
                    });

                    // valor frete
                    var inputFreteEntregaValorFrete = new ValidatorMask({
                        idInput: "inputFreteEntregaValorFrete",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                            inputTotaisPrazoPropostaValorFrete.setValue(inputFreteEntregaValorFrete.getValue());

                            var paramsResquest = {
                                CodigoGuid: params.CodigoGuid,
                                valorFrete: inputFreteEntregaValorFrete.getValue()
                            }

                            request("Compras/Movimentos/UpdateFrete", paramsResquest,
                                function (data) {
                                    try {
                                        if (data.IsAlert) {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        } else {
                                            loadGridItens(data.Itens);
                                            inputTotaisPrazoPropostaValorTotalCotacao.setValue(convertStringDecimalPtBrToFloat(data.ValorTotalCotacaoProposta));
                                            loadGridParcelas(data.Parcelas);
                                        }
                                    }
                                    catch (err) {
                                        u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                    }
                                },
                                function (data) {
                                    u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                                },
                                true
                            );
                        }
                    });

                    //
                    // totais/prazo proposta
                    //

                    // valor total bruto
                    var inputTotaisPrazoPropostaValorTotalBruto = new ValidatorMask({
                        idInput: "inputTotaisPrazoPropostaValorTotalBruto",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00"
                    });

                    // valor total desconto
                    var inputTotaisPrazoPropostaValorTotalDescontos = new ValidatorMask({
                        idInput: "inputTotaisPrazoPropostaValorTotalDescontos",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00"
                    });

                    // valor frete
                    var inputTotaisPrazoPropostaValorFrete = new ValidatorMask({
                        idInput: "inputTotaisPrazoPropostaValorFrete",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00"
                    });

                    // valor total cotacao
                    var inputTotaisPrazoPropostaValorTotalCotacao = new ValidatorMask({
                        idInput: "inputTotaisPrazoPropostaValorTotalCotacao",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00"
                    });

                    // prazo proposta
                    var inputTotaisPrazoPropostaPrazoProposta = new ValidatorDate({
                        idInput: "inputTotaisPrazoPropostaPrazoProposta",
                        isEmptyValid: true,
                        onChange: function () {
                            if (inputTotaisPrazoPropostaPrazoProposta.isMinorDateNow()) {
                                u.dialogOk("Data de Prazo de Proposta deve ser igual ou superior a data de hoje", null, true, null, alertBehavior.warning);
                                inputTotaisPrazoPropostaPrazoProposta.setValue("");
                            }
                        }
                    });

                    //
                    // informacoes pagamento
                    //

                    // codicao pagamento
                    var inputPagamentoCondicaoPagamento = new ValidatorDropDown({
                        idInputCodigo: "inputPagamentoCondicaoPagamento",
                        dataSource: [],
                        enable: false,
                        onChange: function () {
                            makeParcelas(true);
                        }
                    });

                    // numero parcelas
                    var inputPagamentoNumeroParcelas = new ValidatorNumber({
                        idInput: "inputPagamentoNumeroParcelas",
                        isEmptyValid: true,
                        maxLength: 3,
                        onInput: function () {
                            inputPagamentoCondicaoPagamento.setValue(0);
                            makeParcelas();
                        }
                    });

                    // data primeiro vencimento
                    var inputPagamentoDataPrimeiroVencimento = new ValidatorDate({
                        idInput: "inputPagamentoDataPrimeiroVencimento",
                        isEmptyValid: true,
                        onChange: function () {
                            if (inputPagamentoDataPrimeiroVencimento.isValid) {
                                if (inputPagamentoDataPrimeiroVencimento.getValue() === "" || inputPagamentoDataPrimeiroVencimento.isMinorDateNow()) {
                                    u.dialogOk("Data do Vencimento da parcela inválida", null, true, null, alertBehavior.warning);
                                    inputPagamentoDataPrimeiroVencimento.setValue("");
                                }

                                inputPagamentoCondicaoPagamento.setValue(0);
                                makeParcelas();
                            }
                        }
                    });

                    // tipo periodo
                    var inputPagamentoTipoPeriodo = new ValidatorDropDown({
                        idInputCodigo: "inputPagamentoTipoPeriodo",
                        dataSource: [],
                        enable: false,
                        onChange: function () {
                            inputPagamentoCondicaoPagamento.setValue(0);
                            makeParcelas();
                        }
                    });

                    //
                    // parcelas cotacao
                    //

                    // parcelas
                    var gridParcelas = new Grid({
                        id: "gridParcelas",
                        columns: [
                            { field: "Numero", title: "Parcela", width: 40, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { field: "DataVencimento", title: "Vencimento", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, type: "date", format: "{0:dd/MM/yyyy}" },
                            { field: "ValorBruto", title: "Valor Bruto", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" },
                            { field: "ValorAcumulado", title: "Valor Acumulado", width: 80, headerAttributes: { style: "color: black; text-align: right;" }, attributes: { style: "text-align: right;" }, format: "{0:C}" }
                        ],
                        onChange: function (data) {
                            inputPagamentoParcela.setValue(data.Numero);
                            inputPagamentoDataVencimento.setValue(data.DataVencimento);
                            inputPagamentoValorBrutoParcela.setValue(data.ValorBruto);
                            u.enable("inputPagamentoDataVencimento");
                            u.enable("inputPagamentoValorBrutoParcela");
                            u.enable("buttonPagamentoAlterar");
                        },
                        height: 142
                    });

                    // parcela
                    var inputPagamentoParcela = new ValidatorMask({
                        idInput: "inputPagamentoParcela",
                        mask: "radar-valor-3-0"
                    });

                    // data vencimento
                    var inputPagamentoDataVencimento = new ValidatorDate({
                        idInput: "inputPagamentoDataVencimento",
                        isEmptyValid: true
                    });

                    // valor bruto parcela
                    var inputPagamentoValorBrutoParcela = new ValidatorMask({
                        idInput: "inputPagamentoValorBrutoParcela",
                        mask: "radar-valor-10-2",
                        isEmptyValid: false,
                        defaultValue: "0,00",
                        onChange: function () {
                        }
                    });

                    // button alterar
                    byId("buttonPagamentoAlterar").onclick = function () {
                        if (isFieldEnabled("buttonPagamentoAlterar")) {
                            var paramsResquest = {
                                CodigoGuid: params.CodigoGuid,
                                index: gridParcelas.getSelectedDataIndex(),
                                DataVencimento: inputPagamentoDataVencimento.getValue(),
                                ValorBrutoParcela: inputPagamentoValorBrutoParcela.getValue()
                            }

                            request("Compras/Movimentos/UpdateParcela", paramsResquest,
                                function (data) {
                                    try {
                                        if (data.IsAlert) {
                                            u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                        } else {
                                            loadGridParcelas(data);
                                            inputPagamentoParcela.setValue("");
                                            inputPagamentoDataVencimento.setValue("");
                                            inputPagamentoValorBrutoParcela.setValue("");
                                            u.disable("inputPagamentoDataVencimento");
                                            u.disable("inputPagamentoValorBrutoParcela");
                                            u.disable("buttonPagamentoAlterar");
                                        }
                                    }
                                    catch (err) {
                                        u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                    }
                                },
                                function (data) {
                                    u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                                },
                                true
                            );
                        }
                    }

                    function makeParcelas(changeCondicaoPagamento) {
                        var paramsResquest = {
                            CodigoGuid: params.CodigoGuid,
                            CondicaoPagamento: inputPagamentoCondicaoPagamento.getValue(),
                            ChangeCondicaoPagamento: changeCondicaoPagamento,
                            NumeroParcelas: inputPagamentoNumeroParcelas.getValue(),
                            DataPrimeiroVencimento: inputPagamentoDataPrimeiroVencimento.getValue(),
                            TipoPeriodo: inputPagamentoTipoPeriodo.getValue()
                        }

                        request("Compras/Movimentos/MakeParcelas", paramsResquest,
                            function (data) {
                                try {
                                    if (data.IsAlert) {
                                        u.dialogOk(data.Message, null, true, null, alertBehavior.warning);
                                    } else {
                                        if (inputPagamentoCondicaoPagamento.getValue()) {
                                            inputPagamentoNumeroParcelas.setValue(data.NumeroParcelas);
                                        }

                                        inputPagamentoParcela.setValue("");
                                        inputPagamentoDataVencimento.setValue("");
                                        inputPagamentoValorBrutoParcela.setValue("");
                                        u.disable("inputPagamentoDataVencimento");
                                        u.disable("inputPagamentoValorBrutoParcela");
                                        u.disable("buttonPagamentoAlterar");

                                        if (data.Parcelas.length > 0) {
                                            loadGridParcelas(data.Parcelas);
                                            u.enable("buttonOK");
                                        }
                                        else {
                                            gridParcelas.clear();
                                            u.disable("buttonOK");
                                        }
                                    }
                                } catch (err) {
                                    u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                }
                            },
                            function (data) {
                                u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                            },
                            true
                        );
                    }

                    //
                    // principal
                    //

                    // button OK
                    byId("buttonOK").onclick = function () {
                        if (isFieldEnabled("buttonOK")) {
                            saveCotacao();
                        }
                    }

                    function saveCotacao() {
                        request("Compras/Movimentos/SaveCotacao",
                            {
                                CodigoGuid: params.CodigoGuid,
                                
                                QtdDiasPrazoEntrega: inputFreteEntregaQtdDiasPrazoEntrega.getValue(),
                                DataEntrega: inputFreteEntregaDataEntrega.getValue(),
                                ValorFrete: inputFreteEntregaValorFrete.getValue(),
                                
                                DataPrazoProposta: inputTotaisPrazoPropostaPrazoProposta.getValue(),
                                ObservacaoProposta: getVal("inputTotaisPrazoPropostaObservacao")
                            },
                            function (model) {
                                try {
                                    if (model.IsAlert) {
                                        u.dialogOk(model.Message, null, true, null, alertBehavior.warning);
                                    } else if (model.CotacaoJaCotadaException) {
                                        u.dialogOk(model.Message, null, true, null, alertBehavior.warning);
                                    } else {
                                        window.location = window.baseUrl + "Compras/Relatorios/Cotacao?CodigoGuid=" + params.CodigoGuid;
                                    }
                                }
                                catch (err) {
                                    u.dialogOk(err.message, null, true, null, alertBehavior.warning);
                                }
                            },
                            function (data) {
                                u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning);
                            },
                            true
                        );
                    }

                    function getCotacao() {
                        request("Compras/Movimentos/GetCotacao",
                            {
                                CodigoGuid: params.CodigoGuid
                            },
                            function (model) {
                                try {
                                    if (model.IsAlert) {
                                        u.dialogOk(model.Message, null, true, null, alertBehavior.warning, null, true);
                                    } else if (model.Status === model.EnumStatus.DATA_LIMITE_ULTRAPASSADA) {
                                        u.dialogOk("Cotação com data limite ultrapassada.", function () {
                                                window.location = window.baseUrl + "Compras/Relatorios/Cotacao?CodigoGuid=" + params.CodigoGuid;
                                            },
                                            true, null, alertBehavior.warning, null, false);
                                    } else {
                                        loadCotacao(model);
                                    }
                                }
                                catch (err) {
                                    u.dialogOk(err.message, null, true, null, alertBehavior.warning, null, true);
                                }
                            },
                            function (data) {
                                u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning, null, true);
                            },
                            true
                        );
                    }

                    function loadCotacao(model) {
                        setHtml("inputCabecalhoEmpresa", model.NomeEmpresa);
                        setHtml("inputCabecalhoCotacao", model.Codigo);

                        setVal("inputPrincipalFornecedor", model.Fornecedor);
                        setVal("inputPrincipalDataCotacao", model.Data);
                        setVal("inputPrincipalDataLimite", model.DataLimite);
                        setVal("inputPrincipalMoeda", model.Moeda);
                        setVal("inputPrincipalObservacao", model.Observacao);

                        // itens
                        loadGridItens(model.Itens);

                        // informacoes frete/entrega
                        setVal("inputFreteEntregaLocalEntrega", model.LocalEntrega);
                        setVal("inputFreteEntregaQtdDiasPrazoEntrega", "");
                        setVal("inputFreteEntregaDataEntrega", model.DataEntrega);
                        setVal("inputFreteEntregaValorFrete", model.ValorFrete);

                        // totais/prazo proposta
                        setVal("inputTotaisPrazoPropostaValorTotalBruto", model.ValorTotalBrutoProposta);
                        setVal("inputTotaisPrazoPropostaValorTotalDescontos", model.ValorTotalDescontoProposta);
                        setVal("inputTotaisPrazoPropostaValorFrete", model.ValorFrete);
                        setVal("inputTotaisPrazoPropostaValorTotalCotacao", model.ValorTotalCotacaoProposta);
                        setVal("inputTotaisPrazoPropostaPrazoProposta", model.DataPrazoProposta);
                        setVal("inputTotaisPrazoPropostaObservacao", model.ObservacaoProposta);

                        // informacoes pagamento
                        inputPagamentoCondicaoPagamento.setDataSource(model.CondicoesPagamento);
                        setVal("inputPagamentoDataPrimeiroVencimento", model.DataPrimeiroVencimento);
                        inputPagamentoTipoPeriodo.setDataSource(model.TiposPeriodo);

                        // parcelas
                        loadGridParcelas(model.Parcelas);
                    }

                    function loadGridItens(dados) {
                        gridItens.setValue(dados, function (reg) {
                            return {
                                Indice: reg.Indice,
                                IdProdServ: reg.IdProdServ,
                                IsProduto: reg.IsProduto,
                                Descricao: reg.Descricao,
                                UnidadeMedida: reg.UnidadeMedida,
                                Quantidade: reg.Quantidade,
                                ValorUnitario: convertStringDecimalPtBrToFloat(reg.ValorUnitario),
                                ValorDescontoUnitario: convertStringDecimalPtBrToFloat(reg.ValorDescontoUnitario),
                                ValorTotal: convertStringDecimalPtBrToFloat(reg.ValorTotal),
                                AliqIPI: convertStringDecimalPtBrToFloat(reg.AliqIPI),
                                AliqICMS: convertStringDecimalPtBrToFloat(reg.AliqICMS),
                                Observacao: reg.Observacao
                            }
                        });
                    }

                    function loadGridParcelas(dados) {
                        if (dados !== undefined) {
                            gridParcelas.setValue(dados, function (reg) {
                                return {
                                    Numero: reg.Numero,
                                    DataVencimento: reg.DataVencimento,
                                    ValorBruto: reg.ValorBruto,
                                    ValorAcumulado: reg.ValorAcumulado,
                                    Observacao: reg.Observacao
                                }
                            });
                        }
                    }

                    getCotacao();
                })(params);
            },

            Resumo: function (params) {
                return (function () {
                    $("<div id='modalDiv'>").appendTo("body");
                    carregaLogoClienteCompras(params.CodigoGuid);
                }(params));
            }
        };
    })();

    Test = (function () {
        return {
            TestKendoGrid: function (params) {
                return (function () {
                    var u = new Util();
                    //$("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    //u.alert("TestKendoGrid", alertBehavior.success);

                    //for (var i in navigator) {
                    //    if (typeof navigator[i] === 'string')
                    //        logd(i + ": " + navigator[i]);
                    //    if (typeof navigator[i] === "function") {
                    //        try {
                    //            logd(navigator[i]());
                    //        }
                    //        catch (err) {
                    //            logd("erro na function " + i);
                    //        }
                    //    }
                    //}

                    // cliente
                    var inputPrincipalCodigoCliente = new ValidatorLookup({
                        abrev: "PrincipalCodigoCliente",
                        fieldSearch: "CodigoCliente",
                        fieldDescription: "RazaoSocial",
                        msgPendencyMessagePartEnd: "do cliente.",
                        route: "Empresarial/F4Cliente/GetCliente",
                        routeTable: "Empresarial/F4Cliente/GetClientes",
                        columnsTable: [
                            { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                            { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                        ],
                        titleModal: "Clientes"
                    });

                    // grid2
                    var dataSource2 = {
                        type: "JSON",
                        transport: {
                            read: function (options) {
                                var data = {};

                                data['Paging'] = {
                                    Page: 1,
                                    PageSize: 5,
                                    Skip: 0,
                                    Take: 5
                                }

                                //data["Sorting"] = self.getSortingOptions(options);
                                //data["Filter"] = filter;
                                //data['Paging'] = self.getPagingOptions(options);
                                //data["classePai"] = self.classePai;
                                //var params = self.getParams();
                                //if (params != undefined) {
                                //    data['Params'] = params;
                                //}

                                $.ajax({
                                    headers: {
                                        'Accept': 'application/json',
                                        'Content-Type': 'application/json'
                                    },
                                    url: window.baseUrl + "Empresarial/F4Cliente/GetClientes",
                                    dataType: "json",
                                    type: "POST",
                                    data: JSON.stringify(data),
                                    success: function (result) {
                                        if (result.IsAlert) {
                                            options.success({ data: new Array(), total: 0 });
                                        } else {
                                            options.success(result);
                                        }

                                        log("datasource succes");
                                        vt3 = result;
                                        $(".k-loading-mask").remove();
                                    },
                                    error: function (result) {
                                        log("datasource erro");
                                        vt3 = result;
                                        $(".k-loading-mask").remove();
                                    }
                                });
                            }
                        },
                        schema: {
                            data: 'data',
                            total: 'total'
                        },
                        serverPaging: true,
                        serverSorting: true,
                        pageSize: 5
                    };

                    byId("buttonReloadGrid2").onclick = function () {
                        var grid = $("#inputPrincipalGrid2").kendoGrid({
                            dataSource: dataSource2,

                            change: function (ev) {
                            },
                            dataBound: function (ev) {
                            },
                            dataBinding: function (ev) {
                            },
                            columnReorder: function () {
                            },

                            toolbar: "toolbar",
                            reorderable: true,
                            resizable: true,
                            selectable: true,
                            columnMenu: true,
                            sortable: {
                                allowUnsort: true
                            },
                            pageable: {
                                refresh: true,
                                numeric: true,
                                pageSizes: [5, 10, 15],
                                buttonCount: 5
                            },
                            columns: [
                                { title: "Código", field: "Codigo", width: 75, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "Razão Social", field: "RazaoSocial", width: 230, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } },
                                { title: "CPF/CNPJ", field: "CnpjCpf", width: 115, headerAttributes: { style: "color: black; text-align: left;" }, attributes: { style: "text-align: left;" } }
                            ]
                        });
                        $("#inputPrincipalGrid2" + " .k-grid-content").height("150px");
                        //$("#inputPrincipalGrid2").addClass("k-state-selected-radar");

                        vt1 = grid;
                        vt2 = $("#inputPrincipalGrid2").data("kendoGrid");
                    };

                    byId("buttonSendHtml").onclick = function () {
                        request("TempDB/Write",
                            {
                                //dados: document.getElementsByTagName('html')[0].innerHTML
                                dados: JSON.stringify($("html"))
                            },
                            function (model) {
                                try {
                                    if (model.IsAlert) {
                                        u.dialogOk(model.Message, null, true, null, alertBehavior.warning, null, true);
                                    } else {
                                        u.dialogOk("Ok.", null, true, null, alertBehavior.success, null, false);
                                    }
                                }
                                catch (err) {
                                    u.dialogOk(err.message, null, true, null, alertBehavior.warning, null, true);
                                }
                            },
                            function (data) {
                                u.dialogOk(data.jqxhr.status + "-" + data.jqxhr.statusText, null, true, null, alertBehavior.warning, null, true);
                            },
                            true
                        );
                    };

                }(params));
            },

            TestComponentes: function (params) {
                return (function () {
                    var u = new Util();
                    $("<div id='modalDiv'>").appendTo("body");
                    u.addButtonHelpBreadcrumb("RadarWEB.htm", "Tela Inicial");

                    byId("buttonRequestOk").onclick = function () {
                        request2("Test/RequestOk", { Id: 123 },
                            function (model) {
                                u.dialogOk(model, null, true, function () { }, alertBehavior.success);
                            });
                    };

                    byId("buttonRequestErroAlert").onclick = function () {
                        request2("Test/RequestErroAlert", { Id: 123 }, null);
                    };

                    byId("buttonRequestErroAlertCustom").onclick = function () {
                        request2("Test/RequestErroAlertCustom", { Id: 123 },
                            null,
                            null,
                            function (model) {
                                u.dialogOk(model.Message + " CodeError=" + model.CodeError, null, true,
                                    function () {
                                    },
                                    getAlertBehavior(model.Level));
                            });
                    };

                    byId("buttonRequestErroInterno").onclick = function () {
                        request2("Test/RequestOk", { Id: 123 },
                            function (model) {
                                var x = xxx;
                            });
                    };

                    byId("buttonRequestErroServidor").onclick = function () {
                        request2("Test/RequestErroServidor", { Id: 123 },
                            null,
                            function (model) {
                                u.alert("rotina custom RequestErroServidor", alertBehavior.warning);
                            });
                    };

                    byId("buttonRequestRedirectLogin").onclick = function () {
                        request2("Test/RequestRedirectLogin", { Id: 123 },
                            null,
                            function (model) {
                            });
                    };
                }(params));
            }
        }
    }());

    // export

    $export.Util = Util;
    $export.alertBehavior = alertBehavior;

    return {
        // manter como esta, nao usar mais o Main no nome, e deixar o () no final,
        // assim o namespace fica mais simples e compativel
        // ex: "Radar.Web.Home.Personalizar(params)"
        Home: (function () {
            return {
                Personalizar: Home.Personalizar,
                Menu: Home.Menu
            };
        })(),

        EmpresarialMain: (function () {
            return {
                Listar: Empresarial.Manager.Listar,
                Cadastros: Empresarial.Manager.Cadastros,
                CadastrosFiliais: Empresarial.Manager.CadastrosFiliais,
                CadastrosFilial: Empresarial.Manager.CadastrosFilial,
                RelatoriosPlanoEmpresarial: Empresarial.Manager.RelatoriosPlanoEmpresarial,
                RelatoriosPlanoGerencial: Empresarial.Manager.RelatoriosPlanoGerencial,
                Propriedades: Empresarial.Manager.Propriedades
            };
        }),

        ContabilMain: (function () {
            return {
                MovimentosLancamentos: Contabil.Manager.MovimentosLancamentos,
                MovimentosLancamento: Contabil.Manager.MovimentosLancamento,
                ConsultasSaldoContabil: Contabil.Manager.ConsultasSaldoContabil,
                ConsultasAcompanhamento: Contabil.Manager.ConsultasAcompanhamento,
                RelatoriosBalancete: Contabil.Manager.RelatoriosBalancete,
                RelatoriosRazao: Contabil.Manager.RelatoriosRazao,
                RelatoriosDiarioDetalhado: Contabil.Manager.RelatoriosDiarioDetalhado,
                RelatoriosAcompanhamentoMensal: Contabil.Manager.RelatoriosAcompanhamentoMensal,
                RelatoriosInversaoGerencialBalancete: Contabil.Manager.RelatoriosInversaoGerencialBalancete,
                RelatoriosGerador: Contabil.Manager.RelatoriosGerador
            };
        }),

        ComercialMain: (function (params) {
            return {
                MovimentosPedidos: Comercial.Manager.MovimentosPedidos,
                MovimentosPedido: Comercial.Manager.MovimentosPedido,
                MovimentosAgendamentos: Comercial.Manager.MovimentosAgendamentos,
                MovimentosAgendamento: Comercial.Manager.MovimentosAgendamento,
                ConsultasHistoricoClientes: Comercial.Manager.ConsultasHistoricoClientes,
                ConsultasSaldoProdutoNoEstoque: Comercial.Manager.ConsultasSaldoProdutoNoEstoque,
                RelatoriosRelacaoDePedidos: Comercial.Manager.RelatoriosRelacaoDePedidos,
                RelatoriosComissoesAPagar: Comercial.Manager.RelatoriosComissoesAPagar,
                RelatoriosMovimentos: Comercial.Manager.RelatoriosMovimentos
            }
        }),

        GerenciadorMain: (function (params) {
            return {
                MovimentosAtendimentosTecnicos: Gerenciador.Manager.MovimentosAtendimentosTecnicos,
                MovimentosAtendimentoTecnico: Gerenciador.Manager.MovimentosAtendimentoTecnico
            };
        }),

        GedMain: (function (params) {
            return {
                Busca: Ged.Manager.Busca
            };
        }),

        ExecutivoMain: (function (params) {
            return {
                Dashboard: Executivo.Manager.Dashboard
            };
        }),

        FinanceiroMain: (function () {
            return {
                MovimentosAutorizacaoPagamento: Financeiro.Manager.MovimentosAutorizacaoPagamento,
                ConsultasPosicaoFinanceiraClientesFornecedores: Financeiro.Manager.ConsultasPosicaoFinanceiraClientesFornecedores,
                ConsultasSaldoDeContasBancarias: Financeiro.Manager.ConsultasSaldoDeContasBancarias,
                RelatoriosFluxoDeCaixa: Financeiro.Manager.RelatoriosFluxoDeCaixa,
                RelatoriosTesourariaMovimentos: Financeiro.Manager.RelatoriosTesourariaMovimentos
            };
        }),

        EstoqueMain: (function () {
            return {
                ConsultasSaldoPorLocal: Estoque.Manager.ConsultasSaldoPorLocal,
                RelatoriosInventario: Estoque.Manager.RelatoriosInventario,
                RelatoriosMovimentos: Estoque.Manager.RelatoriosMovimentos,
                RelatoriosPontoDeReposicao: Estoque.Manager.RelatoriosPontoDeReposicao,
                RelatoriosRegistroEstoque: Estoque.Manager.RelatoriosRegistroEstoque,
                RelatoriosSaldoDoEstoque: Estoque.Manager.RelatoriosSaldoDoEstoque
            };
        }),

        AssistecMain: (function () {
            return {
                MovimentosAssistenciasTecnicas: Assistec.Manager.MovimentosAssistenciasTecnicas,
                MovimentosAssistenciaTecnica: Assistec.Manager.MovimentosAssistenciaTecnica
            }
        })(),

        ComprasMain: (function () {
            return {
                MovimentosCotacao: Compras.Manager.Cotacao,
                RelatoriosResumo: Compras.Manager.Resumo
            };
        }),

        Test: (function () {
            return {
                TestKendoGrid: Test.TestKendoGrid,
                TestComponentes: Test.TestComponentes
            };
        })()
    };
})();