/* eslint-disable no-unused-vars */
function encriptografarSenha(senha) {
    let encrypted = btoa(`sISPKJSDLK${senha}@klSIp1q34534sS`);

    return encrypted;
}

let beep = null;
let erro = null;

const $traducaoSelecioneOsRegistros = {
    P: "Selecione o(s) registro(s)",
    I: "Select the records",
    E: "Seleccionar los registros",
    M: "选择记录"
}

const $traducaoDigite = { P: "Digite", I: "Type", E: "Escribe", M: "输入" };
const $traducaoBuscar = {
    P: "ou mais caracteres para pesquisar.",
    I: "or more characters to search.",
    E: "o más caracteres para buscar.",
    M: "或更多字符进行搜索。"
}

function abreEstatisticasCliente(codcli, nome) {
    if (codcli == '') {
        msgErro("Não é possível mostrar as estatísticas, nenhum cliente informado.");
        return;
    }
    insereValor('#txtEstatisticaCliente', codcli, nome);
    $('#txtEstatisticaNomeCliente').html(`${codcli} - ${nome}`);
    $('#modal-estatisticas').modal('show');

    $('#btnEstatisticaConsultar').click();
}

async function abreModalAnexos(sChave, sDescricao, sTela, dtData = '') {
    async function buscaDataAtual() {
        Date.prototype.toDateInputValue = (function () {
            var local = new Date(this);
            local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
            return local.toJSON().slice(0, 10);
        });

        $(document).ready(function () {
            $('#dtCadastro').val(new Date().toDateInputValue());
        });

        $(document).ready(function () {
            $('#dtValidade').val(new Date().toDateInputValue());
        });
    }

    const sUsuario = getCookie("cod_usuario");
    if (sChave == '') {
        msgErro("Não é possível mostrar os anexos.");
        return;
    }
    $('#txtTela').val(sTela);
    $('#txtUsuario').val(sUsuario);
    insereValor('#txtChave', `${sChave}`);
    $('#txtCodigoTittle').html(`${sChave} - ${sDescricao}`);
    if (dtData) {
        $('#dtCadastro').val(dtData)
    } else {
        buscaDataAtual();
    }
    $('#modal-anexos').modal('show');
}


async function abreModalMedidas(sChave, sDescricao) {
    $('#txtTitulo').html(`${sChave} - ${sDescricao}`);
    $('#btnBuscaMedidas').trigger('click');
    $('#modal-medidas').modal('show');
};

async function abreModalCombinacao(sCodigoProd, sDescricaoProd) {
    $('#txtCodigoProdTittle').html(`${sCodigoProd} - ${sDescricaoProd}`);
    $('#txtCodigoProdTittle').val(sCodigoProd);
    $('#modal-combinacao').modal('show');
    $('#btnBuscaMedidas').trigger('click');
};

async function abreModalHistProd(vCodigoProd, vDescricaoProd) {
    $('#txtTituloProduto').html(`${vCodigoProd} - ${vDescricaoProd}`);
    $('#txtTituloProduto').val(vCodigoProd);
    $('#modal-histprod').modal('show');
};

async function abreModalFluxoProd(codigo, descricao) {
    $('#txtTituloFluxo').html(`${codigo} - ${descricao}`);
    $('#modal-fluxoProduto').prop('codigoProduto', codigo);
    $('#modal-fluxoProduto').prop('descricaoProduto', descricao);
    $('#modal-fluxoProduto').modal('show');
};

async function abreModalProdItensEst(iCodigo, iDescricao) {
    $('#txtTituloProdEst').html(`${iCodigo} - ${iDescricao}`);
    $('#txtTituloProdEst').val(iCodigo);
    $('#modal-proditensest').modal('show');
};

function montaParametros(codigoOriginal, codigoNovo, codigoFaixaNova, configuracaoNova) {
    let parametros = `CODIGO_ORIGINAL=${encodeURIComponent(codigoOriginal)}&CODIGO_NOVO=${encodeURIComponent(codigoNovo)}&CODIGO_FAIXA_NOVA=${encodeURIComponent(codigoFaixaNova)}`;

    parametros += `&MODELO=${configuracaoNova.MODELO ? encodeURIComponent(configuracaoNova.MODELO) : ''}`;
    parametros += `&COLECAO=${configuracaoNova.COLECAO ? encodeURIComponent(configuracaoNova.COLECAO) : ''}`;
    parametros += `&MARCA=${configuracaoNova.MARCA ? encodeURIComponent(configuracaoNova.MARCA) : ''}`;
    parametros += `&GRUPO=${configuracaoNova.GRUPO ? encodeURIComponent(configuracaoNova.GRUPO) : ''}`;
    parametros += `&LINHA=${configuracaoNova.LINHA ? encodeURIComponent(configuracaoNova.LINHA) : ''}`;
    parametros += `&ETIQUETA=${configuracaoNova.ETIQUETA ? encodeURIComponent(configuracaoNova.ETIQUETA) : ''}`;
    parametros += `&TIPO=${configuracaoNova.TIPO ? encodeURIComponent(configuracaoNova.TIPO) : ''}`;

    return parametros;
}

async function duplicaCadastroProduto({ codigoOriginal, codigoNovo, codigoFaixaNova, dadosSeq }) {
    try {
        $.LoadingOverlay('show');
        try {
            const params = montaParametros(codigoOriginal, codigoNovo, codigoFaixaNova, dadosSeq);
            let response = await requisicao(
                "POST",
                "/sisplan/funcoes/v1/duplicaproduto?",
                params,
                null,
                150000
            );
            if (!response) {
                return;
            }
            let jsonStr = await response.json();
            if (response.status != 200) {
                msgAlerta(jsonStr.mensagem);
                return;
            }

            let codigoResultado = jsonStr.json;

            window.location.href = `produto/${criptografaUrl(codigoResultado)}`;

        } catch (error) {
            console.error(error);
            msgErro(`Ocorreu um erro ao duplicar o produto.`);
        }
    } finally {
        $.LoadingOverlay('hide');
    }
};

async function duplicaCadastroMaterial(codigo) {
    try {
        $.LoadingOverlay('show');
        try {

            let response = await requisicao(
                "POST",
                "/sisplan/funcoes/v1/duplicamaterial?",
                `codigo=${codigo}`,
                null
            );
            if (!response) {
                return;
            }
            let jsonStr = await response.json();
            if (response.status != 200) {
                msgAlerta(jsonStr.mensagem);
                return;
            }

            let codigoNovo = jsonStr.json;

            window.location.href = `material/${codigoNovo}`;

        } catch (e) {
            console.error(e);
            msgErro(`Não foi possível duplicar o material: ${error}`);
        }
    } finally {
        $.LoadingOverlay('hide');
    }
};

async function duplicaCadastroNatureza(natureza) {
    window.location.href = 'natureza/create';
    localStorage.setItem('naturezaDuplicada', natureza);

};

async function abreCadConsumo(sProduto) {
    window.location.href = `cadconsumo/${btoa(sProduto)}`;
};

async function abreMatItensEst(sMaterial) {
    window.location.href = `matitensest/${btoa(sMaterial)}`;
};

async function abreProdItensEst(sProduto) {
    window.location.href = `proditensest/${btoa(sProduto)}`;
};

function toggleTheme(theme) {
    if (theme === "light") {
        $('#option_sun').closest('button').addClass('active');
        $('#option_moon').closest('button').removeClass('active');
        $('html').removeClass('theme-dark').addClass('theme-light');
        localStorage.setItem("theme", "theme-light");

        $('iframe[src]').each(function () {
            let iframe = $(this);
            if (iframe.length > 0) {
                let iframeDocument = iframe.contents();
                iframeDocument.find('html').removeClass("theme-dark").addClass("theme-light");
            }
        });
    } else if (theme === "dark") {
        $('#option_moon').closest('button').addClass('active');
        $('#option_sun').closest('button').removeClass('active');
        $('html').removeClass('theme-light').addClass('theme-dark');
        localStorage.setItem("theme", "theme-dark");

        $('iframe[src]').each(function () {
            let iframe = $(this);
            if (iframe.length > 0) {
                var iframeDocument = iframe.contents();
                iframeDocument.find('html').removeClass("theme-light").addClass("theme-dark");
            }
        });
    }
}

function setInitialTheme() {
    const currentTheme = localStorage.getItem("theme") || "theme-light";
    if (currentTheme === "theme-dark") {
        $('#option_moon').prop('checked', true).closest('button').addClass('active');
        $('#option_sun').prop('checked', false).closest('button').removeClass('active');
    } else {
        $('#option_sun').prop('checked', true).closest('button').addClass('active');
        $('#option_moon').prop('checked', false).closest('button').removeClass('active');
    }
    toggleTheme(currentTheme.split('-')[1]);
}

$('#option_sun').on('click', function () {
    toggleTheme('light');
});

$('#option_moon').on('click', function () {
    toggleTheme('dark');
});

setInitialTheme();





function setTheme(themeName) {
    localStorage.setItem("theme", themeName);
    document.documentElement.className = themeName;
    let element = document.getElementById("theme-slider");
    if (element) {
        element.checked = themeName != "theme-light";
    }
}

(function () {
    if (localStorage.getItem("theme") === "theme-dark") {
        setTheme("theme-dark");
        $('#themeIcon').addClass('fa-sun');
    } else {
        setTheme("theme-light");
        $('#themeIcon').addClass('fa-moon');
    }
})();

async function retornaCamposObrigatorios(sTela) {
    try {
        // 1) Verifica se existe pelo PHP
        const respCheck = await fetch(`../verifica_validacoes.php?tela=${sTela}`);
        const jsonCheck = await respCheck.json();

        if (!jsonCheck.existe) {
            return undefined;
        }

        // 2) Agora sim carrega o JSON seguro
        const resp = await fetch(`../validacoes_internas/${sTela}.json`);
        const data = await resp.json();

        return data?.campos_obrigatorios ?? undefined;

    } catch (e) {
        return undefined;
    }
}

function inputValido(e) {
    // eslint-disable-next-line no-var, no-redeclare
    var e = window.e || e;
    if (e.target.tagName !== "INPUT" && e.target.tagName !== "SELECT") { return false; };
    if (e.target.type !== "text" && e.target.type !== "number" && e.target.type !== "date" && e.target.type !== "email" && e.target.tagName !== 'SELECT') { return false; };

    return true;
}

async function transformaCamposObrigatorios(sCamposObrigatorios, sCamposTela) {
    if (sCamposObrigatorios == undefined) {
        return;
    }
    for (let i = 0; i < sCamposObrigatorios.length; i++) {
        const campo = sCamposObrigatorios[i];
        const found = jQuery.grep(sCamposTela, function (element) {
            return element.id == campo;
        });
        if (found.length > 0) {
            $(found[0]).prop("required", true);
            jQuery.validator.addClassRules(found[0].name, {
                required: true,
            });
        }
    }
    jQuery.extend(jQuery.validator.messages, {
        required: "Campo obrigatório (regra da empresa)",
    });
}

async function BuscaCep(cepInput) {
    try {
        let cep = cepInput.val().replace("-", "").trim();
        let response = await requisicao(
            "GET",
            "/sisplan/funcoes/v1/pesquisa?",
            `JSON={ "tabela":"CADCEP", "camposSelect":["CIDADE.NOME CIDADE", "CIDADE.COD_UF UF"], "leftJoin": [{"tabela": "CIDADE", "condicao": "CADCEP.CODMUN = CIDADE.CODIGO"}], "where": ["CADCEP.cep = '${cep}'"]}`,
            null
        );
        if (!response) {
            var cidade = "";
            var uf = "";
        } else {
            let jsonStr = await response.json();
            if (response.status != 200) {
                $.LoadingOverlay("hide");
                msgErro(jsonStr.RESULT[0].mensagem);
                return;
            }

            var cidade = jsonStr.RESULT[0][0].CIDADE;
            var uf = jsonStr.RESULT[0][0].UF;
        }
    } catch (error) {
        var cidade = "";
        var uf = "";
    }
    return [cidade, uf];
}

async function buscaDadosEntidadeContabil(cliente) {
    try {
        var response = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"CONT_ENTIDADE", "camposSelect":["CODCLI", "CON_CLI", "ADI_CLI", "DEV_CLI", "CON_FOR", "ADI_FOR", "DEV_FOR"], "where": ["CODCLI = '${cliente}'"]}`,
            null
        );
        if (!response) {
            return;
        }
        var jsonStr = await response.json();

        try {
            let resposta1 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                    "camposSelect":["descricao"], 
                    "where": ["codigo = '${jsonStr.RESULT[0][0].CON_CLI}'"]}`,
                null
            );


            let jsonStr1 = await resposta1.json();

            insereValor(
                $("#txtContaCliente"),
                jsonStr.RESULT[0][0].CON_CLI,
                jsonStr1.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }
        try {
            let resposta2 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                      "camposSelect":["descricao"], 
                      "where": ["codigo = '${jsonStr.RESULT[0][0].ADI_CLI}'"]}`,
                null
            );

            let jsonStr2 = await resposta2.json();

            insereValor(
                $("#txtContaCAdiantamento"),
                jsonStr.RESULT[0][0].ADI_CLI,
                jsonStr2.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }

        try {
            let resposta3 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                        "camposSelect":["descricao"], 
                        "where": ["codigo = '${jsonStr.RESULT[0][0].DEV_CLI}'"]}`,
                null
            );


            let jsonStr3 = await resposta3.json();

            insereValor(
                $("#txtContaCDevolucao"),
                jsonStr.RESULT[0][0].DEV_CLI,
                jsonStr3.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }

        try {
            let resposta4 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                          "camposSelect":["descricao"], 
                          "where": ["codigo = '${jsonStr.RESULT[0][0].CON_FOR}'"]}`,
                null
            );

            let jsonStr4 = await resposta4.json();

            insereValor(
                $("#txtContaFornecedor"),
                jsonStr.RESULT[0][0].CON_FOR,
                jsonStr4.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }

        try {
            let resposta5 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                            "camposSelect":["descricao"], 
                            "where": ["codigo = '${jsonStr.RESULT[0][0].ADI_FOR}'"]}`,
                null
            );

            let jsonStr5 = await resposta5.json();

            insereValor(
                $("#txtContaFAdiantamento"),
                jsonStr.RESULT[0][0].ADI_FOR,
                jsonStr5.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }

        try {
            let resposta6 = await requisicao(
                "GET",
                "/Sisplan/Funcoes/v1/pesquisa?",
                `JSON={ "tabela":"conta_cont", 
                              "camposSelect":["descricao"], 
                              "where": ["codigo = '${jsonStr.RESULT[0][0].DEV_FOR}'"]}`,
                null
            );

            let jsonStr6 = await resposta6.json();

            insereValor(
                $("#txtContaFDevolucao"),
                jsonStr.RESULT[0][0].DEV_FOR,
                jsonStr6.RESULT[0][0].DESCRICAO
            );
        } catch (error) {
        }


    } catch (error) {
        console.error(error);
        msgErro('Erro ao buscar dados do banco');
    }
}

async function clienteDoExterior(codcli) {
    try {
        if (codcli == '') {
            return false;
        }

        const pesquisa = {
            camposSelect: ['NOMCEP'],
            tabela: 'CADCEP',
            where: [`CEP IN (SELECT CEP FROM [ENTIDADE] WHERE CODCLI = '${codcli}')`]
        };
        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

        if (jsonStr[0].NOMCEP == 'EXTERIOR') {
            return true;
        }
        return false;
    } catch (err) {
        console.error(err);
        return false;
    }

}

async function buscaDadosCliente(cliente, cnpjConsWww = "") {
    try {
        $.LoadingOverlay("show");
        let credito = [];
        const controleLimiteCredito = await CopiaParametro('ENTIDADE', 4);
        if (cnpjConsWww == "") {
            var response = await requisicao(
                "GET",
                "/Sisplan/Cliente/V1/Entidade?",
                `codcli=${cliente}`,
                null
            );

            if (!response) {
                $.LoadingOverlay("hide");
                return;
            }

            var jsonStr = await response.json();
            if (response.status != 200) {
                $.LoadingOverlay("hide");
                msgErro(jsonStr.mensagem);
                return;
            }

            var clienteJson = jsonStr[0];

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["OBS"], "where": ["CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var obs = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var obs = jsonStr.RESULT[0][0].OBS;
            } catch (error) {
                var obs = "";
            }

            try {
                let jsonStr = await buscaDuplicatasEmAberto(cliente, 'S');
                if (!response) {
                    var moedas = "";
                    return;
                }
                // const jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                credito = jsonStr;
                // var credito = jsonStr.RESULT[0][0];
            } catch (error) {
                credito = [];
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"sitcli", "camposSelect":["descricao"], "where": ["codigo = '${clienteJson.SIT_CLI}'"]}`,
                    null
                );
                if (!response) {
                    var sitcli = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var sitcli =
                    jsonStr.RESULT[0][0].SIT_CLI === ""
                        ? ""
                        : `[${clienteJson.SIT_CLI}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var sitcli = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"CADCONTA", "camposSelect":["descricao"], "where": ["CONTA = '${clienteJson.CONTA}'"]}`,
                    null
                );
                if (!response) {
                    var sitcli = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }
                const descricao = !jsonStr.RESULT[0][0]?.DESCRICAO ? clienteJson.CONTA : jsonStr.RESULT[0][0]?.DESCRICAO;
                insereValor('#txtConta', clienteJson.CONTA, descricao);
            } catch (error) {
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"cadban", "camposSelect":["NOME_BANCO"], "where": ["BANCO = '${clienteJson.BANCO}'"]}`,
                    null
                );
                if (!response) {
                    var sitcli = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                insereValor('#txtBanco', clienteJson.BANCO, jsonStr.RESULT[0][0].NOME_BANCO);
            } catch (error) {
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"tabsit", "camposSelect":["DESCRICAO"], "where": ["CODIGO = '${clienteJson.SIT_DUP}'"]}`,
                    null
                );
                if (!response) {
                    var sitcli = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                insereValor('#txtSitDup', clienteJson.SIT_DUP, jsonStr.RESULT[0][0].DESCRICAO);
            } catch (error) {
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/Sisplan/Funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"REG_ESTADO", "camposSelect":["descricao"], "where": ["codigo = '${clienteJson.REG_ESTADO}'"]}`,
                    null
                );
                if (!response) {
                    var regestado = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var regestado =
                    jsonStr.RESULT[0][0].REG_ESTADO === ""
                        ? ""
                        : `[${clienteJson.REG_ESTADO}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var regestado = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.CODREP", "REPRESEN.NOME"], "leftJoin": [{"tabela": "represen", "condicao": "entidade.codrep = represen.codrep"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var represen = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var represen =
                    jsonStr.RESULT[0][0].CODREP === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].CODREP}] - ${jsonStr.RESULT[0][0].NOME}`;
            } catch (error) {
                var represen = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"CLI_REGIAO",
                    "camposSelect":["CLI_REGIAO.CODCLI", "CLI_REGIAO.REGIAO", "REGIAO.DESCRICAO"],
                    "leftJoin": [{"tabela": "REGIAO", "condicao": "REGIAO.REGIAO = CLI_REGIAO.REGIAO"}],
                    "where": ["CLI_REGIAO.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var represen = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }
                for (let i = 0; i < jsonStr.RESULT[0].length; i++) {
                    $('#gridTabelasModal').DataTable().row.add([jsonStr.RESULT[0][i].REGIAO, jsonStr.RESULT[0][i].DESCRICAO, retornaBotaoOpcoesModalTabelas()]).draw(false);
                    // const element = array[i];
                }
                // var represen = jsonStr.RESULT[0][0].CODREP === "" ? "" : `[${jsonStr.RESULT[0][0].CODCLI}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;

            } catch (error) {
                console.log(error);
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.TABELA", "REGIAO.DESCRICAO"], "leftJoin": [{"tabela": "REGIAO", "condicao": "entidade.tabela = regiao.regiao"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var tabPreco = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var tabPreco =
                    jsonStr.RESULT[0][0].TABELA === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].TABELA}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var tabPreco = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.TRANSPORTE", "TABTRAN.NOME"], "leftJoin": [{"tabela": "TABTRAN", "condicao": "ENTIDADE.TRANSPORTE = TABTRAN.CODIGO"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var transportadora = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var transportadora =
                    jsonStr.RESULT[0][0].TRANSPORTE === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].TRANSPORTE}] - ${jsonStr.RESULT[0][0].NOME}`;
            } catch (error) {
                var transportadora = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.GRUPO", "GRUPO_CLI.DESCRICAO"], "leftJoin": [{"tabela": "GRUPO_CLI", "condicao": "ENTIDADE.GRUPO = GRUPO_CLI.CODIGO"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var grupo = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var grupo =
                    jsonStr.RESULT[0][0].GRUPO === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].GRUPO}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var grupo = "";
            }

            try {
                var codigoPais = "";
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.COD_PAIS", "CADPAIS.NOME"], "leftJoin": [{"tabela": "CADPAIS", "condicao": "ENTIDADE.COD_PAIS = CADPAIS.CODIGO"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    codigoPais = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                codigoPais =
                    jsonStr.RESULT[0][0].COD_PAIS === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].COD_PAIS}] - ${jsonStr.RESULT[0][0].NOME}`;
            } catch (error) {
                codigoPais = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"classe_ger", "camposSelect":["CODIGO", "DESCRICAO"], "where": ["CODIGO = '${clienteJson.CLASSE}'"]}`,
                    null
                );
                if (!response) {
                    var classe = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var classe =
                    jsonStr.RESULT[0][0].CODIGO === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].CODIGO}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var classe = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTIDADE", "camposSelect":["ENTIDADE.COD_CONF_XML", "FATCONF_XML.DESCRICAO"], "leftJoin": [{"tabela": "FATCONF_XML", "condicao": "ENTIDADE.COD_CONF_XML = FATCONF_XML.CODIGO"}], "where": ["ENTIDADE.CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var confXML = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var confXML =
                    jsonStr.RESULT[0][0].COD_CONF_XML === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].COD_CONF_XML}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var confXML = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"TIPO_CONTATO", "camposSelect":["CODIGO", "DESCRICAO"], "where": ["CODIGO = '${clienteJson.CANAL_CONTATO}'"]}`,
                    null
                );
                if (!response) {
                    var tpContato = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var tpContato = jsonStr.RESULT[0][0].CODIGO === "" ? "" : `[${jsonStr.RESULT[0][0].CODIGO}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var tpContato = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENTID_DIA", "camposSelect":["DIA"], "where": ["CODCLI = '${cliente}'"]}`,
                    null
                );
                if (!response) {
                    var arrDiasCliente = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var arrDiasCliente = jsonStr.RESULT[0];
            } catch (error) {
                var arrDiasCliente = "";
            }

            try {
                const response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"ENT_MOEDA", "camposSelect":["ENT_MOEDA.CODMOE" , "MOEDA.DESCRICAO"], 
                    "where": ["ENT_MOEDA.CODCLI = '${cliente}'"], 
                    "leftjoin": [{"tabela": "MOEDA", "condicao" : "ENT_MOEDA.CODMOE = MOEDA.CODMOE"}]}`,
                    null
                );
                if (!response) {
                    var moedas = "";
                    return;
                }
                const jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var moedas = jsonStr.RESULT[0];
            } catch (error) {
                var moedas = "";
            }

            try {
                const response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"CLI_COM", "camposSelect":["CLI_COM.CODREP" , "REPRESEN.NOME", "CLI_COM.COM1", "CLI_COM.COM2"], 
                    "where": ["CLI_COM.CODCLI = '${cliente}'"], 
                    "leftjoin": [{"tabela": "REPRESEN", "condicao" : "CLI_COM.CODREP = REPRESEN.CODREP"}]}`,
                    null
                );
                if (!response) {
                    var representantes = "";
                    return;
                }
                const jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var representantes = jsonStr.RESULT[0];
            } catch (error) {
                var representantes = "";
            }

            try {
                var response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"HISTCP", "camposSelect":["HISTORICO", "DESCRICAO"], "where": ["HISTORICO = '${clienteJson.HISTORICO}'"]}`,
                    null
                );
                if (!response) {
                    var historico = "";
                    return;
                }
                var jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var historico =
                    jsonStr.RESULT[0][0].HISTORICO === ""
                        ? ""
                        : `[${jsonStr.RESULT[0][0].HISTORICO}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
            } catch (error) {
                var historico = "";
            }

            try {
                if (clienteJson.CONDICAO_PAGAMENTO != '') {
                    var response = await requisicao(
                        "GET",
                        "/sisplan/funcoes/v1/pesquisa?",
                        `JSON={ "tabela":"CONDICAO", "camposSelect":["CODCOND", "DESCRICAO"], "where": ["CODCOND = '${clienteJson.CONDICAO_PAGAMENTO}'"]}`,
                        null
                    );
                    if (!response) {
                        var condicaopagto = "";
                        return;
                    }
                    var jsonStr = await response.json();
                    if (response.status != 200) {
                        $.LoadingOverlay("hide");
                        msgErro(jsonStr.RESULT[0].mensagem);
                        return;
                    }

                    var condicaopagto =
                        jsonStr.RESULT[0][0].CODCOND === ""
                            ? ""
                            : `[${jsonStr.RESULT[0][0].CODCOND}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
                }
            } catch (error) {
                var condicaopagto = "";
            }

            try {
                const response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"CLI_SETOR", "camposSelect":["CLI_SETOR.SETOR CODIGO" , "CADFLUXO.DESCRICAO"], 
                    "where": ["CLI_SETOR.CODCLI = '${cliente}'"], 
                    "leftjoin": [{"tabela": "CADFLUXO", "condicao" : "CADFLUXO.CODIGO = CLI_SETOR.SETOR"}]}`,
                    null
                );
                if (!response) {
                    var setor = "";
                    return;
                }
                const jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var setor = jsonStr.RESULT[0];
            } catch (error) {
                var setor = "";
            }

            try {
                const response = await requisicao(
                    "GET",
                    "/sisplan/funcoes/v1/pesquisa?",
                    `JSON={ "tabela":"CLI_SETOR", "camposSelect":["CLI_SETOR.SETOR CODIGO", "CLI_SETOR.CODCLI", "CLI_SETOR.PERC_100", "CLI_SETOR.PERC_QUAL", "CLI_SETOR.PERC_PONTUALIDADE", "CADFLUXO.DESCRICAO"], 
                    "where": ["CLI_SETOR.CODCLI = '${cliente}'"], 
                    "leftjoin": [{"tabela": "CADFLUXO", "condicao" : "CADFLUXO.CODIGO = CLI_SETOR.SETOR"}]}`,
                    null
                );
                if (!response) {
                    var tabelaSetor = "";
                    return;
                }
                const jsonStr = await response.json();
                if (response.status != 200) {
                    $.LoadingOverlay("hide");
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }

                var tabelaSetor = jsonStr.RESULT[0];
            } catch (error) {
                var tabelaSetor = "";
            }
        } else {
            try {
                clienteJson = await retornaConsultaWWW(cnpjConsWww);
            } catch {
                console.log("Erro ao consultar");
            }
        }

        if (clienteJson != undefined) {
            if (cnpjConsWww == "") {
                $("#txtCNPJ").val(clienteJson.CNPJ);

                let response = await requisicao("GET", "/sisplan/cliente/v1/validamascara?", `CNPJ=${$('#txtCNPJ').val().length}`, null);

                const mascara = await response.text();

                if (mascara) {
                    $('#rgTipoEnt').val(mascara).change();
                } else if ($('#txtCNPJ').val().length == 18) {
                    $('#rgTipoEnt').val('##.###.###/####-##').change();
                } else {
                    $('#rgTipoEnt').val('###.###.###-##').change();
                }

                $("#rgSexo").val(clienteJson.SEXO == "M" ? "M" : "F").change();
                if (clienteJson.DT_NASC != undefined) {
                    $("#txtDataNascimento").val(clienteJson.DT_NASC.slice(0, 10));
                }
                if (clienteJson.DATA_BUSCA != undefined) {
                    $("#txtDataAlteracao").val(clienteJson.DATA_BUSCA.slice(0, 10));
                }
                if (clienteJson.DATA_CAD != undefined) {
                    $("#txtDataCadastro").val(clienteJson.DATA_CAD.slice(0, 10));
                }
                $("#rgIE").val(clienteJson.IE_DESTINATARIO).change();
                $("#rgPorteEmpresa").val(clienteJson.PORTE_EMPRESA).change();
                $("#cbAtivo").prop("checked", clienteJson.ATIVO == "S");
                $("#cbIntegraShop").prop("checked", clienteJson.INTEGRA_SHOPP == "N");
                $("#cbGeraCashback").prop("checked", clienteJson.GERA_CASHBACK == "N");
                $("#cbConsumidorFinal").prop(
                    "checked",
                    clienteJson.CONS_FINAL == "Sim"
                );
                $("#txtCepEntrega").val(clienteJson.CEP_ENT);
                $("#txtRuaEntrega").val(clienteJson.END_ENT);
                $("#txtNumeroEntrega").val(clienteJson.NUM_ENT);
                $("#txtComplementoEntrega").val(clienteJson.COMP_ENT);
                $("#txtBairroEntrega").val(clienteJson.BAIRRO_ENT);
                $("#txtNomePai").val(clienteJson.NOME_PAI);
                $("#txtNomeMae").val(clienteJson.NOME_MAE);
                $("#txtEstadoCivil").val(clienteJson.ESTADO_CIVIL);
                $("#txtRenda").val(clienteJson.RENDA);
                $("#txtMidiaSocial").val(clienteJson.MIDIAS_SOCIAIS);
                if (clienteJson.DT_ADMISSAO != undefined) {
                    $("#txtDtAdmissao").val(clienteJson.DT_ADMISSAO.slice(0, 10));
                }

                var retorno = await BuscaCep($("#txtCepEntrega"));
                $("#txtCidadeEntrega").val(retorno[0]);
                $("#txtUFEntrega").val(retorno[1]);

                $("#txtCepCobranca").val(clienteJson.CEP_COB);
                $("#txtRuaCobranca").val(clienteJson.END_COB);
                $("#txtNumeroCobranca").val(clienteJson.NUM_COB);
                $("#txtComplementoCobranca").val(clienteJson.COMP_COB);
                $("#txtBairroCobranca").val(clienteJson.BAIRRO_COB);

                var retorno = await BuscaCep($("#txtCepCobranca"));
                $("#txtCidadeCobranca").val(retorno[0]);
                $("#txtUFCobranca").val(retorno[1]);

                $('#rgSemanaMes').val(clienteJson.TIPO_DIAS_VENCTO).change();

                arrDiasCliente.map(item => {
                    if (clienteJson.TIPO_DIAS_VENCTO == 'SEMANA') {
                        $(`#cbSemana${item.DIA}`).prop('checked', true);
                    }
                    if (clienteJson.TIPO_DIAS_VENCTO == 'MES') {
                        $(`#cbDia${item.DIA}`).prop('checked', true);
                    }
                });

                await insereValorPesquisaVarios('txtMoeda', 'CODMOE', 'DESCRICAO', moedas);
                await insereValorPesquisaVarios('txtSetor', 'CODIGO', 'DESCRICAO', setor);

                tabelaSetor.map((item) => {
                    $('#tabelaSetor').DataTable().row.add([
                        '<div style="text-align:start;"> ' +
                        '    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
                        '      ' + item.CODIGO + ' ' +
                        '    </button> ' +
                        '    <div class="dropdown-menu"> ' +
                        '    <button class="dropdown-item" type="button" title="Excluir" id="btn-excluir">Excluir</button>  ' +
                        '</div>',
                        item.DESCRICAO,
                        item.PERC_100,
                        item.PERC_PONTUALIDADE,
                        item.PERC_QUAL,
                    ]).draw(false);
                });

                moedas.map((item) => {
                    $('#tabelaMoedas').DataTable().row.add([
                        '<div style="text-align:start;"> ' +
                        '    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
                        '      ' + item.CODMOE + ' ' +
                        '    </button> ' +
                        '    <div class="dropdown-menu"> ' +
                        '    <button class="dropdown-item" type="button" title="Excluir" id="btn-excluir">Excluir</button>  ' +
                        '</div>',
                        item.DESCRICAO,
                    ]).draw(false);
                });

                if ($.fn.DataTable.isDataTable('#tabelaRepresentantes')) {
                    $('#tabelaRepresentantes').DataTable().destroy();
                    $('#tabelaRepresentantes').empty();
                };


                const titulosRepresentantes = [
                    { title: "Codigo", data: "CODREP" },
                    { title: "Nome", data: "NOME" },
                    { title: "Com. Fat.", data: "COM1" },
                    { title: "Com. Rec.", data: "COM2" }
                ];

                $("#tabelaRepresentantes").DataTable({
                    destroy: true,
                    filter: false,
                    paging: false,
                    scrollX: true,
                    autoWidth: true,
                    columns: titulosRepresentantes,
                    data: representantes,
                    columnDefs: [
                        {
                            "render": function (data) {
                                return parseFloat(data).toLocaleString("pt-BR", {
                                    maximumFractionDigits: 2,
                                    minimumFractionDigits: 2
                                });
                            },
                            "targets": [2, 3],
                            "className": 'pr-4 text-right'
                        },
                        {
                            targets: [0],
                            render: function (data, type, row) {
                                return '<div style="text-align:start;"> ' +
                                    '    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
                                    '      ' + data + ' ' +
                                    '    </button> ' +
                                    '    <div class="dropdown-menu"> ' +
                                    '    <button class="dropdown-item" type="button" title="Excluir" id="btn-excluir">Excluir</button>  ' +
                                    '</div>';
                            },
                        },
                    ]
                });
            } else {
                $("#cbAtivo").prop("checked", true);
                $("#cbConsumidorFinal").prop("checked", true);
                if (!$("#rgIE").val()) { //adicionado para manter o valor se acaso já foi informado pelos valores padrões
                    $("#rgIE").val("9").change();
                }
                $("#txtDataCadastro").val(new Date().toISOString().slice(0, 10));
                $("#txtDataAlteracao").val(new Date().toISOString().slice(0, 10));
                $("#txtDataNascimento").val(
                    new Date("1980-01-01").toISOString().slice(0, 10)
                );
                $("#rgSexo").val("M").change();
            }
            $("#txtNome").val(clienteJson.NOME);
            $("#txtFantasia").val(clienteJson.FANTASIA);
            $("#txtObs").val(obs);
            $("#cbBloqueado").prop("checked", clienteJson.BLOQUEIO == "S");
            $("#txtRG").val(clienteJson.NUM_RG);
            $("#txtEmissor").val(clienteJson.EMI_RG);
            $("#txtIE").val(clienteJson.INSCRICAO);
            $("#txtInscricaoMunicipal").val(clienteJson.INSC_EST);
            $("#txtCep").val(clienteJson.CEP);
            $("#txtPais").val(codigoPais || "[1058] - BRASIL");
            $("#txtRua").val(clienteJson.ENDERECO);
            $("#txtNumero").val(clienteJson.NUMERO);
            $("#txtComplemento").val(clienteJson.COMPLEMENTO);
            $("#txtBairro").val(clienteJson.BAIRRO);
            $('#txtAgencia').val(clienteJson.AGENCIA);
            $('#txtCodImportado').val(clienteJson.COD_IMPORTADO);

            await BuscaECadastraCep($("#txtCep"));
            var retorno = await BuscaCep($("#txtCep"));
            $("#txtCidade").val(retorno[0]);
            $("#txtUF").val(retorno[1]);

            $("#txtDDI").val(!clienteJson.DDI.startsWith('+') && clienteJson.DDI ? `+${clienteJson.DDI}` : clienteJson.DDI);
            $("#txtDDD").val(clienteJson.DDD_FONE);
            $("#txtTelefone").val(clienteJson.TELEFONE);
            $("#txtEmail").val(clienteJson.EMAIL);
            $("#txtRepresentante").val(represen);

            $('#txtCreditoGrupo').val(clienteJson.CRED_CONSIGNADO);
            $("#txtLimiteUsado").val(clienteJson.CREDITO_UTILIZADO);
            $("#txtLimiteCredito").val(clienteJson.CREDITO);
            insereValor('#txtCnae', clienteJson.CNAE, { tabela: 'CADCNAE', campoBusca: 'DESCRICAO', campoWhere: 'CODIGO', valorWhere: clienteJson.CNAE })
            insereValor('#txtEntidadeAux', clienteJson.ENTID_AUX, { tabela: 'ENTID_AUX', campoBusca: 'DESCRICAO', campoWhere: 'CODIGO', valorWhere: clienteJson.ENTID_AUX })
            $('#cbAutorizaDados').prop('checked', clienteJson.AUTORIZADADOS != 'N')
            $('#cbMalaDireta').prop('checked', clienteJson.MALA_DIRETA === 'S')
            let data = new Date();
            let vAVencer = 0;
            let vVencido = 0;
            let vAnteci = 0;
            let vCheqD = 0;
            let vAberto = 0;
            data = `${data.getUTCFullYear()}-${String(
                data.getUTCMonth() + 1
            ).padStart(2, 0)}-${String(data.getUTCDate()).padStart(2, 0)}`;

            for (let i = 0; i < credito.length; i++) {
                if ((credito[i].DT_VENCTO <= data) && (['DUPL', 'CHEQ'].includes(credito[i].STATUS))) {
                    vVencido = parseFloat(vVencido) + parseFloat(credito[i].SALDO);
                } else if ((credito[i].DT_VENCTO > data) && (['DUPL', 'CHEQ'].includes(credito[i].STATUS))) {
                    vAVencer = parseFloat(vAVencer) + parseFloat(credito[i].SALDO);
                } else if (['ANTE'].includes(credito[i].STATUS)) {
                    vAnteci = parseFloat(vAnteci) + parseFloat(credito[i].SALDO);
                } else if (['CHDE'].includes(credito[i].STATUS)) {
                    vCheqD = parseFloat(vCheqD) + parseFloat(credito[i].SALDO);
                }
            };

            vAberto = parseFloat(vVencido) + parseFloat(vAVencer) + parseFloat(vCheqD) - parseFloat(vAnteci);
            $("#txtLimiteFidelidade").val(clienteJson.LIMITE_FID);
            if (controleLimiteCredito == '1') {
                await buscaLimiteUtilizadoCliente(cliente);
            } else {
                $("#txtLimiteUsado").val(vAberto.toFixed(2));

                // $("#txtLimiteUsado").val(credito.VALOR);
                // $("#txtLimiteCredito").val(clienteJson.CREDITO);
                // $("#txtLimiteDisponivel").val(TruncaDecimaisNova(2, clienteJson.CREDITO - credito.VALOR));

                $("#txtLimiteFidelidadeUsado").val(clienteJson.LIMITE_UTIL_FID);
            }
            $("#txtLimiteDisponivel").val(TruncaDecimaisNova(2, clienteJson.CREDITO - $("#txtLimiteUsado").val()));
            $("#txtLimiteFidelidadeDisponivel").val(TruncaDecimaisNova(2, $("#txtLimiteFidelidade").val() - $("#txtLimiteFidelidadeUsado").val()));

            $("#txtTabela").val(tabPreco);
            $("#txtGrupo").val(grupo);
            $('#txtHistorico').val(historico);
            $("#rgTipoFrete").val(clienteJson.TP_FRETE);
            $("#txtTransportadora").val(transportadora);
            $("#txtClasse").val(classe);
            $('#txtConfXML').val(confXML);
            $("#txtCanalContato").val(tpContato);

            $('#txtCondicaoPagto').val(condicaopagto);

            $("#txtRamoAtividade").val(sitcli);
            $("#txtRegiao").val(regestado);
            $("#txtLocalTrab").val(clienteJson.LOCAL_TRAB);
            $("#rgTributacao").val(clienteJson.SIMPLES);
            $("#txtCodCli").val(clienteJson.CODCLI);
            $("#txtInscCob").val(clienteJson.INSC_COB);

            $("#txtCNPJCob").val(clienteJson.CNPJ_COB);
            $("#txtCNPJEnt").val(clienteJson.CNPJ_ENT);

            $("#txtCNPJFavorecido").val(clienteJson.CNPJ_FAVOR);
            $("#txtNomeFavorecido").val(clienteJson.NOME_FAVOR);
            if (clienteJson.DT_NASC_FAVOR) {
                $("#txtDataNascimentoFavorecido").val(clienteJson.DT_NASC_FAVOR.slice(0, 10));
            }

            if (clienteJson.DT_VALID_LIMITE) {
                $("#txtValidadeLimiteCredito").val(clienteJson.DT_VALID_LIMITE.slice(0, 10));
            }
            $("#cbLimiteSuspenso").prop("checked", clienteJson.LIMITE_SUSPENSO == "S");

            //CERTIFICAÇÔES
            $("#txtABVTEX").val(clienteJson.ABVTEX);
            $("#txtDisney").val(clienteJson.DISNEY);
            $("#dtABVTEX").val(clienteJson.VALIDA_ABVTEX);
            $("#dtLicenciado").val(clienteJson.LICENCIADO);
            //SINTEGRA
            $("#txtSintegra").val(clienteJson.SINTEGRA);
            //CLASSIFICA
            $("#rgClassificacao").val(clienteJson.CLASSIFICA.trim());
            //DADOSSPC
            $('#dtUltimaConsultaSPC').val(clienteJson.DT_CONSULTA_SPC);
            $('#dtEntradaSPC').val(clienteJson.DT_ENTRADA_SPC);
            $('#dtSaidaSPC').val(clienteJson.DT_SAIDA_SPC);
            $('#txtDuplicataSPC').val(clienteJson.DUPLICATA_SPC);
            clienteJson.REGISTRO_SPC == 'S' ? $('#cbClienteSPC').prop('checked', true) : $('#cbClienteSPC').prop('checked', false);
            clienteJson.COLOCADO_SPC == 'S' ? $('#cbColocadoSPC').prop('checked', true) : $('#cbColocadoSPC').prop('checked', false);
            clienteJson.REGISTRADO_SPC == 'S' ? $('#cbCientePassouSPC').prop('checked', true) : $('#cbCientePassouSPC').prop('checked', false);
            clienteJson.REQUER_ANALISE == 'S' ? $('#cbClienteRequerAnalise').prop('checked', true) : $('#cbClienteRequerAnalise').prop('checked', false);
            clienteJson.ANALISADO_SERASA == 'S' ? $('#cbClienteAnalisado').prop('checked', true) : $('#cbClienteAnalisado').prop('checked', false);
            clienteJson.RENEG_ATRASADA == 'S' ? $('#cbPossuiRenegociacaoAtrasadaSPC').prop('checked', true) : $('#cbPossuiRenegociacaoAtrasadaSPC').prop('checked', false);
            $('#txtValidadeUltimaConsulta').val(clienteJson.VALIDA_CONS_SPC);
            $('#txtScoreSerasa').val(clienteJson.SCORE_SERASA);
            ///////////////
            $('#txtPercDesconto').val(clienteJson.DESCONTO);
            $('#txtPercRetencao').val(clienteJson.PERC_IR_RET);
            $("#txtInscEnt").val(clienteJson.INSC_ENT);

            if (clienteJson.TIPO_ENTIDADE.includes('C')) {
                $("#cbTipoCliente").prop("checked", true);
            }
            if (clienteJson.TIPO_ENTIDADE.includes('F')) {
                $("#cbTipoFornecedor").prop("checked", true);
            }
            if (clienteJson.TIPO_ENTIDADE.includes('T')) {
                $("#cbTipoTerceiros").prop("checked", true);
            }
            if (clienteJson.TIPO_ENTIDADE.includes('R')) {
                $("#cbTipoRepresentante").prop("checked", true);
            }
            if (clienteJson.TIPO_ENTIDADE.includes('P')) {
                $("#cbTipoProspecto").prop("checked", true);
            }

            if (clienteJson.TIPO_ENTIDADE.includes('E')) {
                $("#cbTipoFuncionario").prop("checked", true);
            }

            $('#txtSuframa').val(clienteJson.SUFRAMA);
            if (clienteJson.VALIDA_SUFRAMA != undefined && clienteJson.VALIDA_SUFRAMA != null && clienteJson.VALIDA_SUFRAMA != '') {
                $('#txtValidadeSuframa').val(clienteJson.VALIDA_SUFRAMA.substring(0, '10'));
            }
            if (clienteJson.SUFRAMA_CONF.includes('I')) {
                $('#cbBenefIcms').prop('checked', true);
            }
            if (clienteJson.SUFRAMA_CONF.includes('P')) {
                $('#cbBenefPis').prop('checked', true);
            }
            if (clienteJson.SUFRAMA_CONF.includes('C')) {
                $('#cbBenefCofins').prop('checked', true);
            }

            insereValor('#txtPerfil', clienteJson.PERFIL, {
                tabela: 'PERFIL',
                campoBusca: 'DESCRICAO',
                campoWhere: 'CODIGO',
                valorWhere: clienteJson.PERFIL
            })

            if (clienteJson.STATUS) {
                $('#selectStatus').val(clienteJson.STATUS ?? 0);
            }
        }
        $.LoadingOverlay("hide");
    } catch (error) {
        $.LoadingOverlay("hide");
        msgErro(`Não foi possível buscar os dados do cliente: ${error}`);
    }
}

async function BuscaECadastraCep(cepInput) {
    try {
        $.LoadingOverlay("show");
        try {
            let cep = cepInput.val().replace("-", "").trim();
            let response = await requisicao(
                "GET",
                "/sisplan/cep/v1/CEP?",
                `CEP=${cep}`,
                null
            );
            if (!response) {
                var cidade = "";
                var uf = "";
                var endereco = "";
                var bairro = "";
            } else {
                let jsonStr = await response.json();
                if (response.status != 200) {
                    msgErro(jsonStr.RESULT[0].mensagem);
                    return;
                }
                var cidade = jsonStr.nOMCIDADE;
                var uf = jsonStr.eSTCEP;
                var endereco = jsonStr.nOMCEP;
                var bairro = jsonStr.bAIRRO;
            }
        } catch (error) {
            var cidade = "";
            var uf = "";
        }
        return [cidade, uf, endereco, bairro];
    } finally {
        $.LoadingOverlay("hide");
    }
}


async function importaMenu(path = '') {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', `${path}menu.html`);
    xhr.onload = function () {
        if (xhr.status === 200) {
            // Insere o conteúdo do arquivo modal.html na div #modal-container
            document.getElementById('import-menu').innerHTML = xhr.response;
            const scripts = document.querySelectorAll('#import-menu script');
            for (var i = 0; i < scripts.length; i++) {
                eval(scripts[i].innerHTML);
            }
        } else {
            console.log('Erro ao carregar o menu: ' + xhr.status);
        }
    };
    xhr.send();
}

async function importaFooter(path = '') {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', `${path}footer.html`);
    xhr.onload = function () {

        if (xhr.status === 200) {
            document.getElementById('import-footer').innerHTML = xhr.responseText;
            const scripts = document.querySelectorAll('#import-footer script');
            console.log('total', scripts.length);
            // for (var i = 0; i < scripts.length; i++) {
            //   eval(scripts[i].innerHTML);
            // }
        } else {
            console.log('Erro ao carregar o footer: ' + xhr.status);
        }
    };
    xhr.send();
}

async function insereJavaScriptPagina(sArquivo) {
    (async function () {
        let li = document.createElement("script");
        li.type = "text/javascript";
        li.src = sArquivo;
        li.async = true;
        let s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(li, s);

        await insereJavaScriptTraducoes()
    })();
}

async function insereJavaScriptTraducoes() {
    if (!document.querySelector(`script[src="${BASE_URI}/utils/traducoes.js?versao=3.263.17.1"]`)) {
        await carregaArquivoTraducoes(`${BASE_URI}/utils/traducoes.js?versao=3.263.17.1`);
    }

    await esperaFuncoesTraducao();

    await traduzPagina();
}

function carregaArquivoTraducoes(url) {
    return new Promise((resolve, reject) => {
        let script = document.createElement("script");
        script.type = "text/javascript";
        script.src = url;
        script.async = true;

        script.onload = () => resolve();
        script.onerror = () => reject(new Error(`Erro ao carregar ${url}`));

        document.head.appendChild(script);
    });
}

function esperaFuncoesTraducao() {
    return new Promise((resolve) => {
        const checkAvailability = setInterval(() => {
            if (
                typeof window.translatePage === 'function' &&
                typeof window.translateSentence === 'function' &&
                typeof window.translateDataTableElement === 'function'
            ) {
                clearInterval(checkAvailability);
                resolve();
            }
        }, 50);
    });
}

async function traduzPagina() {
    await window.translatePage()
}

async function traduzSentenca(sentenca) {
    if (typeof window.translateSentence === 'function') {
        return await window.translateSentence(sentenca);
    }
}

async function traduzirElementosDataTable(instance) {
    if (typeof window.translateDataTableElement === 'function') {
        await window.translateDataTableElement(instance);
    }
}

async function traduzirLogin(loginForm) {
    if (typeof window.translateLoginForm === 'function') {
        await window.translateLoginForm(loginForm);
    }
}

async function traduzSentencaComPromise(sentenca) {
    return new Promise(async resolve => {
        if (typeof window.translateSentence === 'function') {
            const traducao = await window.translateSentence(sentenca);
            resolve(traducao);
        }
    });
}

async function salvaCamposObrigatorios(objeto, sTela) {
    let response;
    let campos_object = new Object();
    campos_object.campos_obrigatorios = objeto;
    try {
        response = await fetch(`../salvar_validacao_interna.php?tela=${sTela}`, {
            method: "POST",
            body: `${JSON.stringify(campos_object)}`,
        });
    } catch (error) {
        msgAlerta("Erro ao salvar campos obrigatórios");
    }
    return response;
}

async function salvaArquivoCamposObrigatorios(sTela, sCampo) {
    let campos_obrigatorios = await retornaCamposObrigatorios(sTela);
    if (campos_obrigatorios == undefined) {
        campos_obrigatorios = [];
    }
    if (campos_obrigatorios.indexOf(sCampo) == -1) {
        campos_obrigatorios.push(sCampo);
        toastr.success(`Tornado campo (${sCampo}) obrigatório.`);
    } else {
        campos_obrigatorios.splice(campos_obrigatorios.indexOf(sCampo), 1);
        toastr.warning(`Tornado campo (${sCampo}) opcional.`);
    }
    await salvaCamposObrigatorios(campos_obrigatorios, sTela);
}

async function habilitaCamposObrigatoriosTela(nomeTela) {
    async function ativaCampoObrigatorio(e) {
        if (inputValido(e) && e.ctrlKey && e.key == "F8") {
            // ctrl + b por enquanto
            await salvaArquivoCamposObrigatorios(nomeTela, e.target.id);
            let campos_obrigatorios = await retornaCamposObrigatorios(nomeTela); // pega os campos do json do arquivo
            if (campos_obrigatorios == undefined) {
                campos_obrigatorios = [];
            }
            transformaCamposObrigatorios(campos_obrigatorios, $("input"));
        }
    }

    document.addEventListener("keydown", ativaCampoObrigatorio, false);
    let campos_obrigatorios = await retornaCamposObrigatorios(nomeTela); // pega os campos do json do arquivo
    if (campos_obrigatorios == undefined) {
        campos_obrigatorios = [];
    }
    transformaCamposObrigatorios(campos_obrigatorios, $("input"));
}

function pegaChave(componente, _) {
    if (!componente) {
        return "";
    }
    let campo = "";
    try {
        campo = $(componente).val();
        // if (!campo.includes('[')) {
        //     return ""
        // }
        if (campo == undefined) {
            campo = componente;
        }
    } catch (error) {
        campo = componente;
    }
    return campo.substring(1, campo.indexOf("]"));
}

function pegaDescricao(componente, retorno) {
    let campo = "";
    try {
        campo = $(componente).val();
        if (campo == undefined) {
            campo = componente;
        }
    } catch (error) {
        campo = componente;
    }
    return (retorno = campo.substring(campo.indexOf("]") + 4, campo.length));
}

async function SalvaParametro(param) {
    let response = await requisicao(
        "POST",
        "/Sisplan/Parametro/v1/Loja?",
        "",
        `JSON=${encodeURIComponent(JSON.stringify(param))}`,
        30000
    );

    if (!response) {
        throw "Não foi possível buscar os dados.";
    }

    if (response.status != 200) {
        let jsonStr = await response.json();
        throw new Error(jsonStr.mensagem);
    }
}

function inicializarAudios(baseURL = '/sisplan_web') {
    beep = new Audio(`${baseURL}/dist/sounds/beep.mp3`);
    erro = new Audio(`${baseURL}/dist/sounds/erro.mp3`);

    beep.preload = 'auto';
    erro.preload = 'auto';
}

function SomAlerta(_baseURLOld = '/sisplan_web', bErro = false) {
    if ($('.somAtivo').hasClass('d-none')) {
        return;
    }
    try {
        const baseURL = BASE_URI;
        const som = bErro == false ? 'beep.mp3' : 'erro.mp3';
        const music = new Audio(`${baseURL}/dist/sounds/${som}`);
        music.currentTime = 0;
        music.play();
    } catch (e) {
        console.error(e);
    }
}


document.addEventListener('DOMContentLoaded', () => {
    inicializarAudios(BASE_URI);
});

function SomDemanda(baseURL = '/sisplan_web') {
    const music = new Audio(`${baseURL}/dist/sounds/sino.wav`);
    music.play();
}

function retornaBotaoOpcoesModalTabelas() {
    return '<div class="divBtnOpcoes"> ' +
        '    <button class="botaoOpcoes btn-excluir" type="button"><span class="fas fa-trash-alt" style="color:red"></span></button>  ' +
        '   </div>';
}

async function BuscaParametrosCustos() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'CUSTOS'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosLoja() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'VENDA'"], "orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosReceber() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'RECEBER'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosFaturamento() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'FATURAMENTO'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosProduto() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'PRODUTO'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosMaterial() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'MATERIAL'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosExpedicao() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'EXPEDICAO'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosSistema(apenasValor = 'N') {
    try {
        const parametrosLogin = sessionStorage.getItem('web@parametros') ?? [];
        if (parametrosLogin.length > 0) {
            const parametrosObject = JSON.parse(parametrosLogin);
            const valores = apenasValor == 'S' ? parametrosObject.filter(param => param.TIPO == 'SISTEMA').map(param => param.VALOR)
                : parametrosObject.filter(param => param.TIPO == 'SISTEMA');
            // console.log('params buscaparamsistemas', valores);
            return valores;
        }

        const empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'SISTEMA'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        const jsonStr = await response.json();

        if (apenasValor == 'S') {
            if (jsonStr.RESULT[0].length > 0) {
                for (let i = 0; i < jsonStr.RESULT[0].length; i++) {
                    jsonStr.RESULT[0][i] = jsonStr.RESULT[0][i].VALOR;
                }
                // console.log('params buscaparamsistemas2', jsonStr.RESULT[0]);
                return jsonStr.RESULT[0];
            }
            return [];
        } else {
            // console.log('params buscaparamsistemas3', jsonStr.RESULT[0]);
            return jsonStr.RESULT[0];
        }
    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosEntidade() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'ENTIDADE'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosMercadorias(apenasValor = 'N') {
    try {
        const parametrosLogin = sessionStorage.getItem('web@parametros') ?? [];
        if (parametrosLogin.length > 0) {
            const parametrosObject = JSON.parse(parametrosLogin);
            const valores = apenasValor == 'S' ? parametrosObject.filter(param => param.TIPO == 'MERCADORIAS').map(param => param.VALOR)
                : parametrosObject.filter(param => param.TIPO == 'MERCADORIAS');
            // console.log('params buscaparamsistemas', valores);
            return valores;
        }

        const empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'MERCADORIAS'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        const jsonStr = await response.json();

        if (apenasValor == 'S') {
            if (jsonStr.RESULT[0].length > 0) {
                for (let i = 0; i < jsonStr.RESULT[0].length; i++) {
                    jsonStr.RESULT[0][i] = jsonStr.RESULT[0][i].VALOR;
                }
                // console.log('params buscaparamsistemas2', jsonStr.RESULT[0]);
                return jsonStr.RESULT[0];
            }
            return [];
        } else {
            // console.log('params buscaparamsistemas3', jsonStr.RESULT[0]);
            return jsonStr.RESULT[0];
        }
    } catch (error) {
        console.error(error);
    }
}

async function UsuarioMasterOuSupervisor() {
    try {
        const usuarioLogado = getCookie('cod_usuario');
        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const response = await requisicao('GET', url, `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["CODIGO", "TIPO"], "where": ["CODIGO = '${usuarioLogado}'"]}`, null);
        if (!response) {
            msgErro('Não foi possível buscar dados do usuário logado.');
            return;
        };
        if (response.status == 400) {
            msgErro('Não foi possível buscar os dados do usuário logado.');
            return;
        };
        const jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
        msgErro('Não foi possível buscar os dados do usuário logado.');
        return;
    }
};

async function CopiaParametro(sTipo, iPosicao) {

    try {
        const parametrosLogin = sessionStorage.getItem('web@parametros') ?? [];
        if (parametrosLogin.length > 0) {
            const parametrosObject = JSON.parse(parametrosLogin);
            const valor = parametrosObject.find(param => param.TIPO == sTipo && param.POSICAO == iPosicao)?.VALOR ?? "";

            // console.log('params copiaparam', valor);
            return valor;
        }


        const emp_id = getCookie("emp_id");
        if (!emp_id) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        const _url = `/sisplan/funcoes/v1/pesquisa?`;
        const response = await requisicao(
            "GET",
            _url,
            `JSON={ "tabela":"loja_param", "camposSelect":["valor"], "where": ["tipo = '${sTipo}'", "posicao = ${iPosicao}", "emp_id = ${emp_id}"]}`,
            null
        );

        if (!response) {
            throw "Não foi possível buscar os dados.";
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgAlerta(jsonStr.RESULT[0].mensagem);
            throw "Não foi possível buscar os dados.";
        }

        if (jsonStr.RESULT[0].length > 0) {
            // console.log('params copiaparam2', jsonStr.RESULT[0][0].VALOR);
            return jsonStr.RESULT[0][0].VALOR;
        }
    } catch (error) {
        console.error(`Ocorreu um erro na rotina CopiaParametro com o tipo ${sTipo} e posição ${iPosicao}\n${error}`);
    }
}

async function BuscaParametrosVenda() {
    const parametrosLogin = sessionStorage.getItem('web@parametros') ?? [];
    if (parametrosLogin.length > 0) {
        const parametrosObject = JSON.parse(parametrosLogin);
        const valores = parametrosObject.filter(param => param.TIPO == 'VENDA').map(param => param.VALOR);
        // console.log('params venda', valores);
        return valores;
    }

    const url = `/sisplan/funcoes/v1/pesquisa?`;
    const empId = getCookie("emp_id");
    if (!empId) {
        window.location.href = `${BASE_URI}/login`;
        return [];
    }
    const response = await requisicao(
        "GET",
        url,
        `JSON={ "tabela":"loja_param", "camposSelect":["valor"], "where": ["tipo = 'VENDA'", "emp_id = ${empId}"], "orderby": ["POSICAO"]}`,
        null
    );

    if (!response) {
        throw new Error("Não foi possível buscar os dados.");
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
        msgAlerta(jsonStr.RESULT[0].mensagem);
        throw new Error("Não foi possível buscar os dados.");
    }

    if (jsonStr.RESULT[0].length > 0) {
        for (let i = 0; i < jsonStr.RESULT[0].length; i++) {
            jsonStr.RESULT[0][i] = jsonStr.RESULT[0][i].VALOR;
        }

        // console.log('params venda2', jsonStr.RESULT[0]);
        return jsonStr.RESULT[0];
    }
    return [];
}

async function BuscaParametrosPedidoB2B() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'PEDIDOB2B'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosPedido() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'PEDIDO'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosEscritural() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'ESCRITURAL'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosOrdemProducao() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'ORDEMPRODUCAO'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosContabil() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'CONTABIL'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

async function BuscaParametrosCompras() {
    try {
        let empId = getCookie("emp_id");
        if (!empId) {
            window.location.href = `${BASE_URI}/login`;
            return '';
        }
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"LOJA_PARAM", "camposSelect":["VALOR", "POSICAO"], "where": ["EMP_ID = ${empId} AND TIPO = 'COMPRAS'"],"orderby": ["posicao"]}`,
            null
        );

        if (!response) {
            msgErro("Não foi possível buscar os dados.");
            return;
        }

        let jsonStr = await response.json();

        return jsonStr.RESULT[0];

    } catch (error) {
        console.error(error);
    }
}

function disableselect(e) {
    return false;
}

function reEnable() {
    return true;
}

$('input[type="date"]').keydown(function (e) {
    let data = new Date();
    if (e.keyCode == 84) {
        $(this).val(`${data.getUTCFullYear()}-${String(data.getUTCMonth() + 1).padStart(2, 0)}-${String(data.getUTCDate()).padStart(2, 0)}`);
    } else if (e.keyCode == 82) {
        $(this).val(`1200-01-01`);
    } else if (e.keyCode == 89) {
        $(this).val(`2500-12-31`);
    } else if (e.keyCode === 189 || e.keyCode === 109) {
        let dtAtual = new Date($(this).val());
        dtAtual.setDate(dtAtual.getDate() - 1);
        let newData = dtAtual.toISOString().slice(0, 10);
        $(this).val(newData);
    } else if (e.keyCode === 187 || e.keyCode === 107) {
        let dtAtual = new Date($(this).val());
        dtAtual.setDate(dtAtual.getDate() + 1);
        let newData = dtAtual.toISOString().slice(0, 10);
        $(this).val(newData);
    }
});

$("input[type='date']").off("blur");
$(document).on('blur', 'input[type="date"]', async function () {
    $(this).next('.data-error-message').remove();
    if (this.validity.badInput) {
        const errorMessage = $('<div class="data-error-message" style="color: #d32f2f; font-size: 12px; margin-top: 5px; display: block;">A data informada é inválida</div>');
        $(this).after(errorMessage);
        $("html").addClass("error-edenilson");
    }
})

// if IE4+
// document.onselectstart = () => false;
document.oncontextmenu = () => false;
// if NS6
if (window.sidebar) {
    document.onmousedown = disableselect;
    document.onclick = reEnable;
}
$.fn.once = function (events, callback) {
    return this.each(function () {
        let myCallback = function (e) {
            callback.call(this, e);
            $(this).off(events, myCallback);
        };
        $(this).on(events, myCallback);
    });
};

async function retornaADEmpresa() {
    try {
        const codigoUsuario = getCookie('cod_usuario');
        const nomeUsuario = getCookie('usuario');
        setCookie('usuario', codigoUsuario); // setado o código pq dentro da requisição abaixo ele precisa do parametro codigo
        const response = await requisicao('GET', '/sisplan/usuario/v1/empresas?', `EMPRESA=_001&usuario=${codigoUsuario}`, null);
        setCookie('usuario', nomeUsuario); // volta ao padrao do sistema

        if (!response) {
            return;
        }

        const jsonStr = await response.json();
        const ad = jsonStr[0].EMP_AD;
        return ad;
    } catch (error) {
        console.log(error);
    }
}

async function senhaSupervisor(sMsg, callBack, props, bDesconto = false, callBackDesistir, callbackClose, callBackErro, bMaster = false, sNomeTela = '', sChave = undefined, sCodCli = '', sValor = 0, valorLiq = 0, percDesc = 0, desconto = 0, codrep = '') {
    try {
        const tipo = bMaster ? 'Master' : 'Supervisor/Master';
        const adEmpresa = await retornaADEmpresa();
        $('#txtUsuarioAD').val('');

        if (adEmpresa != '') {
            $('.txtUsuarioAD').removeClass('d-none');
        }

        $("#modal-supervisor-titulo").html("Senha Supervisor");
        $("#txtSenhaSupervisor").val("");
        $("#modal-supervisor-conteudo").html(
            `${sMsg} <br> Informe uma senha de usuário ${tipo} para continuar.`
        );
        $("#modal-supervisor-rodape").html(
            `<div class="row col-12 pl-0">
          <div class="col-3">
          <button type="button" id="btn-supervisor-confirmar" class="btn btn-primary btn-sisp" data-dismiss="modal">Confirmar</button>
          </div>
          <div class="col-3">
          <button type="button" id="btnSolicitaLibSupervisor" class="btn btn-success btnGreen btn-sisp">Solicitar</button>
          </div>
          <div class="col-3">
          <button type="button" id="btnVerificaLibSupervisor" class="btn btn-secondary btn-sisp">Verificar</button>
          </div>
          <div class="col-3">
          <button type="button" id="btnSupervisorDesistir" class="btn btn-danger btn-sisp" data-dismiss="modal">Desistir</button>
          </div>
          </div>`
        );
        if ((sNomeTela) && (sNomeTela != '')) {
            $("#txtNomeTelaSupervisor").val(sNomeTela);
        }

        $("#modal-supervisor").modal({
            backdrop: "static",
            keyboard: true,
            show: true,
        });

        const acessoRetaguarda = sessionStorage.getItem('acessoretaguardasupervisor');
        if (acessoRetaguarda == 'S') {
            $('#btnSolicitaLibSupervisor').removeClass('d-none');
            $('#btnVerificaLibSupervisor').removeClass('d-none');
            $('#btnSolicitaLibSupervisor').off('click');
            $('#btnSolicitaLibSupervisor').on('click', async function () {
                $.LoadingOverlay('show');
                try {
                    await abreModalLiberacaoSupervisor(sMsg, sNomeTela, sChave, sCodCli, sValor, valorLiq, percDesc, desconto, codrep);
                } catch (error) {
                    console.error(error);
                    msgAlerta(error.message);
                } finally {
                    $.LoadingOverlay('hide');
                }
            });
            $('#btnVerificaLibSupervisor').off('click');
            $('#btnVerificaLibSupervisor').on('click', async function () {
                $.LoadingOverlay('show');
                try {
                    await verificaSolicitacao(callBack, callBackErro, sNomeTela, bDesconto, props);
                } catch (error) {
                    console.error(error);
                    msgAlerta(error.message);
                } finally {
                    $.LoadingOverlay('hide');
                }
            });
        } else {
            $('#btnSolicitaLibSupervisor').addClass('d-none');
            $('#btnVerificaLibSupervisor').addClass('d-none');
        }

        // <button type="button" class="btn btn-outline-light">Save changes</button>
        $('#modal-supervisor-chave').html(sChave);
        $("#modal-supervisor").modal("show");

        $("#btn-supervisor-confirmar").on("click", async function () {
            if ($("#txtSenhaSupervisor").val() == '') {
                msgErro(`Senha de ${tipo} não pode ficar em branco! Impossível continuar.`);
                if (callBackErro && callBackErro != '') {
                    callBackErro();
                };
                return;
            }
            let retorno = await requisicaoSenhaSupervisor(
                $("#txtSenhaSupervisor").val(),
                callBack,
                props,
                bDesconto,
                bMaster,
                $('#txtUsuarioAD').val()
            );
            if (retorno.valor) {
                await requisicaoLiberacaoSupervisor(
                    'Liberado direto com senha de supervisor',
                    '',
                    sNomeTela,
                    sChave,
                    sCodCli,
                    sValor,
                    valorLiq,
                    percDesc,
                    desconto,
                    codrep,
                    false
                );
            } else {
                msgErro(`Senha de ${tipo} incorreta, impossível continuar.`);
                if (callBackErro && callBackErro != '') {
                    callBackErro();
                };
                return;
            }
        });
        $('#btnSupervisorDesistir').on('click', function () {
            if (callBackDesistir && callBackDesistir != '') {
                callBackDesistir();
            }
        });

        $('#btn-supervisor-close').on('click', function () {
            if (callbackClose && callbackClose != '') {
                callbackClose();
            }
        });

    } finally {
        // return false;
    }

}

$("#modal-supervisor").on("shown.bs.modal", async function () {
    $("#txtSenhaSupervisor").focus();
    const possuiLiberacaoAberta = localStorage.getItem(`liberacaoSupervisor${$('#txtNomeTelaSupervisor').val()}${getCookie('emp_id')}`);
    if (possuiLiberacaoAberta) {
        const chaveGravada = JSON.parse(possuiLiberacaoAberta).chave ?? '';
        if (chaveGravada == $('#modal-supervisor-chave').html()) {
            $('#btnSolicitaLibSupervisor').prop('disabled', true);
            $('#btnVerificaLibSupervisor').prop('disabled', false);
            $('#btnSolicitaLibSupervisor').attr('title', `Solicitação: ${JSON.parse(possuiLiberacaoAberta).id} ainda está pendente. \nConclua a solicitação antes de incluir uma nova.`);
            $('#btnVerificaLibSupervisor').attr('title', '');
        } else {
            $('#btnSolicitaLibSupervisor').prop('disabled', false);
            $('#btnVerificaLibSupervisor').prop('disabled', true);
            $('#btnSolicitaLibSupervisor').attr('title', '');
            $('#btnVerificaLibSupervisor').attr('title', 'Não existe nenhuma solicitação pendente para esta tela.');
        }
    } else {
        $('#btnSolicitaLibSupervisor').prop('disabled', false);
        $('#btnVerificaLibSupervisor').prop('disabled', true);
        $('#btnSolicitaLibSupervisor').attr('title', '');
        $('#btnVerificaLibSupervisor').attr('title', 'Não existe nenhuma solicitação pendente para esta tela.');
    }
});

async function setarDataAtual(componente, primeiroDia = false, qtdeDiasParaFrente = 0) {
    let today = new Date();
    today.setDate(today.getDate() + qtdeDiasParaFrente);
    const dy = primeiroDia ? "01" : String(today.getDate()).padStart(2, "0");
    const mt = String(today.getMonth() + 1).padStart(2, "0");
    const yr = today.getFullYear();
    $(`#${componente}`).val(`${yr}-${mt}-${dy}`);
}

function pegarDataAtual(primeiroDia = false, qtdeDiasParaFrente = 0) {
    let today = new Date();
    today.setDate(today.getDate() + qtdeDiasParaFrente);
    const dy = primeiroDia ? "01" : String(today.getDate()).padStart(2, "0");
    const mt = String(today.getMonth() + 1).padStart(2, "0");
    const yr = today.getFullYear();
    return `${yr}-${mt}-${dy}`;
}

function setarDataPraFrente(componente, today, qtdeDiasParaFrente = 0,) {
    today.setDate(today.getDate() + qtdeDiasParaFrente);
    const dy = String(today.getDate()).padStart(2, "0");
    const mt = String(today.getMonth() + 1).padStart(2, "0");
    const yr = today.getFullYear();
    $(`#${componente}`).val(`${yr}-${mt}-${dy}`);

    return `${yr}-${mt}-${dy}`;
}

function retornaDataPraFrente(today, qtdeDiasParaFrente = 0,) {
    today.setDate(today.getDate() + qtdeDiasParaFrente);
    const dy = String(today.getDate()).padStart(2, "0");
    const mt = String(today.getMonth() + 1).padStart(2, "0");
    const yr = today.getFullYear();

    return `${yr}-${mt}-${dy}`;
}

function retornaDataMenosDias(today, qtdeDias = 0,) {
    today.setDate(today.getDate() - qtdeDias);
    const dy = String(today.getDate()).padStart(2, "0");
    const mt = String(today.getMonth() + 1).padStart(2, "0");
    const yr = today.getFullYear();

    return `${yr}-${mt}-${dy}`;
}

async function fazSelectNaEmpValor(codigo, tabela) {
    try {
        const empID = getCookie("emp_id");
        if (codigo != "") {
            const empValorLogin = sessionStorage.getItem('web@empValor') ?? [];
            if (empValorLogin.length > 0) {
                const empValorObject = JSON.parse(empValorLogin);
                const valores = empValorObject.filter(val => val.TABELA == tabela && val.VALOR == codigo).map(val => ({ EMP_ID: empID }));
                // console.log('consultou por codigo', valores, tabela);
                return valores;
            }
            const url = "/Sisplan/Funcoes/v1/pesquisa?";
            const response = await requisicao(
                "GET",
                url,
                `JSON={ "tabela":"EMP_VALOR", "camposSelect":["EMP_ID"], "where": ["VALOR = '${codigo}' AND TABELA = '${tabela}'"]}`
            );

            if (!response) {
                return [];
            }

            const jsonStr = await response.json();
            if (response.status != 200) {
                msgErro(jsonStr.mensagem);
                return [];
            }
            // console.log('consultou por codigo2', jsonStr.RESULT[0], tabela);
            return jsonStr.RESULT[0];
        }

        const empValorLogin = sessionStorage.getItem('web@empValor') ?? [];
        if (empValorLogin.length > 0) {
            const empValorObject = JSON.parse(empValorLogin);
            const valores = empValorObject.filter(val => val.TABELA == tabela).map(val => ({ EMP_ID: empID, VALOR: val.VALOR }));
            // console.log('consultou sem codigo', valores, tabela);
            return valores;
        }

        const url = "/Sisplan/Funcoes/v1/pesquisa?";
        const response = await requisicao(
            "GET",
            url,
            `JSON={ "tabela":"EMP_VALOR", "camposSelect":["EMP_ID", "VALOR"], "where": ["TABELA = '${tabela}' AND EMP_ID=${getCookie(
                "emp_id"
            )}"]}`
        );

        if (!response) {
            return [];
        }

        const jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.mensagem);
            return [];
        }
        // console.log('consultou sem codigo2', jsonStr.RESULT[0], tabela);
        return jsonStr.RESULT[0];
    } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar as empresas.`);
        return [];
    }
}

function msgErro($mensagem, $callbackOk, $callbackClose) {
    if (!$mensagem) return;
    $("#modal-warning-titulo").html("Atenção");
    $("#modal-warning-conteudo").val($mensagem);
    $("#modal-warning-rodape").html(
        `<button type="button" id="btn-msg-alerta" class="btn bg-gradient-success btn-sisp" data-dismiss="modal">Ok <small>(ALT + S)</small></button>`
    );
    // <button type="button" class="btn btn-outline-light" data-dismiss="modal">Close</button>
    // <button type="button" class="btn btn-outline-light">Save changes</button>

    $("#modal-warning").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    $("#modal-warning").modal("show");
    if ($callbackOk != undefined) {
        $("#btn-msg-alerta").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackOk();
        });
    }

    if ($callbackClose != undefined) {
        $("#btn-warning-close").on("click", function () {
            $("#modal-warning").modal("hide");
            $callbackClose();
        });
    }

    $("#modal-warning").click();
    $("#btn-msg-alerta").focus();
}

$("#modal-danger").on("shown.bs.modal", function () {
    $("#btn-msg-erro").focus();
});

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function buscaDuplicatasEmAberto(codcli, todasEmpresas) {
    try {
        if (codcli == '') {
            return [];
        }
        const url = "/sisplan/receber/v1/receberabertos?";
        const response = await requisicao(
            "GET",
            url,
            `CLIENTE=${codcli}&DUPLICATA=S&ANTECIPACAO=S&CHEQUE=S&CHEQUEDEV=S&TODASEMPRESAS=${todasEmpresas}`,
            null
        );

        if (!response) {
            return;
        }
        if (response.status != 200) {
            msgErro(response.mensagem);
            return;
        }

        const jsonStr = await response.json();

        return jsonStr;
    } catch (error) {
        console.error(error);
    }
}

async function retornaValorCadPadrao(tabela, campo) {
    try {
        const pesquisa = await buscaValoresPadroes(tabela)
        const jsonStr = pesquisa.filter((item) => item.CAMPO == campo)
        return jsonStr[0]?.VALOR ?? '';
    } catch (error) {
        return '';
    }
}

async function retornaPaisPadraoEntidade() {
    try {
        const valPadrao = await retornaValorCadPadrao('ENTIDADE', 'PAIS');
        if (valPadrao) {
            const pais = `[${valPadrao}] - ${(await buscaValor('CADPAIS', 'NOME', 'CODIGO', valPadrao)).NOME}`;
            return pais.substring(pais.indexOf("]") + 4, pais.length).trim() != 'undefined' ? pais : '';
        }

        return '';
    } catch (error) {
        console.log(error);
    }
}


async function aguardaMsgAlerta($mensagem, $callback) {
    return new Promise((resolve) => {
        msgAlerta($mensagem,
            undefined,
            undefined,
            () => {
                $callback();
                resolve(true);
            });
    });
}


async function msgHTML($mensagem, $footer) {
    $("#modal-html-titulo").html("Atenção");
    $('#btn-msg-alerta').html('Confirmar (ALT + S)');
    $("#modal-html-conteudo").html($mensagem);
    if ($footer != undefined) {
        $("#modal-html-rodape").html($footer);
    } else {
        $("#modal-html-rodape").html(
            '<button data-dismiss="modal" id="btn-msg-alerta" type="button" class="btn bg-gradient-success btn-sisp">Ok <small>(ALT + S)</small></button>'
        );
    }
    $("#modal-html").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });
    $("#modal-html").click();
    $("#modal-html").focus();
}

async function msgAlerta($mensagem, $callback, $callbackCancelar, $callbackOk, $callbackClose, bSimNao = false, bEscondeCanc = false, bloquearBotoes = false, textoBotaoConfirmar = 'Confirmar', textoBotaoNegar = 'Cancelar', hintBotaoConfirmar = '') {
    $("#modal-warning-titulo").html("Atenção");
    $('#btn-msg-alerta').html('Confirmar (ALT + S)');
    $("#modal-warning-conteudo").val($mensagem);

    if ($callback != undefined) {
        $("#modal-warning-rodape").html(
            `<button id="btn-msg-alerta" type="button" title="${hintBotaoConfirmar}" class="btn controleBotoesModal bg-gradient-success btn-sisp" ${bloquearBotoes && 'disabled'}>${bSimNao ? "Sim" : textoBotaoConfirmar} <small>(ALT + S)</small></button>` +
            `<button type="button" id="btn-msg-cancelar" class="btn controleBotoesModal bg-gradient-danger btn-sisp ${bEscondeCanc ? 'd-none' : ''}" ${bloquearBotoes && 'disabled'} ${!bloquearBotoes && 'data-dismiss="modal"'}>${bSimNao ? "Não" : textoBotaoNegar} <small>(ALT + N)</small></button>`
        );
    } else {
        $("#modal-warning-rodape").html(
            `<button data-dismiss="modal" id="btn-msg-alerta" type="button" class="btn controleBotoesModal bg-gradient-success btn-sisp" ${bloquearBotoes && 'disabled'}>Ok <small>(ALT + S)</small></button>`
        );
    }

    $("#modal-warning").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    if (bloquearBotoes) {
        $('#modal-warning').on('shown.bs.modal', () => $('.controleBotoesModal').prop('disabled', false))
    }

    $("#btn-msg-alerta").on("click", async function () {
        $("#modal-warning").modal("hide");
        await sleep(500);
        if ($callback != undefined) {
            $callback();
        }
    });

    if ($callback != undefined && $callbackCancelar != undefined) {
        $("#btn-msg-cancelar").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackCancelar();
        });
    }
    if ($callbackOk != undefined) {
        $("#btn-msg-alerta").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackOk();
        });
    }
    if ($callbackClose != undefined) {
        $("#btn-warning-close").off().on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackClose();
        });
    }
    $("#modal-warning").click();
    $("#modal-warning").focus();
}

async function msgAlertaHtml(html, callbackOk, callbackCancelar, callbackClose, textoBotaoConfirmar = 'Confirmar', textoBotaoNegar = 'Cancelar', somenteBotaoConfirmar = false) {
    $("#modal-warning-titulo-html").html("Atenção");
    $('#btn-msg-alerta-html').html('Confirmar (ALT + S)');
    $("#modal-warning-conteudo-html").html(html);

    $("#modal-warning-rodape-html").html(
        `<button id="btn-msg-alerta-html" type="button" class="btn controleBotoesModal bg-gradient-success btn-sisp" disabled>${textoBotaoConfirmar} <small>(ALT + S)</small></button>` +
        `${!somenteBotaoConfirmar ? `<button type="button" id="btn-msg-cancelar-html" class="btn controleBotoesModal bg-gradient-danger btn-sisp" disabled data-dismiss="modal">${textoBotaoNegar} <small>(ALT + N)</small></button>` : ''}`
    );

    $("#modal-warning-html").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    $('#modal-warning-html').on('shown.bs.modal', () => $('.controleBotoesModal').prop('disabled', false))

    $("#btn-msg-alerta-html").on("click", async function () {
        $("#modal-warning-html").modal("hide");
        await sleep(500);
    });
    $("#btn-msg-alerta-html").on("click", async function () {
        $("#modal-warning-html").modal("hide");
        await sleep(500);
        callbackOk?.();
    });
    $("#btn-msg-cancelar-html").on("click", async function () {
        $("#modal-warning-html").modal("hide");
        await sleep(500);
        callbackCancelar?.();
    });
    $("#btn-warning-close-html").on("click", async function () {
        $("#modal-warning-html").modal("hide");
        await sleep(500);
        callbackClose?.();
    });
    $("#modal-warning-html").click();
    $("#modal-warning-html").focus();
}

async function msgAlertaComInput($mensagem, $callback, $callbackCancelar, $callbackOk, $callbackClose, bSimNao = false, date) {
    $("#modal-dtRetorno-titulo").html("Atenção");
    $('#btn-msg-alerta').html('Confirmar (ALT + S)');
    $("#modal-dtRetorno-conteudo").val($mensagem);
    if (date != undefined) {
        $('#dtRetorno').val(date);
    }
    if ($callback != undefined) {
        $("#modal-dtRetorno-rodape").html(
            `<button id="btn-confirmarDataRetorno" type="button" class="btn bg-gradient-success btn-sisp">${bSimNao ? "Sim" : "Confirmar"} <small>(ALT + S)</small></button>` +
            `<button type="button" id="btn-cancelarDataRetorno" class="btn bg-gradient-danger btn-sisp" data-dismiss="modal">${bSimNao ? "Não" : "Cancelar"} <small>(ALT + N)</small></button>`
        );
    } else {
        $("#modal-dtRetorno-rodape").html(
            '<button data-dismiss="modal" id="btn-confirmarDataRetorno" type="button" class="btn bg-gradient-success btn-sisp">Ok <small>(ALT + S)</small></button>'
        );
    }

    $("#modal-dtRetorno").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    $("#btn-confirmarDataRetorno").on("click", async function () {
        $("#modal-dtRetorno").modal("hide");
        await sleep(500);
        if ($callback != undefined) {
            $callback();
        }
    });

    if ($callback != undefined && $callbackCancelar != undefined) {
        $("#btn-cancelarDataRetorno").on("click", async function () {
            $("#modal-dtRetorno").modal("hide");
            await sleep(500);
            $callbackCancelar();
        });
    }
    if ($callbackOk != undefined) {
        $("#btn-confirmarDataRetorno").on("click", async function () {
            $("#modal-dtRetorno").modal("hide");
            await sleep(500);
            $callbackOk();
        });
    }
    if ($callbackClose != undefined) {
        $("#btn-warning-close").on("click", async function () {
            $("#modal-dtRetorno").modal("hide");
            await sleep(500);
            $callbackClose();
        });
    }
    $("#modal-dtRetorno").click();
    $("#modal-dtRetorno").focus();
}

function msgAlertaSemConfirmacao($mensagem, $modal, $callback = undefined) {
    $("#modal-warning-titulo").html("Atenção");
    $("#modal-warning-conteudo").val($mensagem);

    $("#modal-warning-rodape").html(
        '<button data-dismiss="modal" id="btn-msg-alerta" type="button" class="btn bg-gradient-success btn-sisp">Ok</button>'
    );
    // <button type="button" class="btn btn-outline-light" data-dismiss="modal">Close</button>
    // <button type="button" class="btn btn-outline-light">Save changes</button>
    $("#modal-warning").modal("show");
    $(`#${$modal}`).modal("hide");
    $("#btn-msg-alerta").on("click", async function () {
        $(`#${$modal}`).modal("hide");
        $("#modal-warning").modal("hide");
        if ($callback != undefined) {
            await sleep(500);
            $callback();

        }
    });
}

function msgConfirmacao($mensagem, $callbacks) {
    $("#modal-confirmacao-titulo").html("Atenção");
    $("#modal-confirmacao-conteudo").html($mensagem);
    if ($callbacks != undefined) {
        $("#modal-confirmacao-rodape").html(
            '<button title="Ao abandonar venda, você perderá os dados que estão na tela." id="btn-cfm-abandonar" type="button" class="btn bg-gradient-danger btn-sisp">Abandonar Venda</button>' +
            '<button title="Ao deixar a venda pendente, você irá salvar e poderá continuar futuramente." id="btn-cfm-pendente" type="button" class="btn bg-gradient-success btn-sisp">Deixar Pendente</button>' +
            '<button title="Desistir de sair da venda." type="button" class="btn bg-gradient-secondary btn-sisp" data-dismiss="modal">Voltar</button>'
        );
    }
    $("#modal-confirmacao").modal("show");
    $("#btn-cfm-abandonar").on("click", function () {
        $callbacks[0]();
        $("#modal-confirmacao").modal("hide");
    });
    $("#btn-cfm-pendente").on("click", function () {
        $callbacks[1]();
        $("#modal-confirmacao").modal("hide");
    });
}

function msgSucesso($mensagem) {
    $("#modal-success-titulo").html("Atenção");
    $("#modal-success-conteudo").val($mensagem);
    $("#modal-success-rodape").html(
        `<button type="button" class="btn bg-gradient-success btn-sisp" data-dismiss="modal">Ok</button>`
    );
    // <button type="button" class="btn btn-outline-light" data-dismiss="modal">Close</button>
    // <button type="button" class="btn btn-outline-light">Save changes</button>
    $("#modal-success").modal("show");
}

function ConfirmYesNo(title, msg) {
    let dfd = jQuery.Deferred();
    let $confirm = $("#myModal");
    $confirm.modal("show");
    $("#myModalLabel").html(title);
    $("#myModalText").html(msg);
    $("#btnYes")
        .off("click")
        .click(function () {
            $confirm.modal("hide");
            dfd.resolve(1);
            return 1;
        });
    $("#btnNo")
        .off("click")
        .click(function () {
            $confirm.modal("hide");
            dfd.resolve(0);
            return 0;
        });
    return dfd.promise();
}

function formataData(date) {
    let year = date.getFullYear();

    let month = (1 + date.getMonth()).toString();
    month = month.length > 1 ? month : `0${month}`;

    let day = date.getDate().toString();
    day = day.length > 1 ? day : `0${day}`;

    return `${year}-${month}-${day}`;
}

function formataDataCompleta(date) {
    let year = date.getFullYear();
    let hours = date.getHours();
    let minutes = date.getMinutes();
    let seconds = date.getSeconds();
    // let miliseconds = date.getMilliseconds();

    let month = (1 + date.getMonth()).toString();
    month = month.length > 1 ? month : `0${month}`;

    let day = date.getDate().toString();
    day = day.length > 1 ? day : `0${day}`;

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

function formataDataCompletaBonita(date) {
    let year = date.getFullYear();
    let hours = date.getHours();
    let minutes = date.getMinutes();
    let seconds = date.getSeconds();
    // let miliseconds = date.getMilliseconds();

    let month = (1 + date.getMonth()).toString();
    month = month.length > 1 ? month : `0${month}`;

    let day = date.getDate().toString();
    day = day.length > 1 ? day : `0${day}`;

    return `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
}

function formataDataBonita(date, anoCompleto = true) {
    if (date == '') {
        return '';
    }

    const dateParts = date.split("-");
    const dia = dateParts[2].padStart(2, '0');
    const mes = dateParts[1].padStart(2, '0');
    const ano = anoCompleto ? dateParts[0] : dateParts[0].substring(2);

    return dia + "/" + mes + "/" + ano;
}

function formataDataComTraco(date, anoCompleto = true) {
    const dateParts = date.split("/");
    const dia = dateParts[0].padStart(2, '0');
    const mes = dateParts[1].padStart(2, '0');
    const ano = anoCompleto ? dateParts[2] : dateParts[2].substring(2);

    return ano + "-" + mes + "-" + dia;
}

function formataDateTimeBackEnd(dateString) {
    const parts = dateString.split(' ');
    const datePart = parts[0].split('-');
    let timePart = parts[1].split(':');

    if (timePart[2].length === 1) {
        timePart[2] = '0' + timePart[2];
    }

    const formattedDateString = datePart.join('-') + 'T' + timePart.join(':') + 'Z';

    return formattedDateString;
}

function retornarDataISOEmYMD({
    dataISO = new Date(),
    separadorData = '/',
    separadorHora = ':',
    incluirHora = false,
    reverso = false,
    usarUTC = false
} = {}) {
    try {
        const data = new Date(dataISO)

        if (isNaN(data.getTime())) return ''

        const dia = usarUTC ? String(data.getUTCDate()).padStart(2, '0') : String(data.getDate()).padStart(2, '0')
        const mes = usarUTC ? String(data.getUTCMonth() + 1).padStart(2, '0') : String(data.getMonth() + 1).padStart(2, '0')
        const ano = usarUTC ? data.getUTCFullYear() : data.getFullYear()

        const partesData = [dia, mes, ano]
        const dataFormatada = reverso
            ? partesData.join(separadorData)
            : partesData.reverse().join(separadorData)

        if (incluirHora) {
            const horas = usarUTC ? String(data.getUTCHours()).padStart(2, '0') : String(data.getHours()).padStart(2, '0')
            const minutos = usarUTC ? String(data.getUTCMinutes()).padStart(2, '0') : String(data.getMinutes()).padStart(2, '0')
            const segundos = usarUTC ? String(data.getUTCSeconds()).padStart(2, '0') : String(data.getSeconds()).padStart(2, '0')

            return `${dataFormatada} ${horas}${separadorHora}${minutos}${separadorHora}${segundos}`
        }

        return dataFormatada
    } catch (error) {
        return ''
    }
}

async function GeraRelatorio(sUrl, RequestType, timeOut, result = true, layout = '', body = null, tela = "") {
    if (RequestType == undefined) RequestType = "GET";

    if (timeOut == undefined) {
        timeOut = typeof TIMEOUT_API === 'undefined' ? 15000 : TIMEOUT_API;
    }
    let response;
    try {
        // fazer segunda
        // sUrl.split('?')[1].replace(sUrl.split('?')[1].slice(-1), '')

        const urls = sUrl.split("?");
        let parametros = "";
        if (urls.length > 1) {
            parametros = urls[1];
        }

        response = await requisicao(
            RequestType,
            `${urls[0]}?`,
            parametros,
            body,
            timeOut
        );
    } catch (error) {
        console.log(error);
        return;
    }

    let jsonStr = await response.json();

    if (response.status == 502) {
        await msgAguardaConfirmacao(jsonStr.mensagem, () => { }, () => { }, false, true, "Continuar");
        jsonStr = JSON.parse(jsonStr.json);
    } else if (response.status != 200) {
        if (jsonStr.mensagem.mensagem != undefined) {
            msgErro(jsonStr.mensagem.mensagem);
        } else {
            msgErro(jsonStr.mensagem);
        }

        return;
    }
    if (!result && jsonStr.base64Arquivo != undefined) {
        await imprimirAutomatico(jsonStr.base64Arquivo, layout);
        const bReimpressaoRelatorioNFCE = (await CopiaParametro('VENDA', 90) == 1);
        if (bReimpressaoRelatorioNFCE && layout == "NFCE" && tela == "VENDA") {
            const codVen = $('#txtCodVen').val();
            await reimpressaoRelatorioNFCE(codVen, async () => { await imprimirAutomatico(jsonStr.base64Arquivo, layout); });
        }
    }
    if (jsonStr.arquivo != undefined) {
        return jsonStr.arquivo;
    }
    return jsonStr;
}

async function requisicaoSenhaSupervisor(sSenha, callBack, props, bDesconto = false, bMaster = false, usuarioAD = '') {
    let encrypt = btoa(`sISPKJSDLK${sSenha}@klSIp1q34534sS`);
    try {
        try {
            const tipo = bMaster ? '&TIPO=MASTER' : '';
            const paramUsuario = usuarioAD != '' ? `&USUARIO_AD=${usuarioAD}` : '';
            let response = await requisicao(
                "GET",
                "/Sisplan/funcoes/v1/SenhaSupervisor?",
                `senha=${encrypt}${tipo}${paramUsuario}`,
                null
            );

            if (!response) {
                return false;
            }

            let jsonStr = await response.json();
            if (response.status != 200) {
                return false;
            }
            if (!jsonStr.valor) {
                return false;
            }
            if (!bDesconto) {
                if (props != undefined) {
                    callBack(props);
                } else {
                    callBack();
                }
            } else if (props) {
                // quando for desconto ele vai receber uma função de callback no props
                const callbackDesconto = props;
                callBack(jsonStr.usuario, callbackDesconto);
            }
            return jsonStr;
        } finally {
        }
    } catch (error) {
        return false;
    }
}

async function limparRelatorios() {
    try {
        try {
            $.LoadingOverlay("show");
            let response = await requisicao(
                "GET",
                "/Sisplan/funcoes/v1/limparImpressos?",
                "",
                null
            );

            if (!response) {
                $.LoadingOverlay("hide");
                return;
            }

            let jsonStr = await response.json();
            if (response.status != 200) {
                $.LoadingOverlay("hide");
                return;
            }
        } finally {
            $.LoadingOverlay("hide");
        }
    } catch (error) {
        $.LoadingOverlay("hide");
    }
}

async function RetornaDoctoELancto(
    sTipo,
    sTabela,
    sCampo,
    sTamanho,
    bOffline = false
) {
    if (!bOffline) {
        let _url = `/sisplan/funcoes/v1/Proximo?`;
        let _params = `tabela=${sTabela}&campo=${sCampo}&tamanho=${sTamanho}&tipo=${sTipo}`;

        try {
            let response = await requisicao("GET", _url, _params, null);

            if (!response) {
                return;
            }

            let jsonStr = await response.json();
            if (response.status != 200) {
                msgErro(jsonStr.RESULT[0].mensagem);
                return;
            }
            return jsonStr.json;
        } catch (error) {
            msgErro("Não foi possível buscar o Número de documento.");
        }
    }
}

async function RetornaProximo(sTipo, sTabela, sCampo, sTamanho, bUsaCodigosValor = true) {
    let _url = `/sisplan/funcoes/v1/Proximo?`;
    let _params = `tabela=${sTabela}&campo=${sCampo}&tamanho=${sTamanho}&tipo=${sTipo}&usacodigosvalor=${bUsaCodigosValor}`;

    try {
        let response = await requisicao("GET", _url, _params, null);

        if (!response) {
            return;
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return;
        }
        return jsonStr.json;
    } catch (error) {
        msgErro(`Não foi possível buscar o próximo número. Tipo = ${sTipo}, Tabela = ${sTabela}.`);
    }
}

async function RetornaIDGenerator(sTabela, sCampo) {
    let _url = `/sisplan/funcoes/v1/retorna_generator?`;
    let _params = `tabela=${sTabela}&campo=${sCampo}`;

    try {
        let response = await requisicao("GET", _url, _params, null);

        if (!response) {
            return;
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return;
        }
        return jsonStr.json;
    } catch (error) {
        msgErro(`Não foi possível buscar o próximo id. Campo = ${sCampo}, Tabela = ${sTabela}.`);
    }
}

async function baixaCodigo(sTabela, sCampo, sValor) {
    let _url = `/sisplan/funcoes/v1/baixacodigo?`;
    let _params = `tabela=${sTabela}&campo=${sCampo}&valor=${sValor}`;

    try {
        let response = await requisicao("GET", _url, _params, null);

        if (!response) {
            return;
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return;
        }
        return jsonStr.json;
    } catch (error) {
        console.error(error);
    }
}

async function deletaRegistro(sTela, _sUsuario, sValor, sUserSistema = "") {
    let url = `/sisplan/controleedicao/v1/controleedicao?`;
    try {
        let response = await requisicao(
            "DELETE",
            url,
            `TELA=${sTela}&VALOR=${sValor}&USUARIOREGISTRO=${sUserSistema}`,
            null
        );

        if (!response) {
            return;
        }

        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return;
        }
    } catch (error) {
        msgErro("Não foi possível liberar os registros.");
    }
}

function insereValor(componente, codigo, descricao, retornaProximo = false) {
    let valor = '';
    if (typeof (codigo) == 'string' && codigo === '' && !retornaProximo) {
        return;
    }
    if (descricao == undefined) {
        $(componente).val(codigo);
        $(componente).attr("data-chave", codigo);
        $(componente).attr("data-selecionado", true);
    }
    else if (typeof (descricao) == 'object') {
        if (retornaProximo) {
            RetornaProximo(descricao.tipo, descricao.tabela, descricao.campo, descricao.tamanho)
                .then((value => {
                    $(componente).val(value);
                    $(componente).attr("data-chave", value);
                }
                ));
        }
        else {
            buscaValor(descricao.tabela, descricao.campoBusca, descricao.campoWhere, descricao.valorWhere)
                .then((value => {
                    let desc;
                    if (value == undefined) {
                        desc = 'VALOR INVÁLIDO';
                    } else {
                        desc = value[Object.keys(value)[0]];
                    }
                    $(componente).val(`[${codigo}] - ${desc}`);
                    $(componente).attr("data-chave", codigo);
                    $(componente).attr("data-desc", desc);
                    $(componente).attr("data-selecionado", true);
                }
                ));
        }
    }
    else {
        $(componente).val(`[${codigo}] - ${descricao}`);
        $(componente).attr("data-chave", codigo);
        $(componente).attr("data-desc", descricao);
        $(componente).attr("data-selecionado", true);
    }
}

function limpaValor(componente) {
    $(componente).val($(componente).attr("type") == "number" ? 0 : "");
    $(componente).val("");
    $(componente).attr("data-selecionado", false);
    $(componente).attr("data-chave", "");
    $(componente).attr("data-desc", "");
}

async function preencheOrdenacaoTela(sTela, sCampo = '', sDivPai = '') {
    const ordens = await retornaOrdensRelatorio(sTela);
    ordens.forEach((ordem) => {
        $(sCampo == '' ? '#txtOrdem' : `#${sCampo}`).append(
            `<option value="${ordem.ORDEM}" nome_prt="${ordem.NOME_PRT}">${ordem.NOME_ORD_TELA}</option>`
        );
    });
    if (sDivPai == '') {
        if (sCampo != '') {
            $(`#${sCampo}`).attr('nome_tela', sTela);
            $('.btnEdicaoRelatorio').attr('nome_tela', sTela);
        } else {
            $('#txtOrdem').attr('nome_tela', sTela);
            $('.btnEdicaoRelatorio').attr('nome_tela', sTela);
        }
    } else {
        if (sCampo != '') {
            $(`#${sCampo}`).attr('nome_tela', sTela);
            $(`#${sDivPai} .btnEdicaoRelatorio`).attr('nome_tela', sTela);
        } else {
            $('#txtOrdem').attr('nome_tela', sTela);
            $(`#${sDivPai} .btnEdicaoRelatorio`).attr('nome_tela', sTela);
        }
    }
}

// function CriaPesquisaPadrao(numIniciaAutoCompleta = 0, pSeletorInput, pSeletorButton, pPesquisa) {
//     $(pSeletorInput).autocompleta(numIniciaAutoCompleta, pPesquisa);
//     $(pSeletorButton).pesquisa(pSeletorInput, )
//     $('#btnUnidadeVenda').pesquisa('#txtUnidadeVenda', 'UNIDADE', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"unidade", "camposSelect":[ "unidade", "descricao"]}`, 'Pesquisa Unidade', 'unidade');

// }

function CriaTabelaPadrao(sSeletor) {
    $(sSeletor).DataTable({
        autoWidth: false,
        destroy: true,
        order: false,
        filter: false,
        paginate: false,
        // scrollY: "300px",
        // scrollX: 'auto',
        key: "true",
        columnDefs: [
            {
                targets: [7, 8],
                visible: false,
            },
            {
                "targets": [5, 6],
                "className": 'pr-4 text-right'
            }
        ],
    });

    $(`${sSeletor} tbody`).on("click", "tr", async function () {
        $(`${sSeletor} tbody tr td`)[0].click();
        $(`${sSeletor} tbody tr.selected`).removeClass("selected");
        $(this).addClass("selected");
    });
}

async function retornaOrdensRelatorio(sTela) {
    const pesquisa = {
        tabela: "ORDEM_TELA",
        camposSelect: ["ORDEM", "NOME_ORD_TELA", "NOME_PRT"],
        where: [`NOME_TELA = '${sTela}'`],
        orderBy: ["ORDEM"],
    };
    const json = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
    return json;
}

async function retornaConsultaWWW(sCNPJ, sCaptcha = '', jsonCaptcha = {}, sUF = '', usaCertificadoA3 = 0) {
    try {
        $.LoadingOverlay("show");
        if (usaCertificadoA3 == '1') {
            const url = '/cliente/consultacnpj?';
            const infoEmpresa = await retornaInformacaoEmpresa();
            const responseLocal = await requisicao_ecf('POST', url, `CNPJ=${sCNPJ}&CAPTCHA=${sCaptcha}&UF=${sUF}&JSON=${encodeURIComponent(JSON.stringify(jsonCaptcha))}`, JSON.stringify(infoEmpresa), 120000);
            if (!responseLocal) {
                msgAlerta('Não foi possível realizar a consulta, atualize o captcha e tente novamente.');
                return;
            }
            if (responseLocal.status == 200) {
                let jsonStr = await responseLocal.json();
                return jsonStr;
            }
            if (responseLocal.status != 200) {
                let jsonStr = await responseLocal.json();
                msgErro(jsonStr.mensagem);
                return;
            };
        } else {
            const url = `/sisplan/cliente/v1/consultawww?`;
            const params = `CNPJ=${sCNPJ}&CAPTCHA=${sCaptcha}&UF=${sUF}`;
            let response = await requisicao("POST", url, params, JSON.stringify(jsonCaptcha), 120000);
            if (!response) {
                msgAlerta('Não foi possível realizar a consulta, atualize o captcha e tente novamente.');
                return;
            }
            if (response.status == 200) {
                let jsonStr = await response.json();
                return jsonStr;
            }
            if (response.status != 200) {
                let jsonStr = await response.json();
                msgErro(jsonStr.mensagem);
                return;
            }
        }
    } finally {
        $.LoadingOverlay("Hide");
    }
}

async function verificarRegistro(tela, valor) {
    let _url = `/sisplan/controleedicao/v1/controleedicao?`;
    try {
        $.LoadingOverlay("Show");
        try {
            let response = await requisicao(
                "GET",
                _url,
                `TELA=${tela}&VALOR=${valor}`,
                null
            );

            let jsonStr = await response.json();

            if (response.status == 200) {
                if (jsonStr[0].TELA == tela && jsonStr[0].VALOR == valor) {
                    msgAlerta("Registro está sendo alterado");
                    return false;
                }
            }
        } catch (error) {
            return true;
        }
    } finally {
        $.LoadingOverlay("Hide");
    }
};

async function retornaDepositoUsuario(usuario) {
    try {
        $.LoadingOverlay("show");
        try {
            const url = '/Sisplan/Funcoes/v1/pesquisa?';
            const params = `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["DEPOSITOS"], "where": ["CODIGO = '${usuario}'"]}`;
            const response = await requisicao('GET', url, params, null);

            if (!response) {
                return 'null';
            }

            const jsonStr = await response.json();

            if (jsonStr.codigo == 400) {
                return 'null';
            }
            const result = jsonStr.RESULT[0][0].DEPOSITOS != '' ? `["CODIGO IN (${jsonStr.RESULT[0][0].DEPOSITOS})"]` : 'null';
            return result;
        } catch (error) {
            console.error(error);
            return 'null';
        }
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function retornaSetoresUsuario(usuario) {
    try {
        $.LoadingOverlay("show");

        const url = '/Sisplan/Funcoes/v1/pesquisa?';
        const params = `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["SETORES"], "where": ["CODIGO = '${usuario}'"]}`;
        const response = await requisicao('GET', url, params, null);

        if (!response) {
            return 'null';
        }

        const jsonStr = await response.json();

        if (jsonStr.codigo == 400) {
            return 'null';
        }
        const result = jsonStr.RESULT[0][0].SETORES != '' ? `["CODIGO IN (${jsonStr.RESULT[0][0].SETORES})"]` : 'null';
        return result;
    } catch (error) {
        console.error(error);
        return 'null';
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function retornaWhereOperFiscalUsuario(usuario) {
    try {
        $.LoadingOverlay("show");
        try {
            const url = '/Sisplan/Funcoes/v1/pesquisa?';
            const params = `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["OPER_FISCAL"], "where": ["CODIGO = '${usuario}'"]}`;
            const response = await requisicao('GET', url, params, null);

            if (!response) {
                return 'null';
            }

            const jsonStr = await response.json();

            if (jsonStr.codigo == 400) {
                return 'null';
            }
            const result = jsonStr.RESULT[0][0].OPER_FISCAL != '' ? `["CODIGO IN (${jsonStr.RESULT[0][0].OPER_FISCAL})"]` : 'null';
            return result;
        } catch (error) {
            console.error(error);
            return 'null';
        }
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function retornaRegistroBloqueado(sValor, sTela) {
    try {
        const pesquisa = {
            camposSelect: ['ID', 'TELA', 'VALOR', 'USUARIO'],
            tabela: 'CONTROLE_EDICAO',
            where: [`TELA = '${sTela}' AND VALOR = '${sValor}'`]
        };
        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
        const obj = {
            id: '',
            tela: '',
            valor: '',
            usuario: ''
        };

        const permissao = await permissaoAcessos("LIBERA_REGISTRO");
        if (permissao.INCLUI == 'S') {
            if ((jsonStr[0]) && (jsonStr[0].TELA != '')) {
                obj.id = jsonStr[0].ID;
                obj.tela = jsonStr[0].TELA;
                obj.valor = jsonStr[0].VALOR;
                obj.usuario = jsonStr[0].USUARIO;
            }
        }
        return obj;
    } catch (error) {
        return '';
    }
}

async function liberarRegistro(sTela, iValor) {
    try {
        $.LoadingOverlay("show");
        let response = await requisicao(
            "POST",
            "/sisplan/controleedicao/v1/controleedicao?",
            `valor=${iValor}&tela=${sTela}`,
            null
        );
        if (!response) {
            $.LoadingOverlay("hide");
            return false;
        }
        let jsonStr = await response.json();
        if (response.status != 200) {
            $.LoadingOverlay("hide");
            const registroBloqueado = await retornaRegistroBloqueado(iValor, sTela);
            if (registroBloqueado.tela != '') {
                return new Promise((resolve, reject) => {
                    msgAlerta('Registro já está em alteração, deseja forçar a liberação?', async () => {
                        await deletaRegistro(registroBloqueado.tela, registroBloqueado.usuario, registroBloqueado.valor);
                        criaMensagemSucesso('Liberação efetuada com sucesso, tente realizar ação novamente.');
                        resolve();
                    },
                        () => {
                            resolve();
                        },
                        undefined,
                        () => {
                            resolve();
                        }
                    );
                });
            } else {
                msgAlerta(jsonStr.mensagem);
            }
            return false;
        }

        $.LoadingOverlay("hide");
        return true;
    } catch (error) {
        $.LoadingOverlay("hide");
        msgErro(`Não foi possível alterar o registro: ${error}`);
    }
}

function retornaQtdeCasasDecimais(valor) {
    const strValor = String(valor);
    let posicao = strValor.indexOf(".");
    if (posicao == -1) {
        posicao = strValor.indexOf(",");
    }
    if (posicao == -1) {
        return 0;
    }

    return strValor.substr(posicao + 1).length;
}

async function selecionarLinhaTabela(tabela, inputCheck, LinhaSelecionada) {
    let bColunaClique = $(LinhaSelecionada).html().indexOf(inputCheck) > 0;
    if (bColunaClique) {
        if (!$(LinhaSelecionada).closest("tr").hasClass("selected")) {
            $(LinhaSelecionada).closest("tr").addClass("selected");
            $(LinhaSelecionada)
                .closest(LinhaSelecionada)
                .find(`.${inputCheck}`)
                .prop("checked", true);
            $("#btnBaixar").prop("disabled", false);
            $("#btnBaixarComAntecipacao").prop("disabled", false);
            data = $(tabela)
                .DataTable()
                .rows($(LinhaSelecionada).parents(".sorting_1"))
                .data();
        } else {
            $(LinhaSelecionada).closest("tr").removeClass("selected");
            $(LinhaSelecionada)
                .closest(LinhaSelecionada)
                .find(`.${inputCheck}`)
                .prop("checked", false);
        }
    }
}

async function naoPermiteFechar() {
    window.onbeforeunload = function () {
        return "Gostaria mesmo de sair desta página?";
    };
}

async function adicionaHint(componente) {
    tippy(componente, {
        content: $(componente).val(),
    });
}

async function adicionaHintValor(componente, valor) {
    tippy(componente, {
        content: valor,
    });
}

async function verificarBloqueio(cnpj) {
    try {
        if (getCookie("cod_usuario") == "0000") {
            return true;
        }

        const response = await requisicao(
            "GET",
            "/sisplan/funcoes/v1/verificarcnpjweb?",
            `CNPJ=${cnpj}&COD_USUARIO=${getCookie("cod_usuario")}`,
            null,
            100000
        );

        if (!response) {
            return false;
        }

        const jsonStr = await response.json();

        if (response.status != 200) {
            msgAlerta(jsonStr.mensagem);
            return false;
        }

        if (String(jsonStr.codigo) == '400') {
            const retorno = await aguardaMsgAlerta(jsonStr.mensagem, () => { });
            return retorno;
        }

        if (jsonStr.toString() === "false") {
            msgAlerta('Acesso Bloqueado. Falar com o ADMINISTRADOR da empresa ou contate o SUPORTE da Sisplan Sistemas.');
            return false;
        }
        return true;
    } catch (error) {
        console.error(error);
        msgAlerta('Acesso Bloqueado. Falar com o ADMINISTRADOR da empresa ou contate o SUPORTE da Sisplan Sistemas.');
        return false;
    }
}

async function validarProdutoAcessoTela(idProduto) {
    try {
        if (getCookie("cod_usuario") == "0000") {
            return true;
        }

        const cnpj = sessionStorage.getItem('g_cnpj_empresa_logada');

        const produtoSisp = {
            '3': 'LOJA WEB',
            '136': 'ERP WEB'
        };

        const response = await requisicao(
            "GET",
            "/sisplan/funcoes/v1/validarprodutoacessotela?",
            `CNPJ=${cnpj}&ID_PROD=${idProduto}&COD_USUARIO=${getCookie("cod_usuario")}`,
            null,
            100000
        );

        if (!response) {
            return false;
        }

        const jsonStr = await response.json();

        if (response.status != 200) {
            msgAlerta(jsonStr.mensagem);
            return false;
        }

        if (String(jsonStr.codigo) == '400') {
            const retorno = await aguardaMsgAlerta(jsonStr.mensagem, () => { });
            return retorno;
        }

        if (jsonStr.toString() === "false") {
            msgAlerta(`Acesso Bloqueado ao produto ${produtoSisp[idProduto]}. Falar com o ADMINISTRADOR da empresa ou contate o SUPORTE da Sisplan Sistemas.`);
            return false;
        }
        return true;
    } catch (error) {
        console.error(error);
        msgAlerta(`Acesso Bloqueado ao produto ${produtoSisp[idProduto]}. Falar com o ADMINISTRADOR da empresa ou contate o SUPORTE da Sisplan Sistemas.`);
        return false;
    }
}



async function verificarQuantidadeUsuarios(cnpj, usuario, idMaquina) {
    try {
        if (getCookie("cod_usuario") == "0000") {
            return true;
        }
        let response = await requisicao(
            "GET",
            "/sisplan/funcoes/v1/verificarquantidadeusuarios?",
            `CNPJ=${cnpj}&USUARIO=${usuario}&IDMAQUINA=${idMaquina}&TIPO=WEB`,
            null,
            10000
        );

        if (!response) {
            return true;
        }

        let jsonStr = await response.json();

        if (response.status != 200) {
            console.error(jsonStr.mensagem);
            return true;
        }

        if (jsonStr.toString() === "false") {
            return false;
        }
        return true;
    } catch (error) {
        console.error(error);
        return true;
    }
}

async function retornaUsuariosLogados(cnpj, usuario) {
    const response = await requisicao(
        "GET",
        "/sisplan/funcoes/v1/retornamensagemusuariologado?",
        `CNPJ=${cnpj}&USUARIO=${usuario}`,
        null,
        10000
    );

    const json = await response.json();

    return json;

}

async function retornaIpUsuario() {
    const ip = await fetch('https://api.sisplansistemas.com.br:10555/ping').then(async (resp) => {
        const data = await resp.json();
        return data.ip;
    });

    return ip;
}

async function loginUsuario() {
    try {
        if (getCookie("cod_usuario") == "0000") {
            return;
        }
        const cnpj = getCookie('g_cnpj_empresa_logada');
        const ipUsuario = await retornaIpUsuario();
        await requisicao(
            "POST",
            "/sisplan/funcoes/v1/quantidadeusuarios?",
            `CNPJ=${cnpj}&IDMAQUINA=${getCookie('idMaquina')}&TIPO=WEB&IP_USUARIO=${ipUsuario}`,
            null,
            10000
        );
    } catch (error) {
        console.error(error);
    }
}

async function logoutUsuario(idMaquina, usuario) {
    try {
        if (getCookie("cod_usuario") == "0000") {
            return;
        }
        const cnpj = getCookie('g_cnpj_empresa_logada');
        await requisicao(
            "DELETE",
            "/sisplan/funcoes/v1/quantidadeusuarios?",
            `CNPJ=${cnpj}&IDMAQUINA=${idMaquina}&USUARIO=${usuario}&TIPO=WEB`,
            null,
            10000
        );
    } catch (error) {
        console.error(error);
    }
}

async function buscaSolucao(variavel, descricao) {
    try {
        const result = await requisicao('GET', '/Sisplan/Funcoes/v1/pesquisa?',
            `JSON={ "tabela":"SOLUCAO",
            "camposSelect":["SOLUCAO.DESCRICAO, SOLUCAO.DESCRICAO2, SOLUCAO.DESCRICAO3, SOLUCAO.DESCRICAO4"], 
            "where": ["SOLUCAO.VARIAVEL = '${variavel}'", "SOLUCAO.DESCRICAO = '${descricao}'"]}`,
        );

        if (!result) {
            return;
        }

        if (result.status != 200) {
            msgErro(tecelagem.mensagem);
            return;
        }
        const jsonStr = await result.json();
        const dados = jsonStr.RESULT[0];
        if (dados.length > 0) {
            return dados[0].DESCRICAO2;
        }
        return '';

    } catch (error) {
        console.error(error);
        msgErro('Não foi possível buscar solução.');
    }
}

async function busca_cnpj() {
    try {
        $.LoadingOverlay("show");

        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const response = await requisicao('GET', url,
            `JSON={ "tabela":"EMPRESA", "camposSelect": ["EMP_CNPJ"], "where": ["emp_pat = '${sessionStorage.getItem('g_empresa_logada')}'"] }`,
            null);

        if (!response) {
            return;
        }

        const jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr['RESULT'][0].mensagem);
            return;
        }
        return jsonStr['RESULT'][0][0].EMP_CNPJ;
    } catch (error) {
        console.error(error);
        msgErro('Não foi possível buscar os dados da empresa logada.');
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function temAcessoTela(tela) {
    try {
        $.LoadingOverlay("show");

        let object = new Object();
        object.resultado = true;
        object.bloqueio = false;
        object.mensagem = "";

        const empid = getCookie("emp_id");
        if (!empid) {
            object.resultado = false;
            object.mensagem = "Acesso negado, Usuário não tem acesso a essa tela!";

            return object;
        }

        if (getCookie("cod_usuario") == "0000") {
            parent.$('#listaAbas li a.nav-link.active').prop('title', 'Nome tela: ' + tela);
            return object;
        }

        try {
            const cnpj = getCookie('g_cnpj_empresa_logada');

            const codusuario = getCookie("cod_usuario");
            if (!codusuario) {
                object.resultado = false;
                object.mensagem = "Acesso negado, Usuário não tem acesso a essa tela!";

                return object;
            }
            await loginUsuario();
            const response = await requisicao(
                "GET",
                `/Sisplan/AcessoMenu/v1/Acesso?`,
                `codusuarios='${codusuario}'&telas='${tela}'&CNPJ=${cnpj}`,
                null,
                60000
            );

            if (!response) {
                object.resultado = false;
                object.mensagem =
                    "Ocorreu um erro ao validar se usuário tem acesso a tela";
                return object;
            }

            let valida = await response.json();
            if (response.status != 200) {
                console.error(valida.RESULT[0].mensagem);

                object.resultado = false;
                object.mensagem =
                    "Ocorreu um erro ao validar se usuário tem acesso a tela";

                return object;
            }

            if (valida.length <= 0) {
                object.resultado = false;
                object.mensagem = `Acesso negado '${tela}', Usuário não tem acesso a essa tela!`;

                return object;
            }

            if (valida[0].CONSULTA == "N") {
                object.resultado = false;
                object.mensagem = `Acesso negado '${tela}', Usuário não tem acesso a essa tela!`;

                return object;
            }
            object.resultado = true;
            object.mensagem = "";

            return object;
        } catch (error) {
            console.error(error);

            object.resultado = false;
            object.mensagem = "Erro ao validar o acesso a tela.";

            return object;
        }
    } finally {
        $.LoadingOverlay("hide");
    }
}

// String.prototype.replaceAll = function(de, para){
//     var str = this;
//     var pos = str.indexOf(de);
//     while (pos > -1){
//     str = str.replace(de, para);
//     pos = str.indexOf(de);
//     }
//     return (str);
// }

function moeda2float(moeda) {
    if (moeda == '' || moeda == undefined) {
        return 0;
    }
    moeda = moeda.replaceAll(".", "");
    moeda = moeda.replace(",", ".");
    return parseFloat(moeda);
}
function float2moeda(number, decimals, dec_point, thousands_sep) {
    if (decimals == undefined) {
        decimals = 2;
    }
    //decimals = casasDecimaisValor;
    dec_point = ',';
    thousands_sep = '.';

    number = (number + '')
        .replace(/[^0-9+\-Ee.]/g, '');
    var n = !isFinite(+number) ? 0 : +number,
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        s = '',
        toFixedFix = function (n, prec) {
            var k = Math.pow(10, prec);
            return '' + (Math.round(n * k) / k)
                .toFixed(prec);
        };
    // Fix for IE parseFloat(0.55).toFixed(0) = 0;
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n))
        .split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '')
        .length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1)
            .join('0');
    }
    return s.join(dec);
}

// $('.mascara-valor')
// .on('keypress', function (e) {
//     if (window.event) {
//         tecla = e.keyCode;
//     } else if (e.which) {
//         tecla = e.which;
//     } else {
//         tecla = 0;
//     }

//     if (tecla == 13) {
//         return false;
//     }

//     if ((tecla >= 48 && tecla <= 57) || (tecla == 8) || (tecla == 44) || (tecla == 46) || (tecla == 45) || e.ctrlKey) {
//         if (tecla == 13) {
//             $(this).blur();
//         }
//         return true;
//     } else {
//         return false;
//     }
// })
// .on('blur', function (e) {
//     valor = $(this).val();
//     if (valor != '') {
//         $(this).val(float2moeda(valor));
//         valor = moeda2float(valor);
//         if ($(this).attr('casas') != undefined) {
//             valor = float2moeda(valor, $(this).attr('casas'));
//         } else {
//             valor = float2moeda(valor);
//         }
//         $(this).val(valor);
//     }
// })
// .on('focus', function () {
//     if ($(this).attr('casas') != undefined) {
//         $(this).attr('placeholder', float2moeda(0, $(this).attr('casas')));
//     } else {
//         $(this).attr('placeholder', float2moeda(0));
//     }
//     campo = $(this);
//     window.setTimeout(function () {
//         campo.select();
//     }, 100);
// })
// .on('blur', function () {
//     $(this).attr('placeholder', '');
// });

function toastrAcesso(objTemAcesso, baseUri) {
    toastr
        .error(objTemAcesso.mensagem, "Erro", {
            toastClass: "alert",
            iconClasses: {
                error: "alert-error",
                info: "alert-info",
                success: "alert-success",
                warning: "alert-warning",
            },
            positionClass: "toast-top-center",
            progressBar: true,
            timeOut: 3000,
            fadeOut: 1000,
            async onHidden() {
                try {
                    if (window.parent && window.parent.$) {
                        window.parent.$('.nav-item.active .btn-iframe-close').trigger('click');
                    }

                    sessionStorage.removeItem('@telasAbertas');

                    if (window.top !== window.self) {
                        if (objTemAcesso.bloqueio) {
                            window.top.location.href = `${baseUri}/login`;
                        } else {
                            const iframeAtivo = parent.document.querySelector('.nav-link.active');
                            if (iframeAtivo) iframeAtivo.remove();
                            window.top.location.href = `${baseUri}/index`;
                        }
                    } else {
                        if (objTemAcesso.bloqueio) {
                            window.location.href = `${baseUri}/login`;
                        } else {
                            window.location.href = `${baseUri}/index`;
                            const iframeAtivo = parent.document.querySelector('.nav-link.active');
                            if (iframeAtivo) iframeAtivo.remove();
                        }
                    }
                } catch (e) {
                    console.error("Erro ao fechar iframe e redirecionar:", e);
                }

            },
        })
        .css({
            "margin-top": "20%",
            width: "500px",
            "max-width": "500px",
        });
}

async function TruncaDecimais(decimal, valor, __) {
    if (decimal > 0) {
        valor = (valor * Math.pow(10, decimal)) / Math.pow(10, decimal);
        return Math.round(valor * 100) / 100;
    }
    return valor;
}

function TruncaDecimaisNova(decimal, valor) {
    // if (decimal > 0) {
    //     valor = (valor * Math.pow(10, decimal)) / Math.pow(10, decimal);
    //     return Math.round(valor * 100) / 100;
    // }
    // return valor;

    if (decimal > 0) {
        valor = parseFloat((valor * Math.pow(10, decimal)).toFixed(2));
        valor = Math.round(valor);
        return parseFloat((valor / Math.pow(10, decimal)).toFixed(decimal));
    }
    return parseFloat(valor.toFixed(decimal));
}

function SomaComTruncamento(array, decimal) {
    return array.reduce((acc, cur) => {
        return acc + TruncaDecimaisNova(decimal, cur);
    }, 0).toFixed(decimal);
}

function ArredondarValor(number, decimalPlaces) {
    // eslint-disable-next-line no-restricted-properties
    const factorOfTen = Math.pow(10, decimalPlaces);
    return Math.round(number * factorOfTen) / factorOfTen;
}

async function AlterarSenha() {
    try {
        $.LoadingOverlay("show");
        try {
            const url = "/sisplan/alterarsenha/v1/alterarsenha?";
            let senhaAntiga = encriptografarSenha(
                $("#txtSenhaAntiga").val().toUpperCase()
            );
            let senhaNova = encriptografarSenha(
                $("#txtSenhaNova").val().toUpperCase()
            );
            const params = `SENHANOVA=${senhaNova}&SENHAANTIGA=${senhaAntiga}`;

            const response = await requisicao("POST", url, params, 20000);

            if (!response) {
                return;
            }
            const jsonStr = await response.json();
            if (response.status === 200) {
                $("#modalAlterarSenha").modal("hide");
                msgSucesso("Senha alterada com sucesso!");
                $("#txtSenhaAntiga").val("");
                $("#txtSenhaNova").val("");
                $("#txtConfirmarSenha").val("");
                return;
            }
            msgErro(jsonStr.mensagem);
            return;
        } catch (error) {
            console.error(error);
            msgErro("Erro ao alterar senha");
        }
    } finally {
        $.LoadingOverlay("hide");
    }
}

function validarSenha(senha) {
    // Expressões regulares para cada requisito
    const temMaiuscula = /[A-Z]/;
    const temMinuscula = /[a-z]/;
    const temNumero = /[0-9]/;
    const temEspecial = /[!@#\$%\^&\*\(\),\.\?":\{\}\|<>]/;

    // Verificando se a senha atende a todos os critérios
    if (
        senha.length >= 8 &&
        temMaiuscula.test(senha) &&
        temMinuscula.test(senha) &&
        temNumero.test(senha) &&
        temEspecial.test(senha)
    ) {
        return true;
    } else {
        return false;
    }
}

async function ValidaSenhaIgual() {
    try {
        $.LoadingOverlay("show");
        try {
            if ($("#txtSenhaNova").val() != $("#txtConfirmarSenha").val()) {
                msgAlerta("Senhas não conferem");
                return false;
            }

            return true;
        } catch (error) {
            console.error(error);
        }
    } finally {
        $.LoadingOverlay("hide");
    }
}

async function mostrarSenha(input) {
    if (
        $(input).parent().parent().parent().find("input").attr("type") ===
        "password"
    ) {
        $(input).parent().parent().parent().find("input").attr("type", "text");
        $(input).addClass("d-none");
        $($(input).parent().find(".olhoFechado")[0]).removeClass("d-none");
    } else {
        $(input).parent().parent().parent().find("input").attr("type", "password");
        $(input).removeClass("d-none");
        $($(input).parent().find(".olhoAberto")[0]).removeClass("d-none");
        $($(input).parent().find(".olhoFechado")[0]).addClass("d-none");
    }
}

async function verificaPermissoes(sTela) {
    const sUsuario = getCookie("cod_usuario");
    const sEmp_id = getCookie("emp_id");
    try {
        let response = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"PERMISSOES_TELA",
            "camposSelect":["TELA", "ACAO", "PERMISSAO"],
            "where": ["USUARIO = '${sUsuario}' AND EMP_ID = ${sEmp_id} AND TELA = '${sTela}'"]}`,
            null
        );
        if (!response || response.status != 200) {
            return;
        }
        let jsonStr = await response.json();
        for (let i = 0; i < jsonStr.RESULT[0].length; i++) {
            if (jsonStr.RESULT[0][i].PERMISSAO == "N") {
                bloqueiaPermissoes(sTela, jsonStr.RESULT[0][i].ACAO);
            }
        }
    } catch (error) {
        console.error(error);
    }
}

function bloqueiaPermissoes(sTela, sAcao) {
    if (sTela == "LOJA" && sAcao == "VISUALIZA_DASHBOARD") {
        $("#painelLojaTour").addClass("d-none");
    }
    if (sTela == "RECEBER" && sAcao == "VISUALIZA_DASHBOARD") {
        $("#boxDashboard").addClass("d-none");
    }
    if (sTela == "INICIO" && sAcao == "VISUALIZA_GRAFICOS") {
        $(".pnlDashboard").addClass("d-none");
    }
    if (sTela == "FATURAMENTO" && sAcao == "ALTERA_MOV_ESTOQUE") {
        $('#movEstoqueCheck').prop('disabled', true);
    }
    if (sTela == "PAGAR" && sAcao == "VISUALIZA_DASHBOARD") {
        $('#boxdashboard').addClass("d-none");
    }
    if (sTela == "CHEQUE" && sAcao == "CHECK_LANCAR_ANTECIPACAO") {
        $('#divLancAnte').addClass("d-none");
    }
    if (sTela == "ENTRADA_NF" && sAcao == "INCLUI_NOVO_ITEM") {
        $('#btnCadastrarItens').prop("disabled", true);
    }
    if (sTela == "CONSULTA_PRECO" && sAcao == "DESABILITA_ABA_ESTOQUE") {
        $('#tabEstoque').addClass('d-none');
    }
    if (sTela == "ANALISEFINAN") {
        switch (sAcao) {
            case 'ESCONDER_GRAFICOS_ESTATISTICA':
                $('.divGraficoAF').addClass('d-flex');
                $('.divTabelaEstatisticas').addClass('col-sm-7');
                $('.divTabelaEstatisticas').removeClass('col-sm-12');
                break;

            case 'DUP_LISTAR_TODOS':
                $('#chkTodosListarDuplicatas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_DUPLICATAS':
                $('#chkListarDuplicatas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_ANTECIPACAO':
                $('#chkAntecipacaoDuplicatas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_ORCAMENTO':
                $('#chkOrcamentos').prop('disabled', true);
                break;

            case 'DUP_LISTAR_CHEQUES':
                $('#chkCheques').prop('disabled', true);
                break;

            case 'DUP_LISTAR_CHEQUES_DEV':
                $('#chkChequesDevolvidos').prop('disabled', true);
                break;

            case 'DUP_LISTAR_DESDOBRADAS':
                $('#chkDesdobradas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_AGRUPADAS':
                $('#chkAgrupadas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_CANCELADAS':
                $('#chkCanceladas').prop('disabled', true);
                break;

            case 'DUP_LISTAR_DEVOLUCAO':
                $('#chkDevolucao').prop('disabled', true);
                break;

            case 'DUP_LISTAR_AVISO_DEBITO':
                $('#chkAvisoDebito').prop('disabled', true);
                break;

            case 'DUP_LISTAR_CARTAO_PRESENTE':
                $('#chkCartaoPresente').prop('disabled', true);
                break;
        }
    }
}

function gerarGuid() {
    return ([1e7] + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, (c) =>
        // eslint-disable-next-line no-bitwise
        (
            c ^
            (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
        ).toString(16)
    );
}

function verificaSeTemIdNaMaquina() {
    const idMaquina = getCookie("idMaquina");

    if (
        idMaquina == "" ||
        idMaquina == undefined ||
        idMaquina == null ||
        idMaquina == "undefined" ||
        idMaquina == "null"
    ) {
        setCookie("idMaquina", gerarGuid(), 365);
    }
}


async function retornaJsonPesquisaPadrao(jsonParametro) {
    try {
        const url = "/sisplan/funcoes/v1/pesquisa?";
        const params = `JSON=${jsonParametro}`;

        const response = await requisicao("GET", url, params);

        if (!response) {
            return;
        }

        const jsonPesquisa = await response.json();
        if (response.status != 200) {
            msgErro(jsonPesquisa.RESULT[0].mensagem);
            return;
        }

        return jsonPesquisa.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}
async function retornaJsonPesquisaPadraoPost(jsonParametro) {
    try {
        const url = "/sisplan/funcoes/v1/pesquisa?";
        const params = `JSON=${jsonParametro}`;

        const response = await requisicao("POST", url, '', params);

        if (!response) {
            return;
        }

        const jsonPesquisa = await response.json();
        if (response.status != 200) {
            msgErro(jsonPesquisa.RESULT[0].mensagem);
            return;
        }

        return jsonPesquisa.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}

async function retornaJsonPesquisaPadraoComBlob(jsonParametro) {
    try {
        const url = "/sisplan/funcoes/v1/pesquisa?";
        const params = `JSON=${jsonParametro}`;

        const response = await requisicao("GET", url, params);

        if (!response) return;

        const text = await response.text();

        const cleanText = text
            .replace(/[\u0000-\u001F]+/g, "")
            .normalize("NFC");

        const jsonPesquisa = JSON.parse(cleanText);

        if (response.status != 200) {
            msgErro(jsonPesquisa.RESULT[0].mensagem);
            return;
        }

        return jsonPesquisa.RESULT[0];
    } catch (error) {
        console.error(error);
    }
}


async function buscaVersaoAPI() {
    try {
        const url = "/versao?";
        const response = await requisicao("GET", url, "");
        if (!response) {
            return;
        }

        if (response.status != 200) {
            const jsonPesquisa = await response.json();
            msgErro(jsonPesquisa.mensagem);
            return;
        }

        return response.text();
    } catch (error) {
        console.error(error);
    }
}

function RetornaFiltroTexto(sCampo, sValor, bVarios = false, bLike = false, bConsiderar = true) {
    let reuslt = '';
    if ((sValor != '') && (sValor != '%%') && (sValor != '%')) {
        begin;
        if (!bVarios) {
            if (!bLike) {
                begin;
                if (!bConsiderar) {
                    return result = result + 'AND ' + sCampo + ' LIKE ' + sValor;
                }
                else
                    result = result + 'AND ' + sCampo + ' NOT LIKE ' + sValor;
                end;
            } else {
                if (!bConsiderar) {
                    return result = result + 'AND ' + sCampo + ' = ' + sValor;
                }
                else {
                    return result = result + 'AND ' + sCampo + ' <> ' + sValor;
                }
            }
        } else {
            if (!bConsiderar) {
                return result = result + 'AND ' + sCampo + ' IN (' + sValor + ')';
            } else {
                return result = result + 'AND ' + sCampo + ' NOT IN (' + sValor + ')';
            }
        }
    }
}

async function buscaValor(sTabela, sCampoBusca, sCampoWhere, sCodigo) {
    const dadosSelect = {
        tabela: `${sTabela}`,
        camposSelect: [`${sCampoBusca.toString()}`],
        where: [`${sCampoWhere} = '${sCodigo}'`],
    };
    const retornoSelect = await retornaJsonPesquisaPadrao(JSON.stringify(dadosSelect));
    if (!retornoSelect) {
        return;
    }

    if (retornoSelect[0] == undefined) {
        return '';
    } else {
        return retornoSelect[0];
    }
}

async function buscaValorListaWhere(sTabela, sCampoBusca, sCampoWhere, sCodigo) {
    let dadosWhere = '';

    if (sCampoWhere.length > 1) {
        for (let i = 1; i < sCampoWhere.length; i++) {
            // dadosSelect.where.push(`${sCampoWhere[i]} = '${sCodigo[i]}'`)
            dadosWhere = dadosWhere + ` AND ${sCampoWhere[i]} = '${sCodigo[i]}'`;
        };
    };

    let dadosSelect = {
        tabela: `${sTabela}`,
        camposSelect: [`${sCampoBusca.toString()}`],
        where: [`${sCampoWhere[0]} = '${sCodigo[0]}' ${dadosWhere}`]
    };

    const retornoSelect = await retornaJsonPesquisaPadrao(JSON.stringify(dadosSelect));

    if (!retornoSelect) {
        return;
    }

    if (retornoSelect[0] == undefined) {
        return '';
    } else {
        return retornoSelect[0];
    }
}

async function buscaValorPorNumero(sTabela, sCampoBusca, sCampoWhere, sCodigo) {
    const dadosSelect = {
        tabela: `${sTabela}`,
        camposSelect: [`${sCampoBusca.toString()}`],
        where: [`${sCampoWhere} = ${sCodigo}`],
    };
    const retornoSelect = await retornaJsonPesquisaPadrao(JSON.stringify(dadosSelect));
    if (!retornoSelect) {
        return;
    }

    if (retornoSelect[0] == undefined) {
        return '';
    } else {
        return retornoSelect[0];
    }
}

function formataEmReais(valor) {
    return valor.toLocaleString('pt-BR', {
        style: 'currency', currency: 'BRL',
        maximumFractionDigits: 2,
        minimumFractionDigits: 2
    });
}

function formataValorSemRS(valor) {
    return valor.toLocaleString('pt-BR', {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2
    });
}

function retornarFloatFormatadoEmMonetario({ valor = 0, quantidadeCasasDecimais = 2 } = { valor: 0, quantidadeCasasDecimais: 2 }) {
    try {
        return parseFloat(valor).toLocaleString('pt-BR', {
            minimumFractionDigits: quantidadeCasasDecimais,
            maximumFractionDigits: quantidadeCasasDecimais,
        })
    } catch (error) {
        const valor = 0
        return valor.toLocaleString('pt-BR', {
            minimumFractionDigits: quantidadeCasasDecimais,
            maximumFractionDigits: quantidadeCasasDecimais,
        })
    }
}

function criaDataTablePadrao(
    sIdTabela,
    sPaging = true,
    sFilter = true,
    sInfo = true,
    sOrder = true,
    sDestroy = true,
    sScrollX = false,
    sScrollY = false,
    sData = null,
    sColumns = null,
    sColunasInvisiveis = [],
    sColunasDatasFormatadas = [],
    sColunasDinheiro = [],
    sColunasDecimais = [],
    botaoDinamico = {},
    casasDecimais = 2,
    sBotaoColunas = '',
    sBotaoExcel = '',
    sOrdemColunas = false,
    sColunasCentro = [],
    sColunasDireita = [],
    sOrderVazio = false,
    bDataHora = false,
    padraoNovo = false,
    sBotoesOpcoes = false,
    sBotoesOpcoesPersonalizados = [],
    iPageLength = 25,
    vScrollY = '55vh',
    ordering = true,
) {

    const columnDefs = [
        {
            render: render = function (data, type, row) {
                if (data) {

                    let isIE = function () {
                        if (/MSIE/i.test(navigator.userAgent) == true || /Edge/i.test(navigator.userAgent) == true) {
                            return true;
                        }
                        return false;

                    };

                    let dataHora = '';

                    if (bDataHora && (data.length > 10)) {
                        dataHora = ' ' + data.split(' ')[1];
                    }


                    if (isIE()) {
                        x = data.slice(0, 10).split('-');
                        return `${x[2]}/${x[1]}/${x[0]}${dataHora}`;
                    }
                    x = data.slice(0, 10).split('-');

                    return `${x[2]}/${x[1]}/${x[0]}${dataHora}`;
                } else {
                    return ''
                }

            },
            targets: sColunasDatasFormatadas,
        },
        {
            targets: sColunasInvisiveis,
            visible: false,
        },
        {
            render(data) {
                return parseFloat(data).toLocaleString("pt-br", {
                    style: "currency",
                    currency: "BRL",
                });
            },
            targets: sColunasDinheiro,
            className: 'pr-4 text-right'
        },
        {
            render(data) {
                let valor = parseFloat(data ?? 0);
                if (isNaN(valor)) valor = 0;
                return valor.toLocaleString("pt-BR", {
                    maximumFractionDigits: casasDecimais,
                    minimumFractionDigits: casasDecimais
                });
            },
            targets: sColunasDecimais,
            className: 'pr-4 text-right'
        },
        {
            className: 'text-center',
            targets: sColunasCentro
        },
        {
            targets: sColunasDireita,
            className: 'pr-4 text-right'
        }
    ];

    if (botaoDinamico.targets) {
        columnDefs.push({
            targets: botaoDinamico.targets,
            render: botaoDinamico.funcao
        }
        );
    };


    /* 
        * exemplo de como passar o array
        * [["label","id","href (se tiver)"],["label","id","href (se tiver)"]]
        * - Kauê
    */
    if (sBotoesOpcoes) {
        if (sBotoesOpcoesPersonalizados.length === 0)
            sBotoesOpcoesPersonalizados = [
                ["Alterar", "btnAlterar"],
                ["Duplicar", "btnDuplicar"],
                ["Imprimir", "btnImprimir"],
                ["Excluir", "btnExcluir"]
            ];

        columnDefs.push({
            targets: [0],
            render: (data, type, row) => {
                var botoes = "";
                var retorno = `<div style="text-align:start;">
                                <div class="dropdown">
                                    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                        ${data}
                                    </button>
                                    <div class="dropdown-menu">`;

                for (i = 0; i < sBotoesOpcoesPersonalizados.length; i++) {
                    botoes += `<button class="dropdown-item ${sBotoesOpcoesPersonalizados[i][1]}" href="${sBotoesOpcoesPersonalizados[i][2] || ""}">${sBotoesOpcoesPersonalizados[i][0]}</button>`
                };

                retorno += botoes;
                retorno += `</div>
                        </div>
                    </div>`;
                return retorno;
            }
        });
    };

    let orderConfig = sOrder ? [[0, 'asc']] : sOrder;

    if (sOrderVazio) {
        orderConfig = [];
    }

    if (padraoNovo)
        $(`${sIdTabela}`).DataTable({
            search: false,
            scrollX: true,
            scrollY: vScrollY,
            pageLength: iPageLength,
            autoWidth: true,
            lengthChange: true,
            sortable: true,
            paging: sPaging,
            filter: sFilter,
            info: sInfo,
            order: orderConfig,
            destroy: sDestroy,
            colReorder: sOrdemColunas,
            data: sData,
            columns: sColumns,
            columnDefs: columnDefs,
            ordering,
        })
    else
        $(`${sIdTabela}`).DataTable({
            paging: sPaging,
            filter: sFilter,
            info: sInfo,
            order: orderConfig,
            destroy: sDestroy,
            scrollX: sScrollX,
            scrollY: sScrollY,
            colReorder: sOrdemColunas,
            data: sData,
            columns: sColumns,
            columnDefs: columnDefs,
            ordering,
        })

    if (sBotaoColunas != '') {
        $(sIdTabela + '_length').prepend('<button class="buttonColVis" id="' + sBotaoColunas + '"><i class="fas fa-cogs"></i></button>');
        $(`#${sBotaoColunas}`).prop('title', 'Configurar colunas visíveis');
    }
    if (sBotaoExcel != '') {
        $(sIdTabela + '_length').prepend('<button class="buttonExcel" id="' + sBotaoExcel + '"><i class="fas fa-file-excel"></i></button>');
        $(`#${sBotaoExcel}`).prop('title', 'Exportar');
    }

}

$(document).ready(function () {
    let urlPagina = window.location.pathname;
    let numeroBarra = urlPagina.replace('sisplan_web/', '').replace('sisplan_web_teste/', '').split('/').length - 1;

    ipInterno = IP_INTERNO;
    ipExterno = IP_EXTERNO;
    basicAuth = BASIC_AUTH;

    if (numeroBarra === 1) {
        let linkCSS = $('<link>', {
            rel: 'stylesheet',
            href: 'plugins/icheck-bootstrap/icheck-bootstrap.min.css?versao=3.263.17.1'
        });

        let select2 = $('<script>', {
            type: 'text/javascript',
            src: 'plugins/select2/js/select2.full.min.js?versao=3.263.17.1'
        }).attr('defer', true);

        let sisplan = $('<script>', {
            type: 'text/javascript',
            src: 'dist/js/sisplan.js?versao=3.263.17.1'
        }).attr('defer', true);

        $('head').append(linkCSS);
        $('head').append(select2);
        $('head').append(sisplan);

    } else if (numeroBarra === 2) {
        let linkCSS = $('<link>', {
            rel: 'stylesheet',
            href: '../plugins/icheck-bootstrap/icheck-bootstrap.min.css?versao=3.263.17.1'
        });
        let select2 = $('<script>', {
            type: 'text/javascript',
            src: '../plugins/select2/js/select2.full.min.js?versao=3.263.17.1'
        }).attr('defer', true);

        let sisplan = $('<script>', {
            type: 'text/javascript',
            src: '../dist/js/sisplan.js?versao=3.263.17.1'
        }).attr('defer', true);

        $('head').append(linkCSS);
        $('head').append(select2);
        $('head').append(sisplan);
    }
});


async function carregaEmpresasDisponiveis(mostraModal = true, todasEmpresas = false) {
    let dadosSelect = "";
    try {
        $('#cbTodasAsEmpresas').off();
        $('#cbTodasAsEmpresas').on('click', function () {
            $('.empresa_selecionada').toArray().map(input => {
                $(`#${input.id}`).prop('checked', $('#cbTodasAsEmpresas').prop('checked'));
            });
        });

        if ($('.empresa_selecionada').length > 0) {
            if (mostraModal) {
                $('#modal-empresas').modal('show');
            }
            return;
        }
        if (todasEmpresas) {
            dadosSelect = {
                tabela: `EMPRESA`,
                camposSelect: ['EMP_ID', 'EMP_NOME', "REPLACE(EMP_PAT,'_','') EMPRESA", "EMP_FANTASIA"],
                where: null,
                orderBy: ["EMP_ID"]
            };
        } else {
            dadosSelect = {
                orderBy: ['EMPRESA.EMP_PAT'],
                tabela: `ACESSO_EMPRESA`,
                leftJoin: [{ "tabela": "EMPRESA", "condicao": "REPLACE(EMPRESA.EMP_PAT,'_','') = ACESSO_EMPRESA.EMPRESA" }],
                camposSelect: ['EMPRESA.EMP_ID', 'ACESSO_EMPRESA.EMPRESA', 'EMPRESA.EMP_FANTASIA', "EMP_NOME"],
                where: [`ACESSO_EMPRESA.USUARIO = '${getCookie('cod_usuario')}'`],
            };
        }
        const retornoSelect = await retornaJsonPesquisaPadrao(JSON.stringify(dadosSelect));
        if (!retornoSelect) {
            return;
        }
        if (retornoSelect && retornoSelect.length > 0) {
            if (mostraModal) {
                $('#modal-empresas').modal('show');
            }
            $('#modal-empresas-body').html('');

            for (let index = 0; index < retornoSelect.length; index++) {
                const empresa = retornoSelect[index];
                $('#modal-empresas-body').append(
                    `<div class="form-check icheck-primary" style ="margin-left: 0px !important">
                        <input id="cbEmpresa-${empresa.EMP_ID}" data-emp-id="${empresa.EMP_ID}" class="form-check-input empresa_selecionada" type="checkbox" ${getCookie('emp_id') == empresa.EMP_ID ? 'checked' : ''}> 
                        <label for="cbEmpresa-${empresa.EMP_ID}">${`${empresa.EMPRESA} - ${empresa.EMP_FANTASIA == "" ? empresa.EMP_NOME : empresa.EMP_FANTASIA}`}</label>
                     </div>`
                );
            }
        }
    } finally {

    }
}

async function criaMensagemErro(sMensagem, $callback, tempo = 3000) {
    await toastr
        .error(sMensagem, "Erro", {
            toastClass: "alert",
            iconClasses: {
                error: "alert-error",
                info: "alert-info",
                success: "alert-success",
                warning: "alert-warning",
            },
            positionClass: "toast-top-center",
            progressBar: true,
            timeOut: tempo,
            fadeOut: 1000,
            onHidden() {
                $callback();
            },
        })
        .css({
            "margin-top": "20%",
            width: "500px",
            "max-width": "500px",
        });
}

async function criaMensagemAlerta(sMensagem, $callback, tempo = 3000) {
    await toastr
        .warning(sMensagem, "Atenção", {
            toastClass: "alert",
            iconClasses: {
                error: "alert-error",
                info: "alert-info",
                success: "alert-success",
                warning: "alert-warning",
            },
            positionClass: "toast-top-center",
            progressBar: true,
            timeOut: tempo,
            fadeOut: 1000,
            onHidden() {
                $callback();
            },
        })
        .css({
            "margin-top": "20%",
            width: "500px",
            "max-width": "500px",
        });
}

async function criaMensagemSucesso(sMensagem, $callback, tempo = 3000) {
    await toastr
        .success(sMensagem, "Confirmação", {
            toastClass: "alert",
            iconClasses: {
                error: "alert-error",
                info: "alert-info",
                success: "alert-success",
                warning: "alert-warning",
            },
            positionClass: "toast-top-center",
            progressBar: true,
            timeOut: tempo,
            fadeOut: 1000,
            onHidden() {
                if ($callback != undefined) {
                    $callback();
                }
            },
        })
        .css({
            "margin-top": "20%",
            width: "500px",
            "max-width": "500px",
        });
}

function gravaIdAba() {
    try {
        let abasLocal = localStorage.getItem('g_abas');

        if (!abasLocal) {
            localStorage.setItem('g_abas', 1);
            sessionStorage.setItem('g_idAba', 1);
            return;
        }

        const novoId = Number(abasLocal) + Number(1);
        abasLocal = novoId;
        localStorage.setItem('g_abas', abasLocal);
        sessionStorage.setItem('g_idAba', novoId);

    } catch (error) {
        console.error(error);
    }
}
async function permissaoAcessos(tela) {
    try {
        $.LoadingOverlay("show");

        let object = new Object();
        object.resultado = true;
        object.mensagem = "";

        if (getCookie("cod_usuario") == "0000") {
            object.ALTERA = "S";
            object.CONSULTA = 'S';
            object.EXCLUI = 'S';
            object.INCLUI = 'S';
            return object;
        }

        try {
            const codusuario = `'${getCookie("cod_usuario")}'`;
            const cnpj = getCookie('g_cnpj_empresa_logada');
            const response = await requisicao(
                "GET",
                `/Sisplan/AcessoMenu/v1/Acesso?`,
                `codusuarios=${codusuario}&telas='${tela}'&CNPJ=${cnpj}`,
                null,
                60000
            );

            if (!response) {
                msgErro("Erro ao buscar permissões da tela.");
                return;
            }

            let valida = await response.json();
            if (response.status != 200) {
                console.error(valida.RESULT[0].mensagem);
                msgErro("Erro ao buscar permissões da tela.");
                return;
            }

            if (valida.length <= 0) {
                object.ALTERA = "N";
                object.CONSULTA = 'N';
                object.EXCLUI = 'N';
                object.INCLUI = 'N';
                return object;
            }

            return valida[0];
        } catch (error) {
            console.error(error);
            msgErro("Erro ao buscar permissões da tela.");
        }
    } finally {
        $.LoadingOverlay("hide");
    }
}

async function carregaArquivo(nomedoarquivo) {
    const hostname = `${nomedoarquivo}-${getCookie("idMaquina")}`;
    let response;
    let myHeaders = new Headers();
    myHeaders.append("pragma", "no-cache");
    myHeaders.append("cache-control", "no-cache");
    try {
        response = await fetch(`${hostname}.txt`, {
            headers: myHeaders,
            method: "GET",
            body: null,
        });
    } catch (error) {
        return;
    }
    return response;
}

async function rotinaGeraLog(tela, chave, descricao, operacao) {
    try {
        const url = "/sisplan/log/v1/geralog?";
        const objetoLog = {
            tela,
            chave,
            descricao,
            operacao
        };

        const response = await requisicao(
            "POST",
            url,
            `JSON=${JSON.stringify(objetoLog)}`
        );

    } catch (error) {
        console.error(error);
    }
}

async function salvaArquivo(nomedoarquivo, jsonarquivo) {
    try {
        const response = await fetch(`salvar_arquivo.php?tipo=${nomedoarquivo}`, {
            method: "POST",
            body: `${JSON.stringify(jsonarquivo)}`,
        });

        return response;
    } catch (error) {
        msgAlerta("Erro ao salvar dados digitados!");
    }
}

async function deletaArquivo(nomedoarquivo) {
    const hostname = `${nomedoarquivo}-${getCookie("idMaquina")}`;
    try {
        const response = await fetch(
            `deletar_arquivo.php?nomedoarquivo=${hostname}.txt`,
            {
                method: "GET",
                body: null,
            }
        );
    } catch (error) {
        console.log(error);
    }
}

function retornaRepresentanteUsuario() {
    return getCookie('codrepUsuario');
}

async function apenasClientesVinculadosAoRepresentante() {
    const params = await BuscaParametrosSistema();
    const isMaster = await uMasterOuSupervisor();
    const parametroApenasClientesVinculados = params[2];
    return parametroApenasClientesVinculados.VALOR == 1 && !isMaster;
}

function bloqueiaCampos(divPrincipal, habilita) {
    $(`.${divPrincipal} :input`).attr("disabled", habilita);
};

async function imprimirAutomatico(arquivo, layout) {
    try {
        const response = await requisicao_ecf('POST', '/arquivo/imprimir?', `RELATORIO=${layout}`, arquivo, 180000);

        if (!response) {
            return;
        }

        if (response.status != 200) {
            return;
        }

    } catch (error) {
        console.log(error);
    }

}

async function verificaImprimirAutomatico(layout) {
    try {
        const response = await requisicao_ecf("GET", "/arquivo/verificaimprimirautomatico?", `RELATORIO=${layout}`, 20000);

        if (!response) {
            return false;
        }

        if (response.status != 200) {
            return false;
        }

        if (await response.text() == 'false') {
            return false;
        } else {
            return true;
        }

    } catch (error) {
        console.log(error);
    }

}

function pegaValor(sComponente) {
    return $(sComponente).val();
}

function isChecked(sComponente) {
    return $(sComponente).is(':checked');
}

function RetornaIdTamFormatado(id, inverso = false) {
    return (!inverso) ? id.replace('/', '_') : id.replace('_', '/');
}

async function retornaCampoList(campo, separador = ",", unico = false) {
    try {
        const response = await requisicao("GET", "/sisplan/funcoes/v1/retornacampolist?", `CAMPO=${campo}&SEPARADOR=${separador}&UNICO=${unico}`, 60000);

        if (!response) {
            return '';
        }

        if (response.status != 200) {
            return '';
        }

        const jsonStr = await response.text();
        return jsonStr;


    } catch (error) {
        console.log(error);
    }
}

async function formataListas(lista, bSemAspas = false, bEspaco = false) {
    let listaFormatada = '';
    if (lista == '') {
        return '';
    }
    if (lista.length > 1) {
        lista = lista.split(',');
        for (let i = 0; i < lista.length; i++) {
            if (bSemAspas) {
                listaFormatada += `${lista[i]},`;
            } else {
                listaFormatada += `'${lista[i]}',`;
            }
        }
        return bEspaco ? listaFormatada.substring(0, listaFormatada.length - 1).replaceAll(",", ", ") : listaFormatada.substring(0, listaFormatada.length - 1);
    }

    if (bSemAspas) {
        return bEspaco ? lista[0].replaceAll(",", ", ") : lista[0];
    } else {
        return bEspaco ? (`'${lista[0]}'`).replaceAll(",", ", ") : `'${lista[0]}'`;
    }
}


function formataListasSemAwait(lista, bSemAspas = false, bEspaco = false) {
    let listaFormatada = '';
    if (lista == '') {
        return '';
    }
    if (lista.length > 1) {
        lista = lista.split(',');
        for (let i = 0; i < lista.length; i++) {
            if (bSemAspas) {
                listaFormatada += `${lista[i]},`;
            } else {
                listaFormatada += `'${lista[i]}',`;
            }
        }
        return bEspaco ? listaFormatada.substring(0, listaFormatada.length - 1).replaceAll(",", ", ") : listaFormatada.substring(0, listaFormatada.length - 1);
    }

    if (bSemAspas) {
        return bEspaco ? lista[0].replaceAll(",", ", ") : lista[0];
    } else {
        return bEspaco ? (`'${lista[0]}'`).replaceAll(",", ", ") : `'${lista[0]}'`;
    }
}

function transformaPDFemBase64(url) {
    return fetch(url)
        .then(response => response.blob())
        .then(blob => new Promise(callback => {
            let reader = new FileReader();
            reader.onload = function () {
                callback(this.result);
            };
            reader.readAsDataURL(blob);
        }));
}

async function bloqueiaFiltroEPreencheValorRepresentante(seletorInput, seletorPesquisa, seletorLimpeza) {
    const codrep = retornaRepresentanteUsuario();
    if (codrep == '') {
        return;
    }
    const nomeRep = (await buscaValor('REPRESEN', 'NOME', 'CODREP', codrep)).NOME;
    const campoTipoSelect = $(`select${seletorInput}`).length > 0;

    if (campoTipoSelect) {
        $(seletorInput).empty().trigger('change');
        const option = {
            id: '1',
            text: `[${codrep}] - ${nomeRep}`
        };
        const newOption = new Option(option.text, codrep, true, true);
        $(seletorInput).append(newOption).trigger('change');
        $(`.select2-selection--multiple .select2-selection__rendered.${seletorInput.replace('#', '')}`).css('height', '100%');
    } else {
        insereValor(seletorInput, codrep, nomeRep);
    }
    $(seletorInput).attr('disabled', true);
    $(seletorPesquisa).attr('disabled', true);
    $(seletorLimpeza).attr('disabled', true);
}

async function preencheRegiao(seletorInput) {
    const codrep = retornaRepresentanteUsuario();
    if (codrep == '') {
        return;
    }
    const regiao = await buscaDepositoUltimoMovimento(codrep);
    const campoTipoSelect = $(`select${seletorInput}`).length > 0;


    if (campoTipoSelect) {
        $(seletorInput).empty().trigger('change');
        const option = {
            id: '1',
            text: `[${regiao.REGIAO}] - ${regiao.DESC_REGIAO}`
        };
        const newOption = new Option(option.text, regiao.REGIAO, true, true);
        $(seletorInput).append(newOption).trigger('change');
        $('.select2-selection--multiple .select2-selection__rendered.txtRepresentante').css('height', '100%');
    } else {
        insereValor(seletorInput, regiao.REGIAO, regiao.DESC_REGIAO);
    }
}

async function produtoComStatusBloqueio(sCodigo) {
    try {
        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const pesquisa = {
            tabela: "SITPROD",
            leftJoin: [{ tabela: 'PRODUTO', condicao: "PRODUTO.STATUS = SITPROD.CODIGO" }],
            camposSelect: ["SITPROD.BLOQ_PRODPED"],
            where: [`PRODUTO.CODIGO = '${sCodigo}'`]
        };

        const response = await requisicao('GET', url, `JSON=${JSON.stringify(pesquisa)}`, null);
        if (!response) {
            return false;
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return false;
        }
        if ((jsonStr.RESULT[0].length > 0) && (jsonStr.RESULT[0][0].BLOQ_PRODPED)) {
            return jsonStr.RESULT[0][0].BLOQ_PRODPED == 'S';
        }
        return false;
    } catch (error) {
        console.error(error);
        return false;
    }
}

async function produtoComStatusBloqueioVenda(sCodigo) {
    try {
        const url = `/sisplan/funcoes/v1/pesquisa?`;
        const pesquisa = {
            tabela: "SITPROD",
            leftJoin: [{ tabela: 'PRODUTO', condicao: "PRODUTO.STATUS = SITPROD.CODIGO" }],
            camposSelect: ["SITPROD.BLOQ_VENDA"],
            where: [`PRODUTO.CODIGO = '${sCodigo}'`]
        };

        const response = await requisicao('GET', url, `JSON=${JSON.stringify(pesquisa)}`, null);
        if (!response) {
            return false;
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return false;
        }
        if ((jsonStr.RESULT[0].length > 0) && (jsonStr.RESULT[0][0].BLOQ_VENDA)) {
            return jsonStr.RESULT[0][0].BLOQ_VENDA == 'S';
        }
        return false;
    } catch (error) {
        console.error(error);
        return false;
    }
}

async function enviarMensagem(telefone = '', mensagem = '', tela = '', campoChave = '', bExisteArq = false, nomeArquivo = '', anexosPersonalizados = [], enviaCaption = 'S') {
    try {
        $.LoadingOverlay('show');
        try {
            if (bExisteArq) {
                const response = await requisicao('POST', `/sisplan/config_whatsapp/v1/inserearqwhatsappweb?`, '', `TELA=${tela}&CAMPO_CHAVE=${campoChave}&TELEFONE=${telefone}&NOME_ARQUIVO=${nomeArquivo}&ANEXOS_PERSONALIZADOS=${anexosPersonalizados}&ID_SESSAO=${getCookie('Session@Whatsapp')}&ENVIA_CAPTION=${enviaCaption}`, 240000);
                if (!response) {
                    return;
                }
                if (![200, 201].includes(response.status)) {
                    msgErro('Erro ao enviar mensagem via WhatsApp, se o erro persistir, reconecte o aparelho.');
                    return false;
                }
            } else {
                const response = await requisicao('POST', `/sisplan/config_whatsapp/v1/inseremsgwhatsappweb?`, '', `MENSAGEM=${encodeURIComponent(mensagem)}&TELA=${tela}&CAMPO_CHAVE=${campoChave}&TELEFONE=${telefone}&ID_SESSAO=${getCookie('Session@Whatsapp')}`, 240000);
                if (!response) {
                    return;
                }
                if (![200, 201].includes(response.status)) {
                    msgErro('Erro ao enviar mensagem via WhatsApp, se o erro persistir, reconecte o aparelho.');
                    return false;
                }
            }
            return true;
        } catch (error) {
            msgErro('Erro ao enviar mensagem via WhatsApp, se o erro persistir, reconecte o aparelho.');
            console.error(error);
        }
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function utilizaWhatsapp() {
    const pesquisa = {
        camposSelect: ['COUNT(*) AS QTDE'],
        tabela: 'WHATS_CONTAS',
    };

    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

    return jsonStr[0].QTDE > 0;
};


async function getWhatsapp(codcli) {
    function onlyNumbers(telefone) {
        return telefone.replace(/[^0-9]/g, '');
    }

    function validPhoneNumber(telefone) {
        const validacao = telefone.match(/^\s*(\d{2}|\d{0})[-. ]?(\d{5}|\d{4})[-. ]?(\d{4})[-. ]?\s*$/);
        return ((validacao) && (validacao.length == 4) && (validacao != null));
    }

    try {
        if (codcli == '') {
            return '';
        }

        const pesquisa = {
            camposSelect: ['DDD_FONE DDD', 'TELEFONE'],
            tabela: 'ENTIDADE',
            where: [`CODCLI = '${codcli}'`]
        };
        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
        const ddd = onlyNumbers(jsonStr[0].DDD);
        const telefone = onlyNumbers(jsonStr[0].TELEFONE);

        if ((ddd != '')
            && (telefone != '')
            && (ddd.length === 2)
            && (validPhoneNumber(ddd + telefone))) {
            return ddd + telefone;
        }
        return '';
    } catch (err) {
        console.error(err);
        return '';
    }
}

async function vencimentoCertificado() {
    const empId = getCookie('emp_id');

    const pesquisa = {
        camposSelect: ['VALIDADE_CERT'],
        tabela: 'EMPRESA',
        where: [`EMP_ID = ${empId}`]
    };
    const jsonStr = (await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa)))[0];

    if (!jsonStr.VALIDADE_CERT) {
        return;
    }

    $('#txtVencimentoCertificadoDigital').text('Certificado digital válido até ' +
        jsonStr.VALIDADE_CERT.split('-')[2] +
        '/' +
        jsonStr.VALIDADE_CERT.split('-')[1] +
        '/' +
        jsonStr.VALIDADE_CERT.split('-')[0]);
}

async function faturamentoParaguai() {
    const empId = getCookie('emp_id');

    const pesquisa = {
        camposSelect: ['EMP_FANTASIA'],
        tabela: 'EMPRESA',
        where: [`EMP_ID = ${empId}`]
    };

    const jsonStr = (await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa)))[0];

    if (!jsonStr.EMP_FANTASIA) {
        return false;
    }

    if (jsonStr.EMP_FANTASIA.includes('PARAGUAY')) {
        return true;
    }

    return false;
}

async function retornaDatabase() {
    try {
        const response = await requisicao("GET", "/sisplan/funcoes/v1/retornadatabase?", '', '', 60000);

        if (!response) {
            return '';
        }

        if (response.status != 200) {
            return '';
        }

        const jsonStr = await response.text();
        return jsonStr;


    } catch (error) {
        console.log(error);
    }
}

async function usaFatApp() {
    try {
        const response = await requisicao("GET", "/sisplan/funcoes/v1/retornausaappfat?", '', '', 60000);

        if (!response) {
            return '';
        }

        if (response.status != 200) {
            return '';
        }

        const jsonStr = await response.text();
        return jsonStr;


    } catch (error) {
        console.log(error);
    }
}

async function setarDataAnoAnterior(componente) {
    const today = new Date();
    $(`#${componente}`).val(`${today.getFullYear() - 1}-${'01'}-${'01'}`);
}

async function insereValorPesquisaVarios(componente, campoChave, campoDescricao, objeto) {
    objeto.forEach(dado => {
        const option = {
            id: dado[campoChave],
            text: `[${dado[campoChave]}] - ${dado[campoDescricao]}`
        };
        const newOption = new Option(option.text, option.id, true, true);
        $(`#${componente}`).append(newOption).trigger('change');
        setTimeout(() => {
            $('.select2-search__field').attr('placeholder', $traducaoSelecioneOsRegistros[['I', 'E', 'M'].includes(getCookie('idiomaUsuario')) ? getCookie('idiomaUsuario') : 'P']);
        }, 0);
    });
}

async function verificaDepositosEmpresaLogada(empresa) {
    try {
        let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"EMPRESA", "camposSelect":["EMP_DEPOSITO"], "where": ["EMP_PAT = '${empresa}'"]}`, null);

        if (!response) {
            return '';
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return '';
        }

        return jsonStr.RESULT[0][0].EMP_DEPOSITO;

    } catch (error) {
        console.error(error);
        return '';
    }
}

async function verificaSetorUsuario(usuario) {
    try {
        let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["SETORES"], "where": ["CODIGO = '${usuario}'"]}`, null);

        if (!response) {
            return '';
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return '';
        }

        return jsonStr.RESULT[0][0].SETORES;

    } catch (error) {
        console.error(error);
        return '';
    }
}

async function verificaTodosDepositos() {
    try {
        let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"DEPOSITO", "camposSelect":["CODIGO"]}`, null);

        if (!response) {
            return '';
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return '';
        }

        const codigos = jsonStr.RESULT[0];
        const retorno = codigos.map(obj => `'${obj.CODIGO}'`).join(',');
        return retorno;

    } catch (error) {
        console.error(error);
        return '';
    }
}

async function verificaMoedasCliente(codcli) {
    try {
        const moedas = [];
        let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"ENT_MOEDA", "camposSelect":["CODMOE"], "where": ["CODCLI = '${codcli}'"]}`, null);

        if (!response) {
            return '';
        }

        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return '';
        }

        if (jsonStr.RESULT[0].length > 0) {
            jsonStr.RESULT[0].forEach(moeda => {
                moedas.push(moeda.CODMOE);
            });
            return moedas;
        } else {
            return '';
        }

    } catch (error) {
        console.error(error);
        return '';
    }
}

async function pingTEF() {
    try {

        const response = await requisicao_ecf('GET', '/tef/pingtef?', '');

        if (!response) {
            return false;
        }

        if (response.status != 200) {
            return false;
        }

        return true;
    } catch (error) {
        console.log(error);
        return false;
    }
}

function preencheDadosCheque(campo) {
    const sLeitura = $(campo).val();
    if (sLeitura.length == 34) {
        const row = $(campo).closest('tr');
        const id = row.index();
        const banco = sLeitura.substring(1, 4);
        const agencia = sLeitura.substring(4, 8);
        const CodBanco = parseInt(banco);
        let digIgnorar;
        switch (CodBanco) {
            case 1:
                digIgnorar = 2;    // 001 - Banco do Brasil
                break;
            case 33:
                digIgnorar = 2;    // 033 - Santander / Banespa
                break;
            case 41:
                digIgnorar = 0;    // 041 - Banrisul Obs: Este banco utiliza todo o campo para o número da conta
                break;
            case 85:
                digIgnorar = 2;
                break;
            case 104:
                digIgnorar = 0;    // 104 - CEF. Utiliza apenas 7, mas os 3 primeiros são necessários para calcular o dv
                break;
            case 237:
                digIgnorar = 3;    // 237 - Bradesco
                break;
            case 341:
                digIgnorar = 4;    // 341 - Itau
                break;
            case 389:
                digIgnorar = 1;    // 389 - Mercantil
                break;
            case 399:
                digIgnorar = 4;    // 399 - HSBC
                break;
            //  409: Result := 3;    // 409 - Unibanco
            case 479:
                digIgnorar = 2;    // 479 - Bank of Boston
                break;
            default: digIgnorar = 3;
        }
        const conta = sLeitura.substring(22 + digIgnorar, 32);
        const numero = sLeitura.substring(13, 19);
        insereValor(`#banco_col_${id}_row_2`, banco, banco);
        $($(".campoAgencia")[id]).val(agencia);
        $($(".campoConta")[id]).val(conta);
        $($(".campoNumero")[id]).val(numero);
        return false;
    }
    return true;
}

async function buscaParametroERP(tipo, numero, posicao, len) {
    try {

        const response = await requisicao('GET', '/Sisplan/Funcoes/v1/buscaparametro?', `TIPO=${tipo}&NUMERO=${numero}&POSICAO=${posicao}&LEN=${len}`, 60000);
        if (!response) {
            return false;
        }

        if (response.status != 200) {
            return false;
        }

        let valor = await response.text();

        return valor;

    } catch (error) {
        console.log(error);
        return false;
    }
}

async function retornaInformacaoEmpresa() {
    try {
        let url = `/sisplan/funcoes/v1/pesquisa?`;
        let response = await requisicao('GET', url, `JSON={ 
        "tabela":"empresa", 
        "camposSelect":["emp_estado", "emp_csrt", "emp_csrt_id", "emp_pat", "emp_cert", "emp_crt", "emp_cnpj", "emp_id"], 
        "where": ["emp_id = ${getCookie('emp_id')}"] 
      }`, null);
        if (!response) {
            return;
        }
        let jsonStr = await response.json();
        if (response.status != 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return;
        }
        return jsonStr.RESULT[0][0];
    } catch (error) {
        console.error(error);
        msgErro('Erro ao retornar dados da empresa, Erro: ');
    }
};

function primeiraLetraMaiuscula(texto) {
    return texto.charAt(0).toUpperCase() + texto.slice(1);
}

async function buscaDepositoEmpresaUsuario() {
    let dep;

    dep = await verificaDepositosUsuarioLogado(getCookie('cod_usuario'));

    if (dep == '') {
        dep = await verificaDepositosEmpresaLogada(getCookie('empresa'));
    }

    return dep;
}

async function buscaSetorUsuario() {
    let setor;

    setor = await verificaSetorUsuario(getCookie('cod_usuario'));

    return setor;
}

async function verificaDepositosUsuarioLogado(usuario) {
    try {
        $.LoadingOverlay("show");
        try {
            const url = '/Sisplan/Funcoes/v1/pesquisa?';
            const params = `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["DEPOSITOS"], "where": ["CODIGO = '${usuario}'"]}`;
            const response = await requisicao('GET', url, params, null);

            if (!response) {
                return 'null';
            }

            const jsonStr = await response.json();

            if (jsonStr.codigo == 400) {
                return 'null';
            }

            return jsonStr.RESULT[0][0].DEPOSITOS;
        } catch (error) {
            console.error(error);
            return 'null';
        }
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function componenteFiltro(tabela, retornaMaisDeUmRegistro = false, serverSide = true, id = '', where = [], ignorarPesquisasPadroes = false, callback = null, pAtivo = '') {
    try {
        let filtroDeposito;
        let depositos;
        let empresas = '';
        if ((['depositoUsuario', 'depositoEmpresaUsuario', 'lote'].includes(tabela))) {
            filtroDeposito = await buscaDepositoEmpresaUsuario();
        } else if (tabela == 'empresaEmp_Pat') {
            empresas = await pegaEmpresasUsuarioLogado();
        };
        depositos = `(${filtroDeposito})`;
        filtroDeposito = filtroDeposito == '' ? null : `CODIGO IN (${filtroDeposito})`;

        const tabelaTratada = primeiraLetraMaiuscula(tabela);
        const pesquisaTabelas = {
            colecao: { serverSide: false, nomePesquisa: 'Coleção', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'COLECAO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            entidade: { serverSide: serverSide, nomePesquisa: 'Cliente', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'ENTIDADE', camposSelect: ['CODCLI', 'NOME', "CNPJ", "FANTASIA"], where } },
            produto: { serverSide: serverSide, nomePesquisa: 'Produto', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'PRODUTO', camposSelect: ['CODIGO', 'DESCRICAO', 'CODIGO2'] } },
            etiqueta: { serverSide: false, nomePesquisa: 'Etiqueta', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ETQ_PROD', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            marca: { serverSide: false, nomePesquisa: 'Marca', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MARCA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            grupo: { serverSide: false, nomePesquisa: 'Grupo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_PA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            linha: { serverSide: false, nomePesquisa: 'Linha', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABLIN', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tabPreco: { serverSide: false, nomePesquisa: 'Tabela de Preço', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REGIAO', camposSelect: ['REGIAO', 'DESCRICAO'] } },
            cor: { serverSide: false, nomePesquisa: 'Cor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCOR', camposSelect: ['COR', 'DESCRICAO'], where: where } },
            deposito: { serverSide: false, nomePesquisa: 'Depósito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEPOSITO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            vendedor: { serverSide: false, nomePesquisa: 'Vendedor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REPRESEN', camposSelect: ['CODREP', 'NOME'], where: where } },
            grupoCli: { serverSide: false, nomePesquisa: 'Grupo de Cliente', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_CLI', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            grupoPA: { serverSide: serverSide, nomePesquisa: 'Grupo de Produto', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_PA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            cliente: { serverSide: serverSide, nomePesquisa: 'Cliente', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'ENTIDADE', camposSelect: ['CODCLI', 'NOME'], where: where }, },
            guia: { serverSide: serverSide, nomePesquisa: 'Guia', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REPRESEN', camposSelect: ['CODREP', 'NOME'], where: ["ATIVO = 'S'", "GRUPO_REP = 'U'"] } },
            tipoVenda: { serverSide, nomePesquisa: 'Tipo Venda', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'VENDA_TIPO', camposSelect: ['ID', 'DESCRICAO'] } },
            tipoProduto: { serverSide, nomePesquisa: 'Tipo Produto', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CAD_TIPO_PROD', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            fornecedor: { serverSide: serverSide, nomePesquisa: 'Fornecedor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ENTIDADE', camposSelect: ['CODCLI', 'NOME'] } },
            usuario: { serverSide: true, nomePesquisa: 'Usuário', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ACESSO_USUARIOS', camposSelect: ['NOME', 'CODIGO'], where: where == '' ? ["ATIVO = 'S'"] : where } },
            usuario2: { serverSide: true, nomePesquisa: 'Usuário', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ACESSO_USUARIOS', camposSelect: ['CODIGO', 'NOME'], where: where == '' ? ["ATIVO = 'S'"] : where } },
            usuario3: { serverSide, nomePesquisa: 'Usuário', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ACESSO_USUARIOS', camposSelect: ['ID', 'NOME'], where: where == '' ? ["ATIVO = 'S'"] : where } },
            material: { serverSide: serverSide, nomePesquisa: 'Material', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'MATERIAL', camposSelect: ['CODIGO', 'DESCRICAO', 'CODIGO2'], where: where } },
            grupoMA: { serverSide: serverSide, nomePesquisa: 'Grupo Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_MA', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            subGrupo: { serverSide: serverSide, nomePesquisa: 'SubGrupo Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SUBGRUPO_MA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            modelo: { serverSide, nomePesquisa: 'Modelo Produto', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MODELO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tamanho: { serverSide: serverSide, nomePesquisa: 'Tamanho', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABTAM', camposSelect: ['TAM', 'CODIGO2'], where: where } },
            qualidade: { serverSide: serverSide, nomePesquisa: 'Qualidade', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABQUL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tipoMov: { serverSide: serverSide, nomePesquisa: 'Tipo Movimentação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABBAI', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            depositoUsuario: { serverSide: false, nomePesquisa: 'Depósito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEPOSITO', camposSelect: ['CODIGO', 'DESCRICAO'], where: [filtroDeposito] } },
            depositoCru: { serverSide: false, nomePesquisa: 'Depósito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEPOSITO', camposSelect: ['CODIGO', 'DESCRICAO'], where: [] } },
            depositoFio: { serverSide: false, nomePesquisa: 'Depósito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEPOSITO', camposSelect: ['CODIGO', 'DESCRICAO'], where: [] } },
            venda: { serverSide: false, nomePesquisa: 'Venda', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'VENDA', camposSelect: ['CODVEN', 'NOME_CONSUMIDOR'] } },
            moeda: { serverSide: serverSide, nomePesquisa: 'Moeda', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MOEDA', camposSelect: ['CODMOE', 'DESCRICAO'] } },
            classe: { serverSide: serverSide, nomePesquisa: 'Classe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_GER', camposSelect: ['CODIGO', 'DESCRICAO'], where: [] } },
            banco: { serverSide: serverSide, nomePesquisa: 'Banco', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADBAN', camposSelect: ['BANCO', 'NOME_BANCO'] } },
            situacao: { serverSide: serverSide, nomePesquisa: 'Situação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABSIT', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            historico: { serverSide: serverSide, nomePesquisa: 'Histórico', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'HISTCP', camposSelect: ['HISTORICO', 'DESCRICAO'] } },
            representante: { serverSide: serverSide, nomePesquisa: 'Representante', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REPRESEN', camposSelect: ['CODREP', 'NOME'], where: where } },
            perfil: { serverSide: false, nomePesquisa: 'Grupo Econômico', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PERFIL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            ramoAtividade: { serverSide: false, nomePesquisa: 'Ramo de Atividade', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SITCLI', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            regEstado: { serverSide: false, nomePesquisa: 'Região Cliente', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REG_ESTADO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            regFrete: { serverSide: false, nomePesquisa: 'Frete', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REGIAO_FRETE', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            transportadora: { serverSide: false, nomePesquisa: 'Transportadora', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABTRAN', camposSelect: ['CODIGO', 'NOME'] } },
            centroCusto: { serverSide: serverSide, nomePesquisa: 'Centro de Custo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CENTROCUSTO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            conta: { serverSide: false, nomePesquisa: 'Conta', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCONTA', camposSelect: ['CONTA', 'DESCRICAO'], where } },
            subColecao: { serverSide: false, nomePesquisa: 'Sub Coleção', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADTAG', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            status: { serverSide: false, nomePesquisa: 'Status', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SITPROD', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            tabPrazo: { serverSide: false, nomePesquisa: 'Período', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABPRZ', camposSelect: ['PRAZO', 'DESCRICAO'] } },
            categoria: { serverSide: false, nomePesquisa: 'Categoria', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'AUXILIAR', camposSelect: ['ID', 'DESCRICAO'] } },
            gramatura: { serverSide: false, nomePesquisa: 'Gramatura', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADGRAMAT', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            composicao: { serverSide: false, nomePesquisa: 'Composição', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCOMPOSI', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            carteira: { serverSide: false, nomePesquisa: 'Carteira', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CARTEIRA', camposSelect: ['CARTEIRA', 'DESCRICAO'] } },
            camposPosEscritural: { serverSide: false, nomePesquisa: 'Campos', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'POSICAO', camposSelect: ['CAMPO', `CAMPO`], where: ["POSICAO.CAMPO IS NOT NULL", "POSICAO.CAMPO <> ''"], groupby: ['CAMPO'] } },
            alterarBanco: { serverSide: serverSide, nomePesquisa: 'Banco', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADBAN', camposSelect: ['BANCO', 'NOME_BANCO'] } },
            fatura: { serverSide: true, nomePesquisa: 'Fatura', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'RECEBER', camposSelect: ['FATURA', 'NUMERO'] } },
            cidade: { serverSide: true, nomePesquisa: 'Cidade', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'CIDADE', camposSelect: ['COD_UF', 'NOME', 'CODIGO'] } },
            codcidade: { serverSide: true, nomePesquisa: 'Cidade', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'CIDADE', camposSelect: ['CODIGO', 'NOME', 'COD_UF'] } },
            cuidado: { serverSide: true, nomePesquisa: 'Cuidado', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ETIQUETA', camposSelect: ['CODIGO', 'NOME'], where: ["TIPO = 'C'"] } },
            codfornecedor: { serverSide: serverSide, nomePesquisa: 'Cod. Fornecedor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCORTI', camposSelect: ['CODIGO', 'COD_ENTRADA', 'CODCLI', 'TIPO'], where: ["CODIGO <> NULL OR CODIGO <> ''"] } },
            endosso: {
                serverSide: true, nomePesquisa: 'Endosso', tamanhoAutoCompleta: 3, pesquisa: {
                    tabela: 'RECEBER',
                    camposSelect: ['RECEBER.ENDOSSO CLIENTE', 'ENTIDADE.NOME'],
                    camposSubSelect: ['CLIENTE', 'NOME'],
                    leftJoin: [
                        { tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = RECEBER.ENDOSSO' }
                    ],
                    where: ["RECEBER.ENDOSSO <> ''"]
                }
            },
            classeBaixa: { serverSide: serverSide, nomePesquisa: 'Classe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_GER', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            classeJuros: { serverSide: serverSide, nomePesquisa: 'Classe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_GER', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            classeDesconto: { serverSide: serverSide, nomePesquisa: 'Classe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_GER', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            classeTitulo: { serverSide: serverSide, nomePesquisa: 'Classe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_GER', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            classeMat: { serverSide: serverSide, nomePesquisa: 'Classe Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_MAT', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            ordemProducao: { serverSide: serverSide, nomePesquisa: 'Ordem Produção', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OF1', camposSelect: ['NUMERO', 'CODIGO'] } },
            pedido: { serverSide: serverSide, nomePesquisa: 'Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PEDIDO', camposSelect: ['NUMERO', 'CODCLI'] } },
            integracao: { serverSide: serverSide, nomePesquisa: 'Integração', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'INTEGRACAO', camposSelect: ['ID', 'INTEGRACAO'] } },
            regEstado: { serverSide: serverSide, nomePesquisa: 'Região', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'REG_ESTADO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            lote: { serverSide: serverSide, nomePesquisa: 'Lote', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MAT_ITEN', camposSelect: ['LOTE', 'CODIGO'] }, groupBy: ['CODIGO'] },
            unidade: { serverSide: serverSide, nomePesquisa: 'Unidade', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'UNIDADE', camposSelect: ['UNIDADE', 'DESCRICAO'] } },
            matLinha: { serverSide: serverSide, nomePesquisa: 'Linha de Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MAT_LINHA', camposSelect: ['CODIGO', 'LINHA'] } },
            maquina: { serverSide: serverSide, nomePesquisa: 'Máquina', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MAQUINA', camposSelect: ['MAQUINA', 'DESCRICAO'], where } },
            tipo: { serverSide: serverSide, nomePesquisa: 'Tipo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO', camposSelect: ['ID', 'DESCRICAO'], where: where } },
            grupoCCusto: { serverSide: serverSide, nomePesquisa: 'Grupo de Centro de Custo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_CCUSTO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            veiculo: { serverSide: serverSide, nomePesquisa: 'Veículo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'VEICULO', camposSelect: ['PLACA', 'MODELO'] } },
            reboque: { serverSide: serverSide, nomePesquisa: 'Veículo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'VEICULO', camposSelect: ['PLACA', 'MODELO'] } },
            motorista: { serverSide: serverSide, nomePesquisa: 'Motorista', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MOTORISTA', camposSelect: ['CODIGO', 'NOME'] } },
            tabuf: { serverSide: serverSide, nomePesquisa: 'UF', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABUF', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            setor: { serverSide: serverSide, nomePesquisa: 'Setor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADFLUXO', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            parte: { serverSide: serverSide, nomePesquisa: 'Parte', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO_APL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            notaFac: { serverSide: serverSide, nomePesquisa: 'Nota', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FACCAO3', camposSelect: ['NOTA', 'NUMERO', 'CODCLI'], where: ["NOTA <> ''"], groupBy: ['NOTA', 'NUMERO', 'CODCLI'] } },
            descAcresc: { serverSide: serverSide, nomePesquisa: 'Desconto/Acréscimo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FACCAO4', camposSelect: ['LANCAMENTO', 'NUMERO', 'VALOR'] } },
            funcionario: { serverSide: serverSide, nomePesquisa: 'Funcionário', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PESSOAL', camposSelect: ['CODIGO', 'NOME'] } },
            movimento: { serverSide: serverSide, nomePesquisa: 'Movimento', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FACCAO', camposSelect: ['MOV', 'NUMERO', 'OP'] } },
            of: {
                serverSide: serverSide, nomePesquisa: 'OF', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'FACCAO',
                    camposSelect: ['FACCAO.NUMERO NUMERO', 'FACCAO.CODIGO NUMERO2'],
                    camposSelectSubSelect: ['NUMERO', 'NUMERO2'],
                    groupBy: ['FACCAO.NUMERO', 'FACCAO.CODIGO'],
                    groupBySubSelect: ['NUMERO', 'NUMERO2'],
                    camposWhereServerSide: ['FACCAO.NUMERO', 'FACCAO.CODIGO']
                }, camposSelect: ['FACCAO.NUMERO NUMERO', 'FACCAO.CODIGO NUMERO2']
            },
            celula: { serverSide: serverSide, nomePesquisa: 'Célula', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CELULA', camposSelect: ['CODIGO', 'FABRICA', 'DESCRICAO'] } },
            empresa: { serverSide: serverSide, nomePesquisa: 'Empresa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'EMPRESA', camposSelect: ['EMP_ID', 'EMP_PAT', 'EMP_NOME'] } },
            empresaFantasia: { serverSide: serverSide, nomePesquisa: 'Empresa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'EMPRESA', camposSelect: ['EMP_ID', 'EMP_FANTASIA', 'EMP_PAT', 'EMP_NOME'] } },
            programacao: { serverSide: serverSide, nomePesquisa: 'Programação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OF1', camposSelect: ['PROGRAMACAO', 'NUMERO'] } },
            aplicacao: { serverSide: serverSide, nomePesquisa: 'Aplicação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PCPAPL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tipoPag: { serverSide: serverSide, nomePesquisa: 'Tipo Transferência', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO_PAG', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            ocorrencia: { serverSide: serverSide, nomePesquisa: 'Ocorrência', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OCORRENCIA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            motivo: { serverSide: serverSide, nomePesquisa: 'Motivo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MENSAGEM', camposSelect: ['CODMEN', 'DESCRICAO'] } },
            motivoid: { serverSide: serverSide, nomePesquisa: 'Motivo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MENSAGEM', camposSelect: ['ID', 'DESCRICAO'] } },
            info_compl: { serverSide: serverSide, nomePesquisa: 'Informação Complementar', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABREF', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tipo_fiscal: { serverSide: serverSide, nomePesquisa: 'Tipo Fiscal', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO_FISCAL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            duplicata: { serverSide: serverSide, nomePesquisa: 'Duplicata', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'RECEBER', camposSelect: ['NUMERO', 'FATURA'] } },
            tipoPessoa: { serverSide: serverSide, nomePesquisa: 'Tipo Pessoa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TPDOCPESSOA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            projecao: { serverSide: serverSide, nomePesquisa: 'Projeção', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PROG_COMPRA', camposSelect: ['NUMERO', 'CODIGO'] } },
            corFt: { serverSide: false, nomePesquisa: 'Cor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCOR', camposSelect: ['COR', 'DESCRICAO'] } },
            setorFt: { serverSide: serverSide, nomePesquisa: 'Setor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADFLUXO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            aplicacaoFt: { serverSide: serverSide, nomePesquisa: 'Aplicação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PCPAPL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            statusPed: { serverSide: false, nomePesquisa: 'Status', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SITPROD', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tipoOp: { serverSide: serverSide, nomePesquisa: 'Tipo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO', camposSelect: ['ID', 'DESCRICAO'] } },
            setorPend: { serverSide: serverSide, nomePesquisa: 'Setor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADFLUXO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            grupoCor: { serverSide: serverSide, nomePesquisa: 'Grupo Cor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_COR', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            reserva: {
                serverSide: serverSide, nomePesquisa: 'Reserva', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'PED_RESERVA',
                    camposSelect: ['RESERVA', 'NUMERO'],
                    groupBy: ['RESERVA', 'NUMERO']
                }
            },
            tipoPedido: { serverSide: serverSide, nomePesquisa: 'Tipo Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO', camposSelect: ['ID', 'DESCRICAO'], where: ["AREA = 'COM'"] } },
            grupoPedido: { serverSide: serverSide, nomePesquisa: 'Grupo Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_PED', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            faixaDesconto: { serverSide: serverSide, nomePesquisa: 'Faixa Desconto', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FAIXA_DESCONTO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            auxiliar: { serverSide: serverSide, nomePesquisa: 'Categoria', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'AUXILIAR', camposSelect: ['ID', 'DESCRICAO'] } },
            grupo_ped: { serverSide: serverSide, nomePesquisa: 'Grupo Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_PED', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            cadFio: { serverSide: serverSide, nomePesquisa: 'Fio', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADFIO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            categoriaProd: { serverSide: serverSide, nomePesquisa: 'Categoria Produto', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'AUXILIAR', camposSelect: ['ID', 'DESCRICAO'] } },
            grupoPed: { serverSide: serverSide, nomePesquisa: 'Grupo Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_PED', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            empresaEmp_Pat: { serverSide: serverSide, nomePesquisa: 'Empresa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'EMPRESA', camposSelect: ['EMP_PAT', 'EMP_NOME'], where: empresas.length ? [`EMP_PAT IN (${empresas.map(emp => `'_${emp}'`).join(',')})`] : [] } },
            caixa: { serverSide: serverSide, nomePesquisa: 'Caixa Loja', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CAIXA_LOJA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            natureza: { serverSide: serverSide, nomePesquisa: 'Natureza', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'NATUREZA', camposSelect: ['NATUREZA', 'DESCRICAO'] } },
            operacao: { serverSide: serverSide, nomePesquisa: 'Operação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OPER_FISCAL', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            classeCor: { serverSide: serverSide, nomePesquisa: 'Classe de Cor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CLASSE_COR', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            composicaoMaterial: { serverSide: false, nomePesquisa: 'Composição do Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'COMPOSICAO_MAT', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            obra: { serverSide: serverSide, nomePesquisa: 'Obra', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OBRA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            faixa: { serverSide: serverSide, nomePesquisa: 'Faixa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FAIXA', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            markup: { serverSide: serverSide, nomePesquisa: 'Markup', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CAD_MARKUP', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            ncm: { serverSide: serverSide, nomePesquisa: 'NCM', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABFIS', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            caracteristica: { serverSide: serverSide, nomePesquisa: 'Característica', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CARACTERISTICA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            fluxo: { serverSide: serverSide, nomePesquisa: 'Fluxo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ROTEIRO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            subGrupoCor: { serverSide: serverSide, nomePesquisa: 'SubGrupo Cor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SUBGRUPO_COR', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            pais: { serverSide: serverSide, nomePesquisa: 'País', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADPAIS', camposSelect: ['CODIGO', 'NOME'] } },
            subCaracteristica: { serverSide: serverSide, nomePesquisa: 'Sub Caracteristica', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CARACTERISTICA', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            funcao: { serverSide: serverSide, nomePesquisa: 'Função', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'FUNCAO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            medidas: { serverSide: serverSide, nomePesquisa: 'Medidas', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MEDIDAS', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            naturezaFrete: { serverSide: serverSide, nomePesquisa: 'Natureza Frete', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'NAT_FRETE', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            servico: { serverSide: serverSide, nomePesquisa: 'Serviço', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SERVICO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            cilindro: { serverSide: serverSide, nomePesquisa: 'Cilindro', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CILINDRO', camposSelect: ['CODIGO', 'DESCRICAO'] } },
            tabPrecoRepresentante: {
                serverSide: serverSide, nomePesquisa: 'Tabela de Preço', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'REP_REGIAO',
                    camposSelect: ['REP_REGIAO.REGIAO', 'REGIAO.DESCRICAO'],
                    leftJoin: [{ tabela: 'REGIAO', condicao: 'REGIAO.REGIAO = REP_REGIAO.REGIAO' }],
                    where
                }
            },
            nota: { serverSide: serverSide, nomePesquisa: 'Nota', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'NOTA', camposSelect: ['FATURA', 'SERIE'], where: where } },
            notaNfce: { serverSide: serverSide, nomePesquisa: 'NFCe', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'NOTA_NFCE', camposSelect: ['FATURA', 'SERIE'], where: where } },
            notaEntra: { serverSide: serverSide, nomePesquisa: 'Nota Entrada', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'NOTA_ENTRA', camposSelect: ['NOTAFISCAL', 'SERIE'], where: where } },
            loteInterno: { serverSide: serverSide, nomePesquisa: 'Lote Interno', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MAT_ITEN', camposSelect: ['LOTE_INTERNO', 'CODIGO'], where: ["LOTE_INTERNO <> '' OR LOTE_INTERNO IS NOT NULL"], groupBy: ['LOTE_INTERNO', 'CODIGO', 'COR'] } },
            tonalidade: { serverSide: serverSide, nomePesquisa: 'Tonalidade', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'MAT_ITEN', camposSelect: ['TONALIDADE', 'ATIVO'], where: ["TONALIDADE <> '' OR TONALIDADE IS NOT NULL"], groupBy: ["TONALIDADE", "ATIVO"] } },
            operacaoTempos: { serverSide: serverSide, nomePesquisa: 'Operação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'OPERACAO', camposSelect: ['CODIGO', 'DESCRICAO'], where: where } },
            local: { serverSide: serverSide, nomePesquisa: 'Local', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CAD_LOC_ESTOQ', camposSelect: ['CODIGO', 'DESCRICAO'], where: where } },
            codigoSped: { serverSide: serverSide, nomePesquisa: 'Código Sped', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABSPED', camposSelect: ['CODIGO', 'DESCRICAO'], where: where } },
            recSenior: { serverSide: serverSide, nomePesquisa: 'Receber', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'RECEBER', camposSelect: ['NUMERO', 'COD_IMPORTADO'] } },
            faturaNfeSenior: { serverSide: serverSide, nomePesquisa: 'Fatura NFE', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'NOTA', camposSelect: ['FATURA', 'SERIE', 'EMP_ID'] } },
            faturaNfceSenior: { serverSide: serverSide, nomePesquisa: 'Fatura NFCE', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'NOTA_NFCE', camposSelect: ['FATURA', 'SERIE', 'EMP_ID'] } },
            clienteSenior: { serverSide: serverSide, nomePesquisa: 'Cliente', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ENTIDADE', camposSelect: ['CODCLI', 'CNPJ', 'NOME', 'COD_IMPORTADO'], where: where }, },
            pagtoSenior: { serverSide: serverSide, nomePesquisa: 'Pagto', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'PAGTO', camposSelect: ['NUM_AP', 'COD_IMPORTADO'], where: where }, },
            cnae: { serverSide: serverSide, nomePesquisa: 'CNAE', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CADCNAE', camposSelect: ['CODIGO', 'DESCRICAO'], where }, },
            cstIcms: { serverSide: serverSide, nomePesquisa: 'CST ICMS', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABTRI', camposSelect: ['CODIGO', 'DESCRICAO'], where }, },
            cstIpi: { serverSide: serverSide, nomePesquisa: 'CST IPI', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABIPI', camposSelect: ['CODIGO', 'DESCRICAO'], where }, },
            movimentacaoProduto: { serverSide, nomePesquisa: 'Movimentação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PA_MOV', camposSelect: ['NUM_DOCTO', 'OPERACAO'], where, groupBy: ['NUM_DOCTO', 'OPERACAO'] } },
            faixaMaterial: { serverSide, nomePesquisa: 'Faixa', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PCPFAIXA', camposSelect: ['FAIXA', 'DESCRICAO'], where } },
            enquadramentoIpi: { serverSide, nomePesquisa: 'Enquadramento IPI', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ENQUADRA', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            contaContabil: { serverSide, nomePesquisa: 'Conta Contábil', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CONTA_CONT', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            ordemCompra: {
                serverSide,
                nomePesquisa: 'Ordem de Compra',
                tamanhoAutoCompleta: 1,
                pesquisa: {
                    tabela: 'COMPRA',
                    camposSelect: ['COMPRA.NUMERO', 'COMPRA.CODFOR', 'ENTIDADE.NOME'],
                    where,
                    leftJoin: [
                        {
                            tabela: 'ENTIDADE',
                            condicao: 'COMPRA.CODFOR = ENTIDADE.CODCLI',
                        },
                    ],
                    camposSelectSubSelect: ['NUMERO', 'CODFOR', 'NOME'],
                    groupBySubSelect: ['NUMERO', 'CODFOR', 'NOME'],
                    camposWhereServerSide: ['COMPRA.NUMERO', 'COMPRA.CODFOR', 'ENTIDADE.NOME'],
                }
            },
            tamanho2: { serverSide: serverSide, nomePesquisa: 'Tamanho', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TABTAM', camposSelect: ['TAM', 'ACRESCIMO'], where: where } },
            solicitacao: { serverSide: serverSide, nomePesquisa: 'Solicitação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'SOL_COMPRA', camposSelect: ['NUMERO', 'SOLICITANTE'], where: where } },
            consignado: {
                serverSide: serverSide, nomePesquisa: 'Consignado', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'VEN_CONSIG',
                    camposSelect: ['ID', 'DATA_ACERTO'],
                    orderBy: ['ID DESC'],
                    where
                }
            },
            tipoMalha: { serverSide: serverSide, nomePesquisa: 'Tipo Malha', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'TIPO_MALHA', camposSelect: ['CODIGO', 'DESCRICAO'], where: where } },
            metas: { serverSide: serverSide, nomePesquisa: 'Metas', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'METAVENDA', camposSelect: ['ID', 'DESCRICAO'], where: where } },
            cotacao: { serverSide, nomePesquisa: 'Cotação', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'COTACAO', camposSelect: ['NUMERO', 'CODCRE'], where, groupby: ['NUMERO', 'CODCRE'] } },
            condicaoPagamento: { serverSide, nomePesquisa: 'Condição de pagamento', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CONDICAO', camposSelect: ['CODCOND', 'DESCRICAO'], where } },
            itensCompra: { serverSide, nomePesquisa: 'Itens de Compra', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CO_ITEN', camposSelect: ['CODIGO', 'DESCRICAO'], where, groupBy: ['CODIGO', 'DESCRICAO'] } },
            pagto: { serverSide: serverSide, nomePesquisa: 'Pagto', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'PAGTO', camposSelect: ['NUM_AP', 'DT_EMI'], where: where }, },
            loteProduto: { serverSide: serverSide, nomePesquisa: 'Lote', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PA_ITEN', camposSelect: ['LOTE', 'CODIGO'], where, groupBy: ['LOTE', 'CODIGO'], orderBy: ['LOTE'] } },
            grupoPreco: { serverSide, nomePesquisa: 'Grupo Preço', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PRECO_GRUPO', camposSelect: ['CODIGO', 'DESCRICAO'] }, where },
            ordemCompraBaixa: {
                serverSide,
                nomePesquisa: 'Ordem de Compra',
                tamanhoAutoCompleta: 1,
                pesquisa: {
                    tabela: 'COMPRA',
                    camposSelect: ['COMPRA.NUMERO', 'COMPRA.CODFOR', 'ENTIDADE.NOME', 'COMPRA.OBS'],
                    where,
                    leftJoin: [
                        {
                            tabela: 'ENTIDADE',
                            condicao: 'COMPRA.CODFOR = ENTIDADE.CODCLI',
                        },
                    ],
                    camposSelectSubSelect: ['NUMERO', 'CODFOR', 'NOME', 'OBS'],
                    groupBySubSelect: ['NUMERO', 'CODFOR', 'NOME', 'OBS'],
                    camposWhereServerSide: ['COMPRA.NUMERO', 'COMPRA.CODFOR', 'ENTIDADE.NOME', 'COMPRA.OBS'],
                }
            },
            composicaoMat: { serverSide, nomePesquisa: 'Composição Material', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'COMPOSICAO_MAT', camposSelect: ['CODIGO', 'DESCRICAO'] }, where },
            acessoPedido: {
                serverSide: serverSide, nomePesquisa: 'Pedido', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'PEDIDO',
                    camposSelect: ['PEDIDO.NUMERO', 'PEDIDO.CODCLI', 'ENTIDADE.NOME'],
                    where,
                    leftJoin: [
                        {
                            tabela: 'ENTIDADE',
                            condicao: 'PEDIDO.CODCLI = ENTIDADE.CODCLI',
                        },
                    ],
                    camposSelectSubSelect: ['NUMERO', 'CODCLI', 'NOME'],
                    groupBySubSelect: ['NUMERO', 'CODCLI', 'NOME'],
                    camposWhereServerSide: ['PEDIDO.NUMERO', 'PEDIDO.CODCLI', 'ENTIDADE.NOME'],
                }
            },
            entidadeAux: { serverSide, nomePesquisa: 'Entidade Auxiliar', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ENTID_AUX', camposSelect: ['CODIGO', 'DESCRICAO'] }, where },
            defeito: { serverSide, nomePesquisa: 'Defeito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEFEITO', camposSelect: ['CODIGO', 'DESCRICAO'] }, where },
            gestor: { serverSide, nomePesquisa: 'Gestor', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PESSOAL', camposSelect: ['CODIGO', 'NOME'], where: where } },
            tecnico: { serverSide, nomePesquisa: 'Técnico', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PESSOAL', camposSelect: ['CODIGO', 'NOME'], where: where } },
            clienteSolicitacoes: { serverSide: serverSide, nomePesquisa: 'Cliente', tamanhoAutoCompleta: 3, pesquisa: { tabela: 'ENTIDADE', camposSelect: ['CODCLI', 'NOME', 'CNPJ', 'FANTASIA'], where: where }, },
            numeroKit: {
                serverSide,
                nomePesquisa: 'Número Kit',
                tamanhoAutoCompleta: 1,
                pesquisa: {
                    camposSelectSubSelect: ['NUMERO', 'TIPO'],
                    groupBySubSelect: ['NUMERO', 'TIPO'],
                    tabela: 'KIT_ITEM',
                    camposSelect: ['NUMERO', 'TIPO'],
                    groupBy: ['NUMERO', 'TIPO'],
                },
                where
            },
            itemSolicitacao: {
                serverSide, nomePesquisa: 'Item', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'SOL_ITEN',
                    camposSelect: ['SOL_ITEN.CODIGO', "(CASE SOL_ITEN.TP_ITEM WHEN 'M' THEN MATERIAL.DESCRICAO WHEN 'P' THEN PRODUTO.DESCRICAO WHEN 'S' THEN SERVICO.DESCRICAO END) DESCRICAO"],
                    where,
                    leftJoin: [
                        {
                            tabela: 'MATERIAL',
                            condicao: 'SOL_ITEN.CODIGO = MATERIAL.CODIGO',
                        },
                        {
                            tabela: 'PRODUTO',
                            condicao: 'SOL_ITEN.CODIGO = PRODUTO.CODIGO',
                        },
                        {
                            tabela: 'SERVICO',
                            condicao: 'SOL_ITEN.CODIGO = SERVICO.CODIGO',
                        },
                    ],
                    camposWhereServerSide: ['SOL_ITEN.CODIGO', 'MATERIAL.DESCRICAO', 'PRODUTO.DESCRICAO', 'SERVICO.DESCRICAO'],
                    camposSelectSubSelect: ['CODIGO', 'DESCRICAO'],
                    groupBySubSelect: ['CODIGO', 'DESCRICAO'],
                }
            },
            itemCotacao: {
                serverSide, nomePesquisa: 'Item', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'COTACAO',
                    camposSelect: ['COTACAO.MATERIAL CODIGO', "(CASE COTACAO.TP_ITEM WHEN 'M' THEN MATERIAL.DESCRICAO WHEN 'P' THEN PRODUTO.DESCRICAO WHEN 'S' THEN SERVICO.DESCRICAO END) DESCRICAO"],
                    where,
                    leftJoin: [
                        {
                            tabela: 'MATERIAL',
                            condicao: 'COTACAO.MATERIAL = MATERIAL.CODIGO',
                        },
                        {
                            tabela: 'PRODUTO',
                            condicao: 'COTACAO.MATERIAL = PRODUTO.CODIGO',
                        },
                        {
                            tabela: 'SERVICO',
                            condicao: 'COTACAO.MATERIAL = SERVICO.CODIGO',
                        },
                    ],
                    camposWhereServerSide: ['COTACAO.MATERIAL', 'MATERIAL.DESCRICAO', 'PRODUTO.DESCRICAO', 'SERVICO.DESCRICAO'],
                    camposSelectSubSelect: ['CODIGO', 'DESCRICAO'],
                    groupBySubSelect: ['CODIGO', 'DESCRICAO'],
                }
            },
            itemCompra: {
                serverSide, nomePesquisa: 'Item', tamanhoAutoCompleta: 1, pesquisa: {
                    tabela: 'CO_ITEN',
                    camposSelect: ['CO_ITEN.CODIGO', "(CASE CO_ITEN.TP_ITEM WHEN 'M' THEN MATERIAL.DESCRICAO WHEN 'P' THEN PRODUTO.DESCRICAO WHEN 'S' THEN SERVICO.DESCRICAO END) DESCRICAO"],
                    where,
                    leftJoin: [
                        {
                            tabela: 'MATERIAL',
                            condicao: 'CO_ITEN.CODIGO = MATERIAL.CODIGO',
                        },
                        {
                            tabela: 'PRODUTO',
                            condicao: 'CO_ITEN.CODIGO = PRODUTO.CODIGO',
                        },
                        {
                            tabela: 'SERVICO',
                            condicao: 'CO_ITEN.CODIGO = SERVICO.CODIGO',
                        },
                    ],
                    camposWhereServerSide: ['CO_ITEN.CODIGO', 'MATERIAL.DESCRICAO', 'PRODUTO.DESCRICAO', 'SERVICO.DESCRICAO'],
                    camposSelectSubSelect: ['CODIGO', 'DESCRICAO'],
                    groupBySubSelect: ['CODIGO', 'DESCRICAO'],
                }
            },
            depositoEmpresaUsuario: { serverSide, nomePesquisa: 'Depósito', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'DEPOSITO', camposSelect: ['CODIGO', 'DESCRICAO'], where: [filtroDeposito] } },
            grupoVenda: { serverSide, nomePesquisa: 'Tipo', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'GRUPO_VENDA', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            variante: { serverSide, nomePesquisa: 'Composição', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'VARIANTE', camposSelect: ['CODIGO', 'DESCRICAO'], where } },
            contato: { serverSide, nomePesquisa: 'Contato', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'CONTATO', camposSelect: ['ID', 'NOME'], where } },
            orcamentoTingimento: { serverSide, nomePesquisa: 'Orçamento', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'ORCA_TIN', camposSelect: ['NUMERO', 'ID'], where } },
            pedRegras: { serverSide, nomePesquisa: 'Regras de Pedido', tamanhoAutoCompleta: 1, pesquisa: { tabela: 'PED_REGRAS', camposSelect: ['CODIGO', 'REGRA'], where: where } },
        };

        const pesquisa = pesquisaTabelas[tabela];
        const input = id == '' ? $(`#txt${tabelaTratada}`) : $(`#txt${id}`);
        const botao = id == '' ? $(`#btn${tabelaTratada}`) : $(`#btn${id}`);
        const botaoLimpar = id == '' ? $(`#btnLimpa${tabelaTratada}`) : $(`#btnLimpa${id}`);

        if (!pesquisa || !input[0] || !botao[0] || !botaoLimpar[0]) {
            throw new Error('algum dos componentes está errado');
        }
        let pesquisaAutoCompleta = {};

        if (retornaMaisDeUmRegistro) {
            pesquisaAutoCompleta = {
                ...pesquisa.pesquisa, camposSelect: [...pesquisa.pesquisa.camposSelect.map((coluna) => coluna)]
            };
            $(input).pesquisa_variosServerside(
                pesquisa.tamanhoAutoCompleta,
                `${JSON.stringify(pesquisaAutoCompleta)}`,
                pesquisa?.pesquisa?.camposSelectSubSelect?.[0] ?? pesquisa.pesquisa.camposSelect[0],
                pesquisa?.pesquisa?.camposSelectSubSelect?.[1] ?? pesquisa.pesquisa.camposSelect[1]
            );
            $(botao).pesquisa_serversideSel(input, `${JSON.stringify(pesquisa.pesquisa)}`, `Pesquisa ${pesquisa.nomePesquisa}`, undefined, pAtivo);
        } else if (pesquisa.serverSide && !retornaMaisDeUmRegistro) {
            pesquisaAutoCompleta = {
                ...pesquisa.pesquisa, camposSelect: [...pesquisa.pesquisa.camposSelect.map((coluna, idx) => idx == 0 ? `${coluna} CHAVE`
                    : `${coluna} DESCRICAO`)]
            };
            $(botao).pesquisa_serverside([input], [...pesquisa.pesquisa.camposSelect.map(coluna => coluna)], [...pesquisa.pesquisa.camposSelect.map(coluna => coluna)], JSON.stringify(pesquisa.pesquisa), `Pesquisa de ${pesquisa.nomePesquisa}`, undefined, undefined, '', pAtivo);
            $(input).pesquisa_variosServerside(pesquisa.tamanhoAutoCompleta, `${JSON.stringify(pesquisaAutoCompleta)}`, pesquisa.pesquisa.camposSelect[0], pesquisa.pesquisa.camposSelect[1]);
        } else {
            const pesquisaAutoCompleta = {
                ...pesquisa.pesquisa, camposSelect: [...pesquisa.pesquisa.camposSelect.map((coluna, idx) => idx == 0 ? `${coluna} CHAVE`
                    : `${coluna} DESCRICAO`)]
            };
            $(input).autocompleta(
                pesquisa.tamanhoAutoCompleta,
                `JSON=${JSON.stringify(pesquisaAutoCompleta)}`,
                undefined,
                undefined,
                undefined,
                callback,
                undefined,
                '',
                [],
                ignorarPesquisasPadroes
            )
            $(botao).pesquisa(input, pesquisa.pesquisa.camposSelect[0], pesquisa.pesquisa.camposSelect[1], `/sisplan/funcoes/v1/pesquisa?JSON=${JSON.stringify(pesquisa.pesquisa)}`, `Pesquisa de ${pesquisa.nomePesquisa}`, pesquisa.pesquisa.tabela.toUpperCase(), undefined, callback);
        }

        $(input).addClass('camposFiltros');

        // switch (pesquisa.serverSide) {
        //     case 'serverSideSel':
        //         pesquisaAutoCompleta = {
        //             ...pesquisa.pesquisa, camposSelect: [...pesquisa.pesquisa.camposSelect.map((coluna) => coluna)]
        //         };
        //         $(input).pesquisa_variosServerside(pesquisa.tamanhoAutoCompleta, `${JSON.stringify(pesquisaAutoCompleta)}`, pesquisa.pesquisa.camposSelect[0], pesquisa.pesquisa.camposSelect[1]);
        //         $(botao).pesquisa_serversideSel(input, `${JSON.stringify(pesquisa.pesquisa)}`, `Pesquisa ${pesquisa.pesquisa.tabela}`);
        //         break;
        //     case 'serverSide':
        //         pesquisaAutoCompleta = {
        //             ...pesquisa.pesquisa, camposSelect: [...pesquisa.pesquisa.camposSelect.map((coluna, idx) => idx == 0 ? `${coluna} CHAVE`
        //                 : `${coluna} DESCRICAO`)]
        //         };
        //         $(botao).pesquisa_serverside([input], [...pesquisa.pesquisa.camposSelect.map(coluna => coluna)], [...pesquisa.pesquisa.camposSelect.map(coluna => coluna)], JSON.stringify(pesquisa.pesquisa), `Pesquisa ${pesquisa.pesquisa.tabela}`);
        //         $(input).autocompleta(pesquisa.tamanhoAutoCompleta, `JSON=${JSON.stringify(pesquisaAutoCompleta)}`);
        //         break;
        //     default:
        //         $(botao).pesquisa(input, pesquisa.pesquisa.camposSelect[0], pesquisa.pesquisa.camposSelect[1], `/sisplan/funcoes/v1/pesquisa?JSON=${JSON.stringify(pesquisa.pesquisa)}`, pesquisa.nomePesquisa, pesquisa.pesquisa.tabela.toUpperCase());
        //         break;
        // }

        $(botaoLimpar).on('click', function () {
            $(input).empty().trigger('change');
            $(input).val('');
            $(input).attr('data-chave', '');
            $(input).attr('data-desc', '');
        });
    } catch (err) {
        console.error('Atenção ! Provavelmente você esqueceu de seguir o padrão de nome do input, botão de pesquisa e botão de limpar, ou ainda não está na lista padronizada, verifique !!!', `tabela: ${tabela}`);
    }
}

function limparFiltros(select = false) {

    if (select) {
        const botaoLimparFiltros = $('#btnLimparFiltros');

        botaoLimparFiltros.on('click', function () {
            const listaInputs = $('#modal-filtros .modal-body input').toArray();
            listaInputs.forEach(input => {
                if (input.type != 'radio') {
                    $(input).val('');
                }
            });

            const listaSelects = $('#modal-filtros .modal-body select').toArray();
            listaSelects.forEach(input => {
                $(input).empty().trigger('change');
            });
        });

        return;
    }

    const botaoLimparFiltros = $('#btnLimparFiltros');

    botaoLimparFiltros.on('click', function () {
        const listaInputs = $('#modal-filtros .modal-body input').toArray();
        listaInputs.forEach(input => {
            if (input.type != 'radio') {
                $(input).val('');
            }
        });
        const listaSelects = $('#modal-filtros .modal-body select').toArray();
        listaSelects.forEach(input => {
            $(input).val('');
        });
    });
}

function adicionaColunas(colunas, invisiveis, desabilitadas = [], naoExibir = []) {
    $('#colunasInvisiveis').html('');
    colunas.forEach((coluna, i) => {
        if (naoExibir.includes(coluna.title)) return;

        $('#colunasInvisiveis').html(`
            ${$('#colunasInvisiveis').html()}
            <label htmlFor="txt${coluna.data}" class="col-3 labelColunasInvisiveis icheck-primary" title='Coluna ${coluna.title}'>
                <input ${desabilitadas.includes(coluna.title) ? 'disabled readonly' : ''} type="checkbox" value=${i} name="txt${coluna.data}" id="txt${coluna.data}" />
                <label for="txt${coluna.data}">${coluna.title}</label>
            </label>
        `);
        if (invisiveis) {
            if (invisiveis.filter((invisivel) => invisivel == coluna.data)[0] == coluna.data) {
                $(`#txt${coluna.data}`).attr('checked', true);
            }
        }
    });
}

function retornaNovasColunasInvisiveis() {
    const colunasInvisiveis = [];
    // const colunas = $($('#colunasInvisiveis'))[0].outerText.split('\n');
    const colunas = $('#colunasInvisiveis label input').map(function () {
        return this.id.replace('txt', '');
    }).get();
    $('#colunasInvisiveis').parent('input');
    colunas.map((coluna) => {
        if (isChecked(`#txt${coluna}`)) {
            colunasInvisiveis.push(coluna);
            return coluna;
        }
    });
    return colunasInvisiveis;
}

function removeColunasFixas(novasColunas, colunasFixas) {
    for (let ci = 0; ci < colunasFixas.length; ci++) {
        const i = novasColunas.indexOf(colunasFixas[ci]);
        if (i > -1) {
            novasColunas.splice(i, 1);
        }
    }
}

async function exportaCSV(
    url, filtros, pesquisaPadrao, timeout, titulo, tabela,
    codPersonalizado = '', arrayJson = 999, body = false,
    maisDeUmaTabela = false, dadosDataTable = undefined,
    dadosRetornamComoObjetoDePaginacao = false, alteraMilhar = false
) {
    $.LoadingOverlay('show');
    let dados = [];

    try {
        if (!dadosDataTable) {
            let response;
            if (body)
                response = await requisicao('POST', url, '', filtros, timeout);
            else
                response = await requisicao('GET', url, filtros, '', timeout);

            if (!response) return;

            if (pesquisaPadrao)
                dados = (await response.json()).RESULT[0];
            else
                dados = await response.json();

            if (dadosRetornamComoObjetoDePaginacao) {
                dados = dados.data;
                if (!dados) {
                    msgErro('Nenhum dado a ser exportado.');
                    return;
                }
            }

            if (maisDeUmaTabela) {
                const tabelas = {
                    '#tabelaDetalha': dados.Detalha,
                    '#tabelaContas': dados.Saldo,
                    '#tabelaAnalise': dados.Analise
                };
                dados = tabelas[tabela];
            }

            if (arrayJson != 999) dados = dados[arrayJson];
            if ((!Array.isArray(dados)) && Array.isArray(dados.resultado))
                dados = dados.resultado;
        } else {
            dados = dadosDataTable;
        }

        eval(codPersonalizado);

        const colunasCabecalho = [];
        const arrayFormatar = [];
        const camposNaOrdem = [];

        if (tabela) {
            const dt = $(tabela).DataTable();
            dt.colReorder.reset();

            dt.columns().every(function () {
                const dataSrc = this.dataSrc();
                if (this.visible() && dataSrc && typeof dataSrc === 'string' &&
                    dataSrc.toUpperCase() !== 'OPCOES' && dataSrc.toUpperCase() !== 'SEL') {
                    colunasCabecalho.push(($(this.header()).text()).trim());
                    camposNaOrdem.push(this.dataSrc());
                    if (typeof this.dataSrc() == 'string') {
                        arrayFormatar.push(
                            `if (typeof e['${this.dataSrc()}'] == 'string') {e['${this.dataSrc()}'] = e['${this.dataSrc()}'].replaceAll(',', '').replaceAll(';', '').replaceAll('\\r\\n', '').replaceAll('\\n', '')}`
                        );
                    }
                }
            });
        } else {
            Object.keys(dados[0] || {}).forEach(titulo => {
                if (titulo.toUpperCase() != 'OPCOES' && titulo.toUpperCase() != 'SEL') {
                    colunasCabecalho.push(titulo.trim());
                    camposNaOrdem.push(titulo);
                    arrayFormatar.push(
                        `if (typeof e['${titulo}'] == 'string') { e['${titulo}'] = e['${titulo}'].replaceAll(',', '').replaceAll(';', '').replaceAll('\\r\\n', '').replaceAll('\\n', '') }`
                    );
                }
            });
        }

        const workerCode = `
      self.onmessage = function (ev) {
        const { dados, camposNaOrdem, arrayFormatar, alteraMilhar, colunasCabecalho } = ev.data;
        const lenDados = dados.length;
        const lenCampos = camposNaOrdem.length;
        const dadosCsv = [];
        dadosCsv.push(colunasCabecalho.join(';'));

        let funcFormatar = null;
        if (arrayFormatar && arrayFormatar.length > 0)
          funcFormatar = new Function('e', arrayFormatar.join(';'));

        for (let i = 0; i < lenDados; i++) {
          const e = dados[i];
          if (funcFormatar) funcFormatar(e);

          const linha = [];
          for (let j = 0; j < lenCampos; j++) {
            const campo = camposNaOrdem[j];
            let v = e[campo];
            if (v === undefined || v === null) v = '';
            else {
              v = String(v);
              if (alteraMilhar && !isNaN(v)) v = v.replace(/\\./g, ',');
              v = v.replace(/;/g, '').replace(/\\r?\\n|\\r/g, ' ');
            }
            linha.push(v);
          }
          dadosCsv.push(linha.join(';'));
          if (i % 5000 === 0)
            self.postMessage({ tipo: 'progresso', atual: i, total: lenDados });
        }

        self.postMessage({ tipo: 'finalizado', csv: dadosCsv.join('\\n') });
        self.close();
      };
    `;
        const blob = new Blob([workerCode], { type: 'application/javascript' });
        const worker = new Worker(URL.createObjectURL(blob));

        worker.postMessage({
            dados, camposNaOrdem, arrayFormatar, alteraMilhar, colunasCabecalho
        });

        worker.onmessage = function (event) {
            const { tipo, csv, atual, total } = event.data;
            if (tipo === 'progresso') {
                $.LoadingOverlay('text', `Gerando CSV: ${atual}/${total}`);
            }
            if (tipo === 'finalizado') {
                const arquivoCsv = new Blob(["\ufeff" + csv], {
                    type: "text/csv;charset=utf-8"
                });
                const downloadLink = document.createElement('a');
                downloadLink.download = (titulo || 'exportacao') + '.csv';
                downloadLink.href = URL.createObjectURL(arquivoCsv);
                downloadLink.click();
                $.LoadingOverlay('hide');
            }
        };

    } catch (e) {
        console.error(e);
        msgErro('Não foi possível realizar a exportação!');
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function exportarCSVBackEnd(json, nomeCSV) {
    $.LoadingOverlay('show');
    try {
        json = JSON.stringify(json);
        const response = await requisicao('GET', '/sisplan/funcoes/v1/exportarcsv?', `JSON=${encodeURIComponent(json)}&EMPRESA=${encodeURIComponent(getCookie('empresa'))})}`);

        const jsonStr = await response.json();
        let base64 = jsonStr.RESULT[0].ARQUIVO_CSV.trim();

        const csv = atob(base64);

        const linhas = csv.split('\n');
        if (!linhas[0].startsWith('sep=')) {
            linhas[0] = 'sep=;\n' + linhas[0];
        };
        const excel = linhas.join('\n');

        const blob = new Blob(["\uFEFF" + excel], {
            type: "text/csv;charset=utf-8;"
        });

        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = nomeCSV || 'dados.csv';
        document.body.appendChild(link);
        link.click();
        setTimeout(() => document.body.removeChild(link), 100);

    } catch (error) {
        console.error('Erro ao exportar CSV:', error.message);
    } finally {
        $.LoadingOverlay('hide');
    };
}

function StringToFloatDef(string, defaultValue) {
    const valor = parseFloat(string);

    if ((!valor) || (isNaN(valor))) {
        return defaultValue;
    }

    return valor;
}

async function buscaPesoBalanca(sTipoItem, sParametro) {
    try {
        $.LoadingOverlay('show');
        let response = await requisicao_ecf('GET', '/balanca/chamapeso?', `TIPO=${sTipoItem}&PARAMETRO=${sParametro}`, '', 15000);

        response = await response.text();
        if (response == '-9') {
            response = '0';
        }

        return response.replace(',', '.');
    } catch (err) {
        console.log(err);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function retornaMsgPersonalizadaWpp(tela, objMsgWpp, retornaLista = false, mostraErro = false) {
    try {
        // ALTERADO METODO PARA POST POIS ERA NECESSÁRIO USAR UM BODY PARA ESSA REQUISIÇÃO
        const response = await requisicao('POST', "/sisplan/config_whatsapp/v1/retornarmensagem?", `TELA=${tela}`, JSON.stringify({ LISTAMSGWHATSAPPWEB: objMsgWpp }));

        if (!response) {
            return "";
        }

        const jsonMensagem = await response.json();

        if (response.status != 200) {
            if (mostraErro) {
                msgAlerta(jsonMensagem.mensagem);
            }
            console.error(jsonMensagem.mensagem);
            return "";
        }

        if (retornaLista) {
            return jsonMensagem.listaMsgWhatsappWeb;
        } else {
            return jsonMensagem.listaMsgWhatsappWeb[0].mensagemPersonalizada;
        }

    } catch (error) {
        console.error(error);
    }
}

function encodeEmoticonsMensagem(mensagem) {
    const regexIdentificadorEmoticon = /<([^<>]+)>/g;
    const emoticons = [];
    let match;

    while ((match = regexIdentificadorEmoticon.exec(mensagem)) !== null) {
        emoticons.push(match[1]);
    }

    emoticons.forEach(emoticon => {
        const emoticonCode = emoticon.codePointAt(0).toString(16).toUpperCase();
        mensagem = mensagem.replaceAll(emoticon, emoticonCode);
    });

    return mensagem;

}

function decodeEmoticonsMensagem(mensagem, formataMsg = false) {
    const regexIdentificadorEmoticon = /<([^<>]+)>/g;
    const emoticonsCode = [];
    let match;

    while ((match = regexIdentificadorEmoticon.exec(mensagem)) !== null) {
        emoticonsCode.push(match[1]);
    }

    emoticonsCode.forEach(code => {
        const emoticon = String.fromCodePoint(parseInt(code, 16));
        mensagem = mensagem.replaceAll(code, emoticon);
    });

    if (formataMsg) {
        mensagem = mensagem.replaceAll('<', '');
        mensagem = mensagem.replaceAll('>', '');
    }

    return mensagem;

}

function carregaFuncoesDataTable(pNome, pTabela) {
    let colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));

    // aqui so valida se nao existe tem que criar para nao dar erro
    if (colunas == null || colunas[pNome] == undefined) {
        colunas[pNome] = [];
        localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify(colunas));
        colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
    }

    // confirma as colunas
    $('#btnConfirmarColunas').on('click', async function () {
        try {
            $.LoadingOverlay('show');

            const novasColunas = retornaNovasColunasInvisiveis();
            colunas[pNome] = novasColunas;
            localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify(colunas));

            $(pTabela).DataTable().columns().visible(true);
            $(pTabela).DataTable().columns().every(
                function () {
                    if ((novasColunas).indexOf(this.dataSrc()) != -1) {
                        this.visible(false);
                    }
                }
            );

        } finally {
            $.LoadingOverlay('hide');
            $('#modal-ColunasVisiveis').modal('hide');
        }
    });
}

function validaFiltroUsuario(usuario) {
    if (usuario.includes("TODOS")) {
        return '';
    }

    return usuario;
}

function adicionaValorPadraoVarios(element, val, desc) {
    if ((!desc) || val === '') {
        return;
    }
    if (typeof desc === 'object') {
        buscaValor(desc.tabela, desc.campoBusca, desc.campoWhere, desc.valorWhere)
            .then((value => {
                let descricao;
                if (!value) {
                    descricao = 'VALOR INVÁLIDO';
                } else {
                    descricao = value[Object.keys(value)[0]];
                }
                let j = new Option(`[${val}] - ${descricao}`, val, true, true);
                $(`#txt${primeiraLetraMaiuscula(element)}`).append(j).trigger('change');
            }));
    } else {
        let j = new Option(`[${val}] - ${desc}`, val, true, true);
        $(`#txt${primeiraLetraMaiuscula(element)}`).append(j).trigger('change');
    }
}

async function enviarMsgPersonalizadaWpp(tela, objMsgWpp, arquivo = undefined, callBackNaoEnviados = undefined, sCampoChave = '') {
    const bUtilizaWhatsapp = await utilizaWhatsapp();
    const listaNaoEnviados = [];
    // const anexosMensagemPersonalizada = await retornaAnexoMsgPersonalizada(tela);

    try {
        if (!bUtilizaWhatsapp) {
            throw msgAlerta("Não está configurado para envio de mensagens.");
        }

        let retornoMsgPersonalizadaWpp = await retornaMsgPersonalizadaWpp(tela, objMsgWpp, true);
        const anexosMensagemPersonalizada = await retornaAnexoMsgPersonalizada(tela);
        const anexos = anexosMensagemPersonalizada.map((anexo) => { return anexo.caminhoArquivo; });

        if (retornoMsgPersonalizadaWpp[0].mensagemPersonalizada != "") {

            for (let i = 0; i < retornoMsgPersonalizadaWpp.length; i++) {
                retornoMsgPersonalizadaWpp[i].mensagemPersonalizada = decodeEmoticonsMensagem(retornoMsgPersonalizadaWpp[i].mensagemPersonalizada, true);

                if (!await enviarMensagem(retornoMsgPersonalizadaWpp[i].celular, retornoMsgPersonalizadaWpp[i].mensagemPersonalizada, tela, sCampoChave, false)) {
                    listaNaoEnviados.push(retornoMsgPersonalizadaWpp[i].parametrosMensagem.split(",")[0] + " - " + retornoMsgPersonalizadaWpp[i].nome);
                }

                if (arquivo != undefined || anexos != undefined) {
                    await enviarMensagem(retornoMsgPersonalizadaWpp[i].celular, '', tela, sCampoChave, true, 'RELANIVERSARIO_PDF', anexos, retornoMsgPersonalizadaWpp[i].enviaCaption);
                }

                // if (anexosMensagemPersonalizada.length > 0) {
                //     for (let k = 0; k < anexosMensagemPersonalizada.length; k++) {
                //         const terminologiaBase64 = retornaTerminologiaBase64(anexosMensagemPersonalizada[k].arquivo);
                //         await enviarMensagem(retornoMsgPersonalizadaWpp[i].celular, terminologiaBase64 + anexosMensagemPersonalizada[k].base64, true, false);
                //     };
                // };

            };
        }

        if (listaNaoEnviados.length > 0) {
            let mensagemErros = `Não foi possível enviar a mensagem para os seguintes clientes, número inválido ou não cadastrado. Deseja reenviar? `;
            listaNaoEnviados.forEach(naoEnviados => {
                mensagemErros += `\n${naoEnviados}`;
            });
            msgAlerta(mensagemErros,
                callBackNaoEnviados,
                undefined,
                undefined,
                undefined,
                true);
        }

        return listaNaoEnviados;

    } catch (error) {
        console.error(error);
    }

}

function salvarFiltrosCache(keyCache, campos) {
    try {
        let filtros = {};

        campos.forEach(function (campo) {
            if ($('#' + campo).hasClass('form-check-input')) {
                filtros[campo] = isChecked('#' + campo);
            }
            else if ($('#' + campo).attr('type') == 'checkbox') {
                filtros[campo] = $('#' + campo).prop('checked');
            }
            else {
                filtros[campo] = $('#' + campo).val();
            }
        });

        localStorage.setItem(keyCache, JSON.stringify(filtros));
    } catch (error) {
        console.log(error);
    }
}

async function restaurarFiltrosCache(keyCache, campos) {
    try {
        let filtrosSalvos = localStorage.getItem(keyCache);
        if (filtrosSalvos) {
            filtrosSalvos = JSON.parse(filtrosSalvos);

            campos.forEach(function (campo) {
                if ($('#' + campo).hasClass('js-states')) {
                    if (filtrosSalvos[campo] && filtrosSalvos[campo].length > 0) {
                        const valores = Array.isArray(filtrosSalvos[campo]) ? filtrosSalvos[campo] : [filtrosSalvos[campo]];

                        $('#' + campo).empty();

                        valores.forEach(item => {
                            const newOption = new Option(`[${item}] - ${item}`, item, true, true);
                            $('#' + campo).append(newOption);
                        });

                        $('#' + campo).val(valores).trigger('change');

                        setTimeout(() => {
                            $('#' + campo).val(valores).trigger('change');
                            $('.select2-search__field').attr('placeholder', $traducaoSelecioneOsRegistros[['I', 'E', 'M'].includes(getCookie('idiomaUsuario')) ? getCookie('idiomaUsuario') : 'P']);

                        }, 10);
                    }
                } else {
                    if ($('#' + campo).hasClass('form-check-input') || $('#' + campo).attr('type') === 'checkbox') {
                        $('#' + campo).prop('checked', filtrosSalvos[campo]);
                    } else {
                        $('#' + campo).val(filtrosSalvos[campo]);
                    }
                }
            });
        }
    } catch (error) {
        console.log(error);
    }
}

function limparFiltrosCache(keyCache) {
    try {
        localStorage.removeItem(keyCache);
    } catch (error) {
        console.log(error);
    }
}

function replaceVarios(texto, listaCaracteres, valorSubstituicao) {
    listaCaracteres.forEach(caractere => {
        texto = texto.replace(caractere, valorSubstituicao);
    });

    return texto;

}

$('#btnInfoRelatorio').on('click', function () {
    $('#btnInfoRelatorio').css('color', 'rgb(255, 255, 0)');
    $('#modalInfoRelatorio').on('hide.bs.modal', function () {
        $('#btnInfoRelatorio').css('color', 'rgb(255, 255, 255)');
    });

    $('#btnFecharInfo').on('click', function () {
        $('#modalInfoRelatorio').modal('hide');
    });
    $('#modalInfoRelatorio').modal('show');
});

function adicionarConteudoModal(titulo, conteudoArray) {
    $('#tituloModal').text(titulo);

    $('.formCardInfo').empty();

    $.each(conteudoArray, function (index, item) {
        if (item.tipo === 'paragrafo') {
            $('<p>').text(item.valor).appendTo('.formCardInfo');
        } else if (item.tipo === 'lista') {
            var ul = $('<ul>');
            $.each(item.itens, function (index, subItem) {
                $('<li>').text(subItem).appendTo(ul);
            });
            ul.appendTo('.formCardInfo');
        }
    });
};

function adicionaOrdenacao(campo, array) {

    let aEx;
    let tipoOrd;

    if (array.length == 0) {
        array.push(campo + ' ASC');
    } else {
        aEx = (array[0].substring(0, array[0].indexOf(' '))).toUpperCase() == campo;
        tipoOrd = array[0].substring(array[0].indexOf(' ') + 1, array[0].length);

        array = array.filter(function (e) {
            return e.substring(0, e.indexOf(' ')) != campo;
        });

        if (aEx) {
            tipoOrd = tipoOrd.toUpperCase() == 'ASC' ? 'DESC' : 'ASC';
        } else {
            tipoOrd = 'ASC';
        }

        array.unshift(campo + ' ' + tipoOrd);
    }

    return array;
}

function retornaDataSrcColuna(tabela, inst) {
    return tabela.DataTable().column(inst[0].attributes['data-column-index'].value).dataSrc();
};

async function enviaBasedeDados(bPasso1 = true, sTipoBanco = 0) {
    try {
        $.LoadingOverlay('show');
        const senhaSisplan = $('#txtSenhaEnvioBD').val();
        const senhaCriptografada = encodeURIComponent(senhaSisplan);
        $('#txtSenhaEnvioBD').val('');
        if (bPasso1) {
            const response = await requisicao('POST', '/sisplan/enviabd/v1/enviabdprasisplan?', '', `TIPO_BANCO=${sTipoBanco}&CODIGO_USUARIO=${getCookie('cod_usuario')}&SENHA_USUARIO=${senhaCriptografada}&PASSO=${1}`, null);
            if (!response) {
                msgErro('Não foi possível fazer o envio da base dados. Tente novamente!');
                return;
            };
            const jsonStr = await response.json();
            if (jsonStr.mensagem.indexOf('Empresa libera envio de bancos somente nos seguintes horários') != -1) {
                msgAlerta(jsonStr.mensagem, () => { enviaBasedeDados(false); });
                return;
            };
            if (response.status == 200) {
                msgSucesso(jsonStr.mensagem);
                return;
            };
            if (response.status == 400 || response.status == 404) {
                msgErro(jsonStr.mensagem);
                return;
            };
            msgAlerta(jsonStr.mensagem);
        };
        if (!bPasso1) {
            const responseSegundaTentativa = await requisicao('POST', '/sisplan/enviabd/v1/enviabdprasisplan?', '', `CODIGO_USUARIO=${getCookie('cod_usuario')}&SENHA_USUARIO=${senhaCriptografada}&PASSO=${2}`, null);
            if (!responseSegundaTentativa) {
                msgErro('Não foi possível fazer o envio da base de dados. Tente novamente!');
                return;
            };
            const jsonStrSegundaTentativa = await responseSegundaTentativa.json();
            if (responseSegundaTentativa.status == 200) {
                msgSucesso(jsonStrSegundaTentativa.mensagem);
                return;
            };
            if (responseSegundaTentativa.status == 400 || responseSegundaTentativa.status == 404) {
                msgErro(jsonStrSegundaTentativa.mensagem);
                return;
            };
            msgAlerta(jsonStrSegundaTentativa.mensagem);
        };

    } catch (error) {
        console.error(error);
        msgErro('Não foi possível fazer o envio da base dados. Tente novamente!');
        return;
    } finally {
        $.LoadingOverlay('hide');
        if ($('#modal-senhaenviadb').hasClass('show')) {
            $('#modal-senhaenviadb').modal('hide');
        }
    }
};

async function alterarBloqueioCliente(codCli, bloquear, tela, mostraMsg = true) { //desbloquearCliente
    try {
        const response = await requisicao('PUT', '/sisplan/cliente/v1/alterarbloqueiocliente?', `CLIENTE=${codCli}&BLOQUEAR=${bloquear ? "S" : "N"}&TELA=${tela}`);

        if (!response) {
            return;
        }

        if (response.status != 200) {
            jsonEntidade['RESULT'][0].mensagem;
            return;
        }

        if (mostraMsg) {
            await criaMensagemSucesso(`Cliente ${bloquear ? "bloqueado" : "desbloqueado"} com sucesso!`);
        }

    } catch (error) {
        console.log(error);
    }
}

async function uMasterOuSupervisor() {
    try {
        const usuario = await retornaJsonPesquisaPadrao(`{"tabela": "ACESSO_USUARIOS", "camposSelect": ["TIPO"], "WHERE": ["CODIGO = '${getCookie('cod_usuario')}'"] }`) ?? 0;

        return usuario[0].TIPO != 0;

    } catch (error) {
        console.error(error);
    }
}

async function buscaDepositoUltimoMovimento(sRepresentante) {
    try {
        let response = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={ 
                                        "tabela":"PA_MOV", 
                                        "camposSelect":["PA_MOV.DEPOSITO", "DEPOSITO.DESCRICAO", "PA_MOV.REGIAO", "REG_ESTADO.DESCRICAO DESC_REGIAO"], 
                                        "leftjoin": [
                                            { "tabela" : "DEPOSITO", "condicao" : "DEPOSITO.CODIGO = PA_MOV.DEPOSITO" },
                                            { "tabela" : "REG_ESTADO", "condicao" : "REG_ESTADO.CODIGO = PA_MOV.REGIAO"}
                                        ],
                                        "where": ["PA_MOV.REPRESENTANTE = '${sRepresentante}'", "PA_MOV.OPERACAO = 'E'"],
                                        "orderBy": ["PA_MOV.HORA DESC"],
                                        "limit": 10
                                      }`, null);

        if (!response) {
            return;
        }

        const jsonStr = await response.json();
        if (response.status !== 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return [];
        }

        if (jsonStr.RESULT[0].length > 0) {
            return jsonStr.RESULT[0][0];
        } else {
            return {
                DEPOSITO: '',
                DESCRICAO: '',
                REGIAO: '',
                DESC_REGIAO: ''
            };
        }
    } catch (error) {
        console.log(error);
    }
}

async function barraDeProgresso(indice, total) {

    if (total == 0) {
        return;
    }

    const p = Math.round((indice / total) * 100);

    $('.loadingoverlay').html(`
    <div class="mt-auto p-0 m-0" style="text-align: center; color:black; transform: translateY(20px)">${p}%</div>
    <div style="height: 20px; overflow: hidden; width: 100%; background-color: gray;">
        <div style="z-index: 99;width: ${p}%; height: 100%; background-color: #8ce62c;">
    </div>
    </div>`);

}

async function Existe(tabela, arrayCampos, arrayValores) {
    try {
        let where = '1=1';

        for (let i = 0; i < arrayCampos.length; i++) {
            where += ` AND ${tabela}.${arrayCampos[i]} = '${arrayValores[i]}'`;
        }

        let response = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={
                "tabela":"${tabela}", 
                "camposSelect":["*"],
                "where": ["${where}"],
                "limit": 1
                }`, null);

        if (!response) {
            return false;
        }

        const jsonStr = await response.json();
        if (response.status !== 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return false;
        }

        if (jsonStr.RESULT[0].length > 0) {
            return true;
        } else {
            return false;
        }

    } catch (e) {
        console.log(e);
        return false;
    }
}

async function buscaCaminho(tabela, camposSelect, camposWhere, valores) {
    try {
        let where = [];

        const campos = camposSelect.map((e) => {
            return `REPLACE(${e}, '[BARRA]', 'DEEP_WEB') ${e}`;
        });

        for (let i = 0; i < camposWhere.length; i++) {
            where.push(`${camposWhere[i]} = '${valores[i]}'`);
        }

        const select = {
            tabela: `${tabela}`,
            camposSelect: campos,
            where: where
        };

        const url = "/sisplan/funcoes/v1/buscacaminho?";
        const params = `JSON=${encodeURIComponent(JSON.stringify(select))}`;

        const response = await requisicao("GET", url, params);

        if (!response) {
            return;
        }

        const jsonPesquisa = await response.json();
        if (response.status != 200) {
            msgErro(jsonPesquisa.RESULT[0].mensagem);
            return;
        }

        if (jsonPesquisa.RESULT[0].length == 0) {
            return;
        }

        const result = camposSelect.map(e => {
            return jsonPesquisa.RESULT[0][0][e].replaceAll('DEEP_WEB', '\\');
        });

        return result;

    } catch (e) {
        console.log(e);
    }
}

function insert(char, string, pos) {

    if (string == undefined || string == null) { return ''; }
    try {
        pos -= 1;
        return string.substr(0, pos) + char + string.substr(pos);
    } catch (e) {
        console.log(e);
    }

}

function validaData(data) {
    try {
        const pattern = /^(\d{2})\/(\d{2})\/(\d{4})$/;
        const match = data.match(pattern);

        if (!match) {
            return false;
        }

        const day = parseInt(match[1], 10);
        const month = parseInt(match[2], 10);
        const year = parseInt(match[3], 10);

        const date = new Date(year, month - 1, day);

        return (
            date.getDate() === day &&
            date.getMonth() === month - 1 &&
            date.getFullYear() === year
        );
    } catch (e) {

    }
}
async function msgModalAguardaConfirmacao($mensagem, $callback, $callbackCancelar, $callbackOk, $callbackClose) {

    new Promise((resolve) => {
        const continueButton = document.getElementById("continueButton");
        continueButton.addEventListener("click", () => {
            modal.style.display = "none";
            resolve(); // Resolve the promise to continue the loop
        });
    });

    $("#modal-warning-titulo").html("Atenção");
    $('#btn-msg-alerta').html('Confirmar (ALT + S)');
    $("#modal-warning-conteudo").val($mensagem);

    $("#modal-warning").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    $("#btn-msg-alerta").on("click", async function () {
        $("#modal-warning").modal("hide");
        await sleep(500);
        if ($callback != undefined) {
            $callback();
        }
    });

    if ($callback != undefined && $callbackCancelar != undefined) {
        $("#btn-msg-cancelar").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackCancelar();
        });
    }
    if ($callbackOk != undefined) {
        $("#btn-msg-alerta").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackOk();
        });
    }
    if ($callbackClose != undefined) {
        $("#btn-warning-close").on("click", async function () {
            $("#modal-warning").modal("hide");
            await sleep(500);
            $callbackClose();
        });
    }
    $("#modal-warning").click();
    $("#modal-warning").focus();
}

async function abrirModalOpcoesImpressao(callback) {
    return new Promise((resolve) => {
        $('#btnImprimirModalImpressao').prop('disabled', false).html('<i class="fas fa-print"></i> Imprimir');

        const $modal = $("#modal-opcoes-impressao");

        function finalizar() {
            $modal.off('hidden.bs.modal', finalizar);
            resolve();
        }

        $modal.modal({
            backdrop: "static",
            keyboard: true,
            show: true,
        });

        $('#btnImprimirModalImpressao')
            .off('click')
            .on('click', async function () {
                if (typeof callback === 'function') {
                    $('#btnImprimirModalImpressao').prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-2"></span>Imprimindo...');
                    await callback();
                }
                $modal.modal('hide');
            });

        $modal.off('hidden.bs.modal').on('hidden.bs.modal', finalizar);
    });
}

async function msgAguardaConfirmacao(mensagem, callBackSim, callBackNao, atalhosConfirmar = false, bEscondeNao = false, sMudaNomeBotaoSim = '') {
    $("#modal-warning-titulo").html("Atenção");
    $("#modal-warning-conteudo").val(mensagem);
    $("#modal-warning").attr("atalhosConfirmar", atalhosConfirmar);

    $("#modal-warning-rodape").html(
        `<button id="btn-msg-alerta" type="button" class="btn bg-gradient-success btn-sisp">${sMudaNomeBotaoSim == '' ? 'Sim' : sMudaNomeBotaoSim} <small>(ALT + S)</small></button>` +
        `<button type="button" id="btn-msg-cancelar" class="btn bg-gradient-danger btn-sisp ${bEscondeNao ? 'd-none' : ''}" data-dismiss="modal">Não <small>(ALT + N)</small></button>`
    );

    $("#modal-warning").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    const promessa = new Promise((resolve, reject) => {
        async function clicouSim() {
            try {
                $("#modal-warning").modal("hide");
                await sleep(500);
                await callBackSim();
                resolve(true);
            } catch (error) {
                msgAlerta(error.message);
                reject(error);
            }
        }

        async function clicouNao() {
            try {
                $("#modal-warning").modal("hide");
                await sleep(500);
                await callBackNao();
                resolve(false);
            } catch (error) {
                msgAlerta(error.message);
                reject(error);
            }
        }

        if (callBackSim != undefined) {
            $("#btn-msg-alerta").on("click", async function () {
                await clicouSim();
            });
        }

        if (callBackNao != undefined) {
            $("#btn-msg-cancelar").on("click", async function () {
                await clicouNao();
            });
        }

        $("#btn-warning-close").off("click").on("click", async function () {
            reject();
        });
    });

    return promessa;
}

async function msgAguardaSelecionar(titulo, label, callBackConfirmar, callBackDesistir, table) {
    $("#modal-titulo-Selecionar").text(titulo);
    $("#label-Selecionar").text(label);

    $("#modalSelecionar").modal({
        backdrop: "static",
        keyboard: true,
        show: true,
    });

    if (!$.fn.DataTable.isDataTable('#tabelaSelecionar')) {
        const dataSetCols = [];
        const keys = Object.keys(table[0]);
        keys.forEach((item) => {
            dataSetCols.push({ 'title': item, 'data': item });
        });
        $("#divTableSelecionar").html('<table style="width:100%" width="100%" cellpadding="0" cellspacing="0" border="0" class="table table-select table-hover table-sm table-condensed" id="tabelaSelecionar" ></table>');
        //cria a tabela usando os dados e colunas
        var table = $('#tabelaSelecionar').dataTable({
            destroy: true,
            keys: true,
            autoWidth: true,
            order: [],
            "data": table,
            "columns": dataSetCols,
        });

        $("body").keydown(function (e) {
            const qtdeLinhas = $("#tabelaSelecionar tbody tr").length;
            if (e.which === 80 && e.altKey) {
                e.preventDefault();
                $("input[type='search']").focus();
            }
            if (e.which === 13 && qtdeLinhas === 1) {
                $("#tabelaSelecionar tbody tr td")[0].click();
                table.$('tr.selected').removeClass('selected');
            }
        });

        // desenha a seleção do registro clicaco
        $('#tabelaSelecionar tbody').on('click', 'tr', function () {
            if ($(this).hasClass('selected')) {
                $(this).removeClass('selected');
            } else {
                table.$('tr.selected').removeClass('selected');
                $(this).addClass('selected');
            }
        });
    } else {
        let tabelaSelecionar = $('#tabelaSelecionar').DataTable();
        tabelaSelecionar.clear().draw();
        tabelaSelecionar.rows.add(table).draw();
    }

    const promessa = new Promise((resolve, reject) => {
        async function clicouConfirmar() {
            try {
                $("#modalSelecionar").modal("hide");
                await sleep(500);
                await callBackConfirmar();
                resolve(true);
            } catch (error) {
                msgAlerta(error.message);
                reject(error.message);
            }
        }

        async function clicouDesistir() {
            try {
                $("#modalSelecionar").modal("hide");
                await sleep(500);
                await callBackDesistir();
                resolve(false);
            } catch (error) {
                msgAlerta(error.message);
                reject(error.message);
            }
        }

        $("#btnConfirmaSelecionar").off("click");
        $("#btnDesistirSelecionar").off("click");
        $("#btn-selecionar-close").off("click");

        if (callBackConfirmar != undefined) {
            $("#btnConfirmaSelecionar").on("click", async function () {
                await clicouConfirmar();
            });
        }

        if (callBackDesistir != undefined) {
            $("#btnDesistirSelecionar").on("click", async function () {
                await clicouDesistir();
            });
        }

        $("#btn-selecionar-close").on("click", async function () {
            reject();
        });
    });

    return promessa;
}

async function enviaWhatsAppPix(codCli, nomeCliente, celular, pixCopiaCola, tela) {
    const objMsgWpp = [];
    try {
        const parametrosMensagem = [`CODCLI: ${codCli}`, `EMP_ID: ${getCookie("emp_id")}`];

        objMsgWpp.push({
            CELULAR: celular,
            NOME: nomeCliente,
            PARAMETROSMENSAGEM: parametrosMensagem.toString(),
            MENSAGEMPERSONALIZADA: pixCopiaCola
        });

        await enviarMsgPersonalizadaWpp(tela,
            objMsgWpp,
            undefined,
            async () => {
                await sleep(500);
                $("#btnWppPix").trigger("click");
            },
            'Pix'
        );
    } catch (error) {
        console.log(error);
    }
}

async function buscaLimiteUtilizadoCliente(codCli) {
    try {
        let valorVenda = 0;
        let valorConsig = 0;

        let responseConsig = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={ 
                "tabela":"VENDA", 
                "camposSelect":["SUM(VENDA.VALOR) VALOR"], 
                "innerjoin": [
                    { "tabela" : "VENDA_TIPO", "condicao" : "VENDA_TIPO.ID = VENDA.TIPO_VENDA"}
                ],
                "where": ["VENDA.CODCLI = '${codCli}' AND VENDA.CANCELADA = 0 AND VENDA.FECHADA = 0 AND VENDA.TROCA = 0 AND VENDA.DEVOLUCAO = 0 AND VENDA.ORCAMENTO = 0"]
            }`, null
        );

        if (responseConsig) {
            const jsonStrConsig = await responseConsig.json();
            if (responseConsig.status !== 200) {
                console.log(jsonStrConsig.RESULT[0].mensagem);
            } else {
                if (jsonStrConsig.RESULT[0].length > 0) {
                    valorConsig += jsonStrConsig.RESULT[0][0].VALOR;
                }
            }
        }


        let response = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={ 
                "tabela":"RECEBER", 
                "camposSelect":["VENDA_TIPO.CONSIGNADO, SUM(RECEBER.VALOR2 [SOMA] RECEBER.JUROS - RECEBER.VALOR_PAGO - RECEBER.VAL_DEV - RECEBER.DESCONTO) VALOR"], 
                "innerjoin": [
                    { "tabela" : "VENDA", "condicao" : "VENDA.CODCLI = RECEBER.CODCLI AND VENDA.CODVEN = RECEBER.NRO_CUPOM AND VENDA.EMP_ID = RECEBER.EMP_ID" },
                    { "tabela" : "VENDA_TIPO", "condicao" : "VENDA_TIPO.ID = VENDA.TIPO_VENDA"}
                ],
                "where": ["RECEBER.CODCLI = '${codCli}' AND RECEBER.STATUS = 'DUPL'"],
                "groupBy": ["VENDA_TIPO.CONSIGNADO"]
            }`, null
        );

        if (response) {
            const jsonStr = await response.json();
            if (response.status !== 200) {
                console.log(jsonStr.RESULT[0].mensagem);
            } else {
                if (jsonStr.RESULT[0].length > 0) {
                    jsonStr.RESULT[0].forEach(item => {
                        if (item.CONSIGNADO == 'S') {
                            // valorConsig += item.VALOR; // comentado pois será validado apenas o valor de consignado pendente
                        } else {
                            valorVenda += item.VALOR;
                        }
                    });
                }
            }
        }

        $("#txtLimiteFidelidadeUsado").val(valorVenda);
        $("#txtLimiteUsado").val(valorConsig);

    } catch (error) {
        console.log(error);
    }
}

async function recalCredCliente(sCodCli, bControlaLimite) {
    try {
        if (bControlaLimite) {
            const url = '/sisplan/cliente/v1/recalclimitcred?';
            const response = await requisicao('POST', url, `CODCLI=${sCodCli}`, null, 30000);
            if ((!response) || (response.status != 200)) {
                return;
            }

            if (response.status != 200) {
                return;
            }
        }
    } catch (error) {
        console.error(error);
    }
}

async function retornaMoedasEmpresa() {
    let empId = getCookie('emp_id');
    let url = `/Sisplan/Funcoes/v1/pesquisa?`;
    let params = `JSON={ "tabela":"empresa", "camposSelect":["emp_moeda"],
                          "where": ["emp_id = ${empId}"]}`;
    try {
        let response = await requisicao('GET', url, params, null, 20000);

        if (!response) {
            return [];
        }

        if (response.status != 200) {
            msgErro(jsonStr['RESULT'][0].mensagem);
            return [];
        }

        let jsonStr = await response.json();
        if (!$.isEmptyObject(jsonStr.RESULT[0])) {
            const retorno = jsonStr.RESULT[0][0].EMP_MOEDA;
            if (retorno == '') {
                return [];
            }
            const moedas = retorno.split(',').map((item) => {
                return parseInt(item.replace("'", '').replace("'", ''));
            });
            return moedas;
        } else {
            return [];
        }
    } catch (error) {
        console.error(error);
        msgErro('Erro ao buscar moedas vinculadas a empresa.');
        return [];
    }
}

function parseDouble(valor) {
    if (typeof valor !== 'string') {
        return valor;
    }
    valor = valor.toString();
    var newValor = valor.replace(/\./g, '').replace(',', '.');

    return parseFloat(newValor);
}

function isEmpty(component) {
    //criei essa função com intuito de otimizar a validação de diversos componentes
    if (component.hasClass('table')) {
        let table = component.DataTable();
        let camposSelecionados = table.rows().data().$(`.campoSelecionado`).toArray().filter((campoSel) => $(campoSel).prop('checked'));
        if (camposSelecionados == 0 && table.rows().data() > 0) {
            return true;
        }
    }
    if (!component.val()) {
        return true;
    }

    //por padrão retorna false caso não caia em nenhuma das condições acima
    return false;
}

function removeCaracteres(texto) {
    // const numeros = texto.replace(/[^0-9]/g, '');
    // return numeros;
    const removeCifrao = texto.replace(/"/g, '').replace(/R\$/g, '').replace(' ', '');
    const valorFinal = removeCifrao.replace(/,/g, '.');
    return valorFinal;
}


function formataDateTimeTZ(dateString) {
    const parts = dateString.split(' ');
    const datePart = parts[0].split('/');
    const timePart = parts[1];
    let dia = datePart[0];
    let mes = datePart[1];
    let ano = datePart[2];

    const formattedDateString = `${ano}-${mes}-${dia}T${timePart}Z`;

    return formattedDateString;
}

function criptografaUrl(sJson) {
    return btoa(sJson).replaceAll('/', '[BARRA]');
}

function descriptografaUrl(sJson) {
    return atob(sJson.replaceAll('[BARRA]', '/'));
}


async function buscaVendedorUsuario() {
    try {
        let response = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={ 
                                        "tabela":"ACESSO_USUARIOS", 
                                        "camposSelect":["ACESSO_USUARIOS.CODREP", "REPRESEN.NOME"], 
                                        "leftjoin": [{ "tabela" : "REPRESEN", "condicao" : "REPRESEN.CODREP = ACESSO_USUARIOS.CODREP" }],
                                        "where": ["ACESSO_USUARIOS.CODIGO = '${getCookie('cod_usuario')}'"]
                                      }`, null);

        if (!response) {
            return;
        }

        const jsonStr = await response.json();
        if (response.status !== 200) {
            msgErro(jsonStr.RESULT[0].mensagem);
            return [];
        }
        if (jsonStr.RESULT[0].length > 0) {
            return jsonStr.RESULT[0][0];
        } else {
            return {
                CODREP: '',
                NOME: ''
            };
        }
    } catch (error) {
        console.log(error);
    }
}

async function testeConexaoApiLocal() {
    try {

        const porta = getCookie('porta_api_local');

        if (porta == '') {
            return false;
        }

        const response = await requisicao_ecf('GET', '/conexao/conexao?', ``, 1000);

        if (!response) {
            return false;
        }
        if (response.status == 200) {
            return true;
        }
    } catch (error) {
        console.error(error);
        return false;
    }
}

async function validaStatusAPI() {
    try {
        const response = await requisicao('GET', '/statusapi?', ``, 1000);

        if (!response) {
            return {
                atualizando: false,
                iniciando: false,
            };
        }

        if (response.status == 200) {
            const model = await response.json();
            return model;
        }
    } catch (error) {
        console.error(error);
        return {
            atualizando: false,
            iniciando: false,
        };
    }
}

function criaRichText(id, options = undefined) {

    // const fontSizeArr = ['16px', '18px', '20px', '22px', '24px', '28px', '32px', '36px', '40px', '44px', '48px', '52px', '26px', '72px', '84px', '144px'];

    // let Size = Quill.import('attributors/style/size');
    // Size.whitelist = fontSizeArr;
    // Quill.register(Size, true);

    let p = {
        theme: 'snow',
        modules: {
            toolbar: [
                [{ 'font': [''] }],
                [{ 'header': [1, 2, 3, 4, 5, 6, false,] }],
                // [{ 'size': fontSizeArr }],
                ['bold', 'italic', 'underline', 'strike'],
                [{ 'align': [] }],
                [{ 'list': 'bullet' }, { 'list': 'ordered' }],
                [{ 'color': [] }, { 'background': [] }],
                ['clean']
            ]
        }
    };

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

    try {
        let quill = new Quill(id, p);

        $('.ql-picker-options').addClass('scrollable');

        $('.ql-size .ql-picker-options .ql-picker-item').map(function () {
            $(this).attr('tam-fonte', parseInt($(this).attr('data-value').replace('px', '')) / 2);
        });

        // $($('.ql-size .ql-picker-label')[0]).attr('tam-fonte', parseInt($($('.ql-size .ql-picker-label')[0]).attr('data-value').replace('px', '')) / 2);

        $('.ql-size .ql-picker-options .ql-picker-item').on('click', function () {
            $($('.ql-size .ql-picker-label')[0]).attr('tam-fonte', parseInt($(this).attr('data-value').replace('px', '')) / 2);
        });

    } catch (e) {
        console.log(`Erro ao criar rich text: ${e}`);
    }
}

function formataHtml(html) {

    if (!html) {
        return '';
    }

    html = html.replace(/(style\s*=\s*)([^>]*?)(\s*>)/ig, function (match, p1, p2, p3) {
        return `${p1}"${p2}"${p3}`;
    });

    html = html.replace(/(class\s*=\s*)([^>]*?)(\s*>)/ig, function (match, p1, p2, p3) {
        return `${p1}"${p2}"${p3}`;
    });

    return html;
}

function removeFormatacao(html) {
    let tempElement = document.createElement('div');
    tempElement.innerHTML = html;

    let elementsWithTags = tempElement.querySelectorAll('*');
    elementsWithTags.forEach(function (element) {
        element.outerHTML = element.innerHTML;
    });

    return tempElement.textContent;
}

function retornaHintRelatorio(btnImprimir, nomeRelatorio) {
    getCookie('cod_usuario') == '0000' ? $(`#${btnImprimir}`).prop('title', `Este botão chama o Layout ${nomeRelatorio}.FR3`) : null;
}

async function componenteTipoClassificacao() {
    const pesquisaAutoCompleta = {
        ... {
            tabela: 'CAD_TP_CLAS',
            camposSelect: ['CAD_TP_CLAS.ID ID', 'CAD_TP_CLAS.TIPO TIPO', 'TIPO_TING.DESCRICAO DESC_TIPO', 'CAD_TP_CLAS.CLASSIFICACAO CLASSIFICACAO', 'CAD_LINHA.DESCRICAO DESC_CLASSIFICACAO'],
            camposSelectSubSelect: ['ID', 'TIPO', 'DESC_TIPO', 'CLASSIFICACAO', 'DESC_CLASSIFICACAO'],
            leftjoin: [{
                tabela: 'TIPO_TING', condicao: 'CAD_TP_CLAS.TIPO = TIPO_TING.CODIGO'
            }, {
                tabela: 'CAD_LINHA', condicao: 'CAD_TP_CLAS.CLASSIFICACAO = CAD_LINHA.CODIGO'
            }],
            groupBy: ['CAD_TP_CLAS.ID', 'CAD_TP_CLAS.TIPO', 'TIPO_TING.DESCRICAO', 'CAD_TP_CLAS.CLASSIFICACAO', 'CAD_LINHA.DESCRICAO'],
            groupBySubSelect: ['ID', 'TIPO', 'DESC_TIPO', 'CLASSIFICACAO', 'DESC_CLASSIFICACAO'],
            camposWhereServerSide: ['CAD_TP_CLAS.ID', 'CAD_TP_CLAS.TIPO', 'TIPO_TING.DESCRICAO', 'CAD_TP_CLAS.CLASSIFICACAO', 'CAD_LINHA.DESCRICAO']
        }, camposSelect: ['CAD_TP_CLAS.ID ID', 'CAD_TP_CLAS.TIPO TIPO', 'TIPO_TING.DESCRICAO DESC_TIPO', 'CAD_TP_CLAS.CLASSIFICACAO CLASSIFICACAO', 'CAD_LINHA.DESCRICAO DESC_CLASSIFICACAO']
    };

    const pesquisaSel = {
        tabela: 'CAD_TP_CLAS',
        camposSelect: ['CAD_TP_CLAS.ID ID', 'CAD_TP_CLAS.TIPO TIPO', 'TIPO_TING.DESCRICAO DESC_TIPO', 'CAD_TP_CLAS.CLASSIFICACAO CLASSIFICACAO', 'CAD_LINHA.DESCRICAO DESC_CLASSIFICACAO'],
        camposSelectSubSelect: ['SEL', 'ID', 'TIPO', 'DESC_TIPO', 'CLASSIFICACAO', 'DESC_CLASSIFICACAO'],
        leftjoin: [{
            tabela: 'TIPO_TING', condicao: 'CAD_TP_CLAS.TIPO = TIPO_TING.CODIGO'
        }, {
            tabela: 'CAD_LINHA', condicao: 'CAD_TP_CLAS.CLASSIFICACAO = CAD_LINHA.CODIGO'
        }],
        groupBy: ['CAD_TP_CLAS.ID', 'CAD_TP_CLAS.TIPO', 'TIPO_TING.DESCRICAO', 'CAD_TP_CLAS.CLASSIFICACAO', 'CAD_LINHA.DESCRICAO'],
        groupBySubSelect: ['ID', 'TIPO', 'DESC_TIPO', 'CLASSIFICACAO', 'DESC_CLASSIFICACAO'],
        camposWhereServerSide: ['CAD_TP_CLAS.ID', 'CAD_TP_CLAS.TIPO', 'TIPO_TING.DESCRICAO', 'CAD_TP_CLAS.CLASSIFICACAO', 'CAD_LINHA.DESCRICAO']
    };

    $('#txtProdClasTipo').pesquisa_variosServerside(1, `${JSON.stringify(pesquisaAutoCompleta)}`, 'ID', 'TIPO');
    $('#btnProdClasTipo').pesquisa_serversideSel('#txtProdClasTipo', `${JSON.stringify(pesquisaSel)}`, 'Pesquisa Tipo e Classificação');
    $('#btnLimpaProdClasTipo').on('click', function () {
        $('#txtProdClasTipo').empty();
        $('#txtProdClasTipo').trigger('change');
    });
}

async function InformaSeCaixaJaEstaFechado(callback) {
    try {
        const caixa = pegaChave(sessionStorage.getItem('g_caixa_logado'));

        if ((!caixa) || (caixa == '')) {
            msgAlerta('Necessário selecionar um caixa.');
            return false;
        }

        let idCaixa = 0;

        if (await CopiaParametro('VENDA', 83) == '1') {
            idCaixa = await buscaValor('CAIXA_F', 'MAX(ID) ID', 'NRCAIXA', `${caixa}' AND EMP_ID = '${getCookie('emp_id')}`);
        }

        const response = await requisicao('GET', '/sisplan/vendas/v1/informasecaixaestafechado?', `CAIXA=${caixa}&ID_CAIXA=${idCaixa?.ID}`, '', 90000);

        if (!response) {
            return false;
        }

        if (response.status != 200) {
            const jsonStr = await response.json();
            msgAlerta(jsonStr.mensagem);
            return false;
        }
        const mensagem = await response.text();
        if ((mensagem != '') && (mensagem != 'false')) {
            msgAlerta(`Caixa ${caixa} já está fechado, deseja prosseguir?`, callback, async () => {

            });
            return false;
        }
        // mensagem = false significa que o caixa do dia atual não está fechado...
        return mensagem == 'false';
    } catch (error) {
        console.error(error);
        msgAlerta('Erro ao verificar caixas em aberto');
        return false;
    }
}

async function VerificaERetornaDataCaixaEmAberto() {
    try {
        const bloqueiaSeCaixaEmAberto = await CopiaParametro('VENDA', 86) ?? 0;
        const caixa = pegaChave(sessionStorage.getItem('g_caixa_logado'));
        const caixaInformadoValorCorreto = sessionStorage.getItem('g_caixa_logado').indexOf('[') >= 0;

        if ((!caixa) || (caixa == '') || (!caixaInformadoValorCorreto)) {
            msgAlerta('Necessário selecionar um caixa.');
            return false;
        }

        if (bloqueiaSeCaixaEmAberto != '1') {
            return true;
        }

        const response = await requisicao('GET', '/Sisplan/Vendas/V1/retornadiacaixaemaberto?', `NRCAIXA=${caixa}`, '', 90000);

        if (!response) {
            return false;
        }

        if (response.status != 200) {
            const jsonStr = await response.json();
            msgAlerta(jsonStr.mensagem);
            return false;
        }
        const mensagem = await response.text();
        if (mensagem != '') {
            msgAlerta(mensagem);
        }
        return mensagem == '';
    } catch (error) {
        console.error(error);
        msgAlerta('Erro ao verificar caixas em aberto');
        return false;
    }
}

async function retornaAnexoMsgPersonalizada(tela) {
    try {
        const url = "/sisplan/config_whatsapp/v1/consultaranexosmensagem?";

        const response = await requisicao("GET", url, `TELA=${tela}`, "", 300000);

        if (!response) {
            throw new Error("Não foi possível consultar os anexos.");
        }

        const json = await response.json();

        if (response.status != 200) {
            throw new Error(json.mensagem);
        }

        return json;

    } catch (error) {
        msgAlerta(error.message);
        console.error(error);
    }
}

function retornaTerminologiaBase64(nomeArquivo) {
    const tipoArquivo = retornaTipoArquivo(nomeArquivo);
    let terminologiaBase64 = "";
    switch (tipoArquivo.toLowerCase()) {
        case ".png":
            terminologiaBase64 = "data:image/png;base64,";
            break;
        case ".jpg":
            terminologiaBase64 = "data:image/jpeg;base64,";
            break;
        case ".jpeg":
            terminologiaBase64 = "data:image/jpeg;base64,";
            break;
        case ".mp4":
            terminologiaBase64 = "data:video/mp4;base64,";
            break;
        case ".pdf":
            terminologiaBase64 = "data:application/pdf;base64,";
            break;
        case ".doc":
            terminologiaBase64 = "data:application/msword;base64,";
            break;
        case ".docx":
            terminologiaBase64 = "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,";
            break;
        case ".xlsx":
            terminologiaBase64 = "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,";
            break;
        case ".xls":
            terminologiaBase64 = "data:application/vnd.ms-excel;base64,";
            break;
        case ".gif":
            terminologiaBase64 = "data:image/gif;base64,";
            break;
        case ".txt":
            terminologiaBase64 = "data:text/plain;base64,";
            break;
        default:
            break;

    }
    return terminologiaBase64;
}

function retornaTipoArquivo(nomeArquivo) {
    const tipoArquivo = "." + nomeArquivo.split(".").reverse()[0];
    return tipoArquivo;
}

function daysBetween(startDate, endDate) {
    const utcStartDate = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
    const utcEndDate = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());

    const millisecondsInDay = 24 * 60 * 60 * 1000;

    const daysDifference = Math.floor((utcEndDate - utcStartDate) / millisecondsInDay);

    return daysDifference;
}

function modulo11(chave) {
    let soma = 0;
    let peso = 2;

    for (let i = chave.length - 1; i >= 0; i--) {
        soma += parseInt(chave[i]) * peso;

        if (peso < 9) {
            peso++;
        } else {
            peso = 2;
        }
    }

    let digito = 11 - (soma % 11);
    if (digito > 9) {
        digito = 0;
    }

    return digito.toString();
}

async function buscaEmpresas() {
    try {
        const dadosSelect = {
            orderBy: ['EMPRESA.EMP_PAT'],
            tabela: `ACESSO_EMPRESA`,
            leftJoin: [{ "tabela": "EMPRESA", "condicao": "REPLACE(EMPRESA.EMP_PAT,'_','') = ACESSO_EMPRESA.EMPRESA" }],
            camposSelect: ['EMPRESA.EMP_ID', 'ACESSO_EMPRESA.EMPRESA', 'EMPRESA.EMP_NOME'],
            where: [`ACESSO_EMPRESA.USUARIO = '${getCookie('cod_usuario')}'`],
        };
        const retornoSelect = await retornaJsonPesquisaPadrao(JSON.stringify(dadosSelect));
        if (!retornoSelect) {
            return;
        }

        return retornoSelect;
    } catch (e) {
        console.log(e);
        msgErro(`Não foi possível carregar as empresas disponíveis: ${e}`);
    }
};

function ZeroE(Quant, Zeros) {
    let Result = Zeros;
    Quant -= Result.length;

    if (Quant > 0) {
        Result = '0'.repeat(Quant) + Result;
    }

    return Result;
}

async function retornaProximoLancamento() {
    const responseLancamento = await requisicao('POST', '/proximolancamentofaccao?');

    if (!responseLancamento) {
        throw new Error('Não foi possível gerar o próximo lançamento.');
    }

    if (responseLancamento.status == 200) {
        const lancamento = await responseLancamento.json();
        if (!lancamento.mensagem) {
            throw new Error('Não foi possível gerar o próximo lançamento.');
        }

        return lancamento.mensagem;
    } else {
        throw new Error('Não foi possível gerar o próximo lançamento.');
    }
}

function roundTo(num, precisao) {
    let fator = Math.pow(10, precisao);
    return Math.round(num * fator) / fator;
}

// Date.prototype.formataPadrao = function () {
//     const dataFormatada = new Date(this).toLocaleDateString().split('/');
//     const [dia, mes, ano] = dataFormatada;
//     return `${ano}-${mes}-${dia}`;
// };


async function verificaSisplanSaas() {
    const url = '/sisplan/funcoes/v1/retornasisplansaas?';

    const response = await requisicao('GET', url, '', null, 10000);

    if (!response) {
        return false;
    };

    if (response.status != 200) {
        const jsonStr = await response.json();
        msgAlerta(jsonStr.mensagem);
        return false;
    };

    const result = await response.text();

    return result == 'true';
};

async function verificaEmpresaKubernetesExisteArquivoIni(tipo, $callback) {
    const verificaKubernetes = await verificaSisplanSaas();

    if (verificaKubernetes) {
        const nomeIni = `${tipo}${sessionStorage.getItem('g_empresa_logada')}.ini`;
        const existeIniEmpresa = await verificaExisteIni(nomeIni);

        if (!existeIniEmpresa) {
            await msgAguardaConfirmacao('O arquivo de configuração não foi configurado para a empresa atual. Por favor, configure-o acessando a tela de impressão.', $callback ? async () => {
                return;
            } : () => { }, () => { }, false, true, 'Ok ');
            return false;
        }
    }
    return true;
}

async function verificaExisteIni(nomeIni) {
    const url = '/sisplan/funcoes/v1/verificaexisteini?';

    const response = await requisicao('GET', url, `NOME_INI=${nomeIni}`, null, 10000);

    if (!response) {
        return false;
    };

    if (response.status != 200) {
        const jsonStr = await response.json();
        msgAlerta(jsonStr.mensagem);
        return false;
    };

    const result = await response.json();

    return result.json == 'true';
};

async function enviaWhatsNFE(fatura, serie, codcli, nome, bValidaParametro = true, tipoNatureza = 'V') {
    if (bValidaParametro) {
        if (!['2', '3'].includes(await CopiaParametro('FATURAMENTO', 7))) {
            return;
        };
    };

    $.LoadingOverlay('show');
    try {
        const bUtilizaWhatsapp = await utilizaWhatsapp();
        if (!bUtilizaWhatsapp) {
            return;
        }

        const telefone = await getWhatsapp(codcli);
        const url = `/sisplan/nfe/v1/imprimirnfe?FATURA=${fatura}&SERIE=${serie}`;
        try {
            if (telefone == '') {
                msgAlerta('Cliente sem telefone cadastrado.');
                return;
            }
            const arquivo = await GeraRelatorio(`${url}&`, "PUT", 15000, false, 'NFE');
            let mensagem = '';
            if (tipoNatureza == 'D') {
                mensagem = `Olá *${nome}*!\r\n\r\nSegue abaixo a nota fiscal de devolução. \r\nTenha um ótimo dia 😊`;
            } else {
                mensagem = `Olá *${nome}*! \nObrigado por comprar conosco 🙌 \nSegue abaixo a nota fiscal. \nTenha um ótimo dia 😊🎉`;
            }
            if (arquivo != undefined) {
                const enviaMsg = await enviarMensagem(telefone, mensagem, 'ImpressaoNFE_WEB', fatura + '-' + serie);
                const enviaArq = await enviarMensagem(telefone, '', 'ImpressaoNFE_WEB', fatura + '-' + serie, true, arquivo);
                await limparRelatorios();
                const enviaBoleto = await enviaWhatsBoleto(fatura, serie, telefone, 'ImpressaoNFE_WEB');

                if (!enviaBoleto) {
                    console.error('Não foi possível fazer o envio do boleto! Favor verificar e tentar novamente.');
                };

                if (enviaArq && enviaMsg) {
                    toastr.success("Mensagem enviada com sucesso!", "Confirmação", {
                        toastClass: "success",
                        iconClasses: {
                            error: "alert-error",
                            info: "alert-info",
                            success: "alert-success",
                            warning: "alert-warning",
                        },
                        positionClass: "toast-top-center",
                        progressBar: true,
                        timeOut: 3000,
                        fadeOut: 1000,
                        onHidden() {
                            window.location.reload();
                        },
                    }).css({
                        "margin-top": "20%",
                        width: "500px",
                        "max-width": "500px",
                    });
                };
            }
        } catch (error) {
            console.error(error);
        }
    } finally {
        $.LoadingOverlay('hide');
    }
};

async function enviaWhatsNFCE(fatura, serie, codcli, nome, codven = false) {
    $.LoadingOverlay('show');
    const bUtilizaWhatsapp = await utilizaWhatsapp();

    if (!['2', '3'].includes(await CopiaParametro('FATURAMENTO', 7))) {
        return;
    };

    if (!bUtilizaWhatsapp) {
        return;
    }

    if (codven) {
        const pesquisaParam = {
            tabela: 'NOTA_NFCE',
            camposSelect: ['NOTA_NFCE.FATURA', 'NOTA_NFCE.SERIE', 'NOTA_NFCE.CODCLI', 'ENTIDADE.NOME'],
            leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = NOTA_NFCE.CODCLI' }],
            where: [`NOTA_NFCE.CODVEN = ${codven} AND NOTA_NFCE.IMPRESSO = 'S'`]
        };

        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

        if (jsonStr.length == 0) {
            return;
        }

        fatura = jsonStr[0].FATURA;
        serie = jsonStr[0].SERIE;
        codcli = jsonStr[0].CODCLI;
        nome = jsonStr[0].NOME;
    }

    try {
        const telefone = await getWhatsapp(codcli);

        const url = `/sisplan/nfce/v1/imprimirnfce?`;
        const params = `FATURA=${fatura}` +
            `&SERIE=${serie}` +
            `&CODVEN=${codven}`;
        try {
            if (telefone == '') {
                msgAlerta('Cliente sem telefone cadastrado.');
                return;
            }

            const arquivo = await GeraRelatorio(`${url}${params}&`, "GET", 15000, true, 'NFCE');

            if (!arquivo) {
                throw new msgAlerta("Não foi possível gerar o relatório da NFC-e para enviar via WhatsApp");
            }

            const mensagem = `Olá *${nome}*! \r\nObrigado por comprar conosco 🙌 \r\n\r\nSegue abaixo a nota fiscal. \r\nTenha um ótimo dia 😊🎉`;
            if (arquivo && arquivo != '') {
                const enviaMsg = await enviarMensagem(telefone, mensagem, 'ImpressaoNFCE_WEB', fatura + '-' + serie);
                const enviaArq = await enviarMensagem(telefone, '', 'ImpressaoNFCE_WEB', fatura + '-' + serie, true, arquivo);
                await limparRelatorios();
                const enviaBoleto = await enviaWhatsBoleto(fatura, serie, telefone, 'ImpressaoNFCE_WEB');

                if (enviaArq && enviaMsg && enviaBoleto) {
                    toastr.success("Mensagem enviada com sucesso!", "Confirmação", {
                        toastClass: "success",
                        iconClasses: {
                            error: "alert-error",
                            info: "alert-info",
                            success: "alert-success",
                            warning: "alert-warning",
                        },
                        positionClass: "toast-top-center",
                        progressBar: true,
                        timeOut: 3000,
                        fadeOut: 1000,
                        onHidden() {
                            window.location.reload();
                        },
                    }).css({
                        "margin-top": "20%",
                        width: "500px",
                        "max-width": "500px",
                    });
                };

                if (!enviaBoleto) {
                    console.log('Não foi possível fazer o envio do boleto! Favor verificar e tentar novamente.');
                    return;
                };
            }
        } catch (error) {
            console.error(error);
        }
    } finally {
        $.LoadingOverlay('hide');
    }
};

async function enviaWhatsBoleto(fatura, serie, telefone, tela) {
    $.LoadingOverlay('show');
    try {
        const url = `/sisplan/impressao/v1/imprimirboletofat?FATURA=${fatura}&TRANSMITIR=N&EMAIL=N`;
        try {
            if (telefone == '') {
                msgAlerta('Cliente sem telefone cadastrado.');
                return false;
            }

            const arquivo = await GeraRelatorio(`${url}&`, "GET", 15000, false, 'NFEBoleto');

            if (arquivo != undefined) {
                await enviarMensagem(telefone, '', 'NFEBoleto', fatura + '-' + serie, true, arquivo);
                await limparRelatorios();
                return true;
            }

            return false;
        } catch (error) {
            console.error(error);
            return false;
        }
    } finally {
        $.LoadingOverlay('hide');
    }
};

async function extraiBarra28(barra, barra28 = 'S', deposito = '') {
    try {
        const url = `/sisplan/barralog/v1/extraibarra28?`;
        const params = `barra=${encodeURIComponent(barra)}&BARRA28=${barra28}&DEPOSITO=${deposito}`;
        const response = await requisicao('GET', url, params, 15000);

        if (!response) {
            return;
        }

        jsonStr = await response.text();
        if (response.status != 200) {
            return jsonStr.mensagem;
        }

        return `${jsonStr}`;
    } catch (error) {
        console.error(error);
    }
}

function retornaDataAtual() {
    const today = new Date();
    const year = today.getFullYear();
    const month = ('0' + (today.getMonth() + 1)).slice(-2);
    const day = ('0' + today.getDate()).slice(-2);
    return year + '-' + month + '-' + day;
}

function coalesce(numero) {
    if (!numero) {
        return 0;
    }
    if (isNaN(numero)) {
        return 0;
    }
    if (numero == '') {
        return 0;
    }
    return numero;
}

async function validaBarraLogLiberada(sBarra) {
    try {
        const pesquisaParam = {
            tabela: 'BARRA_LOG',
            camposSelect: ['LIDA'],
            where: [`BARRA = '${sBarra}'`]
        };

        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

        if (!jsonStr) {
            throw new Error('Não foi possível validar a barra. Por favor, tente novamente.')
        }

        if (jsonStr.length == 0) {
            throw new Error('Não foi possível validar a barra. Por favor, tente novamente.')
        }

        return jsonStr[0].LIDA == 'N'
    } catch (error) {
        msgAlerta(error.message, 'Não foi possível validar a barra. Por favor, tente novamente.')
    }
};

async function validaBarraLogFacBarra(sBarra) {
    try {
        const pesquisaParam = {
            tabela: 'FAC_BARRA',
            camposSelect: ['BARRA'],
            where: [`BARRA = '${sBarra}'`]
        };

        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

        if (!jsonStr) {
            throw new Error('Não foi possível validar a barra. Por favor, tente novamente.')
        }

        return jsonStr.length > 0

    } catch (error) {
        msgAlerta(error.message, 'Não foi possível validar a barra. Por favor, tente novamente.')
    }
};

async function retornaTipoBarra(barra) {
    try {
        const url = `/sisplan/barralog/v1/validarbarra?`;
        const params = `barra=${encodeURIComponent(barra)}`;
        const response = await requisicao('GET', url, params, 15000);

        if (!response) {
            return;
        }

        jsonStr = await response.json();
        if (response.status != 200) {
            return jsonStr.mensagem;
        }

        return jsonStr.mensagem;
    } catch (error) {
        console.error(error);
    }
}

function retornaIdCamposConsulta(modal) {
    const campos = [];
    $(modal).each(function () {
        const id = $(this).attr('id');
        if (id) {
            campos.push(id);
        }
    });

    return campos;
}

async function reimpressaoRelatorioNFCE(codVen, chamadaImpressaoAutomatica) {

    await msgAguardaConfirmacao("Ocorreu a impressão da NFC-e?",
        async () => { await rotinaGeraLog("VENDA", codVen, `Foi confirmado pelo usuário ${getCookie("usuario")} que o NFCE da venda ${codVen} foi impresso com sucesso`, "Inclusão"); },
        async () => {
            await rotinaGeraLog("VENDA", codVen, `O usuário ${getCookie("usuario")} informou que o NFCE da venda ${codVen} não foi impresso`, "Inclusão");
            await chamadaImpressaoAutomatica();
            await reimpressaoRelatorioNFCE(codVen, chamadaImpressaoAutomatica);
        },
        true);

}

async function buscaIni(sessao, variavel) {
    try {
        const response = await requisicao('GET', `/sisplan/funcoes/v1/buscaini?`, `SESSAO=${sessao}&VARIAVEL=${variavel}`, '', 6000);

        const jsonIni = await response.json();
        if (!jsonIni) {
            return;
        }
        if (response.status != 200) {
            console.error(jsonIni.RESULT[0][0].mensagem);
            return;
        }
        return jsonIni.json;

    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function existeValorEmpValor(tabela) {
    try {
        let response = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"EMP_VALOR",
            "camposSelect":["VALOR"],
            "where": ["TABELA = '${tabela}'"], "limit": 1}`,
            null
        );
        let jsonStr = await response.json();

        return jsonStr.RESULT[0].length <= 0;
    } catch (error) {
        console.error(error);
    }
}

async function converteNFCEPagamentoIntegrado(cliente, valor, moeda, dadosTEF, pixIntegrado = '', idPix = "", nfce = {}, codven = -1, bCartaoPresente = false, lancamentoCartaoPresente = 0, listaReceber = []) {
    $.LoadingOverlay("show");
    let paramsImprimirNFCE = "";
    try {
        const infoEmpresa = await buscaValor('EMPRESA', 'EMP_ESTADO', 'EMP_ID', getCookie('emp_id'));

        if (infoEmpresa.EMP_ESTADO != "RS") {
            return "";
        }

        const usaCertificadoA3 = await CopiaParametro("FATURAMENTO", 2);
        const urlConverteNFCE = '/Sisplan/NFCE/v1/convertegeranfcepagamentointegrado?';
        const urlImprimirNFCE = `/sisplan/nfce/v1/imprimirnfce?`;
        const paramsConverteNFCE = `CERTA3=${usaCertificadoA3}` +
            `&CLIENTE=${cliente}` +
            `&VALOR=${valor.toString().replace('.', ',')}` +
            `&DADOS_TEF=${encodeURIComponent(JSON.stringify(dadosTEF))}` +
            `&MOEDA=${moeda}` +
            `&PIX_INTEGRADO=${pixIntegrado}` +
            `&ID_PIX=${idPix}` +
            `&CARTAO_PRESENTE=${bCartaoPresente}` +
            `&LANCAMENTO=${lancamentoCartaoPresente}` +
            `&LISTA_RECEBER=${JSON.stringify({ LISTARECEBER: listaReceber })}`;

        const bImprimeAutomatico = await verificaImprimirAutomatico('NFCE');

        const responseConverteNFCE = await requisicao("POST", urlConverteNFCE, paramsConverteNFCE, null, 120000);

        if (!responseConverteNFCE) {
            msgAlerta("Não foi possível gerar o NFCE.");
            return false;
        }

        const jsonConverteNFCE = await responseConverteNFCE.json();
        paramsImprimirNFCE = `FATURA=${jsonConverteNFCE.fatura}&SERIE=${jsonConverteNFCE.serie}`;
        if (responseConverteNFCE.status == 201) {
            const jsonNFCE = JSON.parse(jsonConverteNFCE.json);
            nfce.fatura = jsonNFCE.fatura;
            paramsImprimirNFCE = `FATURA=${jsonNFCE.fatura}&SERIE=${jsonNFCE.serie}`;
            if (codven != -1) {
                paramsImprimirNFCE += `&CODVEN=${codven}`
            }
            throw new Error(`NFC-e foi gerado mas não foi possível realizar a transmissão, necessário transmitir na tela de NFC-e. \nErro: ${jsonConverteNFCE.mensagem}`);
        } else if (responseConverteNFCE.status != 200) {
            msgAlerta(jsonConverteNFCE.mensagem);
            return false;
        }

        if (codven != -1 && responseConverteNFCE.status != 201) {
            paramsImprimirNFCE += `&CODVEN=${codven}`
        }

        nfce.fatura = jsonConverteNFCE?.fatura;

        if (usaCertificadoA3 == "1") {

            //transmite a nfce na apilocal
            const responseLocal = await requisicao_ecf('POST', '/nfce/emitir?', `EMPRESA=${JSON.stringify(infoEmpresa)}`, JSON.stringify(jsonConverteNFCE), 120000);

            if (!responseLocal) {
                throw new Error("Não foi possível transmitir o NFCE.");
            }

            if (responseLocal.status != 200) {
                const mensagemRetorno = await responseLocal.text();
                throw new Error(mensagemRetorno);
            }

            const retornoNota = await responseLocal.json();
            const tipoNfce = 0;

            // termina de transmitir na api web, da os updates etc
            const responseApiWeb = await requisicao(
                'POST',
                '/sisplan/nfce/v1/finalizanfce?',
                `${paramsImprimirNFCE}&TIPO=${tipoNfce}`,
                JSON.stringify(retornoNota),
                60000
            );

            if (!responseApiWeb) {
                throw new Error("Não foi possível finalizar o NFCE");
            }

            if (responseApiWeb.status != 200) {
                const mensagemRetorno = await responseApiWeb.json();
                throw new Error(mensagemRetorno.mensagem);
            }

        }

        if (bCartaoPresente && lancamentoCartaoPresente > 0) {
            await insereFaturaCartaoPresente(nfce.fatura, lancamentoCartaoPresente);
        }

        if (bImprimeAutomatico) {
            await GeraRelatorio(urlImprimirNFCE + paramsImprimirNFCE + '&', 'GET', 60000, false, 'NFCE');
        } else {
            const arquivo = await GeraRelatorio(urlImprimirNFCE + paramsImprimirNFCE + '&', 'GET', 60000, false, 'NFCE');
            if (arquivo != undefined) {
                window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
                await limparRelatorios();
            }
        }

        geraContabilizacaoNFCE(jsonConverteNFCE.fatura, jsonConverteNFCE.serie);

        return paramsImprimirNFCE;

    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
        return paramsImprimirNFCE;
    } finally {
        $.LoadingOverlay("hide");
    }

}

async function buscaDadosOrdenacao(sNomeTela) {
    try {
        $.LoadingOverlay('show');
        const url = "/sisplan/ordenacaorelatorio/v1/buscadados?";
        const params = `NOME_TELA=${sNomeTela}`;
        const response = await requisicao("GET", url, params);

        if (!response) {
            return;
        }

        const json = await response.json();
        if (response.status != 200) {
            msgErro(json.mensagem);
            return;
        }

        return json;
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function gravarOrdenacao() {
    const nomesNaoUtilizaveis = ['PADRÃO', 'PADRAO', 'SIMPLIFICADO', 'RESUMIDO', 'DETALHADO'];

    if (nomesNaoUtilizaveis.findIndex(it => it == $('#txtNomeOrdenacao').val().toUpperCase()) != -1) {
        msgAlerta(`Não é possível gravar uma nova ordenação tendo ${nomesNaoUtilizaveis.toString()} no nome! Altere o nome da ordenação e tente novamente.`);
        return;
    }
    msgAlerta(`Tem certeza que deseja gravar a ordenação?`, async () => {
        try {
            try {
                $.LoadingOverlay('show');
                const obj = {
                    ordem: $('#txtOrdemOrdenacao').val(),
                    id: $('#txtIdOrdenacao'),
                    nome: $('#txtNomeOrdenacao').val(),
                    nome_layout: $('#txtNomeLayout').val(),
                    tipo: $('#radioTipoOrdenacaoAscendente').prop('checked') ? 'ASC' : 'DESC',
                    campos: $('#tabela-campos-ordenacao').DataTable().data().toArray().map(it => it.campos).toString().replaceAll(',', ';'),
                    tela: $('#modal-ordenacao').attr('nome_tela'),
                    campo_sum: -1
                };

                if (obj.tela == 'RelRankLoja') {

                    if ($('#radioTipoOrdenacaoRankingQtde').prop('checked')) {
                        obj.campo_sum = 0;
                        if ($('#tabela-campos-ordenacao').DataTable().data().toArray().filter(it => it.campos == 'QUANTIDADE').length == 0) {
                            msgAlerta('Necessário conter o campo escolhido na ordenação também nos campos selecionados');
                            return;
                        }
                    } else {
                        obj.campo_sum = 1;
                        if ($('#tabela-campos-ordenacao').DataTable().data().toArray().filter(it => it.campos == 'VALOR').length == 0) {
                            msgAlerta('Necessário conter o campo escolhido na ordenação também nos campos selecionados');
                            return;
                        }
                    }
                }

                const response = await requisicao("POST", "/sisplan/ordenacaorelatorio/v1/gravar?", "", JSON.stringify(obj), 300000);

                if (!response) {
                    throw msgAlerta("Não foi possível gravar a ordenação.");
                }

                if (response.status != 200) {
                    const json = await response.json();
                    throw msgAlerta(json.mensagem);
                }

                criaMensagemSucesso("Ordenação gravada com sucesso", async () => {
                    window.location.reload();
                });

            } catch (error) {
                console.error(error);
            }
        } finally {
            $.LoadingOverlay('hide');
        }
    });
}

async function excluirOrdenacao(sId) {
    msgAlerta(`Tem certeza que deseja excluir a ordenação?`, async () => {
        try {
            const response = await requisicao("POST", "/sisplan/ordenacaorelatorio/v1/excluir?", `ID=${sId}`, "", 300000);

            if (!response) {
                throw msgAlerta("Não foi possível excluir a ordenação.");
            }

            if (response.status != 200) {
                throw msgAlerta("Não foi possível excluir a ordenação.");
            }

            criaMensagemSucesso("ordenação excluída com sucesso", async () => {
                window.location.reload();
            });

        } catch (error) {
            console.error(error);
        }
    });
}

async function setarOrdenacaoAtiva(sID, sAtivo) {
    try {
        $.LoadingOverlay('show');

        if (!sID) {
            msgAlerta('Necessário selecionar uma ordem para setar ativa/inativa.');
            return;
        }

        const url = "/sisplan/ordenacaorelatorio/v1/setarativo?";
        const params = `ID=${sID}&ATIVO=${sAtivo}`;
        const response = await requisicao("POST", url, params);

        if (!response) {
            return;
        }

        const json = await response.text();
        if (response.status != 200) {
            msgErro(json.mensagem);
            return;
        }
        if (json == 'ok') {
            const index = $('#tabela-ordenacoes').DataTable().data().toArray().findIndex(item => item.ID == sID);
            const data = $('#tabela-ordenacoes').DataTable().row(index).data();
            if (data) {
                const newData = { ...data, ATIVO: sAtivo };
                $('#tabela-ordenacoes').DataTable().row(index).data(newData).draw(false);
            }
        }
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function buscaCamposDisponiveisOrdenacao(sNomeTela) {
    try {
        $.LoadingOverlay('show');
        const url = "/sisplan/ordenacaorelatorio/v1/buscacampos?";
        const params = `NOME_TELA=${sNomeTela}`;
        const response = await requisicao("GET", url, params);

        if (!response) {
            return;
        }

        const json = await response.json();
        if (response.status != 200) {
            msgErro(json.mensagem);
            return;
        }
        return json;
    } finally {
        $.LoadingOverlay('hide');
    }
}


async function carregaDadosOrdenacao(dados = undefined) {
    const nomeTela = $('#modal-ordenacao').attr('nome_tela') ?? '';
    if (nomeTela) {
        const campos = await buscaCamposDisponiveisOrdenacao(nomeTela);
        criaDataTablePadrao('#tabela-campos-ordenacao', false, false, false, false, true, false, '400px', [], [{
            'title': 'Campos',
            'data': 'campos'
        }]);
        criaDataTablePadrao('#tabela-campos-disponiveis-ordenacao', false, false, false, false, true, false, '400px', [], [{
            'title': 'Campos',
            'data': 'campos'
        }]);


        if (nomeTela == 'RelRankLoja') {
            $('#radioTipoOrdenacaoRanking').removeClass('d-none');
            $('#radioTipoOrdenacaoRelatorio').addClass('d-none');
        } else {
            $('#radioTipoOrdenacaoRanking').addClass('d-none');
            $('#radioTipoOrdenacaoRelatorio').removeClass('d-none');
        }

        // se está em alteração

        if (dados) {

            $('#txtNomeOrdenacao').val(dados.NOME_ORD_TELA);
            $('#txtOrdemOrdenacao').val(dados.ORDEM);
            $('#txtIdOrdenacao').val(dados.ID);
            $('#txtNomeLayout').val(dados.NOME_PRT);

            if (dados.NOME_TELA == 'RelRankLoja') {
                if (dados.CAMPO_SUM == 0) {
                    $('#radioTipoOrdenacaoRankingQtde').trigger('click');
                } else {
                    $('#radioTipoOrdenacaoRankingValor').trigger('click');
                }
            }

            if (dados.TIPO_ORDENACAO == 'ASC') {
                $('#radioTipoOrdenacaoAscendente').trigger('click');
            } else {
                $('#radioTipoOrdenacaoDecrescente').trigger('click');
            }
            const camposAtuais = dados.NOME_ORD_SIST.split(';');
            for (let i = 0; i < camposAtuais.length; i++) {
                for (let j = 0; j < campos.length; j++) {
                    if ((camposAtuais[i].toUpperCase() == campos[j].toUpperCase())) {
                        $('#tabela-campos-ordenacao').DataTable().row.add({ campos: camposAtuais[i].toUpperCase() }).draw(false);
                        campos.splice(j, 1);
                    }
                }
            }
        } else {
            $('#txtNomeOrdenacao').val('');
            $('#txtIdOrdenacao').val('');
            $('#txtNomeLayout').val('');
            $('#txtOrdemOrdenacao').val('');
        }

        for (let y = 0; y < campos.length; y++) {
            $('#tabela-campos-disponiveis-ordenacao').DataTable().row.add({ campos: campos[y].toUpperCase() });
        }

        $('#btn-campos-up').off('click');
        $('#btn-campos-up').on('click', function () {
            if ($('#tabela-campos-ordenacao .selected').length > 0) {
                const indice = $('#tabela-campos-ordenacao .selected').closest('tr').index();
                if (indice == 0) {
                    return;
                }
                const oldData = $('#tabela-campos-ordenacao').DataTable().row(indice).data();
                const newData = $('#tabela-campos-ordenacao').DataTable().row(indice - 1).data();
                $('#tabela-campos-ordenacao').DataTable().row(indice).data(newData).draw(false);
                $('#tabela-campos-ordenacao').DataTable().row(indice - 1).data(oldData).draw(false);
                $('#tabela-campos-ordenacao').DataTable().$('tr.selected').removeClass('selected');
                $($(`#tabela-campos-ordenacao tbody tr:eq(${indice - 1})`)).addClass('selected');
            }
        });

        $('#btn-campos-down').off('click');
        $('#btn-campos-down').on('click', function () {
            if ($('#tabela-campos-ordenacao .selected').length > 0) {
                const indice = $('#tabela-campos-ordenacao .selected').closest('tr').index();
                if (indice == $('#tabela-campos-ordenacao').DataTable().data().toArray().length - 1) {
                    return;
                }
                const oldData = $('#tabela-campos-ordenacao').DataTable().row(indice).data();
                const newData = $('#tabela-campos-ordenacao').DataTable().row(indice + 1).data();
                $('#tabela-campos-ordenacao').DataTable().row(indice).data(newData).draw(false);
                $('#tabela-campos-ordenacao').DataTable().row(indice + 1).data(oldData).draw(false);
                $('#tabela-campos-ordenacao').DataTable().$('tr.selected').removeClass('selected');
                $($(`#tabela-campos-ordenacao tbody tr:eq(${indice + 1})`)).addClass('selected');
            }
        });


        $('#tabela-campos-disponiveis-ordenacao tbody').unbind('dblclick');
        $('#tabela-campos-disponiveis-ordenacao tbody').on('dblclick', 'tr', async function (e) {
            if ($('#tabela-campos-disponiveis-ordenacao').DataTable().data().length > 0) {
                const dt = $('#tabela-campos-disponiveis-ordenacao').DataTable().row(this).data();
                $('#tabela-campos-ordenacao').DataTable().row.add({ campos: dt.campos.toUpperCase() }).draw(false);
                $('#tabela-campos-disponiveis-ordenacao').DataTable().row($(this)).remove().draw(false);
            }
        });


        $('#tabela-campos-disponiveis-ordenacao tbody').unbind('click');
        $('#tabela-campos-disponiveis-ordenacao tbody').on('click', 'tr', async function (e) {
            if ($('#tabela-campos-disponiveis-ordenacao').DataTable().data().length > 0) {
                $('#tabela-campos-disponiveis-ordenacao').DataTable().$('tr.selected').removeClass('selected');
                $(this).addClass('selected');
            }
        });

        $('#tabela-campos-ordenacao tbody').unbind('click');
        $('#tabela-campos-ordenacao tbody').on('click', 'tr', async function (e) {
            if ($('#tabela-campos-ordenacao').DataTable().data().length > 0) {
                $('#tabela-campos-ordenacao').DataTable().$('tr.selected').removeClass('selected');
                $(this).addClass('selected');
            }
        });

        $('#tabela-campos-ordenacao tbody').unbind('dblclick');
        $('#tabela-campos-ordenacao tbody').on('dblclick', 'tr', async function (e) {
            if ($('#tabela-campos-ordenacao').DataTable().data().length > 0) {
                const dt = $('#tabela-campos-ordenacao').DataTable().row(this).data();
                $('#tabela-campos-disponiveis-ordenacao').DataTable().row.add({ campos: dt.campos.toUpperCase() }).draw(false);
                $('#tabela-campos-ordenacao').DataTable().row($(this)).remove().draw(false);
            }
        });

        $('#btn-confirmar-ordenacao').off('click');
        $('#btn-confirmar-ordenacao').on('click', async function () {
            await gravarOrdenacao();
        });
        $('#modal-cadastro-ordenacao').modal('show');
        setTimeout(() => {
            $(`#tabela-campos-ordenacao`).DataTable().columns.adjust().draw(false);
            $(`#tabela-campos-disponiveis-ordenacao`).DataTable().columns.adjust().draw(false);
        }, 300);
    }
}


async function abreModalOrdenacao(sNomeTela) {
    try {
        const data = await buscaDadosOrdenacao(sNomeTela);
        const coluns = [];
        let keys;
        if (data.length <= 0) {
            keys = ['ORDEM', 'NOME_ORD_SIST', 'NOME_ORD_TELA', 'NOME_PRT', 'NOME_TELA', 'NOME_ABA', 'TIPO_ORDENACAO', 'ATIVO', 'POSICAO', 'NOME_COMBO', 'CAMPO_SUM', 'ID'];
        } else {
            keys = Object.keys(data[0]);
        }
        for (let k in keys) {
            coluns.push({
                'title': keys[k],
                'data': keys[k]
            });
        };
        $('#modal-filtros').modal('hide');
        $('#modal-ordenacao').modal('show');
        $('#modal-ordenacao').attr('nome_tela', sNomeTela);
        $('#modal-ordenacao .modal-body').html('<div class="row"><div class="col-12 table-responsive"><table width="100%" style="width: 100%" class="table table-sm table-hover table-select" id="tabela-ordenacoes"><thead></thead><tbody></tbody></table></div></div>');
        criaDataTablePadrao('#tabela-ordenacoes', false, false, true, false, true, '400px', false, data, coluns);
        setTimeout(() => {
            $(`#tabela-ordenacoes`).DataTable().columns.adjust().draw(false);
        }, 300);
        $('#tabela-ordenacoes tbody').unbind('click');
        $('#tabela-ordenacoes tbody').on('click', 'tr', async function (e) {
            if ($('#tabela-ordenacoes').DataTable().data().length > 0) {
                $('#tabela-ordenacoes').DataTable().$('tr.selected').removeClass('selected');
                $(this).addClass('selected');
            }
        });

        $('#btnOrdenacaoIncluir').unbind('click');
        $('#btnOrdenacaoIncluir').on('click', async function () {
            await carregaDadosOrdenacao();
        });

        $('#btnOrdenacaoAlterar').unbind('click');
        $('#btnOrdenacaoAlterar').on('click', async function () {
            const dados = $('#tabela-ordenacoes').DataTable().rows('.selected').data().toArray()[0];
            const nomesNaoUtilizaveis = ['PADRÃO', 'PADRAO', 'SIMPLIFICADO', 'RESUMIDO', 'DETALHADO'];
            if (!dados) {
                msgAlerta('Necessário selecionar uma ordenação para alterar');
                return;
            }

            if (nomesNaoUtilizaveis.findIndex(it => it == dados.NOME_ORD_TELA.toUpperCase()) != -1) {
                msgAlerta(`Ordenação selecionada para alteração é PADRÃO do sistema! Impossível continuar.`);
                return;
            }

            await carregaDadosOrdenacao(dados);
        });

        $('#btnOrdenacaoExcluir').unbind('click');
        $('#btnOrdenacaoExcluir').on('click', async function () {
            const dados = $('#tabela-ordenacoes').DataTable().rows('.selected').data().toArray()[0];
            const nomesNaoUtilizaveis = ['PADRÃO', 'PADRAO', 'SIMPLIFICADO', 'RESUMIDO', 'DETALHADO'];
            if (!dados) {
                msgAlerta('Necessário selecionar uma ordenação para excluir.');
                return;
            }

            if ((dados.NOME_TELA == 'RelRankLoja') && ([0, 1, 2, 3, 4, 5].includes(dados.ORDEM))) {
                msgAlerta(`Ordenação selecionada para exclusão é PADRÃO do sistema! Impossível realizar exclusão.`);
                return;
            }

            if (nomesNaoUtilizaveis.findIndex(it => it == dados.NOME_ORD_TELA.toUpperCase()) != -1) {
                msgAlerta(`Ordenação selecionada para exclusão é PADRÃO do sistema! Impossível realizar exclusão.`);
                return;
            }

            await excluirOrdenacao(dados.ID);
        });

        $('#btnOrdenacaoSetarAtivo').unbind('click');
        $('#btnOrdenacaoSetarAtivo').on('click', async function () {
            const dados = $('#tabela-ordenacoes').DataTable().rows('.selected').data().toArray()[0];
            const nomesNaoUtilizaveis = ['PADRÃO', 'PADRAO', 'SIMPLIFICADO', 'RESUMIDO', 'DETALHADO'];

            if (!dados) {
                msgAlerta('Necessário selecionar uma ordenação para setar ativo/inativo.');
                return;
            }

            if (nomesNaoUtilizaveis.findIndex(it => it == dados.NOME_ORD_TELA.toUpperCase()) != -1) {
                msgAlerta(`Ordenação selecionada é PADRÃO do sistema! Impossível continuar.`);
                return;
            }

            await setarOrdenacaoAtiva(dados.ID, dados.ATIVO == 'S' ? 'N' : 'S');
        });

    } finally {
        //
    }
}

$('.btnEdicaoRelatorio').on('click', async function () {
    const nomeTela = $(this).attr('nome_tela') ?? '';
    if (nomeTela) {
        await abreModalOrdenacao(nomeTela);
    }
});

async function buscaValoresPadroes(tabela) {
    const pesquisa = {
        camposSelect: ['CAMPO', 'VALOR'],
        tabela: 'TABPADRAO',
        where: [`TABPADRAO.TABELA = '${tabela}' AND TABPADRAO.EMP_ID = ${getCookie('emp_id')}`]
    };

    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

    if (jsonStr.length > 0) {
        return jsonStr;
    }

    pesquisa.where = [`TABPADRAO.TABELA = '${tabela}'`]

    const jsonStr2 = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

    return jsonStr2;
}

async function pesquisaDiaUtil(dt) {
    const dataFormatada = formataData(dt);
    const pesquisa = {
        camposSelect: ['DIA_UTIL'],
        tabela: 'ANO',
        where: [`DATA = '${dataFormatada}'`]
    };
    const responseDiaUtil = await retornaJsonPesquisaPadrao(encodeURIComponent(JSON.stringify(pesquisa)));

    return responseDiaUtil[0].DIA_UTIL == 'S';
}

async function validaDiaUtil(dataUtil) {
    let dataUtilValidacao = dataUtil;
    try {
        while (!await pesquisaDiaUtil(dataUtilValidacao)) {
            dataUtilValidacao.setDate(dataUtilValidacao.getDate() + 1);
        };

        return dataUtilValidacao;
    } catch (error) {
        return dataUtil;
    }
}

async function rotinaGeraLogComBody(tela, chave, descricao, operacao) {
    try {
        const url = "/sisplan/log/v1/geralog?";
        const objetoLog = {
            tela,
            chave,
            descricao,
            operacao
        };

        const response = await requisicao(
            "POST",
            url,
            `POSSUIBODY=S`,
            `&JSON=${encodeURIComponent(JSON.stringify(objetoLog))}`
        );

    } catch (error) {
        console.error(error);
    }
}

async function abreModalLiberacaoSupervisor(motivo, nomeTela, chave, codcli, valor, valorLiq, percDesc, desconto, codrep) {
    $.LoadingOverlay('show');
    try {
        $('#txtMotivoLibSupervisor').val(motivo);

        $("#modal-liberacao-supervisor-rodape").html(`<button type="button" id="btn-liberacao-supervisor-confirmar" class="btn btn-primary btn-sisp" data-dismiss="modal">Confirmar</button>
                    <button type="button" id="btnLiberacaoSupervisorDesistir" class="btn btn-danger btn-sisp">Desistir</button>`);

        $("#modal-liberacao-supervisor").modal({
            backdrop: "static",
            keyboard: true,
            show: true,
        });

        $("#btn-liberacao-supervisor-confirmar").on("click", async function () {
            if ($("#txtObsLibSupervisor").val() == '') {
                msgErro(`Observação não pode ficar em branco! Impossível continuar.`);
                return;
            }
            await requisicaoLiberacaoSupervisor(
                $("#txtObsLibSupervisor").val(),
                motivo,
                nomeTela,
                chave,
                codcli,
                valor,
                valorLiq,
                percDesc,
                desconto,
                codrep
            );
            $('#txtMotivoLibSupervisor').val('');
            $('#txtObsLibSupervisor').val('');
        });
        $('#btnLiberacaoSupervisorDesistir').on('click', async function () {
            $("#modal-liberacao-supervisor").modal('hide');
            $('#txtMotivoLibSupervisor').val('');
            $('#txtObsLibSupervisor').val('');
        });

        $('#btn-liberacao-supervisor-close').on('click', async function () {
            $('#txtMotivoLibSupervisor').val('');
            $('#txtObsLibSupervisor').val('');
        });
    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function carregaValoresPadroesLista(sTabela) {
    const jsonStr = await buscaValoresPadroes(sTabela);
    const result = {};
    jsonStr.forEach(item => {
        result[item.CAMPO] = item.VALOR;
    });

    return result;
};

async function requisicaoLiberacaoSupervisor(obs, motivo, tela, chave, codcli, valor, valorLiq, percDesc, desconto, codrep, mostrarMensagem = true) {
    $.LoadingOverlay('show');
    try {
        const novaChave = (chave ?? '') == 'create' ? '' : chave ?? '';
        const obj = {
            OBS: obs.replaceAll('"', ''),
            MOTIVO: motivo.replaceAll('"', ''),
            TELA: tela,
            EMPID: getCookie('emp_id'),
            CHAVE: novaChave,
            CODCLI: codcli,
            VALOR: valor,
            VALORLIQ: valorLiq,
            PERCDESC: percDesc,
            DESCONTO: desconto,
            CODREP: codrep,
            LIBERADO: !mostrarMensagem ? 'S' : 'N'
        };
        const response = await requisicao("POST", `/sisplan/retaguardasupervisor/v1/cadastrasolicitacao?`, null, encodeURIComponent(JSON.stringify(obj)), 35000);

        if (!response) {
            return;
        }

        const json = await response.json();
        if (response.status != 200) {
            msgErro(json.mensagem);
            return;
        }

        $("#modal-supervisor").modal('hide');

        if (mostrarMensagem) {
            toastr.success(`Solicitação: ${json[0]} cadastrada com sucesso!`, "Confirmação", {
                toastClass: "alert",
                iconClasses: {
                    error: "alert-error",
                    info: "alert-info",
                    success: "alert-success",
                    warning: "alert-warning",
                },
                positionClass: "toast-top-center",
                progressBar: true,
                timeOut: 3000,
                fadeOut: 1000,
                onHidden() {
                    const obj = {
                        id: json[0],
                        usuario: getCookie('usuario'),
                        motivo: motivo,
                        tela: tela,
                        empid: getCookie('emp_id'),
                        chave: novaChave
                    };
                    localStorage.setItem(`liberacaoSupervisor${tela}${getCookie('emp_id')}`, JSON.stringify(obj));

                    $("#modal-supervisor").modal({
                        backdrop: "static",
                        keyboard: true,
                        show: true,
                    });
                },
            }).css({
                "margin-top": "20%",
                width: "500px",
                "max-width": "500px"
            });
        }

    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function verificaSolicitacao(callback, callBackErro, nomeTela, bDesconto = false, props = '') {
    $.LoadingOverlay('show');
    try {
        const solicitacaoStorage = localStorage.getItem(`liberacaoSupervisor${nomeTela}${getCookie('emp_id')}`);
        const objStorage = JSON.parse(solicitacaoStorage);
        const id = objStorage.id;
        const response = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"LIB_SUPERVISOR", "camposSelect":["ACAO", "USADO", "USER_LIBER"], "where": ["ID = ${id} AND TELA = '${nomeTela}' AND EMP_ID = ${getCookie('emp_id')}"]}`,
            null
        );

        if (!response) {
            return;
        }

        const data = await response.json();

        if (response.status == '200') {
            $("#modal-supervisor").modal('hide');
            if (data.RESULT[0].length > 0) {
                const solicitacao = data.RESULT[0][0];
                const buscaUsr = await buscaValor('ACESSO_USUARIOS', 'NOME', 'NOME', solicitacao.USER_LIBER)
                const usuarioLiberacao = buscaUsr != undefined && buscaUsr != '' ? buscaUsr : 'SISPLAN';

                if ((solicitacao.ACAO == 'L') && (solicitacao.USADO) == 'N') {
                    // Condição específica para desconto na venda, pois é necessário passar usuário supervisor por parametro...
                    if (bDesconto) {
                        if (props != undefined) {
                            criaMensagemSucesso(`Solicitação: ${id} foi liberada!`, async () => {
                                await finalizaLiberacaoSupervisor(id, () => {
                                    callback(usuarioLiberacao, props);
                                }, undefined, nomeTela);
                            }, 7000);
                        } else {
                            criaMensagemSucesso(`Solicitação: ${id} foi liberada!`, async () => {
                                await finalizaLiberacaoSupervisor(id, () => {
                                    callback();
                                }, undefined, nomeTela);
                            }, 7000);
                        }
                    } else {
                        if (props != undefined) {
                            criaMensagemSucesso(`Solicitação: ${id} foi liberada!`, async () => {
                                await finalizaLiberacaoSupervisor(id, callback(props), undefined, nomeTela);
                            }, 7000);
                        } else {
                            criaMensagemSucesso(`Solicitação: ${id} foi liberada!`, async () => {
                                await finalizaLiberacaoSupervisor(id, callback, undefined, nomeTela);
                            }, 7000);
                        }
                    }
                } else if ((solicitacao.ACAO == 'R') && (solicitacao.USADO) == 'N') {
                    criaMensagemErro(`Solicitação: ${id} foi rejeitada!`, async () => {
                        await finalizaLiberacaoSupervisor(id, undefined, callBackErro, nomeTela);
                    }, 7000);
                } else if (solicitacao.USADO == 'S') {
                    criaMensagemAlerta(`Solicitação: ${id} ja foi utilizada!`, async () => {
                        $("#modal-supervisor").modal('hide');
                        localStorage.removeItem(`liberacaoSupervisor${nomeTela}${getCookie('emp_id')}`);
                        $("#modal-supervisor").modal({
                            backdrop: "static",
                            keyboard: true,
                            show: true,
                        });
                    }, 7000);
                } else {
                    criaMensagemAlerta(`Solicitação: ${id} ainda não foi analisada.`, async () => {
                        $("#modal-supervisor").modal({
                            backdrop: "static",
                            keyboard: true,
                            show: true,
                        });
                    }, 5000);
                }
            } else {
                criaMensagemAlerta(`Solicitação não encontrada. Favor tentar novamente!`, async () => {
                    $("#modal-supervisor").modal({
                        backdrop: "static",
                        keyboard: true,
                        show: true,
                    });
                });
            }
            $("#modal-supervisor").modal({
                backdrop: "static",
                keyboard: true,
                show: true,
            });
        }
    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function finalizaLiberacaoSupervisor(id, callback, callBackErro = undefined, tela) {
    $.LoadingOverlay('show');
    try {
        const url = `/sisplan/retaguardasupervisor/v1/atualizasolicitacao?`;
        const response = await requisicao("POST", url, `ID=${id}`, "", 300000);

        if (!response) {
            throw new Error("Não foi possível gravar as informações.");
        }

        if (response.status != 200) {
            throw new Error("Não foi possível gravar as informações.");
        }

        $("#modal-supervisor").modal('hide');
        localStorage.removeItem(`liberacaoSupervisor${tela}${getCookie('emp_id')}`);
        if (callback) {
            callback();
        } else if (callBackErro && callBackErro != '') {
            callBackErro();
        }
    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

async function ajustaSolicitacaoSupervisorVenda(chave, codigo, callback) {
    $.LoadingOverlay('show');
    try {
        const url = `/sisplan/retaguardasupervisor/v1/ajustachave?`;
        const response = await requisicao("POST", url, `CHAVE=${chave}&CODIGO=${codigo}`, "", 300000);

        if (!response) {
            throw new Error("Não foi possível gravar as informações.");
        }

        if (response.status != 200) {
            throw new Error("Não foi possível gravar as informações.");
        }
        if (callback) {
            callback();
        }
    } catch (error) {
        console.error(error);
        msgAlerta(error.message);
    } finally {
        $.LoadingOverlay('hide');
    }
}

function atualizarFiltrosAbasAcessoSessionStorage(nomePagina, filtros) {
    const filtrosGravadosSessionStorage = sessionStorage.getItem('filtrosConsultasAbasAcesso');
    if (filtrosGravadosSessionStorage) {
        const filtrosGravados = JSON.parse(filtrosGravadosSessionStorage);
        filtrosGravados[nomePagina] = filtros;
        sessionStorage.setItem('filtrosConsultasAbasAcesso', JSON.stringify(filtrosGravados));
        return;
    }
    const filtrosGravados = new Object();
    filtrosGravados[nomePagina] = filtros;
    sessionStorage.setItem('filtrosConsultasAbasAcesso', JSON.stringify(filtrosGravados));
    return;
}


async function contemBaixaReceberVenda(sCodVen) {
    try {

        if (sCodVen == "") {
            return;
        }

        const response = await requisicao('GET', '/sisplan/receber/v1/contembaixareceberbvenda?', `CODVEN=${sCodVen}`);
        const jsonStr = await response.text();

        if ((response.status == 200) && (jsonStr != '')) {
            await aguardaMsgAlerta(jsonStr, () => { });
        }
    } catch (error) {
        console.log(error);
    }
}

async function buscaCodrepUsuario() {
    async function retornaCodRepUsuario() {
        const pesquisaParam = {
            tabela: "ACESSO_USUARIOS",
            camposSelect: [
                `CODREP`,
            ],
            where: [`CODIGO = '${getCookie('cod_usuario')}'`]
        }

        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
        if (!jsonStr[0]) return
        return jsonStr[0].CODREP;
    }

    async function retornaSquadUsuario(codrep) {
        const pesquisaParam = {
            tabela: "REPRESEN",
            camposSelect: [
                `CODREP`,
            ],
            where: [`CODSDR = '${codrep}' AND ATIVO = 'S'`]
        }


        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
        if (!jsonStr[0]) return ''

        return jsonStr.map(CODREP => CODREP.CODREP).toString();
    };
    if (sessionStorage.getItem('cod_usuario') === '0000') {
        return '00001'
    }

    const pesquisaParam = {
        tabela: 'ACESSO_USUARIOS',
        camposSelect: [
            'CODFUN',
        ],
        where: [`ACESSO_USUARIOS.CODIGO = '${sessionStorage.getItem('cod_usuario')}'`],
    };

    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
    if (!jsonStr[0]) return ''

    if (jsonStr[0].CODFUN != '') {
        const squad = await retornaSquadUsuario(jsonStr[0].CODFUN);

        if (squad == '') {
            return await retornaCodRepUsuario();
        }

        return squad;
    } else {
        return await retornaCodRepUsuario();
    }
};

function filtrarCaracteres(string, listaCaracteres) {
    return string.split('').filter(char => listaCaracteres.includes(char)).join('');
}

function limitaCaracteresInput(idInput, limit) {
    $(`#${idInput}`).off("keydown");
    $(`#${idInput}`).on("keydown", function (e) {
        const permitidos = ["Backspace", "Delete", "ArrowLeft", "ArrowRight",
            "ArrowUp", "ArrowDown", "Enter", "Tab",
            "Control", "Shift"];

        if (permitidos.includes(e.key)) return;

        // sempre soma +1 por conta do caractere que esta digitando no momento
        if ($(this).val().length + 1 > limit) {
            e.preventDefault();
        }
    })
}

function imprimirBase64Pdf(base64) {
    const byteCharacters = atob(base64);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: "application/pdf" });

    const blobUrl = URL.createObjectURL(blob);

    window.open(blobUrl);
}

function retornarDataPrimeiroDiaMesAtual() {
    try {
        const dataPrimeiroDiaDoMes = new Date();
        dataPrimeiroDiaDoMes.setDate(1);

        return formataData(dataPrimeiroDiaDoMes)
    } catch (error) {
        console.error(error)
        return '1200-01-01'
    }
}
function safeParseFloat(valor) {
    try {
        if (!valor) {
            return 0.00
        }
        return parseFloat(valor)
    } catch {
        return null
    }
}

function safeParseInt(valor) {
    try {
        if (!valor) {
            return 0
        }
        return parseInt(valor)
    } catch {
        return null
    }
}

function retornarValorMonetarioEmFloat(valorFormatado) {
    try {
        if (typeof valorFormatado === "number") {
            return valorFormatado
        }
        const valorEmFloat = safeParseFloat(valorFormatado.replace(',', '.'))

        if (!valorEmFloat) {
            return 0
        }

        return valorEmFloat
    } catch {
        return 0
    }
}

function retornarChaveDescricao(id) {
    const textoInput = $(id).val()
    const chave = textoInput.substring(1, textoInput.indexOf("]"))
    const descricao = textoInput.substring(textoInput.indexOf("]") + 4, textoInput.length)

    return {
        chave,
        descricao,
    }
}

async function removerClienteSPC(BoaVistaSPC) {

    if (!await testeConexaoApiLocal()) {
        await rotinaGeraLog('ACESSO_RECEBER', BoaVistaSPC.codcli, `O cliente não foi removido do SPC por conta de uma falha na comunicação com a ApiLocal. Duplicata: ${BoaVistaSPC.numero}`, 'Inclusão');
        throw new Error("Não foi possível estabelecer comunicação com a ApiLocal. Portanto, a rotina de remoção do cliente do SPC não será executada.");
    }

    const response = await requisicao_ecf('POST', '/boavista/removeclientespc?', "", JSON.stringify(BoaVistaSPC), 50000);

    if (!response) {
        await rotinaGeraLog('ACESSO_RECEBER', BoaVistaSPC.codcli, `O cliente não foi removido do SPC por conta de um erro na requisição. Duplicata: ${BoaVistaSPC.numero}`, 'Inclusão');
        throw new Error("Não foi possível remover o cliente do SPC.");
    }

    const jsonStr = await response.json();

    if (response.status != 200) {
        await rotinaGeraLog('ACESSO_RECEBER', BoaVistaSPC.codcli, `O cliente não foi removido do SPC por conta do erro: ${jsonStr.mensagem}. Duplicata: ${BoaVistaSPC.numero}`, 'Inclusão');
        throw new Error(`Não foi possível remover o cliente do SPC. ${jsonStr.mensagem}`);
    }

    await rotinaGeraLog('ACESSO_RECEBER', BoaVistaSPC.codcli, `O cliente foi removido SPC. Duplicata: ${BoaVistaSPC.numero}`, 'Inclusão');

    await AtualizaEntidadeSPC(JSON.parse(jsonStr.mensagem));

    return true;
}

async function AtualizaEntidadeSPC(obj) {
    try {
        obj.dt_saida_spc = formataDataComTraco(obj.dt_saida_spc)
        const response = await requisicao("PUT", "/Sisplan/Cliente/V1/atualizaclientespc?", '', JSON.stringify(obj));

        if (!response) {
            throw new Error("Não foi possível atualizar os dados do SPC na Entidade.");
        }

        if (response.status != 200) {
            const jsonStr = await response.json();
            throw new Error(`Não foi possível atualizar os dados do SPC na Entidade. ${jsonStr.mensagem}`);
        }

        await rotinaGeraLog('ACESSO_RECEBER', obj.codcli, 'Foi atualizado as informações da remoção do SPC na Entidade', 'Inclusão');

    } catch (error) {
        console.log(error.message);
        await rotinaGeraLog('ACESSO_RECEBER', obj.codcli, error.message, 'Inclusão');
    }
}

function adicionarDias(dateStr, dias) {
    const [ano, mes, dia] = dateStr.split('-').map(Number);
    const data = new Date(ano, mes - 1, dia);
    data.setDate(data.getDate() + dias);
    return formataData(data);
}

async function verificarDiaUtil(data, bDecrementa) {
    const url = "/sisplan/funcoes/v1/verificardiautil?";
    const dataFormatada = formataDataBonita(data, true);
    try {
        const response = await requisicao("GET", url, `DATA=${dataFormatada}&DECREMENTA=${bDecrementa}`, "", 60000);

        if (!response) {
            throw new Error("Não foi possível verificar o dia útil.");
        }

        const jsonRetorno = await response.json();
        if (response.status != 200) {
            throw new Error(`Não foi possível verificar o dia útil. ${jsonRetorno.mensagem}`);
        }

        return jsonRetorno.json;
    } catch (error) {
        console.error(error);
        return data;
    }
}

function diferencaDeDias(dataString) {
    const dataAlvo = new Date(dataString);
    const hoje = new Date();

    dataAlvo.setHours(0, 0, 0, 0);
    hoje.setHours(0, 0, 0, 0);

    const diffMs = hoje - dataAlvo;

    const diffDias = diffMs / (1000 * 60 * 60 * 24);

    return diffDias;
}

function geraContabilizacaoNFCE(fatura, serie, codven) {
    try {
        const params = `FATURA=${fatura}` +
            `&SERIE=${serie}` +
            `&CODVEN=${codven}`;
        const response = requisicao('POST', '/sisplan/contabil/v1/geracontabilizacaonfce?', params, "", 300000);

        if (!response) {
            throw new Error("Não foi possível gerar a contabilização. A API estava inacessível.")
        }

    } catch (error) {
        console.log(error);
    }
}

async function verificaExistePedRegra() {
    $.LoadingOverlay('show')
    try {
        const pesquisa = {
            camposSelect: ['CODIGO'],
            tabela: 'PED_REGRAS',
        };
        const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

        return jsonStr.length > 0;
    } catch (error) {
        console.error(error)
        msgAlerta(error.message)
    } finally {
        $.LoadingOverlay('hide')
    }
}

async function verificaIALiberada(msgErro = true) {
    try {
        const response = await requisicao('GET', '/sisplan/funcoesia/v2/verificaliberacao?')

        if (!response)
            throw new Error("Houve um problema ao se conectar com a SIA. Tente novamente mais tarde.")

        const jsonResponse = await response.json()

        if (response.status !== 200)
            throw new Error(jsonResponse.mensagem)

        return jsonResponse.ia_liberada
    } catch (error) {
        if (msgErro)`Erro ao conectar com a SIA: ${error.message}`
        return false
    }
}

async function verificaIALiberadaCallback(callbackLiberada) {
    try {
        const iaLiberada = await verificaIALiberada();

        if (iaLiberada) {
            await callbackLiberada();
            return true;
        }

        return false;
    } catch (error) {
        return false;
    }
}

async function autenticarSIA() {
    try {
        const usuarioCookie = getCookie('usuario').toUpperCase()
        const usuario = getCookie('cod_usuario') == '0000' ? 'SISPLAN' : usuarioCookie
        const empresa = getCookie('empresa')

        const jsonStrEmailApp = await retornaJsonPesquisaPadrao(
            `{ "tabela":"ACESSO_USUARIOS", "camposSelect":["email_app"], "where": ["nome = '${usuario}'"]}`
        )

        const jsonStrCnpj = await retornaJsonPesquisaPadrao(
            `{ "tabela":"EMPRESA", "camposSelect":["emp_cnpj"], "where": ["emp_pat = '${empresa}'"]}`
        )

        const password = `${usuario.toLowerCase(0)}${jsonStrEmailApp[0].EMAIL_APP}`
        const document = (jsonStrCnpj[0].EMP_CNPJ).replaceAll('.', '').replaceAll('/', '').replaceAll('-', '')

        const response = await requisicaoSia('POST', '/authenticate', null, null, { email: jsonStrEmailApp[0].EMAIL_APP, password, document })

        if (!response)
            throw new Error("Não foi possível se conectar com a SIA. Por favor, tente novamente mais tarde.")

        const jsonResponse = await response.json();

        if (response.status != 200)
            throw new Error(jsonResponse.message);

        return jsonResponse.token
    } catch (error) {
        msgAlerta(error.message)
        return
    }
}

async function autenticarSIAImage() {
    try {
        const usuarioCookie = getCookie('usuario').toUpperCase()
        const usuario = getCookie('cod_usuario') == '0000' ? 'SISPLAN' : usuarioCookie

        const jsonStrEmailApp = await retornaJsonPesquisaPadrao(
            `{ "tabela":"ACESSO_USUARIOS", "camposSelect":["email_app"], "where": ["nome = '${usuario}'"]}`
        )

        const password = `${usuario.toLowerCase(0)}${jsonStrEmailApp[0].EMAIL_APP}`

        const response = await requisicaoSiaImage('POST', '/auth/login', { email: jsonStrEmailApp[0].EMAIL_APP, password })

        if (!response)
            throw new Error("Não foi possível se conectar com a SIA. Por favor, tente novamente mais tarde.")

        const jsonResponse = await response.json();

        if (response.status != 200)
            throw new Error(jsonResponse.message);

        return `Bearer ${jsonResponse.token}`
    } catch (error) {
        msgAlerta(error.message)
        return
    }
}

function processarSvg(svg) {
    const svgContent = svg
        .replaceAll('\\n', '')
        .replaceAll('\\', '')
    return `
      <div class="svg-wrapper">
        ${svgContent}
      </div>
    `;
}

async function retornaRGB(cor) {
    const rgbColor = await retornaJsonPesquisaPadrao(
        `{ "tabela":"CADCOR", "camposSelect":["rgb"], "where": ["cor = '${cor}'"]}`
    )
    return rgbColor[0].RGB
}

async function anexarMockup(sArquivo, baseString) {
    try {
        const response = await requisicao('GET', '/sisplan/funcoes/v1/caminhoanexosmockup?', null);
        if (!response) throw new Error('motivo desconhecido, tente novamente mais tarde.')

        const jsonStr = await response.json();
        if (response.status != 200) throw new Error(jsonStr.mensagem)

        const pastaAnexos = jsonStr.mensagem;

        const anexo = await requisicao(
            'POST', '/sisplan/funcoes/v1/anexoarquivo?',
            `DIRETORIO=${pastaAnexos}&TELA=CADCARACTERISTICAMOCKUP&CHAVE=00000&ARQUIVO=${sArquivo}&`, /*FIXADO A CHAVE PQ PRECISA TER ALGO*/
            `SBASE64=${encodeURIComponent(baseString.arquivo)}&FILETYPE=${baseString.tipo}`
        );

        if (!anexo) throw new Error('motivo desconhecido, tente novamente mais tarde.')

        const anexoStr = await anexo.json();
        if (anexo.status != 200) throw new Error(anexoStr.mensagem)
    } catch (error) {
        msgAlerta(`Não foi possível vincular o mockup: ${error.message}`)
    }
}

async function buscarMockup(sArquivo) {
    try {
        const response = await requisicao('GET', '/sisplan/funcoes/v1/caminhoanexosmockup?', null);
        if (!response) throw new Error('Não foi possível abrir o mockup: Motivo desconhecido, tente novamente mais tarde.')

        const jsonStr = await response.json();
        if (response.status != 200) throw new Error('Não foi possível abrir o mockup: ' + jsonStr.mensagem)

        const pastaAnexos = jsonStr.mensagem;

        const svg = await requisicao('GET', '/sisplan/funcoes/v1/buscarmockup?', `ARQUIVO=${sArquivo}&DIRETORIO=${pastaAnexos}`);
        if (!svg) throw new Error('Não foi possível abrir o mockup: Motivo desconhecido, tente novamente mais tarde.')

        if (svg.status != 200) throw new Error('Não foi possível abrir o mockup: ' + jsonStr.mensagem)
        const blob = await svg.blob();

        return blob;
    } catch (error) {
        msgAlerta(`Não foi possível vincular o mockup: ${error.message}`)
        return null;
    }
}

async function RetornaQuantidadeUnidade(unidade, quantidade) {
    if (!unidade) return quantidade;

    const pesquisaParam = {
        tabela: "UNIDADE",
        camposSelect: [
            `QTDE`,
        ],
        where: [
            `UNIDADE = '${unidade.toUpperCase()}'`,
        ]
    };
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
    if (!jsonStr[0]) return quantidade;

    return quantidade * jsonStr[0].QTDE;
}

async function controlaValorDifParametroEscritural() {
    const parametrosEscritural = await BuscaParametrosEscritural();
    let controlaValorDif = false

    if (parametrosEscritural.length > 0) {
        if (parametrosEscritural[5].VALOR == '1') {
            controlaValorDif = true;
        }
    }

    return controlaValorDif
};

async function buscaValoresDifParametroEscritural() {
    const valoresPadroesEscritural = await buscaValoresPadroes('EXTRATO_CARTAO');
    let valDif = 0;

    if (valoresPadroesEscritural.length > 0) {
        if (valoresPadroesEscritural[0].CAMPO == 'VALOR_DIFERENCA') {
            valDif = valoresPadroesEscritural[0].VALOR;
        }
    } else {
        valDif = 0;
    }

    valDif = valDif / 100;

    return valDif
}

function tratarMaximoCaracteresArrayString(maximoCaracteres, texto) {
    if (texto.length <= maximoCaracteres) {
        return texto
    }

    const textoLimitado = texto.slice(0, maximoCaracteres)
    if (textoLimitado.slice(-1) === "'") {
        return textoLimitado
    }

    const array = textoLimitado.split(',')
    array.pop()

    return array.join(',')
}

async function rotinaModalLogs(campoChave, listaTelas) {
    const dados = await buscarLogs(campoChave, listaTelas);
    preencherModalLogs(dados);
    $('#modalLogs').modal('show');
}

async function buscarLogs(campoChave, listaTelas) {

    if ($.fn.DataTable.isDataTable('#tabelaLogs')) {
        $("#tabelaLogs").DataTable().data().clear().draw(false);
    }

    const url = '/sisplan/log/v1/consultarlogscampochave?';
    const params = `CAMPO_CHAVE=${campoChave}` +
        `&LISTA_TELAS=${listaTelas.toString()}`;

    const response = await requisicao('GET', url, params, '', 60000);

    if (!response) {
        throw new Error("Não foi possível consultar os logs.")
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
        throw new Error(jsonStr.mensagem);
    }

    if (jsonStr.length == 0) {
        throw new Error("Nenhum log encontrado para esse registro.");
    }

    return jsonStr;

}

function preencherModalLogs(dados) {
    const keys = Object.keys(dados[0]);
    const dataSetCols = [];

    for (var k in keys) {
        dataSetCols.push({
            'title': keys[k],
            'data': keys[k]
        });
    };

    criaDataTablePadrao('#tabelaLogs', false, false, false, false, true, false, false, dados, dataSetCols, [], [0], [], [], {}, 2, '', '', false, [], [], false, true);

}

$("#modalLogs").on("shown.bs.modal", function () {
    if ($.fn.DataTable.isDataTable('#tabelaLogs')) {
        $('#tabelaLogs').DataTable().columns.adjust().draw(false);
    }
})

async function existeIntegracaoRelinq() {
    const url = "/sisplan/relinq/v1/existeintegracao?";

    try {
        const response = await requisicao("GET", url, "", "", 30000);

        if (!response) {
            throw new Error("Não foi possível validar a integração com a plataforma Relinq");
        }

        if (response.status != 200) {
            const json = await response.json();
            throw new Error(json.mensagem)
        }

        return true;

    } catch (error) {
        console.error(error);
        return false;
    }

}

async function buscaCadastraCep(cep) {
    try {
        $.LoadingOverlay("show");
        try {
            cep = cep.replace('-', '').trim();
            const response = await requisicao('GET', '/sisplan/cep/v1/CEP?', `CEP=${cep}`, null);

            if (!response) {
                return;
            }

            const jsonStr = await response.json();
            if (response.status != 200) {
                msgAlerta(jsonStr.mensagem, () => { abreCadastroCep(cep) }, undefined, undefined);
                return;
            }

            return {
                cidade: jsonStr.nOMCIDADE,
                uf: jsonStr.eSTCEP,
                rua: jsonStr.nOMCEP,
                bairro: jsonStr.bAIRRO
            };

        } catch (error) {
            console.error(error);
        }
    } finally {
        $.LoadingOverlay("hide");
    }
};

async function validarRegistroExpiracao(tela, valor, callback) {
    try {
        const response = await requisicao('POST', `/sisplan/controleedicao/v1/controleedicaoexpiracao?`, `TELA=${encodeURIComponent(tela)}&VALOR=${encodeURIComponent(valor)}`, null, 3600000)

        const dados = await response.json()

        if (!dados) {
            return
        }

        const { mensagem, resultado } = dados
        if (mensagem?.codigo !== 200) {
            throw mensagem?.mensagem
        }

        if (!resultado) {
            return
        }

        switch (resultado.status.toString().toUpperCase()) {
            case 'DISPONIVEL':
                callback?.()
                break
            case 'BLOQUEADO':
                return new Promise((resolve) => {
                    msgErro(
                        `Registro está sendo alterado pelo usuário ${resultado.usuario} desde ${retornarDataISOEmYMD({ dataISO: resultado.hora, incluirHora: true, reverso: true, usarUTC: true, })}. Aguarde o usuário finalizar a alteração ou ${resultado.tempoParaExpirarEmMinutos || 1} minuto(s) para forçar a liberação.`,
                        resolve,
                        resolve,
                    )
                })
            case 'EXPIRADO':
                return new Promise((resolve) => {
                    msgAlerta(
                        `Registro está sendo alterado pelo usuário ${resultado.usuario} desde ${retornarDataISOEmYMD({ dataISO: resultado.hora, incluirHora: true, reverso: true, usarUTC: true, })}. As suas alterações ou as alterações do usuário ${resultado.usuario} poderão ser excluídas/duplicadas, deseja forçar a liberação mesmo assim?`,
                        async () => {
                            try {
                                $.LoadingOverlay('show')
                                excluirRegistroExpiracao(resultado.tela, resultado.valor, true)
                                criaMensagemSucesso(
                                    'Liberação efetuada com sucesso.',
                                    () => {
                                        resolve()
                                        callback?.()
                                    }
                                )
                            } finally {
                                $.LoadingOverlay('hide')
                            }
                        },
                        resolve,
                        undefined,
                        resolve,
                        true,
                    )
                })
            default:
                break
        }
    } catch (error) {
        console.error(error)
        return null
    }
}

async function excluirRegistroExpiracao(tela, valor, forcarLiberacao) {
    try {
        const response = await requisicao('DELETE', `/sisplan/controleedicao/v1/controleedicaoexpiracao?`, `TELA=${encodeURIComponent(tela)}&VALOR=${encodeURIComponent(valor)}&FORCAR_LIBERACAO=${forcarLiberacao}`, null, 3600000)

        const dados = await response.json()

        if (!dados) {
            return
        }

        const { mensagem } = dados
        if (mensagem?.codigo !== 200) {
            throw mensagem?.mensagem
        }
    } catch (error) {
        console.error(error)
    }
}

async function excluirVariosControleEdicao(registros, forcarLiberacao) {
    try {
        const body = {
            registros,
            forcarLiberacao,
        }
        const response = await requisicao('DELETE', `/sisplan/controleedicao/v1/controleedicaovarios?`, '', JSON.stringify(body), 3600000, false, true)

        const dados = await response.json()

        if (!dados) {
            return
        }

        const { mensagem } = dados
        if (mensagem?.codigo !== 200) {
            throw mensagem?.mensagem
        }
    } catch (error) {
        console.error(error)
    }
}

function adicionarRegistroParaLiberarSessionStorage(aba, tela, valor) {
    const registrosSessionStorage = sessionStorage.getItem('registrosLiberar')
    let registros = []
    if (!registrosSessionStorage) {
        registros = [{
            aba,
            tela,
            valor,
        }]
    } else {
        registros = JSON.parse(registrosSessionStorage)
        const index = registros.findIndex((it) => it.aba === aba)
        if (index > -1) {
            registros[index] = {
                aba,
                tela,
                valor,
            }
        } else {
            registros.push({
                aba,
                tela,
                valor,
            })
        }
    }
    sessionStorage.setItem('registrosLiberar', JSON.stringify(registros))
}

function removerRegistroParaLiberarSessionStorage(aba) {
    const registrosSessionStorage = sessionStorage.getItem('registrosLiberar')
    const registros = JSON.parse(registrosSessionStorage)
    const registrosFiltrados = registros.filter((it) => it.aba !== aba)
    sessionStorage.setItem('registrosLiberar', JSON.stringify(registrosFiltrados))
}

async function pegaEmpresasUsuarioLogado() {
    try {
        const usuario = getCookie('cod_usuario')
        const response = await requisicao('GET',
            '/Sisplan/Funcoes/V1/pesquisa?',
            `JSON={ 
                "tabela":"ACESSO_EMPRESA", 
                "camposSelect":["EMPRESA"], 
                "where": ["USUARIO = '${usuario}'"]
            }`, null
        );
        if (!response) return;
        const jsonStr = await response.json();
        if (response.status !== 200) return [];
        return jsonStr.RESULT[0].map(it => it.EMPRESA);
    } catch (error) {
        console.log(error);
    }
}