/* eslint-disable no-inner-declarations */
/* eslint-disable no-unused-vars */
/* eslint-disable prefer-destructuring */
/* eslint-disable no-param-reassign */

let parametrosVenda = [];
let parametrosEntidade = [];
let listaBarrasBipadas = [];
let listaBarrasRemovidas = [];
let listaBarrasRemovidasTemp = [];
let listaBarrasBipadasEPC = [];
let listaLogsVenda = [];
let codven_devolucao = '';
let numeroBrinde = '';
let bAcessoBrinde = false;
let g_regra = [];
let logDescontoVenda = '';
let g_DescCliente = 0;
let usaProdutoRelacionado = false;
let bPrimeiraCondicaoPagamento = true;

$(`[name="selectFiltros"][value="${localStorage.getItem("@venda.selectFiltros") ?? '1'}"]`).click();

$('[name="selectFiltros"]').on('change', function () {
  const valorSelecionado = $(this).val();
  localStorage.setItem("@venda.selectFiltros", valorSelecionado);
});

$(`[name="rgPesquisaTipo"][value="${localStorage.getItem("@venda.rgPesquisaTipo") ?? '1'}"]`).click();

$('[name="rgPesquisaTipo"]').on('change', function () {
  const valorSelecionado = $(this).val();
  localStorage.setItem("@venda.rgPesquisaTipo", valorSelecionado);
});

$("#btn-reconectar").on("click", async function () {
  try {
    $.LoadingOverlay("show");
    await conectaECF(ipInterno, ipExterno, basicAuth);
    await buscaStatusImpressora();
  } finally {
    $.LoadingOverlay("hide");
  }
});

function formataNumerico(valor) {
  return parseFloat(valor.replace(",", "."));
}

async function BuscaEstadoEmpresa() {
  const url = "/sisplan/menufiscal/v1/menufiscal?";
  const response = await requisicao("GET", url, "", null, 15000);

  if (!response) {
    return;
  }

  const jsonStr = await response.text();
  if (response.status != 200) {
    msgErro("Erro ao buscar as informações");
    return;
  }
  return jsonStr;
}

async function controlaECF() {
  const bUsaECF = parametrosVenda[8];
  const bUsaNFCE = parametrosVenda[6];
  const estado = await BuscaEstadoEmpresa();

  if (bUsaECF == "1" || (estado == "SC" && bUsaNFCE == 1)) {
    if (await maquinaTemImpressora()) {
      await habilitaPanelImpressora(true);
      await buscaStatusImpressora();
      window.setInterval(async function () {
        await buscaStatusImpressora();
      }, 15000);
      window.setInterval(async function () {
        if (
          $("#txtStatusECF").html() == " Offline " ||
          $("#txtEstadoECF").html() == "Desconectado"
        ) {
          conectaECF(ipInterno, ipExterno, basicAuth);
        }
      }, 60000);
    }
  } else {
    await habilitaPanelImpressora(false);
  }
}

async function habilitaPanelImpressora(bHabilita) {
  if (bHabilita) {
    $("#panel_ecf").removeClass("d-none");
    $("#menu_fiscal").removeClass("d-none");
    $("#menu_fiscal").removeClass("d-md-none");
    $("#menu_fiscal").addClass("d-md-block");
  } else {
    $("#panel_ecf").addClass("d-none");
    $("#menu_fiscal").addClass("d-none");
    $("#menu_fiscal").removeClass("d-md-block");
    $("#menu_fiscal").addClass("d-md-none");
  }
}

// async function SalvarRetornoCupom(jsonRetornoCupom) {
//     var url = `SalvarRetornoCupom?`;

//     try {
//         var response = await requisicao_ecf('POST', url, `JSON=${encodeURIComponent(JSON.stringify(jsonRetornoCupom))}`, null);
//         if (!response) {
//             return false;
//         }

//         var jsonStr = await response.json();
//         if (response.status != 200) {
//             return false;
//         } else {
//             return true;
//         }
//     } catch (error) {
//         return false;
//     }
// }

async function RetornaCondicaoImprimeCupomGerencial(venda) {
  try {
    const empId = getCookie("emp_id");
    const params = {
      tabela: "MOEDA",
      camposSelect: ["IMP_GERENCIAL"],
      where: [
        `CODMOE IN (SELECT DISTINCT CDMOEDA FROM [CONDIVENDA] WHERE CDVENDA = ${venda} AND EMP_ID = ${empId}) AND IMP_GERENCIAL = 'S'`,
      ],
    };

    const response = await retornaJsonPesquisaPadrao(JSON.stringify(params));

    if (!response) {
      return false;
    }

    return response.length > 0;
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function ImprimirCupomGerencial(venda, cupom) {
  const url = `/cupom/imprimircupomgerencial?`;
  let sRelParam = "";
  const bTemCupomGerencial = parametrosVenda[11];
  const bCondicaoImprimeCupomGerencial =
    await RetornaCondicaoImprimeCupomGerencial(venda);

  if (
    bTemCupomGerencial == "0" ||
    bTemCupomGerencial == "" ||
    !bCondicaoImprimeCupomGerencial
  ) {
    return;
  }
  if (bTemCupomGerencial == "1") {
    sRelParam = "RECEBIMENTO";
  } else if (bTemCupomGerencial == "2") {
    sRelParam = "ITENS";
  } else {
    sRelParam = "COMPLETO";
  }
  const params = `NRCUPOM=${cupom}&NRVENDA=${venda}&TIPO_REL_GERENCIAL=${sRelParam}`;

  try {
    let response = await requisicao_ecf("GET", url, params, "", 30000);

    if (!response) {
      return;
    }

    // pegar dados pra update
    if (response.status != 200) {
      msgErro("Erro ao imprimir cupom gerencial.");
      return;
    }
    return;
  } catch (error) {
    console.error(error);
    msgErro("Erro ao imprimir cupom gerencial.");
  }
}

async function ImprimirCupomTroca(venda, tipo, lista) {
  const url = `/cupom/imprimircupomtroca?`;
  const params = `NRCUPOM=1&NRVENDA=${venda}&LISTA=${lista}&TIPO=${tipo}`;

  try {
    let response = await requisicao_ecf("POST", url, params, "", 30000);

    if (!response) {
      msgErro("Erro ao imprimir cupom de troca.");
      return;
    }

    // pegar dados pra update
    if (response.status != 200) {
      msgErro("Erro ao imprimir cupom de troca.");
      return;
    }
    return;
  } catch (error) {
    console.error(error);
    msgErro("Erro ao imprimir cupom de troca.");
  }
}

async function ImprimirCupomFiscal(jsonVenda, objeto) {
  let url = `/cupom/imprimircupom?`;
  let objetoParametro = objeto;
  try {
    const response = await requisicao_ecf("POST", url, "", jsonVenda, 3000000);

    if (!response) {
      return false;
    }

    if (response.status != 200) {
      return false;
    }
    const jsonStr = await response.json();
    objetoParametro.nrCupom = jsonStr.nrCupom;
    objetoParametro.erroCupom = jsonStr.erroCupom;
    const bRetorno = jsonStr;
    if (jsonStr.erroCupom == true) {
      setCookie("erro_impressao_cupom", jsonStr.mensagemErro);
      return false;
    }
    return bRetorno;
  } catch (error) {
    console.error(error);
    const numero_venda = $('#txtCodVen').val();
    await rotinaGeraLog('TVENDALOJA', numero_venda, `Erro ao imprimir cupom fiscal - ${numero_venda}`, 'Inclusão');
    return false;
  }
}

async function AtualizarCupom(jsonObject) {
  try {
    const url = '/sisplan/cupom/v1/atualizarcupom?';
    const params = `JSON=${encodeURIComponent(JSON.stringify(jsonObject))}`;
    const response = await requisicao("POST", url, params, null);
    if (!response) {
      msgErro("erro ao atualizar cupom");
      return;
    }

    if (response.status != 200) {
      msgErro("erro ao atualizar cupom");
      return;
    }
  }
  catch (err) {
    console.error('erro ao atualizar cupom', err);
  }
}

async function AtualizarDadosTef(jsonObject, tela) {
  try {
    const url = '/sisplan/vendas/v1/atualizardadostef?';
    const params = `JSON=${encodeURIComponent(JSON.stringify(jsonObject))}`;
    const response = await requisicao("POST", url, `TELA=${tela}`, params, 120000);
    if (!response) {
      msgErro("Erro ao atualizar os dados TEF");
      return;
    }

    if (response.status != 200) {
      msgErro("Erro ao atualizar os dados TEF");
      return;
    }
  }
  catch (err) {
    console.error('Erro ao atualizar os dados TEF', err);
  }
}

async function gravaIdPix(id, codVen, moeda) {
  try {
    const url = '/sisplan/pix/v1/gravaid?';
    const params = `ID=${id}&CODVEN=${codVen}&MOEDA=${moeda}`;
    const response = await requisicao("POST", url, params, null);
    if (!response) {
      msgErro("Erro ao gravar o ID PIX");
      return;
    }

    if (response.status != 200) {
      msgErro("Erro ao gravar o ID PIX");
      return;
    }
  } catch (err) {
    console.error('Erro ao gravar o ID PIX', err);
  }
}

async function FinalizarCupomFiscal(jsonVenda, jsonCupom) {
  const url = `/cupom/finalizarcupom?`;

  try {
    const response = await requisicao_ecf("POST", url, "", jsonVenda, 3000000);

    if (!response) {
      return false;
    }

    // pegar dados pra update
    if (response.status != 200) {
      return false;
    }
    const jsonStr = await response.json();
    if (jsonStr.erroCupom == false) {
      await AtualizarCupom(jsonStr);
      return true;
    }
    setCookie("erro_impressao_cupom", jsonStr.mensagemErro);
    return false;
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function realizaLeituraX() {
  const url = `/cupom/leiturax?`;

  msgAlerta(`Tem certeza que deseja efetuar a Leitura X?`, async function () {
    try {
      $.LoadingOverlay("show");
      try {
        const response = await requisicao_ecf("POST", url, "", "", null);

        if (!response) {
          return;
        }

        // let jsonStr = await response.json();
        if (response.status != 200) {
          msgErro("Não foi possível emitir a Leitura X, tente novamente.");
          return;
        }
      } catch (error) {
        console.error(error);
        msgErro("Não foi possível emitir a Leitura X, tente novamente.");
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });
}

async function ParametrosConfiguracao() {
  const url = `/cupom/parametrosconfiguracao?`;

  try {
    $.LoadingOverlay("show");
    try {
      const response = await requisicao_ecf("GET", url, "", "", 40000);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro(
          "Não foi possível emitir os Parametros de Configuração ECF, tente novamente."
        );
        return;
      }
    } catch (error) {
      console.error(error);
      msgErro(
        "Não foi possível emitir os Parametros de Configuração, tente novamente."
      );
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function registroPAF() {
  // 127.0.0.1:211/RegistroVendas?ano=2021&mes=02&cnpjs=&empresa=_001.
  const url = `/sisplan/cupom/v1/RegistroPAF?`;
  const sDataInicial = moment($("#txtVendasDataDe").val()).format("DD/MM/YYYY");
  const sDataFinal = moment($("#txtVendasDataAte").val()).format("DD/MM/YYYY");

  const totalPRODs = $("#tabela_prods").DataTable().rows().count();
  lista = "";
  for (let index = 0; index < totalPRODs; index++) {
    const codigo = $("#tabela_prods").DataTable().row(index).data()[0];
    lista += lista == "" ? `${codigo}` : `','${codigo}`;
  }
  const sProds = `'${lista}'`; // pegar do datatable;
  const params = `data_inicial=${sDataInicial}&data_final=${sDataFinal}&produtos=${sProds}`;

  try {
    $.LoadingOverlay("show");
    try {
      const response = await requisicao("GET", url, params, "", 40000);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro("Não foi possível emitir o RegistroPAF ECF, tente novamente.");
        return;
      }

      const jsonStr = await response.json();
      msgSucesso(
        `Arquivo gerado com sucesso, caminho: ${jsonStr.RESULT[0].mensagem}`
      );
    } catch (error) {
      console.error(error);
      msgErro("Não foi possível emitir o RegistroPAF ECF, tente novamente.");
    }
  } finally {
    $("#modal-reg").modal("hide");
    $.LoadingOverlay("hide");
  }
}

async function registroVendas() {
  // 127.0.0.1:211/RegistroVendas?ano=2021&mes=02&cnpjs=&empresa=_001.
  const url = `/cupom/registrovendas?`;
  const sAno = $("#txtVendasAno").val();
  const sMes = $("#txtVendasMes").val();

  const totalCNPJs = $("#tabela_cnpjs").DataTable().rows().count();
  lista = "";
  for (let i = 0; i < totalCNPJs; i++) {
    const cnpj = $("#tabela_cnpjs").DataTable().row(i).data()[0];
    lista += lista == "" ? `${cnpj}` : `','${cnpj}`;
  }
  const sCNPJ = `'${lista}'`; // pegar do datatable;
  const params = `ano=${sAno}&mes=${sMes}&cnpjs=${sCNPJ}`;

  try {
    $.LoadingOverlay("show");
    try {
      let response = await requisicao_ecf("GET", url, params, "", 40000);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro(
          "Não foi possível emitir a identificaPAF ECF, tente novamente."
        );
        return;
      }
    } catch (error) {
      console.error(error);
      msgErro("Não foi possível emitir a identificaPAF ECF, tente novamente.");
    }
  } finally {
    $("#modal-vendas").modal("hide");
    $.LoadingOverlay("hide");
  }
}

$("#btn_confirmar_identificacao").on("click", async function () {
  $("#modal-identificao").modal("hide");
});

$("#btn_confirmar_mesaAberta").on("click", async function () {
  $("#modal-mesaAberta").modal("hide");
});

async function MesasAbertas() {
  $("#modal-mesaAberta").modal("show");
}

async function identificaPAF() {

  const parametroVenda8 = (parametrosVenda[8]) == 0;

  if (parametroVenda8) {
    $("#modal-identificao").modal("show");
  } else {
    const url = `/cupom/identificapaf?`;

    try {
      $.LoadingOverlay("show");
      try {
        const response = await requisicao_ecf("GET", url, "", "", 40000);

        if (!response) {
          return;
        }

        if (response.status != 200) {
          msgErro(
            "Não foi possível emitir a identificaPAF ECF, tente novamente."
          );
          return;
        }
      } catch (error) {
        console.error(error);
        msgErro(
          "Não foi possível emitir a identificaPAF ECF, tente novamente."
        );
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  }
}

async function abreVendas() {
  $("#modal-vendas").modal("show");
}

$("#btn_confirmar_lmf").on("click", async function () {
  if ($("#modalLMF-titulo").html().indexOf("17/04") > 0) {
    await confirmaEspelho();
  } else {
    await confirmaLMF();
  }
});

$("#btn_confirmar_reg").on("click", async function () {
  if ($("#txtVendasDataDe").val() == "" || $("#txtVendasDataAte").val() == "") {
    msgErro("Informe as datas para continuar.");
    return;
  }
  registroPAF();
});

$('input[name="rgTipo"]').on("click", function () {
  $("#txtDataLMFDe").prop("disabled", $(this).val() == "1");
  $("#txtDataLMFAte").prop("disabled", $(this).val() == "1");
  $("#txtIntDe").prop("disabled", $(this).val() == "0");
  $("#txtIntAte").prop("disabled", $(this).val() == "0");
});

async function confirmaEspelho() {
  sTipoEmissao = $('input[name="rgTipoEmissao"]:checked').val();
  sTipo = $('input[name="rgTipo"]:checked').val();
  sDtIni = moment($("#txtDataLMFDe").val()).format("DD/MM/YYYY");
  sDtFim = moment($("#txtDataLMFAte").val()).format("DD/MM/YYYY");
  sIntIni = $("#txtIntDe").val();
  sIntFim = $("#txtIntAte").val();

  if (sTipo == "0" && (sDtIni == "" || sDtFim == "")) {
    msgErro("Necessário filtrar as datas.");
    return;
  }
  if (sTipo == "1" && (sIntIni == "" || sIntFim == "")) {
    msgErro("Necessário filtrar os intervalos.");
    return;
  }

  const url = `/cupom/espelho?`;
  const params = `DATA_INICIAL=${sDtIni}&DATA_FINAL=${sDtFim}&tipo=${sTipo}&tipo_emissao=${sTipoEmissao}&COO_INICIAL=${sIntIni}&COO_FINAL=${sIntFim}`;

  try {
    $.LoadingOverlay("show");
    try {
      const response = await requisicao_ecf("POST", url, params, "", 40000);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro(
          "Não foi possível emitir o Arquivo MFD AC 17/04, tente novamente."
        );
        return;
      }
    } catch (error) {
      console.error(error);
      msgErro(
        "Não foi possível emitir o Arquivo MFD AC 17/04, tente novamente."
      );
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function confirmaLMF() {
  sTipoEmissao = $('input[name="rgTipoEmissao"]:checked').val();
  sTipoData = $('input[name="rgTipo"]:checked').val();
  sDtIni = moment($("#txtDataLMFDe").val()).format("DD/MM/YYYY");
  sDtFim = moment($("#txtDataLMFAte").val()).format("DD/MM/YYYY");
  sIntIni = $("#txtIntDe").val();
  sIntFim = $("#txtIntAte").val();
  bSimples = $("#modalLMF-titulo").html().indexOf("Simples") > 0;

  if (sTipoData == "0" && (sDtIni == "" || sDtFim == "")) {
    msgErro("Necessário filtrar as datas.");
    return;
  }
  if (sTipoData == "1" && (sIntIni == "" || sIntFim == "")) {
    msgErro("Necessário filtrar os intervalos.");
    return;
  }

  const url = `/cupom/leituramemoriafiscal?`;
  const params = `dt_inicial=${sDtIni}&dt_final=${sDtFim}&tipo_mf=${bSimples ? "S" : "C"
    }&tipo=${sTipoData}&tipo_emissao=${sTipoEmissao}&int_inicial=${sIntIni}&int_final=${sIntFim}`;

  try {
    $.LoadingOverlay("show");
    try {
      const response = await requisicao_ecf("GET", url, params, "", 40000);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro(
          "Não foi possível emitir a identificaPAF ECF, tente novamente."
        );
        return;
      }
    } catch (error) {
      console.error(error);
      msgErro("Não foi possível emitir a identificaPAF ECF, tente novamente.");
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function abreLMF(sTipo) {
  $("#modalLMF-titulo").html(
    sTipo == "simples"
      ? "Leitura de Memória Fiscal - Simples"
      : "Leitura de Memória Fiscal - Completa"
  );
  $("#espelho_dll").css("display", "none");
  $("#rgTipoEmissao").html("Tipo Emissão");
  $("#rgTipoEmissao1").html("Arquivo/Serial");
  $("#rgTipoEmissao2").html("Impresso");
  $("#modal-lmf").modal("show");
}

async function abreArqMFD() {
  $("#modalLMF-titulo").html("Arquivo MFD AC 17/04");
  $("#espelho_dll").css("display", "visible");
  $("#rgTipoEmissao").html("Tipo Emissão");
  $("#rgTipoEmissao1").html("Arquivo");
  $("#rgTipoEmissao2").html("Espelho");
  $("#modal-lmf").modal("show");
}

async function geraArquivo(sTipo) {
  const url =
    sTipo == "MF" ? "/cupom/gerararquivomf?" : "/cupom/gerararquivomfd?";

  msgAlerta(
    `Tem certeza que deseja gerar o arquivo ${sTipo}?`,
    async function () {
      try {
        $.LoadingOverlay("show");
        try {
          const response = await requisicao_ecf("GET", url, "", "", null);
          if (!response) {
            return;
          }
          if (response.status != 200) {
            msgErro(
              `Não foi possível gerar o arquivo ${sTipo}, tente novamente.`
            );
            return;
          }
        } catch (error) {
          console.error(error);
          msgErro(
            `Não foi possível gerar o arquivo ${sTipo}, tente novamente.`
          );
        }
      } finally {
        $.LoadingOverlay("hide");
      }
    }
  );
}
async function AbreREG() {
  $("#modal-reg").modal("show");
}

async function preencheSelectImpressoras() {
  try {
    const json = await retornaJsonPesquisaPadrao(
      `{"tabela": "VENDA_REDZ", "camposSelect": ["DISTINCT SERIE_ECF"], "where": ["emp_id = '${getCookie(
        "emp_id"
      )}'"] }`
    );

    if (json) {
      for (let i = 0; i < json.length; i++) {
        $("#selectImpressoras").append(
          `<option value="${json[i].SERIE_ECF}">${json[i].SERIE_ECF}</option>`
        );
      }
    }
    return json;
  } catch (error) {
    console.error();
  }
}

async function AbreArqBlocoX(sTipo) {
  $("#modal-blocox-titulo").html(
    sTipo == "RZ"
      ? "Gerar Arquivos Bloco X - Redução Z"
      : "Gerar Arquivos Bloco X - Estoque"
  );
  $("#tabela-blocox-redz").DataTable().rows().remove().draw(false);

  await preencheSelectImpressoras();

  $("#modal-blocox").modal("show");
}

$("#btn_confirmar_titp").on("click", function () {
  $("#modal-titp").modal("hide");
});

// async function preencheSelectImpressoras() {
//     try {
//         if (codMoeda != '') {
//             const json = await retornaJsonPesquisaPadrao(`{"tabela": "moeda", "camposSelect": ["descmax"], "where": ["codmoe = '${codMoeda}'"] }`);
//             if (json) {
//                 return parseFloat(json[0].DESCMAX);
//             }
//         }

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

async function AbreTITP(sTipo) {
  if (sTipo != undefined) {
    $("#modaltitp-titulo").html("Requisições Externas Registradas");
    $("#modaltitp-conteudo").html(
      `Este PAF­ECF não recebe requisições externas.`
    );
  } else {
    $("#modaltitp-titulo").html("Tab. Indíce Técnico de Produção");
    $("#modaltitp-conteudo")
      .html(`Este PAF-ECF não executa funções de baixa de estoque com base
                                       em índices técnicos de produção, não podendo ser utilizado
                                       por estabelecimento que necessite deste recurso.`);
  }
  $("#modal-titp").modal("show");
}

async function retornaRegistrosEst() {
  const url = "/sisplan/cupom/v1/BlocoXEstoque?";
  const sDtInicio = moment($("#txtBlocoXInicio").val()).format("DD/MM/YYYY");
  const sDtFim = moment($("#txtBlocoXFim").val()).format("DD/MM/YYYY");
  const sStatus = $("input[name=rg_status_bloco_x]:checked").val();

  const params = `DT_INICIO=${sDtInicio}&DT_FIM=${sDtFim}&STATUS=${sStatus}`;
  let dataSet = [];
  let dataSetCols = [];
  try {
    try {
      $.LoadingOverlay("show");
      let response = await requisicao("GET", url, params, null);

      if (!response) {
        msgErro("Erro ao buscar registros do Estoque");
        return;
      }

      let jsonStr = await response.json();
      if (response.status != 200) {
        msgErro("Erro ao buscar registros do Estoque");
        return;
      }
      dataSet = jsonStr;
      if (!$.isEmptyObject(dataSet[0])) {
        // preciso dinamicamente ter a relação com o nome das colunas para tabela
        let keys = Object.keys(dataSet[0]);
        for (let k in keys) {
          dataSetCols.push({ title: keys[k], data: keys[k] });
        }

        $("#tabela-blocox-redz").DataTable({
          columns: dataSetCols,
          data: dataSet,
          paging: false,
          filter: false,
          info: false,
          order: false,
          destroy: true,
          autowidth: true,
        });

        $("#tabela-blocox-redz tbody").on("click", "tr", function () {
          if ($(this).hasClass("selected")) {
            $(this).removeClass("selected");
            $("#btn_blocox_transmitir").addClass("d-none");
            $("#btn_blocox_consultar").addClass("d-none");
          } else {
            $("#tabela-blocox-redz")
              .DataTable()
              .$("tr.selected")
              .removeClass("selected");
            $(this).addClass("selected");
            $("#btn_blocox_transmitir").removeClass("d-none");
            $("#btn_blocox_consultar").removeClass("d-none");
          }
        });
      } else {
        dataSet = [];
        dataSetCols = [];
        $("#tabela-blocox-redz").DataTable().rows().remove().draw(false);
      }
    } catch (error) {
      console.error(error);
      msgErro("Erro ao buscar registros da Redução Z");
      return;
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function CancelaUltimoCupom() {
  const url = "/cupom/cancelarultimocupom?";
  try {
    let response = await requisicao_ecf("GET", url, "", null);
    if (!response) {
      return false;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      return false;
    }
    if (jsonStr.status == 0) {
      return true;
    }
    return false;
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function validaCancelamento(obs, venda, cupom) {
  try {
    let response = await requisicao(
      "POST",
      "/Sisplan/Vendas/V1/ValidaCancelamento?",
      `OBS=${obs}&CODVEN=${venda}&NRCUPOM=${cupom}`
    );
    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.mensagem);
      return false;
    }
    return true;
  } catch (error) {
    console.error(error);
  }
}

async function validaPedidoPendente(venda) {
  try {
    let response = await requisicao(
      "GET",
      "/Sisplan/Vendas/V1/validapedidopendente?",
      `CODVEN=${venda}`
    );
    let jsonStr = await response.json();
    
    if (response.status != 200) {
      msgErro(jsonStr.mensagem);
      return false;
    }
    
    if (!jsonStr.bloqueio) {
      if (!jsonStr.numero) return true; // sem pedido pendente
      return await msgAguardaConfirmacao(`O pedido ${jsonStr.numero}, vinculado à venda, possui quantidade pendente. Deseja cancelar a venda e o pedido?`, () => { return true }, () => { return false }); 
    }

    msgAlerta(`O pedido ${jsonStr.numero}, vinculado à venda, possui quantidade faturada ou expedida. Impossível continuar.`);
    return false;
  } catch (error) {
    console.error(error);
  }
}

async function ValidaUltimoCupom(sCupomAtual) {
  const url = "/sisplan/cupom/v1/ValidarNrCupom?";
  const serieECF = getCookie("serie_ecf");
  const numeroCupom = await RetornaUltimoCupomImpressora();

  if (numeroCupom != sCupomAtual) {
    return false;
  }

  const params = `SERIE_ECF=${serieECF}&NRCUPOM=${numeroCupom}`;
  try {
    let response = await requisicao("GET", url, params, null);
    if (!response) {
      return false;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      return false;
    }
    return true; // retorna se é o ultimo cupom gravado no banco...
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function RetornaItensCupom(iVenda) {
  const empId = getCookie("emp_id");
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  const pesquisa = {
    tabela: "itvenda",
    camposSelect: ["ITVENDA.CODVEN VENDA", "ITVENDA.EMP_ID", "VENDA.DT_ORIG DATA_CRIACAO", "VENDA.DATA DATA_ULTIMA_GRAVACAO", "VENDA.HR_VENDA HORA_ULTIMA_GRAVACAO",
      "VENDA.CODCLI", "ENTIDADE.NOME NOME_CLIENTE", "ENTIDADE.CNPJ", "VENDA.NRCAIXA", "CAIXA.DESCRICAO DESC_CAIXA",
      "VENDA.TABELA", "TABELA.DESCRICAO DESC_TABELA", "VENDA.PRAZO", "VENDA.CODREP", "REPRESENTANTE.NOME NOME_REPRESENTANTE",
      "OBS.OBSERVACAO", "ITVENDA.CODREP CODREP_ITENS", "REPRESENTANTEI.NOME NOME_REPRESENTANTE_ITENS",
      "ITVENDA.TABELA TABELA_ITENS", "TABELAI.DESCRICAO DESC_TABELA_ITENS", "ITVENDA.DEPOSITO", "DEPOSITO.DESCRICAO DESC_DEPOSITO",
      "ITVENDA.DT_INCLUSAO DATA_INCLUSAO",
      "case when ITVENDA.TIPO = 'P' then PRODUTO.UNIDADE when ITVENDA.TIPO = 'M' THEN MATERIAL.UNIDADE end as UNIDADE",
      "itvenda.QUALIDADE", "ITVENDA.BARRA", "ITVENDA.LOTE", "ITVENDA.PRECO_LIQ", "ITVENDA.OBS", "ITVENDA.VALOR", "ITVENDA.DESC_ITEM",
      "ITVENDA.VALOR_DESC", "ITVENDA.CASHBACK_VAL", "ITVENDA.TOTAL", "ITVENDA.TOTAL_LIQ",
      "itvenda.coditven", "itvenda.codigo", "case when ITVENDA.TIPO = 'P' then PRODUTO.DESCRICAO when ITVENDA.TIPO = 'M' THEN MATERIAL.DESCRICAO end as DESCRICAO",
      "itvenda.cor", "cadcor.descricao desc_cor",
      "itvenda.tam", "itvenda.quantidade", "itvenda.presente"],
    leftjoin: [{ "tabela": "venda", "condicao": "itvenda.codven = venda.codven and venda.emp_id = itvenda.emp_id" },
    { "tabela": "entidade", "condicao": "entidade.codcli = venda.codcli" },
    { "tabela": "vendaobs", "alias": "obs", "condicao": "OBS.CODVEN = VENDA.CODVEN and OBS.EMP_ID = VENDA.EMP_ID " },
    { "tabela": "caixa_loja", "alias": "caixa", "condicao": "caixa.codigo = venda.nrcaixa " },
    { "tabela": "produto", "condicao": "itvenda.codigo = produto.codigo" },
    { "tabela": "material", "condicao": "itvenda.codigo = material.codigo" },
    { "tabela": "faixa_iten", "condicao": "faixa_iten.faixa = produto.faixa and faixa_iten.tamanho = itvenda.tam" },
    { "tabela": "cadcor", "condicao": "cadcor.cor = itvenda.cor" },
    { "tabela": "represen", "alias": "representante", "condicao": "representante.codrep = venda.codrep" },
    { "tabela": "represen", "alias": "representantei", "condicao": "representantei.codrep = venda.codrep" },
    { "tabela": "regiao", "alias": "tabela", "condicao": "tabela.regiao = venda.tabela" },
    { "tabela": "regiao", "alias": "TABELAI", "condicao": "tabelai.regiao = itvenda.tabela" },
    { "tabela": "deposito", "condicao": "deposito.codigo = itvenda.deposito" }],
    where: [`itvenda.codven = ${iVenda} and itvenda.emp_id = ${empId}`],
    orderby: ["itvenda.coditven", "itvenda.codigo", "itvenda.cor", "faixa_iten.posicao"]
  }
  const params = `JSON=${JSON.stringify(pesquisa)}`;
  try {
    const response = await requisicao("GET", url, params, null);

    if (!response) {
      return "";
    }

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

    return jsonStr.RESULT[0];
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da venda.");
    return "";
  }
}

async function abreCupomTroca() {
  $("#venda-cupom-troca").val("");
  $("#tabela-itens-cupom-troca").DataTable().rows().remove().draw(false);
  retornaHintRelatorio('confirmar-cupom-troca', 'ImprimirCupom')
  $("#modal-cupom-troca").modal("show");
}

async function rotinaSaidaVendaCupomTroca() {
  if (
    $("#venda-cupom-troca").val() == "" ||
    $("#venda-cupom-troca").attr("disabled") == true
  ) {
    // nao faz nada ...
  } else {
    $("#tabela-itens-cupom-troca").DataTable().rows().remove().draw(false);
    const venda = pegaChave("#venda-cupom-troca");
    await buscaItensCupomTroca(parseInt(venda));
  }
}

$("#modal-cupom-troca").on("shown.bs.modal", function () {
  $("#tabela-itens-cupom-troca").DataTable().columns.adjust().draw(false);
  if (
    $("#venda-cupom-troca").attr("disabled") != "disabled" &&
    $("#venda-cupom-troca").val() == ""
  ) {
    $("#venda-cupom-troca").focus();
  }
});

async function RotinaConfirmarPrecoManual(sTabela, sBarra, pPreco, pIdItem) {
  try {
    try {
      $.LoadingOverlay("show");
      const url = `/Sisplan/Vendas/V1/PrecoTabela?`;

      if ($('#modalMaterial').is(':visible')) {
        tipoItem = "M";
      }
      else if ($("#radioProduto").is(":checked")) {
        tipoItem = "P";
      } else {
        tipoItem = 'M'; // necessário para quando o cliente está bipando a barra do material sem o modal aberto
      }


      const params = `tabela=${sTabela}&barra=${encodeURIComponent(sBarra)}&idItem=${pIdItem}&TIPO=${tipoItem}&PRECO=${pPreco}&PRAZO=${pegaValor('#rgPrazo')}`;
      let response = await requisicao("POST", url, params, null);
      if (!response) {
        msgErro("Erro ao consultar gravar preço");
        return;
      }

      if (response.status != 200) {
        msgErro("Erro ao gravar preço");
        return false;
      }

      $("#modalCadPreco").modal("hide");
      $("#txtCodigo").val(sBarra);
      $("#txtIdItem").val(pIdItem);
      $("#txtCodigo").attr("tipoItem", tipoItem);
      $("#txtCodigo").attr("semFoco", true);
      $("#txtCodigo").trigger("blur");
    } catch (error) {
      console.error(error);
      msgErro("Erro ao gravar preço");
      return;
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function RotinaConfirmarPrecoManualEPC(sTabela, sBarra, pPreco, pIdItem) {
  try {
    try {
      $.LoadingOverlay("show");
      const url = `/sisplan/vendas/v1/precotabela?`;

      const params = `tabela=${sTabela}&barra=${encodeURIComponent(sBarra)}&idItem=${pIdItem}&TIPO=${'P'}&PRECO=${pPreco}&PRAZO=${pegaValor('#rgPrazo')}`;
      let response = await requisicao("POST", url, params, null);
      if (!response) {
        msgErro("Erro ao consultar gravar preço");
        return;
      }

      if (response.status != 200) {
        msgErro("Erro ao gravar preço");
        return false;
      }
    } catch (error) {
      console.error(error);
      msgErro("Erro ao gravar preço");
      return;
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function buscaItensCupomTroca(iVenda) {
  const dataSet = await RetornaItensCupom(iVenda);
  for (let i = 0; i < dataSet.length; i++) {
    let data = [
      `<center><input type="checkbox" class="checkCupom" id="cb_itens_troca_${i}"></center>`,
      dataSet[i].CODITVEN,
      dataSet[i].CODIGO,
      dataSet[i].DESCRICAO,
      dataSet[i].COR,
      dataSet[i].DESC_COR,
      dataSet[i].TAM,
      dataSet[i].QUANTIDADE,
      dataSet[i].VENDA,
      dataSet[i].EMP_ID,
      dataSet[i].DATA_CRIACAO,
      dataSet[i].DATA_ULTIMA_GRAVACAO,
      dataSet[i].CODCLI,
      dataSet[i].NOME_CLIENTE,
      dataSet[i].CNPJ,
      dataSet[i].NRCAIXA,
      dataSet[i].DESC_CAIXA,
      dataSet[i].TABELA,
      dataSet[i].DESC_TABELA,
      dataSet[i].PRAZO,
      dataSet[i].CODREP,
      dataSet[i].NOME_REPRESENTANTE,
      dataSet[i].OBSERVACAO,
      dataSet[i].CODREP_ITENS,
      dataSet[i].NOME_REPRESENTANTE_ITENS,
      dataSet[i].TABELA_ITENS,
      dataSet[i].DESC_TABELA_ITENS,
      dataSet[i].DEPOSITO,
      dataSet[i].DESC_DEPOSITO,
      dataSet[i].DATA_INCLUSAO,
      dataSet[i].UNIDADE,
      dataSet[i].QUALIDADE,
      dataSet[i].BARRA,
      dataSet[i].LOTE,
      dataSet[i].PRECO_LIQ,
      dataSet[i].OBS,
      dataSet[i].VALOR,
      dataSet[i].DESC_ITEM,
      dataSet[i].VALOR_DESC,
      dataSet[i].CASHBACK_VAL,
      dataSet[i].TOTAL,
      dataSet[i].TOTAL_LIQ,
      dataSet[i].QUANTIDADE,
      dataSet[i].PRESENTE,
      dataSet[i].HORA_ULTIMA_GRAVACAO
    ];
    $("#tabela-itens-cupom-troca").DataTable().row.add(data).draw(false);
  }
  for (let i = 0; i < $(".checkCupom").length; i++) {
    const element = $($(".checkCupom")[i]).closest("td");
    if (dataSet[i].PRESENTE == "S") {
      selecionarLinhaTabela("#tabela-itens-cupom-troca", "checkCupom", element);
    }
  }
}

async function RetornaUltimoCupomImpressora() {
  // caso retornar -1 significa que não deu certo a comunicação.
  const url = "/cupom/retornanrultimocupom?";
  try {
    const response = await requisicao_ecf("GET", url, "", null);
    if (!response) {
      return -1;
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
      return -1;
    }
    if (jsonStr.status == 0) {
      return jsonStr.valor;
    }
    return -1;
  } catch (error) {
    console.error(error);
    return -1;
  }
}

async function verificaDuplicatasEmAberto(valorAntecipacao) {
  try {
    $.LoadingOverlay("show");
    try {
      let dataSet = [];
      let dataSetCols = [];
      const jsonStr = await buscaDuplicatasEmAberto(pegaChave("#txtCliente"));
      $("#txtValorAntecipacaoAberta").html(
        ArredondarValor(valorAntecipacao, 2)
      );
      if (!$.isEmptyObject(jsonStr)) {
        dataSet = jsonStr;
        if (!$.isEmptyObject(dataSet[0])) {
          const keys = Object.keys(dataSet[0]);
          dataSetCols[0] = { title: "SELECIONAR", data: "SELECIONAR" };
          keys.forEach((key) => {
            dataSetCols.push({ title: key, data: key });
          });

          dataSetCols[0].render = function (data, type, row, meta) {
            return (
              `${'<div class="group-default form-group">' +
              '<div class="relative">' +
              '<input style="height:20px" type="checkbox" id="check_col_'
              }${[meta.row]}_row_${[
                meta.col,
              ]}" class="input-default focus form-control validate campoCheck"> ` +
              `</div>` +
              `</div>`
            );
          };

          $("#tabelaDuplicatasEmAberto").DataTable({
            columns: dataSetCols,
            data: dataSet,
            paging: false,
            filter: false,
            info: false,
            order: false,
            destroy: true,
            autowidth: true,
          });

          $(".campoCheck").on("change", function () {
            if (this.checked) {
              $(this).addClass("selecionado");
            } else {
              $(this).removeClass("selecionado");
            }
          });
        }

        const tableData = $("#tabelaDuplicatasEmAberto")
          .DataTable()
          .column(7, {})
          .data()
          .sum();
        if (tableData > valorAntecipacao) {
          return true;
        }
      }

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

async function retornaRegistrosRedZ() {
  const url = "/sisplan/cupom/v1/BlocoX?";
  const sDtInicio = moment($("#txtBlocoXInicio").val()).format("DD/MM/YYYY");
  const sDtFim = moment($("#txtBlocoXFim").val()).format("DD/MM/YYYY");
  const sSerieECF = $("#selectImpressoras").val();
  const sStatus = $("input[name=rg_status_bloco_x]:checked").val();

  const params = `DT_INICIO=${sDtInicio}&DT_FIM=${sDtFim}&STATUS=${sStatus}&SERIE_ECF=${sSerieECF}`;
  let dataSet = [];
  let dataSetCols = [];
  try {
    $.LoadingOverlay("show");
    try {
      const response = await requisicao("GET", url, params, null);

      if (!response) {
        msgErro("Erro ao buscar registros da Redução Z");
        return;
      }

      const jsonStr = await response.json();
      if (response.status != 200) {
        msgErro("Erro ao buscar registros da Redução Z");
        return;
      }
      dataSet = jsonStr;
      if (!$.isEmptyObject(dataSet[0])) {
        // preciso dinamicamente ter a relação com o nome das colunas para tabela
        let keys = Object.keys(dataSet[0]);
        for (let k in keys) {
          dataSetCols.push({ title: keys[k], data: keys[k] });
        }

        dataSet.map((item) => {
          item.EMITIDO = (item.RECIBO != '') && (item.EMITIDO == 'N') ? 'A' : item.EMITIDO
        });

        $("#tabela-blocox-redz").DataTable({
          columns: dataSetCols,
          data: dataSet,
          paging: false,
          filter: false,
          info: false,
          order: false,
          destroy: true,
          autowidth: true,
        });

        $("#tabela-blocox-redz tbody").on("click", "tr", function () {
          if ($(this).hasClass("selected")) {
            $(this).removeClass("selected");
            $("#btn_blocox_transmitir").addClass("d-none");
            $("#btn_blocox_consultar").addClass("d-none");
          } else {
            $("#tabela-blocox-redz")
              .DataTable()
              .$("tr.selected")
              .removeClass("selected");
            $(this).addClass("selected");
            $("#btn_blocox_transmitir").removeClass("d-none");
            $("#btn_blocox_consultar").removeClass("d-none");
          }
        });
      } else {
        dataSet = [];
        dataSetCols = [];
        $("#tabela-blocox-redz").DataTable().rows().remove().draw(false);
      }
    } catch (error) {
      console.error(error);
      msgErro("Erro ao buscar registros da Redução Z");
      return;
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function VerificaSeEmpresaUsaProdutosRelacionados() {
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  const pesquisa = {
    tabela: "PROD_RELAC",
    camposSelect: ["ID"],
    where: ["1=1"]
  };

  try {
    const response = await requisicao(
      "GET",
      url,
      `JSON=${JSON.stringify(pesquisa)}`,
      null
    );

    if (!response) {
      return;
    }

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

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

$(document).ready(async function () {
  parametrosVenda = await BuscaParametrosVenda();
  parametrosSistema = await BuscaParametrosSistema('S');
  parametrosEntidade = await BuscaParametrosEntidade();
  usaProdutoRelacionado = await VerificaSeEmpresaUsaProdutosRelacionados();
  quantidadeCasasDecimaisParametro = parametrosSistema[1] ?? 0;
  quantidadeCasasDecimaisCampo = (+quantidadeCasasDecimaisParametro) + 2;
  const paramEstoque = parametrosVenda[4]; //0 - bloqueia // 1 - permite //2 - permite sem mensagem;
  const parametroOcultarBotaoGravarBrinde = parametrosVenda[104] == 1 ?? false;

  const bloqNatureza = await CopiaParametro('FATURAMENTO', 13) == '1';

  $("#txtNaturezaNFCE").prop('disabled', bloqNatureza);
  $("#btn-NaturezaNFCE").prop('disabled', bloqNatureza);
  $("#btn-limpa-NaturezaNFCE").prop('disabled', bloqNatureza);
  $("#txtNaturezaNFE").prop('disabled', bloqNatureza);
  $("#btn-NaturezaNFE").prop('disabled', bloqNatureza);
  $("#btn-limpa-NaturezaNFE").prop('disabled', bloqNatureza);

  if (parametrosVenda[89] == 1) {
    if ($('#divCliente').hasClass('col-md-6')) {
      $('#divCliente').removeClass('col-md-6');
      $('#divCliente').addClass('col-md-5');
    } else {
      $('#divCliente').removeClass('col-md-8');
      $('#divCliente').addClass('col-md-7');
    }
    $('#divSenha').removeClass('d-none');
  }
  $("#collapseMenu").on("shown.bs.collapse", function (e) {
    $(".subatalho .fa-angle-down")
      .removeClass("fa-angle-down")
      .addClass("fa-angle-up");
  });
  $("#collapseMenu").on("hidden.bs.collapse", function (e) {
    $(".subatalho .fa-angle-up")
      .removeClass("fa-angle-up")
      .addClass("fa-angle-down");
  });
  let empId = getCookie("emp_id");

  $("#venda-cupom-troca").autocompleta(2, `JSON={ "tabela":"venda", "camposSelect":[ "venda.codven chave", "venda.codven descricao" ], "where": ["venda.emp_id = ${empId}"]}`);
  $('#txtPais').autocompleta(1, `JSON={ "tabela":"cadpais", "camposSelect":[ "codigo chave", "nome descricao"], "where": null}`, [], [], [], preencheDDI);
  $("#txtGrupo").autocompleta(1, `JSON={ "tabela":"GRUPO_CLI", "camposSelect":[ "CODIGO CHAVE", "DESCRICAO DESCRICAO"], "where": null}`);
  $('#txtNaturezaCFe').autocompleta(1, `JSON={ "tabela":"natureza", "camposSelect":["NATUREZA CHAVE, DESCRICAO DESCRICAO"], "where": [] }`);
  $('#txtTransportadoraModal').autocompleta(1, `JSON={ "tabela":"TABTRAN", "camposSelect":[ "CODIGO CHAVE", "NOME DESCRICAO"], "where": null}`);
  $('#txtConfXMLModal').autocompleta(1, `JSON={ "tabela":"FATCONF_XML", "camposSelect":[ "CODIGO CHAVE", "DESCRICAO DESCRICAO"], "where": null}`);
  const sWhereOperFiscal = await retornaWhereOperFiscalUsuario(getCookie('cod_usuario'));

  $("#txtOperacaoCFe").autocompleta(1, `JSON={ "tabela":"oper_fiscal", "camposSelect":["CODIGO CHAVE, DESCRICAO DESCRICAO"], "where": ${sWhereOperFiscal} }`);
  $('#txtPerfil').autocompleta(1, `JSON={ "tabela":"PERFIL", "camposSelect":[ "CODIGO CHAVE", "DESCRICAO DESCRICAO"], "where": null}`);

  $('#btnPerfil').pesquisa('#txtPerfil', 'CODIGO', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"PERFIL", "camposSelect":[ "CODIGO", "DESCRICAO"]}`, 'Pesquisa Perfil', 'PERFIL');
  $("#btn-venda-cupom-troca").pesquisa("#venda-cupom-troca", "CODVEN", "CODVEN", `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"VENDA", "camposSelect":[ "venda.codven", "venda.codcli", "entidade.nome"], "leftjoin":[{"tabela" : "entidade", "condicao" : "entidade.codcli = venda.codcli"}], "where": ["venda.emp_id = ${empId}"], "orderby": ["venda.codven desc"]}`, "Pesquisa Venda", "venda");
  $("#btn-Grupo").pesquisa("#txtGrupo", "CODIGO", "DESCRICAO", `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"GRUPO_CLI", "camposSelect":[ "CODIGO", "DESCRICAO"]}`, "Pesquisa Grupo", "GRUPO_CLI");
  $("#btn-pais-entidade").pesquisa_array(["#txtPais"], ["CODIGO"], ["NOME"], `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"CADPAIS", "camposSelect":[ "CODIGO", "NOME" ], "where": null}`, "Pesquisa País", "CADPAIS", preencheDDI);
  $('#btn-NaturezaCFe').pesquisa('#txtNaturezaCFe', 'NATUREZA', 'DESCRICAO', '/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"natureza", "camposSelect":[ "natureza", "descricao" ], "where": null}', 'Pesquisa Natureza', 'natureza');
  $('#btnPesquisaTransportadoraModal').pesquisa('#txtTransportadoraModal', 'CODIGO', 'NOME', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"TABTRAN", "camposSelect":[ "CODIGO", "NOME"]}`, 'Pesquisa Transportadora', 'TABTRAN');
  $('#btnConfXMLModal').pesquisa('#txtConfXMLModal', 'CODIGO', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"FATCONF_XML", "camposSelect":[ "CODIGO", "DESCRICAO"]}`, 'Pesquisa Conf XML', 'FATCONF_XML');
  $("#btnOperacaoCFe").pesquisa("#txtOperacaoCFe", "CODIGO", "DESCRICAO", `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"oper_fiscal", "camposSelect":[ "codigo", "descricao" ], "where": ${sWhereOperFiscal}}`, "Pesquisa Operação", "oper_fiscal");
  $('#btnClienteCFE').pesquisa_serverside(['#txtClienteCFE', "#txtCpfCFe"], ['CODCLI', 'CNPJ'], ['NOME', 'CNPJ'], `{ "tabela":"ENTIDADE", "camposSelect":[ "CODCLI", "NOME", "FANTASIA", "CNPJ" ], ${(['1', '2'].includes(parametrosVenda[51])) ? `"innerJoin":[{"tabela": "EMP_VALOR", "condicao": "EMP_VALOR.TABELA = 'ENTIDADE' AND EMP_VALOR.VALOR = ENTIDADE.CODCLI AND EMP_VALOR.EMP_ID = ${getCookie("emp_id")}"}],` : ""} "where": ${parametrosVenda[65] == '1' ? ["ENTIDADE.TIPO = '1' AND ENTIDADE.CONS_FINAL = 'Sim'"] : "null"} }`, 'Pesquisa de Cliente', () => { $("#txtCpfCFe").val(pegaChave("#txtCpfCFe")); });

  async function preencheDDI() {
    setTimeout(async () => {
      const pais = pegaChave('#txtPais')
      if (!pais) {
        return
      }
      const ddi = (await buscaValor('CADPAIS', 'DDI', 'CODIGO', pais)).DDI
      $('#txtDDI').val(ddi)
    }, 500)
  }


  $("#btn-limpa-venda-cupom-troca").on("click", function () {
    limpaValor("#venda-cupom-troca");
  });

  $("#btn-AGrupo").on("click", function () {
    $("#txtGrupo").val("");
  });

  $("#btn-limpar-pais-entidade").on("click", function () {
    $("#txtPais").val("");
  });

  $("#btnAOperacaoCFe").on("click", function () {
    $("#txtOperacaoCFe").val("");
  });

  $('#btn-limpa-NaturezaCFe').on('click', function () {
    $('#txtNaturezaCFe').val('');
  });

  $("#btnLimpaTransportadoraModal").on('click', function () {
    $('#txtTransportadoraModal').val('');
  });

  $("#btnLimpaConfXMLModal").on('click', function () {
    $('#txtConfXMLModal').val('');
  });

  $("#btnLimpaPerfil").on('click', function () {
    $('#txtPerfil').val('');
  });

  $("#venda-cupom-troca").on("blur", async function () {
    await rotinaSaidaVendaCupomTroca();
  });

  $("#btnCancelarBrinde").on("click", function () {
    limpaCamposBrinde();
    $('#modal-brinde').modal('hide');
  });

  $('#modal-brinde').on('hidden.bs.modal', function (e) {
    if ($.fn.DataTable.isDataTable('#tabelaAcessoBrinde')) {
      $('#tabelaAcessoBrinde').DataTable().destroy();
      $('#tabelaAcessoBrinde').empty();
    }
    if ($.fn.DataTable.isDataTable('#tabelaItensBrinde')) {
      $('#tabelaItensBrinde').DataTable().destroy();
      $('#tabelaItensBrinde').empty();
    }
  });

  $("#modal-brinde").on("show.bs.modal", function () {
    if (parametroOcultarBotaoGravarBrinde) {
      $("#btnGravarBrinde").addClass("d-none");
    }
  })

  $('#tabelaAcessoBrinde').on('click', '#btnImprimirBrindeIndividual', async function () {
    const data = $('#tabelaAcessoBrinde').DataTable().row($(this).parents('tr')).data();
    await imprimirBrindeIndividual(data.BRINDE);
  });

  $('#tabelaAcessoBrinde').on('click', '#btnCancelarBrinde', async function () {
    const data = $('#tabelaAcessoBrinde').DataTable().row($(this).parents('tr')).data();
    await cancelarBrinde(data.BRINDE, data.LANCAMENTO);
  });

  $('#tabelaAcessoBrinde').on('click', '#btnGerarNFeBrinde', async function () {
    const data = $('#tabelaAcessoBrinde').DataTable().row($(this).parents('tr')).data();
    modalBrindeNFE(data);
  });

  async function modalBrindeNFE(data) {
    if (data.STATUS == 'CANCELADO') {
      msgAlerta('Brinde cancelado, impossível gerar NF-e.')
      return;
    }

    numeroBrinde = data.BRINDE;
    insereValor('#txtClienteBrindeNFE', data.CODCLI, data.CLIENTE);
    bAcessoBrinde = true;
    await buscaOperacaoPadraoBrinde();

    if (await ExisteNotaBrinde(numeroBrinde)) {
      await msgAlerta('Já existe documento fiscal para esse brinde, deseja continuar?', () => { }, () => { }, () => {
        $('#modalBrindeNFE').modal('show');
      }, () => { }, true);
      return;
    }

    $('#modalBrindeNFE').modal('show');
  }

  async function ExisteNotaBrinde(brinde) {
    $.LoadingOverlay('show');
    try {
      const response = await requisicao(
        "GET",
        "/Sisplan/NFe/v1/existenotabrinde?",
        `BRINDE=${brinde}`,
        null
      );

      if (!response) {
        $.LoadingOverlay("hide");
        return;
      }
      const jsonStr = await response.json();

      return jsonStr;
    } catch (error) {
      console.log(error);
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  $("#btnConsultarBrinde").on("click", async function () {
    await buscaBrinde();
  });

  $("#btnImprimirBrinde").on("click", async function () {
    await imprimirBrinde();
  });

  $('#txtSenha').focusout(async function () {
    if ($(this).val() != '') {
      await buscaAgendamentoGuia($(this).val());
    }
  });

  $("#tabela-itens-cupom-troca").DataTable({
    destroy: true,
    order: false,
    filter: false,
    paginate: false,
    search: false,
    autoWidth: false,
    scrollY: "220px",
    scrollX: "500px",
    scrollCollapse: true,
    columnDefs: [
      {
        "targets": [7],
        "className": 'pr-4 text-right'
      },
      {
        "targets": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43],
        "visible": false
      }
    ]
  });

  $("#confirmar-cupom-troca").on("click", async function () {
    try {
      $.LoadingOverlay("show");
      try {
        const fazPerguntaPraImprimirCupomDeTroca = parametrosVenda[120] == 1 ?? false;
        const reiniciaVenda = (fazPerguntaPraImprimirCupomDeTroca) &&
                              ($('#tabelaItens').DataTable().data().toArray().length > 0) &&
                              ($('#txt_venda_atual').text() != 'Nova');
        const existeLayoutCookie = getCookie("serie_ecf");
        let lista = "";
        const tipo = $('input[name="tipo"]:checked').val();
        for (let i = 0; i < $("#tabela-itens-cupom-troca").DataTable().rows().count(); i++) {
          let data = $("#tabela-itens-cupom-troca").DataTable().row(i).data();
          if ($(`#cb_itens_troca_${i}`).prop("checked")) {
            lista += `${data[1]},`;
          }
        }
        lista = lista.substr(0, lista.length - 1);
        if (lista.length == 0) {
          msgErro("Nenhum item selecionado, verifique");
          return;
        }
        if (existeLayoutCookie == "") {
          await imprimirCupomTrocaSemECF(pegaChave('#venda-cupom-troca'), $('#tabela-itens-cupom-troca').DataTable().data());
        } else {
          const nrVenda = pegaChave("#venda-cupom-troca");

          if ($("#venda-cupom-troca").val() == "") {
            msgErro("Nenhuma venda informada, verifique");
            return;
          }

          await ImprimirCupomTroca(nrVenda, tipo, lista);
        }
        if (reiniciaVenda){
          if ($('#fechar-cupom-troca').hasClass('d-none')) {
            window.location.href = `${BASE_URI}/venda/create`;
          } else {
            window.location.reload();
          }
        }
      } catch (error) {
        console.error(error);
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });

  $("#tabela-itens-cupom-troca").on("click", "td", function () {
    selecionarLinhaTabela("#tabela-itens-cupom-troca", "checkCupom", this);
  });

  $("#btn_blocox_transmitir").on("click", async function () {
    try {
      $.LoadingOverlay("show");
      try {
        const url = "/sisplan/cupom/v1/BlocoXReducao?";
        const tr = $("#tabela-blocox-redz tr.selected")[0];
        const data = $("#tabela-blocox-redz").DataTable().row($(tr)).data();
        const dataMov = moment(data.DATA_MOV).format("DD/MM/YYYY");
        const params = `DATA_MOV=${dataMov}&SERIE_ECF=${data.SERIE_ECF}`;

        if (data.EMITIDO == "S" && data.RECIBO != "") {
          msgSucesso(
            "Arquivo com Informações da Redução Z do PAF-ECF já Emitido."
          );
          return;
        }

        const response = await requisicao("POST", url, params, null, 90000);
        if (!response) {
          msgErro("Erro ao transmitir dados do Bloco X");
          return;
        }

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

        const message = await response.text();
        if (message != '') {
          msgAlerta(message);
        }

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

  $("#btn_blocox_consultar").on("click", async function () {
    try {
      $.LoadingOverlay("show");
      try {
        const url = "/sisplan/cupom/v1/blocoxreducao?";
        const tr = $("#tabela-blocox-redz tr.selected")[0];
        const data = $("#tabela-blocox-redz").DataTable().row($(tr)).data();
        if (data.RECIBO == "") {
          msgErro("Registro selecionado não possui recibo para consultar.");
          return;
        }
        const dataMov = moment(data.DATA_MOV).format("DD/MM/YYYY");

        const params = `DATA_MOV=${dataMov}&SERIE=${data.SERIE_ECF}&RECIBO=${data.RECIBO}`;

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

        if (!response) {
          msgErro("Erro ao consultar dados do Bloco X");
          return;
        }
        if (response.status != 200) {
          msgErro("Erro ao consultar dados do Bloco X");
          return;
        }

        const json = await response.text();
        if (json != '') {
          msgAlerta(json);
        }
      } catch (error) {
        console.error(error);
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });

  $('#btnConfiguracaoBlocoX').on('click', function () {
    $('#modal-ConfigBlocoX').modal('show');
  });

  $('#btnConfirmarConfig').on('click', async function () {
    try {

      const url = "/sisplan/ini/v1/blocox?";
      const params = `AMBIENTE=${$('#txtAmbiente').val()}`;
      const response = await requisicao('PUT', url, params, null);

      if (!response) {
        return;
      }

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

      await criaMensagemSucesso('Gravado com sucesso!');
      $('#modal-ConfigBlocoX').modal('hide');

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

  });

  $('#btnGravarBrinde').on('click', async () => {
    await gravaBrinde();
  });

  $('#btnNFeBrinde').on('click', async () => {
    await NFeBrinde();
  });

  $('#btn_confirmar_brinde_nfe').on('click', async function () {
    await faturaNFeBrinde();
  });

  $('#modal-ConfigBlocoX').on('shown.bs.modal', async function () {

    async function carregaDadosIni() {
      try {
        const url = "/sisplan/ini/v1/blocox?";
        const response = await requisicao('GET', url, `NUMEROSERIE=${$('#selectImpressoras').val()}`, null);

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

        return jsonStr;

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

    }

    try {
      $.LoadingOverlay('show');

      const ambiente = await carregaDadosIni();

      $('#txtAmbiente').val(ambiente);

      if (ambiente == '0') {
        $('#txtTipoAmbiente').html('HOMOLOGAÇÃO');
      } else {
        $('#txtTipoAmbiente').html('PRODUÇÃO');
      }

    } finally {
      $.LoadingOverlay('hide');
    }
  });


  $("#btn_blocox_fechar").on("click", (_) => {
    $("#modal-blocox").modal("hide");
  });

  tabela = $("#tabela-blocox-redz").DataTable({
    paging: false,
    filter: false,
    info: false,
    order: false,
    destroy: true,
    autowidth: true,
  });

  $("#btn_consultar_blocox").on("click", function () {
    if ($("#txtBlocoXInicio").val() == "") {
      msgErro("Informe uma data de início para continuar.");
      return;
    }
    if ($("#txtBlocoXFim").val() == "") {
      msgErro("Informe uma data final para continuar.");
      return;
    }
    if ($("#modal-blocox-titulo").html().indexOf("Estoque") > 0) {
      retornaRegistrosEst();
    } else {
      retornaRegistrosRedZ();
    }
  });

  $("#btn_confirmar_vendas").on("click", function () {
    if ($("#txtVendasAno").val() == "") {
      msgErro("Informe um ano para continuar.");
      return;
    }
    if ($("#txtVendasMes").val() == "") {
      msgErro("Informe um mês para continuar.");
      return;
    }
    registroVendas();
  });

  $("#tabela_cnpjs").DataTable({
    paging: false,
    filter: false,
    info: false,
    order: false,
    destroy: false,
    autowidth: true,
  });

  async function addDataTable() {
    const CNPJ = $("#txtListaCNPJ").val();
    $("#txtListaCNPJ").val("");
    const dados = [CNPJ];
    $("#tabela_cnpjs").DataTable().row.add(dados).draw(false);
  }
  $("#btn_limpa_cnpj").on("click", function () {
    $("#tabela_cnpjs").DataTable().rows().remove().draw(false);
  });

  $("#btn_filtra_cnpj").pesquisa(
    "#txtListaCNPJ",
    "CNPJ",
    "CNPJ",
    '/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"entidade", "camposSelect":[ "CNPJ"], "where": null}',
    "Pesquisa CNPJ",
    "entidade",
    true,
    addDataTable
  );

  //
  $("#tabela_prods").DataTable({
    paging: false,
    filter: false,
    info: false,
    order: false,
    destroy: false,
    autowidth: true,
  });

  async function addDataTableProd() {
    const codigo = $("#txtListaPRODS").attr("data-chave");
    const descricao = $("#txtListaPRODS").attr("data-desc");
    limpaValor("#txtListaPRODS");
    const dados = [codigo, descricao];
    $("#tabela_prods").DataTable().row.add(dados).draw(false);
  }
  $("#btn_limpa_prods").on("click", function () {
    $("#tabela_prods").DataTable().rows().remove().draw(false);
  });

  $("#btn_filtra_prods").pesquisa(
    "#txtListaPRODS",
    "CODIGO",
    "DESCRICAO",
    '/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"produto", "camposSelect":[ "CODIGO", "DESCRICAO"], "where": null}',
    "Pesquisa Produtos",
    "produto",
    true,
    addDataTableProd
  );
  //
});

async function AtualizarReducaoZ(jsonObject) {
  try {
    const url = '/sisplan/cupom/v1/reducaoz?';
    const params = `JSON=${encodeURIComponent(JSON.stringify(jsonObject))}`;
    const response = await requisicao("POST", url, params, null, 900000);
    if (!response) {
      msgErro("erro ao atualizar dados reducao z");
      return;
    }

    if (response.status != 200) {
      msgErro("erro ao atualizar dados reducao z");
      return;
    }
  }
  catch (err) {
    console.error('erro ao atualizar dados reducao z', err);
  }
}

async function realizaReducaoZ() {
  const url = `/cupom/reducaoz?`;

  msgAlerta(`Tem certeza que deseja efetuar a Redução Z?`, async function () {
    try {
      $.LoadingOverlay("show");
      try {
        const response = await requisicao_ecf("GET", url, "", "", 900000);

        if (!response) {
          return;
        }

        if (response.status != 200) {
          msgErro("Não foi possível emitir a Redução Z, tente novamente.");
          return;
        }

        const jsonStr = await response.json();
        await AtualizarReducaoZ(jsonStr);

      } catch (error) {
        console.error(error);
        msgErro("Não foi possível emitir a Redução Z, tente novamente.");
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });
}

async function maquinaTemImpressora() {
  // faz uma requisicao de teste na porta da impressora.
  try {
    const serieCookie = getCookie("serie_ecf");
    if (serieCookie && serieCookie !== "") {
      return true;
    }

    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;
    }
    return false;
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function conectaECF(ipInterno, ipExterno, chave) {
  try {
    const ipPorta = getCookie("conexao") == "interna" ? ipInterno : ipExterno;
    const url = `/cupom/conectaecf?`;

    const response = await requisicao_ecf(
      "POST",
      url,
      `ip_porta=${ipPorta}&chave=${chave}`,
      "",
      null
    );

    if (!response) {
      return;
    }

    const jsonStr = await response.json();
    if (jsonStr.valor.toUpperCase() != "TRUE" && jsonStr.valor.toUpperCase() != "FALSE")
      setCookie("serie_ecf", jsonStr.valor);
    if (response.status != 200) {
      msgErro("Não foi possível conectar com a ECF, tente novamente.");
      return;
    }
    if (jsonStr.status == 0) {
      await buscaStatusImpressora();
    } else {
      msgErro("Não foi possível conectar com a ECF, tente novamente.");
      return;
    }
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível conectar com a ECF, tente novamente.");
  }
}

async function buscaStatusImpressora() {
  const url = `/cupom/estado?`;

  try {
    let response = await requisicao_ecf("GET", url, "", "", null);

    if (!response) {
      $("#txtStatusECF").css("background-color", "red");
      $("#txtStatusECF").html(" Offline ");
      $("#txtEstadoECF").html("Desconectado");
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      // msgErro(jsonStr['RESULT'][0].mensagem);
      $("#txtStatusECF").css("background-color", "red");
      $("#txtStatusECF").html(" Offline ");
      $("#txtEstadoECF").html("Desconectado");
      return;
    }
    if (jsonStr.status == 0) {
      $("#txtStatusECF").css("background-color", "green");
      $("#txtStatusECF").html(" Online ");
      $("#txtEstadoECF").html(jsonStr.valor);

      if (jsonStr.valor == 'Requer Z') {
        msgAlerta('Impressora com Redução Z pendente, para emitir, utilize o menu fiscal localizado a direita.');
        return;
      }
    } else {
      $("#txtStatusECF").css("background-color", "green");
      $("#txtStatusECF").html(" Online ");
      $("#txtEstadoECF").html(
        jsonStr.valor != "" ? jsonStr.valor : "Desconectado"
      );
      if (jsonStr.valor == 'Requer Z') {
        msgAlerta('Impressora com Redução Z pendente, para emitir, utilize o menu fiscal localizado a direita.');
        return;
      }
    }
  } catch (error) {
    console.error(error);
    $("#txtStatusECF").css("background-color", "red");
    $("#txtStatusECF").html(" Offline ");
    $("#txtEstadoECF").html("Desconectado");
    // msgErro('Não foi possível buscar o status da Impressora Fiscal.');
  }
}

$("#modal-cliente").on("shown.bs.modal", async function () {
  $("#txtCNPJModalCli").focus();
});

async function PreencheDescDeposito(sDeposito) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"deposito", "camposSelect":["descricao"], "where": ["codigo = '${sDeposito}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let deposito = jsonStr.RESULT[0][0].DESCRICAO;
    $("#txtDeposito").val(`[${sDeposito}] - ${deposito}`);
    $("#txtDeposito").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do depósito.");
  }
}

async function PreencheDescStatus(sStatus) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"sitprod", "camposSelect":["descricao"], "where": ["codigo = '${sStatus}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    const descStatus = jsonStr.RESULT[0][0].DESCRICAO;
    $("#txtStatus").val(`[${sStatus}] - ${descStatus}`);
    $("#txtStatus").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do depósito.");
  }
}

async function PreencheDescRegra(codRegra) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"regra_promocao", "camposSelect":["desc_regra"], "where": ["regra = '${codRegra}'"] }`,
      null
    );

    if (!response) {
      return;
    }

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

    let descRegra = jsonStr.RESULT[0][0].DESC_REGRA;
    $("#txtRegraPromocao").val(`[${codRegra}] - ${descRegra}`);
    $("#txtRegraPromocao").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da Regra.");
  }
}

async function PreencheDescVendedor(sCodRep) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"represen", "camposSelect":["nome"], "where": ["codrep = '${sCodRep}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let nome = jsonStr.RESULT[0][0].NOME;
    $("#txtVendedor").val(`[${sCodRep}] - ${nome}`);
    $("#txtVendedor").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do vendedor.");
  }
}

async function PreencheDescTransportadora(sCodTrans) {
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  if (sCodTrans === '') { return; }

  try {
    const response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"tabtran", "camposSelect":["nome"], "where": ["codigo = '${sCodTrans}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    const nome = jsonStr.RESULT[0][0].NOME;
    insereValor('#txtTransportadora', sCodTrans, nome);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da transportadora");
  }
}

async function PreencheDescGuia(sCodRep2) {
  if (sCodRep2 == "") {
    return;
  }

  let url = `/sisplan/funcoes/v1/pesquisa?`;
  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"represen", "camposSelect":["nome"], "where": ["codrep = '${sCodRep2}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let nome = jsonStr.RESULT[0][0].NOME;
    $("#txtGuia").val(`[${sCodRep2}] - ${nome}`);
    $("#txtGuia").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do guia.");
  }
}

async function PreencheDescTabela(sTabela) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  if (sTabela == '999') {
    $("#txtTabela").val(`[999] - `);
    return;
  }

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"regiao", "camposSelect":["descricao"], "where": ["regiao = '${sTabela}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let tabela = jsonStr.RESULT[0][0].DESCRICAO;
    $("#txtTabela").val(`[${sTabela}] - ${tabela}`);
    $("#txtTabela").attr("data-selecionado", true);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da tabela de preço.");
  }
}

async function PreencheNomeECNPJ(sCodCli) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"entidade", "camposSelect":["nome","cnpj"], "where": ["codcli = '${sCodCli}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let nome = jsonStr.RESULT[0][0].NOME;
    let cnpj = jsonStr.RESULT[0][0].CNPJ;
    $("#txtCliente").val(`[${sCodCli}] - ${nome}`);
    $("#txtCliente").attr("data-selecionado", true);
    $("#txtCNPJ").val(cnpj);
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do cliente.");
  }
}

async function liberarVenda(iCodVen) {
  try {
    $.LoadingOverlay("show");
    let response = await requisicao(
      "POST",
      "/sisplan/controleedicao/v1/controleedicao?",
      `valor=${iCodVen}&tela=LOJA`,
      null
    );

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

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

function retornaCodigosEPC(CodigoVenda, bUsaIntegraçãoITAG) {
  if (bUsaIntegraçãoITAG) {
    const objeto = {
      Numero: CodigoVenda,
      Id: '',
      CodigosEPC:
        listaBarrasBipadasEPC.map((lista) => {
          const objeto = {
            EPC: lista
          }
          return objeto
        }),
    }
    return objeto;
  } else {
    const objeto = {
      Numero: CodigoVenda,
      Id: '',
      CodigosEPC: []
    }
    return objeto
  }
}

async function montaJsonVenda(objetoVenda, numeroVenda, tipoVenda, bOlharCondicoesDePagamento = false, usaCupom = false, barrasKitBipadas = []) {
  const parametroUsaProduto = parametrosVenda[17];
  const bUsaIntegraçãoITAG = parametrosVenda[60] == 1 || parametrosVenda[60] == 2;
  const parametroValorIPIVenda = parametrosVenda[102] == 1 ?? false;
  const paramRetencaoIva = parametrosVenda[105] == 1 ?? false;

  let totalBruto = 0;
  let venda = objetoVenda;
  const itensArray = $("#tabelaItens").DataTable().column(7, {}).data().toArray()
  const totalLiquido = SomaComTruncamento(itensArray, 2);
  // let totalLiquido = $("#tabelaItens").DataTable().column(7, {}).data().sum();
  for (let i = 0; i < $("#tabelaItens").DataTable().rows().count(); i++) {
    const item = $("#tabelaItens").DataTable().row(i).data();
    // totalBruto += TruncaDecimaisNova(2, item[2] * item[3]);
    totalBruto += (parseFloat(item[7]) + parseFloat(coalesce(item[6])));
  }
  if (numeroVenda != "create" && numeroVenda != "create#") {
    venda.codVen = numeroVenda;
  } else {
    venda.codVen = null;
  }

  const utilizaBarraLog = (parametrosVenda[46]) != "0";

  let valorDesconto = $("#tabelaCondicoesDePagamento").DataTable().column(13, {}).data().sum();
  venda.codCli = pegaChave("#txtCliente", venda.codcli);
  venda.data = `${formataData(new Date())}T00:00:00Z`;
  venda.dataEntregaDe = `${!$('#dtEntregaDe').val() ? formataData(new Date()) : $('#dtEntregaDe').val()}T00:00:00Z`;
  venda.dataEntregaAte = `${!$('#dtEntregaAte').val() ? formataData(new Date()) : $('#dtEntregaAte').val()}T00:00:00Z`;
  venda.codRep = pegaChave("#txtVendedor", venda.codRep);
  venda.status = pegaChave("#txtStatus", venda.status);
  venda.codRep2 = $('#txtGuia').val() != undefined ? pegaChave("#txtGuia", venda.codRep2) : '';
  venda.fechada = !!(bOlharCondicoesDePagamento && $("#tabelaCondicoesDePagamento").DataTable().rows().count() > 0);
  venda.tabela = pegaChave("#txtTabela", venda.tabela);
  venda.nrCaixa = pegaChave(sessionStorage.getItem("g_caixa_logado"), venda.NRCAIXA);
  venda.devolucao = tipoVenda == "D";
  venda.usuario = sessionStorage.getItem("g_usuario_logado");
  venda.cNPJ_Consumidor = $("#txtCNPJ").val();
  venda.nome_Consumidor = pegaDescricao("#txtCliente", venda.NOME_CONSUMIDOR);
  venda.base_desc = totalLiquido;
  venda.desconto = valorDesconto;
  if (!venda.devolucao) {
    venda.regra = pegaChave($("#txtRegraPromocao").val());
    venda.acres = $("#txtValorAcrescMoedaSalvo").val() != "" ? $("#txtValorAcrescMoedaSalvo").val() : 0;
    venda.Valor_Frete = $("#txtFrete").val();
    venda.Venda_Tipo = $("#txtTipoVenda").val();
    venda.DebitaDuplicatas = false;
    venda.transportadora = pegaChave('#txtTransportadora');
    venda.volumes = $('#txtVolumes').val();
    venda.fretePor = $('#rgTransportador').val();
    venda.cupomDesconto = $('#txtCupomDesconto').val();
  } else {
    venda.regra = 0;
    venda.Valor_Frete = 0;
    venda.Venda_Tipo = 1;
    venda.acres = 0;
    venda.cupomDesconto = '';
  }
  venda.valor = parseFloat(totalLiquido) + parseFloat(venda.acres) - valorDesconto;
  venda.valor_Bruto = TruncaDecimaisNova(2, totalBruto);
  venda.hr_Venda = `${formataData(new Date())}T00:00:00Z`; // tratar na api
  venda.valor_Promo = 0;
  venda.observacao = "";
  venda.itens = tipoVenda == "D" ? await listaItensDev(parametroUsaProduto, utilizaBarraLog) : await listaItens(parametroUsaProduto, utilizaBarraLog);
  venda.condicao = await listaCondicoes();
  venda.prazo = pegaValor('#rgPrazo');
  venda.preVenda = ""; // tratar na api para caso for put a requisição nao pegar daqui e manter da propria venda..
  venda.dt_Orig = `${formataData(new Date())}T00:00:00Z`;
  venda.lancamento = $("#txtLancamento").val();
  venda.observacao = $("#textDescricaoVenda").val() != undefined ? $("#textDescricaoVenda").val().toUpperCase() : "";
  venda.VendaReceber = usaCupom;
  venda.epc = retornaCodigosEPC(numeroVenda, bUsaIntegraçãoITAG);
  venda.listaBarraLog = await retornaBarraLog(utilizaBarraLog);
  venda.listaBarraLogEstorno = await retornaBarraLogEstorno(utilizaBarraLog);
  venda.valor_troco = +$('#txtTroco').val() ?? 0;
  venda.Valor_IPI = parametroValorIPIVenda ? parseFloat($("#txtTotalIPI").val()) : 0;
  venda.valRetencaoIva = paramRetencaoIva ? TruncaDecimaisNova(2, coalesce(parseFloat(pegaValor('#txtTotalRetIva')))) : 0;
  venda.kits = barrasKitBipadas;
  venda.geraLinkPagto = isChecked('#cbLinkDePagamento');
  venda.idGateway = sessionStorage.getItem('g_id_link_caixa');
  return venda;
}
async function adicionaParcelasCondicao(arrayParcelas) {
  try {
    $("#tabelaParcelasGeradas").DataTable().row.add(arrayParcelas).draw(false);
    let $scrollBody = $($("#tabelaParcelasGeradas").DataTable().table().node()).parent();
    $scrollBody.scrollTop($scrollBody.get(0).scrollHeight);
  } catch (error) {
    console.error(error);
  }
}

async function carregaParcelas(arrayParcelas, indiceCondicao) {
  for (let index = 0; index < arrayParcelas.length; index++) {
    const parcela = arrayParcelas[index];
    if (parcela.nomeSacado != undefined) {
      adicionaParcelasCondicao([
        indiceCondicao,
        parcela.nomeSacado,
        parcela.cPFSacado,
        parcela.banco,
        parcela.nrAgencia,
        parcela.nrConta,
        parcela.numero,
        parcela.vencimento.split("T")[0],
        parcela.valor,
        parcela.valorPago,
      ]);
    } else {
      adicionaParcelasCondicao([
        indiceCondicao,
        parcela.NOMESACADO,
        parcela.CPFSACADO,
        parcela.BANCO,
        parcela.NRAGENCIA,
        parcela.NRCONTA,
        parcela.NUMERO,
        parcela.VENCIMENTO.split("T")[0],
        parcela.VALOR,
        parcela.VALORPAGO,
      ]);
    }
  }
}

async function barraJaEstaBipada(sBarra) {
  try {
    if (listaBarrasBipadas.find(barra => barra === sBarra)) {
      await aguardaMsgAlerta(`Barra ${sBarra} já lida nessa venda, verifique.`, () => { });
      return true;
    }
    return false;
  } catch (error) {
    console.error('barra_log', error);
    msgErro('Erro ao processar barra log.');
    return false;
  }
}

async function retornaBarraLogEPC(sBarra) {
  try {
    const url = `/sisplan/barralog/v1/retornabarralogepc?`;
    const params = `barra=${encodeURIComponent(sBarra)}`;
    const response = await requisicao('GET', url, params, 15000);

    if (!response) {
      return '';
    }

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

    const jsonStr = await response.text();
    return jsonStr;
  } catch (error) {
    console.error(error);
  }
}


async function retornaBarraLogLida(sBarra) {
  try {
    const url = `/sisplan/barralog/v1/validarbarra?`;
    const params = `barra=${encodeURIComponent(sBarra)}`;
    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);
  }
}

async function adicionaBarraBipada(barra) {
  try {
    const retornoBarraLog = await retornaBarraLogLida(barra);
    if (['barra_log'].includes(retornoBarraLog)) {
      listaBarrasBipadas.push(barra);
      if (listaBarrasRemovidasTemp.includes(barra)) {
        listaBarrasRemovidasTemp = listaBarrasRemovidasTemp.filter(it => it != barra);
        listaBarrasRemovidas = listaBarrasRemovidas.filter(it => it != barra);
      }
      return true;
    }
  } catch (error) {
    console.error(error);
  }
}

async function estornaBarraBipada(sBarra, codVen) {
  try {
    if ((codVen != 'create') && (codVen != 'create#')) {
      const bEncontrouNaLista = listaBarrasBipadas.filter(barra => barra == sBarra).length > 0;
      if (bEncontrouNaLista) {
        listaBarrasRemovidas.push(sBarra);
        listaBarrasRemovidasTemp.push(sBarra);
      }
    } else {
      const bEncontrouNaLista = listaBarrasBipadas.filter(barra => barra == sBarra).length > 0;
      if (bEncontrouNaLista) {
        listaBarrasRemovidasTemp.push(sBarra);
      }
    }
    listaBarrasBipadas = [...listaBarrasBipadas.filter(barra => barra !== sBarra)];
  } catch (error) {
    console.error(error);
  }
}

async function removeItemListaBarra(sBarra) {
  try {
    listaBarrasBipadas = [...listaBarrasBipadas.filter(barra => barra !== sBarra)];
  } catch (error) {
    console.error(error);
  }
}

async function retornaSeProdutoTemRelacionamento(sCodigo) {
  const url = '/sisplan/produto/v1/verifica_produtos_relacionados?';
  const response = await requisicao('GET', url, `CODIGO=${sCodigo}`, '', 30000);

  if (!response) {
    return;
  };

  if (response.status != 200) {
    return false;
  }
  const jsonStr = await response.json();

  return jsonStr;
}

async function carregaDadosItens(arrayDeItens, tipo, origemArquivo = false) {
  bConferido = arrayDeItens[0]?.qtde_Conferida > 0;
  const arrayItens = [];
  for (let index = 0; index < arrayDeItens.length; index++) {
    if (tipo == 'D') {
      const produto = arrayDeItens[index];
      adicionaItens([
        produto.codigo,
        `${produto.codigo} - ${produto.descricao} - ${produto.cor} - ${produto.desc_Cor} - ${produto.tam}`,
        produto.quantidade,
        produto.preco_Liq,
        produto.valor,
        produto.perc_Desc,
        produto.desconto,
        produto.total_Liq,
        produto.barra,
        produto.cor,
        produto.tam,
        produto.desc_Cor,
        produto.qualidade,
        produto.iD_Estoque,
        produto.codVenDev != undefined ? produto.codVenDev : 0,
        await retornaBotaoOpcoes(),
        `${produto.codigo} - ${produto.cor} - ${produto.tam} - ${produto.qualidade} - ${produto.lote}`,
        produto.presente,
        produto.lote,
        produto.tipo,
        produto.codRep,
        produto.unidade,
        produto.promocao,
        produto.cashback_val || 0,
        produto.emp_id || getCookie('emp_id'),
        produto.motivo,
        produto.preco_liq_orig,
        produto.desc_item_orig || 0,
        produto.preco_bruto_orig,
        produto.quantidade_orig
      ]);
    } else {
      const produto = arrayDeItens[index];
      const agrupamentoItem = `${produto.codigo} - ${produto.cor} - ${produto.tam} - ${produto.qualidade} - ${produto.lote}`;

      const itemTemProdutoRelacionado = ((usaProdutoRelacionado) && (produto.tipo != 'M')) ? await retornaSeProdutoTemRelacionamento(produto.codigo) : false;

      if (itemTemProdutoRelacionado) {
        $('.itemRelacionado').removeClass('d-none');
        $('.itemRelacionado').addClass('d-flex');
      }


      arrayItens.push([
        produto.codigo,
        `${produto.codigo} - ${produto.descricao} - ${produto.cor} - ${produto.desc_Cor} - ${produto.tam}`,
        produto.quantidade,
        produto.valor,
        produto.preco_Liq,
        produto.perc_Desc || 0,
        produto.desconto || 0,
        origemArquivo ? produto.total_Liq : produto.total_Liq + produto.valor_Desc,
        await retornaBotaoOpcoes(),
        produto.barra,
        produto.cor,
        produto.tam,
        produto.desc_Cor,
        produto.qualidade,
        produto.iD_Estoque,
        produto.codVenDev != undefined ? produto.codVenDev : 0,
        agrupamentoItem,
        produto.presente,
        produto.lote,
        produto.tipo,
        produto.ValorDesc_RegraPromo != undefined ? produto.ValorDesc_RegraPromo : 0,
        produto.BaseDesc_RegraPromo != undefined ? produto.BaseDesc_RegraPromo : 0,
        produto.PercDesc_RegraPromo != undefined ? produto.PercDesc_RegraPromo : 0,
        produto.pedido,
        produto.ordem_ped,
        produto.caixa,
        produto.codRep,
        produto.dt_Inclusao,
        produto.unidade,
        produto.promocao,
        produto.valorOld,
        produto.codRegraPromo,
        produto.observacao,
        produto.deposito,
        produto.tabela,
        itemTemProdutoRelacionado,
        produto.lote_orig != undefined ? produto.lote_orig : '',
        produto.qtde_orig,
        produto.valorIPI
      ]);
    }
  }

  if (tipo != 'D') {
    let table = $('#tabelaItens').DataTable();

    table.rows.add(arrayItens).draw(false);

    table.rows().every(function (rowIdx, tableLoop, rowLoop) {
      const data = this.data();

      if ((data[19] == 'M') && (data[36] == 'DESDOBRADO')) {
        // se for mesmo lote e quantidade for igual
        $(this.node()).addClass('linhaDesdobrado');
      }

      if (data[29]) {
        $(this.node()).addClass('linha-promocao');
      }
      if (data[35]) {
        $(this.node()).addClass('linha-prodRelac');
        $('.prod_relacionados').removeClass('d-none');
      }
    });

    let $scrollBody = $($("#tabelaItens").DataTable().table().node()).parent();
    $scrollBody.scrollTop($scrollBody.get(0).scrollHeight);
    if (!$('#btn-desdobrar-malha').hasClass('d-none')) {
      $('#total_rolos_itens').html(`Rolos: ${$('#tabelaItens').DataTable().rows().count()}`);
    }
    await validaItensRelacionados();
  }
}

async function carregaDescricaoCondicaoEMoeda(arrayDeCondicoes) {
  try {
    const url = `/sisplan/funcoes/v1/pesquisa?`;
    let arrayDescricoes = arrayDeCondicoes;
    for (let index = 0; index < arrayDescricoes.length; index++) {
      if (arrayDescricoes[index].descricaoCondicao == undefined) {
        await carregaParcelas(arrayDescricoes[index].parcelas, index);
        let params = `JSON={ "tabela":"CONDICAO", "camposSelect":[ "CODCOND", "DESCRICAO"], 
                                   "where" : ["CODCOND = '${arrayDescricoes[index].codCondicao}'"]}`;

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

        if (!response) {
          return;
        }

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

        params = `JSON={ "tabela":"MOEDA", "camposSelect":[ "CODMOE", "TIPO", "DESCRICAO"], 
                                   "where" : ["CODMOE = '${arrayDescricoes[index].codMoeda}'"]}`;

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

        if (!response) {
          return;
        }

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

        arrayDescricoes[index].descricaoMoeda = jsonStr.RESULT[0][0].DESCRICAO;
        arrayDescricoes[index].tipomoeda = jsonStr.RESULT[0][0].TIPO;
      }
    }
  } catch (error) {
    console.error(error);
  }
}

async function carregaDadosCondicoesPagamento(arrayDeCondicoes) {
  let bLinkPago = false;
  for (let index = 0; index < arrayDeCondicoes.length; index++) {
    const condicao = arrayDeCondicoes[index];
    $('#cbLinkDePagamento').prop('checked', condicao.adicional.link_Pagto === 'S');
    bLinkPago = condicao.adicional.linkJaPago === 'S';
    const valor = condicao.parcelas[0].valor
      ? ArredondarValor(
        condicao.parcelas.reduce((total, old) => total + old.valor, 0),
        2
      )
      : ArredondarValor(
        condicao.parcelas.reduce((total, old) => total + old.VALOR, 0),
        2
      );
    const valorPago = condicao.parcelas[0].valorPago
      ? ArredondarValor(
        condicao.parcelas.reduce((total, old) => total + old.valorPago, 0),
        2
      )
      : ArredondarValor(
        condicao.parcelas.reduce((total, old) => total + old.VALORPAGO, 0),
        2
      );
    adicionaCondicoesDePagamento([
      index,
      condicao.parcelas[0].valorPago
        ? `${condicao.codMoeda} - ${condicao.descricaoMoeda}`
        : condicao.descricaoMoeda,
      condicao.parcelas[0].valorPago
        ? `${condicao.codCondicao} - ${condicao.descricaoCondicao}`
        : condicao.descricaoCondicao,
      valor,
      valorPago,
      valor / condicao.parcelas.length,
      condicao.cotacaoMoeda,
      condicao.valorMoeda,
      condicao.codMoeda,
      condicao.codCondicao,
      condicao.parcelas,
      condicao.antecipacoes,
      condicao.perc_Desconto,
      condicao.valor_Desc,
      condicao.bandeira,
      condicao.nsu,
      condicao.antecipacoesPresente,
      condicao.tipomoeda,
      condicao.adicional.autorizacao,
      retornaBotaoOpcoesCondicao(condicao.tipomoeda)
    ]);

    condicao?.antecipacoes?.forEach(ante => {
      const indice = $('#tabelaAntecipacoes').DataTable().data().toArray().findIndex(item => item.DUPLICATA == ante.duplicata);
      if (indice >= 0) {
        const data_old = $('#tabelaAntecipacoes').DataTable().row(indice).data();
        data_old.VALOR_PAGO += ante.valor;
        data_old.VALOR_UTILIZADO = data_old.VALOR_PAGO;
        $('#tabelaAntecipacoes').DataTable().row(indice).data(data_old).draw(false);
        $($('.campoCheck')[indice]).prop('checked', true);
      }
    })
  }

  if (!bLinkPago) {
    $('#txtMoeda').val('');
    $('.divCFE').addClass('d-none');
    $('.divNFCE').addClass('d-none');
    $('.divNFE').addClass('d-none');
    $('#btnFinalizar').html(await traduzSentenca('Deixar Pendente (F8)'));
    $('#btnFinalizar').attr('data-original', 'Deixar Pendente (F8)');
  } else {
    $('#btnFinalizar').html(await traduzSentenca('Finalizar (F8)'));
    $('#btnFinalizar').attr('data-original', 'Finalizar (F8)');
  }
}

function CriaRegistrosTabelaParcelas() {
  // tabela por trás para controlar as condições de pagamentos e alterções de data/valor feito pelo usuario.
  let totalParcelas = $("#tabelaParcelas").DataTable().rows().count();
  for (let index = 0; index < totalParcelas; index++) {
    const parcela = $("#tabelaParcelas").DataTable().row(index).data();
    let valorParcelas = parseFloat(
      parseFloat($($(".campoValor")[index]).val()).toFixed(2)
    );
    let vencimentosParcelas = $($(".campoVencimento")[index]).val();
    let nome =
      $($(".campoNome")[index]).val() != undefined
        ? $($(".campoNome")[index]).val()
        : "";
    let cpfCnpj =
      $($(".campoCPFCNPJ")[index]).val() != undefined
        ? $($(".campoCPFCNPJ")[index]).val()
        : "";
    let banco =
      $($(".campoBanco")[index]).val() != undefined
        ? $($(".campoBanco")[index]).val()
        : "";
    let agencia =
      $($(".campoAgencia")[index]).val() != undefined
        ? $($(".campoAgencia")[index]).val()
        : "";
    let conta =
      $($(".campoConta")[index]).val() != undefined
        ? $($(".campoConta")[index]).val()
        : "";
    let numero =
      $($(".campoNumero")[index]).val() != undefined
        ? $($(".campoNumero")[index]).val()
        : "";
    let dados = [
      parcela.Ordem,
      nome,
      cpfCnpj,
      banco,
      agencia,
      conta,
      numero,
      vencimentosParcelas,
      valorParcelas,
      "",
    ];
    $("#tabelaParcelasGeradas").DataTable().row.add(dados).draw(false);
  }
}

async function RetornaVencimentos(iCodCondicao, bCartaoPresente) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;
  let arrVencimentos = [];
  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"cond_item", "camposSelect":[ "parcela", "prazo"], "where": ["codcond = ${iCodCondicao}"], "orderBy": ["parcela"] }`,
      null
    );

    if (!response) {
      return;
    }

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

    let nrParcelas = jsonStr.RESULT[0].length;
    let dataAtual = new Date();
    for (let index = 0; index < nrParcelas; index++) {
      let novoPrazo = new Date();
      let nrDia = jsonStr.RESULT[0][index].PRAZO;
      novoPrazo.setDate(dataAtual.getDate() + nrDia);
      if (!bCartaoPresente) {
        novoPrazo = await validaDiaUtil(novoPrazo);
      }
      arrVencimentos.push(formataData(novoPrazo));
    }
    return arrVencimentos;
    // alert(jsonStr['RESULT'][0]);
    // return jsonStr;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados dos vencimentos.");
  }
}

async function RetornaVencimentosParcelas(iCodCondicao, anoDate, mesDate, diaDate, intervaloDate = 0) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;
  let arrVencimentos = [];
  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"cond_item", "camposSelect":[ "parcela", "prazo"], "where": ["codcond = ${iCodCondicao}"], "orderBy": ["parcela"] }`,
      null
    );

    if (!response) {
      return;
    }

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

    let nrParcelas = jsonStr.RESULT[0].length;
    let dataAtual = new Date(anoDate, mesDate, diaDate);
    for (let index = 0; index < nrParcelas; index++) {
      if (index == 0) {
        let novoPrazo = new Date(anoDate, mesDate, diaDate);
        novoPrazo = await validaDiaUtil(novoPrazo);
        arrVencimentos.push(formataData(novoPrazo));
      } else {
        let novoPrazo = new Date(anoDate, mesDate, diaDate);
        let nrDia = intervaloDate == 0 ? jsonStr.RESULT[0][index - 1].PRAZO : (intervaloDate * index);
        novoPrazo.setDate(dataAtual.getDate() + nrDia);
        novoPrazo = await validaDiaUtil(novoPrazo);
        arrVencimentos.push(formataData(novoPrazo));
      }
    }
    return arrVencimentos;
    // alert(jsonStr['RESULT'][0]);
    // return jsonStr;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados dos vencimentos.");
  }
}

async function temCondicoesEspecificas(iMoeda) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;
  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"COND_MOEDA", "camposSelect":["CODCOND"], "where": ["moeda = ${iMoeda}"] }`,
      null
    );

    if (!response) {
      return false;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return false;
    }
    let bTemCondicoes = jsonStr.RESULT[0].length > 0;
    return bTemCondicoes;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da moeda.");
    return false;
  }
}

async function moedaPresente(iMoeda) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"moeda", "camposSelect":["CARTAO_PRESENTE"], "where": ["codmoe = ${iMoeda}"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    const cartaoPresente = jsonStr.RESULT[0][0].CARTAO_PRESENTE;
    return cartaoPresente;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da moeda.");
  }
}

async function RetornaInformacoesMoeda(iMoeda) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"moeda", "camposSelect":["TEF", "DESC_AUTO", "MAX_PARCELAS", "TP_INTEGRACAO", "HABILITA_NSU"], "where": ["codmoe = ${iMoeda}"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let tef = jsonStr.RESULT[0][0].TEF;
    let descAuto =
      jsonStr.RESULT[0][0].DESC_AUTO == null
        ? 0
        : parseFloat(jsonStr.RESULT[0][0].DESC_AUTO);
    let maxNrParcelas =
      jsonStr.RESULT[0][0].MAX_PARCELAS == null
        ? 0
        : parseFloat(jsonStr.RESULT[0][0].MAX_PARCELAS);
    return [tef, descAuto, maxNrParcelas, jsonStr.RESULT[0][0].TP_INTEGRACAO, jsonStr.RESULT[0][0].HABILITA_NSU];
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da moeda.");
  }
}

async function RetornaDadosMoeda(iMoeda) {
  let url = `/sisplan/funcoes/v1/pesquisa?`;

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"moeda", "camposSelect":["MOEDA.CDCONDI", "CONDICAO.DESCRICAO DESC_CONDI", "MOEDA.BAIXA_ANTE", "MOEDA.TEF", "CONDICAO.NRPAR","MOEDA.ATIVO"], "leftjoin": [{"tabela" : "condicao", "condicao" : "condicao.codcond = moeda.cdcondi"}], "where": ["moeda.codmoe = ${iMoeda}"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    return jsonStr;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados de pagamento da moeda.");
  }
}

async function RetornaCNPJ(sCodCli) {
  try {
    let url = `/sisplan/funcoes/v1/pesquisa?`;
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"entidade", "camposSelect":["cnpj"], "where": ["codcli = '${sCodCli}'"] }`,
      null
    );

    if (!response) {
      return;
    }

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

    let cnpj = jsonStr.RESULT[0][0].CNPJ;
    return cnpj;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do cliente.");
  }
}

async function retornaCidade() {
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  const sEmpresa = getCookie("empresa");

  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"empresa", "camposSelect":["emp_cidade"], "where": ["emp_pat = '${sEmpresa}'"] }`,
      null
    );

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }
    let cidade = jsonStr.RESULT[0][0].EMP_CIDADE;
    return cidade;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados da empresa.");
  }
}

async function CalculaDesconto(campoAlterado) {
  try {
    const listaCamposValores = [
      "#txtPrecoDesc",
      "#txtPercDesconto",
      "#txtValorDesconto",
    ];


    const qtdeProduto = parseFloat($("#txtQuantidadeDesc").val());
    const precoProduto = parseFloat($("#txtPrecoOrig").val().replaceAll('.', '').replace(',', '.'));
    const valBruto = parseFloat($("#txtValBruto").val().replaceAll('.', '').replace(',', '.'));
    const percentualDesconto = parseFloat($("#txtPercDesconto").val().replaceAll('.', '').replace(',', '.'));
    const precoAtual = $("#txtPrecoDesc").val();
    // const valorAtual = $(campoAlterado);
    // { limpar os demais campos para não influenciarem no cálculo }
    for (let i = 0; i < listaCamposValores.length; i++) {
      const campo = listaCamposValores[i];
      if (campo != campoAlterado) {
        $(campo).val(0);
      }
    }

    let precoLiq = 0;
    let percDesc = 0;
    let totalLiq = 0;
    let valDesc = 0;

    switch (campoAlterado) {
      case "#txtPercDesconto":
        $("#txtValorDesconto").val(
          ArredondarValor((percentualDesconto / 100) * precoProduto * qtdeProduto, 2).toLocaleString("pt-BR", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2
          })
        );
        valDesc = parseFloat($("#txtValorDesconto").val().replaceAll('.', '').replace(',', '.'));
        precoLiq = quantidadeCasasDecimaisCampo > 2 ? TruncaDecimaisNova(quantidadeCasasDecimaisCampo, precoProduto - valDesc / qtdeProduto,) : TruncaDecimaisNova(2, precoProduto - valDesc / qtdeProduto);
        $("#txtPrecoLiqDesconto").val(precoLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: quantidadeCasasDecimaisCampo,
          minimumFractionDigits: quantidadeCasasDecimaisCampo
        }));
        $("#txtPrecoDesc").val(precoLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: quantidadeCasasDecimaisCampo,
          minimumFractionDigits: quantidadeCasasDecimaisCampo
        }));
        // totalLiq = TruncaDecimaisNova(2, TruncaDecimaisNova(2, parseFloat(valBruto)) - TruncaDecimaisNova(2, valDesc));
        totalLiq = TruncaDecimaisNova(2, qtdeProduto * precoLiq);
        $("#txtTotalLiq").val(totalLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: 2,
          minimumFractionDigits: 2
        }));
        $("#txtValorDesconto").val(TruncaDecimaisNova(2, valBruto - totalLiq).toLocaleString("pt-BR", {
          maximumFractionDigits: 2,
          minimumFractionDigits: 2
        }));
        break;
      case "#txtPrecoDesc":
        if (parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) != precoProduto) {
          if (parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) > precoProduto) {
            $("#txtPrecoLiqDesconto").val(parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            }));
            $("#txtTotalLiq").val(parseFloat($("#txtPrecoLiqDesconto").val().replaceAll('.', '').replace(',', '.') * qtdeProduto).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            }));
            $("#txtValorDesconto").val(0);
            $("#txtPercDesconto").val(0);
          } else {
            $("#txtValorDesconto").val(
              TruncaDecimaisNova(2,
                precoProduto * qtdeProduto -
                parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) * qtdeProduto
              ).toLocaleString("pt-BR", {
                maximumFractionDigits: 2,
                minimumFractionDigits: 2
              })
            );
            valDesc = parseFloat($("#txtValorDesconto").val().replaceAll('.', '').replace(',', '.'));
            percDesc = TruncaDecimaisNova(2,
              (valDesc /
                valBruto) *
              100
            ).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            });
            $("#txtPercDesconto").val(percDesc.toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            }));

            if (parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) <= precoProduto) {
              // precoLiq = quantidadeCasasDecimaisCampo > 2 ? TruncaDecimaisNova(quantidadeCasasDecimaisCampo, precoProduto - valDesc / qtdeProduto) : quantidadeCasasDecimaisCampo(2, precoProduto - valDesc / qtdeProduto);
              precoLiq = TruncaDecimaisNova(quantidadeCasasDecimaisCampo, $("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.'));
              $("#txtPrecoLiqDesconto").val(precoLiq.toLocaleString("pt-BR", {
                maximumFractionDigits: quantidadeCasasDecimaisCampo,
                minimumFractionDigits: quantidadeCasasDecimaisCampo
              }));
              const soma = + precoLiq * qtdeProduto;
              const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
              const calculoTotal = utilizaImpressoraFiscal && maisDeDoisCaracteresDecimal ? TruncaDecimaisNova(3, soma) : TruncaDecimaisNova(2, parseFloat(soma));
              $("#txtTotalLiq").val(parseFloat(calculoTotal).toLocaleString("pt-BR", {
                maximumFractionDigits: 2,
                minimumFractionDigits: 2
              }));
            }
          }
        } else {
          const soma = + precoProduto * qtdeProduto;
          const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
          const calculoTotal = utilizaImpressoraFiscal && maisDeDoisCaracteresDecimal ? TruncaDecimaisNova(3, soma) : TruncaDecimaisNova(2, parseFloat(soma));
          $("#txtTotalLiq").val(parseFloat(calculoTotal).toLocaleString("pt-BR", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2
          }));
        }
        break;

      case "#txtValorDesconto":
        valDesc = TruncaDecimaisNova(2, $("#txtValorDesconto").val().replaceAll('.', '').replace(',', '.'));
        percDesc = TruncaDecimaisNova(2,
          (valDesc /
            valBruto) *
          100
        );
        $("#txtPercDesconto").val(percDesc.toLocaleString("pt-BR", {
          maximumFractionDigits: 2,
          minimumFractionDigits: 2
        }));
        precoLiq = quantidadeCasasDecimaisCampo > 2 ? TruncaDecimaisNova(quantidadeCasasDecimaisCampo, precoProduto - valDesc / qtdeProduto)
          : TruncaDecimaisNova(2, precoProduto - valDesc / qtdeProduto);
        $("#txtPrecoLiqDesconto").val(precoLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: quantidadeCasasDecimaisCampo,
          minimumFractionDigits: quantidadeCasasDecimaisCampo
        }));
        $("#txtPrecoLiqDesconto").val(precoLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: quantidadeCasasDecimaisCampo,
          minimumFractionDigits: quantidadeCasasDecimaisCampo
        }));
        $("#txtPrecoDesc").val(precoLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: quantidadeCasasDecimaisCampo,
          minimumFractionDigits: quantidadeCasasDecimaisCampo
        }));
        // totalLiq = TruncaDecimaisNova(2,
        //   TruncaDecimaisNova(2, valBruto) -
        //   TruncaDecimaisNova(2, valDesc)
        // );
        // $("#txtTotalLiq").val(totalLiq.toLocaleString("en-US", {
        //   maximumFractionDigits: 2,
        //   minimumFractionDigits: 2
        // }));

        totalLiq = TruncaDecimaisNova(2, qtdeProduto * precoLiq);
        $("#txtTotalLiq").val(totalLiq.toLocaleString("pt-BR", {
          maximumFractionDigits: 2,
          minimumFractionDigits: 2
        }));
        $("#txtValorDesconto").val(TruncaDecimaisNova(2, valBruto - totalLiq).toLocaleString("pt-BR", {
          maximumFractionDigits: 2,
          minimumFractionDigits: 2
        }));
        break;
      default:
        break;
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function verificaDescontoMaximoSupervisor(nome, callBack) {
  try {
    if (nome) {
      const json = await retornaJsonPesquisaPadrao(`{"tabela": "ACESSO_USUARIOS", "camposSelect": ["DESC_MAX", "TIPO"], "where": ["NOME = '${nome}'"] }`);
      if (json && json.length > 0) {
        let tipoUsuario = 'supervisor';
        if (json[0].TIPO === '2') {
          tipoUsuario = 'master';
        }
        if ((parseFloat($("#txtPercDescontoMoeda").val()) > json[0].DESC_MAX) || (parseFloat($("#txtPercDesconto").val()) > json[0].DESC_MAX) || (parseFloat($('#txtDesconto').val()) > json[0].DESC_MAX)) {
          msgAlerta(`Desconto aplicado é maior que o permitido para o ${tipoUsuario}!`);
          return false;
        }

        adicionaLogVenda('TVENDALOJA', '', `Autorizado dar desconto pelo usuario ${nome}, com os ${json[0].DESC_MAX}% do seu usuário`, 'Inclusão');

      }
      return callBack();
    }

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

async function CalculaDescontoMoeda(
  campoAlterado,
  dPrecoOrig,
  dPercentualDesconto,
  dValorDesconto,
  dPrecoNovo,
  dQuantidade,
  executaValidacaoDescontoMoeda = true
) {
  let retorno = true;

  const desconto = {
    perc_desconto: dPercentualDesconto,
    val_desconto: dValorDesconto,
    preco_novo: dPrecoNovo,
    preco_orig: dPrecoOrig,
    quantidade: dQuantidade
  };

  const paramCfe = parametrosVenda[19];
  if (paramCfe == "0" || paramCfe != undefined || paramCfe != null) {
    $("#txtValorAcrescMoeda").prop("disabled", true);
    $("#txtPercAcrescMoeda").prop("disabled", true);
  }

  try {
    let response = await requisicao("GET", "/Sisplan/Vendas/V1/Desconto?", `JSON=${encodeURIComponent(JSON.stringify(desconto))}`, null);

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

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

    const jsonStr = await response.json();
    const descontoUsuario = await retornaDescontoMaximoUsuario();
    const descontoMoeda = await retornaDescontoMaximoMoeda(
      pegaChave("#txtMoeda")
    );
    let parametroSenhaDesconto = parametrosVenda[78];

    function callBackNegacaoSenhaSupervisor() {
      $("#txtValorDescontoMoeda").val("0");
      $("#txtPercDescontoMoeda").val("0");
      $("#txtValorDescontoMoeda").trigger("blur");
      retorno = false;
    }
    const nmrVenda = $('#txt_venda_atual>span').html() == 'Nova' ? 'create' : $('#txt_venda_atual>span').html()

    if (executaValidacaoDescontoMoeda && !await uMasterOuSupervisor() && parseFloat(descontoMoeda ?? 0) > parseFloat(descontoUsuario ?? 0)) {
      if (jsonStr.perc_desconto > descontoMoeda) {
        if (parametroSenhaDesconto == 1) {
          await senhaSupervisor('Desconto maior que o desconto máximo da moeda, necessário a senha de supervisor para continuar!',
            async () => {
              retorno = true;
              resolve();
            },
            '',
            false,
            async () => {
              callBackNegacaoSenhaSupervisor();
              reject();
            },
            async () => {
              callBackNegacaoSenhaSupervisor();
              reject();
            },
            async () => {
              callBackNegacaoSenhaSupervisor();
              reject();
            },
            false,
            'VENDA',
            nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda)
        } else {
          msgAlerta("Desconto maior que o desconto máximo da moeda!");
          callBackNegacaoSenhaSupervisor();
          return false;
        }
      }
    }

    if (campoAlterado != "txtValorDescontoMoeda") {
      if (($("#txtPercDescontoMoeda").val() == descontoUsuario && jsonStr.perc_desconto.toFixed(2) > descontoUsuario)) {
        $("#txtPercDescontoMoeda").val(Math.floor(jsonStr.perc_desconto));
      } else {
        $("#txtPercDescontoMoeda").val(parseFloat(jsonStr.perc_desconto.toFixed(2)));
      }
      $("#txtValorDescontoMoeda").val(parseFloat(jsonStr.val_desconto).toFixed(2));
    }

    if (campoAlterado != "txtPercDescontoMoeda") {
      $("#txtPercDescontoMoeda").val(parseFloat(jsonStr.perc_desconto.toFixed(2)));
      $("#txtValorDescontoMoeda").val(parseFloat(jsonStr.val_desconto.toFixed(2)));
    }

    const bSomaFrete = ((bNaoConsiderarFreteDesconto) && ((parseFloat($("#txtPercDescontoMoeda").val()) > 0) || (parseFloat($("#txtValorDescontoMoeda").val()) > 0)));
    const valFrete = isNaN(parseFloat($('#txtFrete').val())) ? 0 : parseFloat($('#txtFrete').val());
    const valorFrete = bSomaFrete ? valFrete : 0;
    const novoValLiquido = ArredondarValor(parseFloat(jsonStr.total_liq) + parseFloat($("#txtValorAcrescMoeda").val()) + valorFrete, 2);

    if (isNaN(novoValLiquido)) {
      $("#txtValorLiquidoMoeda").val(0);
      msgErro("Erro ao calcular valor líquido, tente novamente");
    } else {
      $("#txtValorLiquidoMoeda").val(novoValLiquido, 2);
      $.LoadingOverlay("hide");
    }

    return retorno;

  } catch (error) {
    console.error(error);
    $("#txtValorAcrescMoeda").prop("disabled", false);
    $("#txtPercAcrescMoeda").prop("disabled", false);
    $.LoadingOverlay("hide");
  }
}

async function MontaTabelaParcelas(sTipo, sNome, sCnpj, iNumParcelas, valorTotal, fValorPago, iCodCondicao, bAlteracao, bMostraTela, ordemAlteracao, codigoMoeda) {

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

  const dataSet = [];
  const dataSetCols = [];
  const columnKeys = ["Nome", "CPF_CNPJ", "Banco", "Agência", "Conta", "Número", "Vencimento", "Valor", "Ordem", "Impressao", "Ler_Cheque"];
  const valorParcela = parseFloat(parseFloat(valorTotal / iNumParcelas).toFixed(2));
  let diferenca = 0;
  let arrayVencimentos;
  const parcelaArredondamento = await retornaParcelaArredondamento(codigoMoeda);

  if (valorTotal > valorParcela * iNumParcelas || valorTotal < valorParcela * iNumParcelas) {
    diferenca = parseFloat(parseFloat(valorTotal - valorParcela * iNumParcelas).toFixed(2));
  }

  if (bAlteracao != "alteracao") {
    arrayVencimentos = await RetornaVencimentos(iCodCondicao);
  }
  const idColunaValor = 7;
  const idColunaVencimento = 6;
  const arrayColunasInvisiveis = [];
  let bloqNomeCpf = '';
  $("#txt_cred_modo").val(bAlteracao);
  $("#txt_cred_valor_total").val(valorTotal);
  $("#txt_cred_valor_pago").val(fValorPago);

  if (sTipo == "cheque") {
    $("#modalParcelas-titulo").html("Manutenção Cheques");
    arrayColunasInvisiveis.push(8);
  } else {
    $("#modalParcelas-titulo").html("Manutenção Crediário");
    arrayColunasInvisiveis.push(2, 3, 4, 5, 8, 9, 10);
    bloqNomeCpf = 'readonly enabled'
  }

  for (let k in columnKeys) {
    dataSetCols.push({
      title: columnKeys[k],
      data: columnKeys[k],
    });
  }

  dataSetCols[0].render = function (data, type, row) {
    return `<input type="text" value="${data}" class="input-default focus form-control campoNome required" ${bloqNomeCpf} style="min-width: 200px;">`;
  };
  dataSetCols[1].render = function (data, type, row) {
    return `<input type="text" value="${data}" class="input-default focus form-control campoCPFCNPJ required" ${bloqNomeCpf} style="min-width: 150px;">`;
  };
  dataSetCols[2].render = function (data, type, row, meta) {
    return `<input type="text" placeholder="Banco" id="banco_col_${[meta.row,]}_row_${[meta.col,]}" class="input-default focus form-control validate campoBanco" required="required" readonly> `;
  };
  dataSetCols[3].render = function (data, type, row) {
    return `<input type="text" value="${data}" class="input-default focus form-control campoAgencia required">`;
  };
  dataSetCols[4].render = function (data, type, row) {
    return `<input type="text" value="${data}" class="input-default focus form-control campoConta required">`;
  };
  dataSetCols[5].render = function (data, type, row) {
    return `<input type="text" value="${data}" class="input-default focus form-control campoNumero required">`;
  };

  dataSetCols[9].render = function (data, type, row) {
    return '<button title="Imprimir na impressora de cheque" class="btn btn-primary btnCheque"><i class="fas fa-print"></i></button>';
  };

  dataSetCols[10].render = function (data, type, row) {
    return '<button title="Ler cheque" class="btn btn-primary btnLerCheque"><i class="fas fa-download"></i></button>';
  };

  dataSetCols[idColunaVencimento].type = "date-br";
  // dataSetCols[idColunaVencimento].render = function (data, type, row) {
  //   return `<input type="date" max="2500-12-31" value="${data}" class="input-default focus form-control campoVencimento required">`;
  // };
  dataSetCols[idColunaVencimento].render = function (data, type, row) {
    return `<input 
            type="date"
            max="2500-12-31"
            value="${data}"
            data-original="${data}"
            class="input-default focus form-control campoVencimento required">`;
  };

  dataSetCols[idColunaValor].render = function (data, type, row) {
    return `<input type="number" step="0.01" value="${parseFloat(data).toFixed(2)}" class="input-default focus form-control campoValor required" style="width: 100px;">`;
  };

  if (bAlteracao == "alteracao") {
    // tabela por trás para controlar as condições de pagamentos e alterções de data/valor feito pelo usuario.
    let totalParcelas = $("#tabelaParcelasGeradas").DataTable().rows().count();

    for (let index = 0; index < totalParcelas; index++) {
      const parcela = $("#tabelaParcelasGeradas").DataTable().row(index).data();
      if (parcela[0] == ordemAlteracao) {
        dataSet.push({
          Nome: parcela[1],
          CPF_CNPJ: parcela[2],
          Banco: parcela[3],
          Agência: parcela[4],
          Conta: parcela[5],
          Número: parcela[6],
          Vencimento: parcela[7],
          Valor: parcela[8],
          Ordem: ordemAlteracao,
          Impressao: "",
        });
      }
    }
  } else {
    for (let i = 0; i < iNumParcelas; i++) {
      let indice = $("#tabelaCondicoesDePagamento").DataTable().rows().count();
      while ($("#tabelaCondicoesDePagamento").DataTable().column(0).data().indexOf(indice) >= 0) {
        indice += 1;
      }
      dataSet.push({
        Nome: sNome,
        CPF_CNPJ: sCnpj,
        Banco: "",
        Agência: "",
        Conta: "",
        Número: "",
        Vencimento: arrayVencimentos[i],
        Valor: valorParcela,
        Ordem: indice,
        Impressao: "",
      });
    }
    if (parcelaArredondamento == "P") {
      dataSet[0].Valor += diferenca;
    } else {
      dataSet[dataSet.length - 1].Valor += diferenca;
    }
  }

  $("#tabelaParcelas").DataTable({
    paging: false,
    filter: false,
    info: false,
    order: false,
    destroy: true,
    autowidth: true,
    columnDefs: [
      {
        targets: arrayColunasInvisiveis,
        visible: false,
      },
    ],
    columns: dataSetCols,
    data: dataSet,
  });

  if (bMostraTela) {
    $("#modalParcelas").modal("show");
  } else {
    $("#btn_confirmar_cred").trigger("click");
  }
  // faz o rateio dos totais das outros
  $(".campoValor").on("change", function () {
    $(this).addClass("alterado");
    let qtdeParaRatear =
      $(".campoValor").length - $(".campoValor.alterado").length;
    let valorAlterado = 0;
    for (let i = 0; i < $(".campoValor.alterado").length; i++) {
      valorAlterado =
        parseFloat(valorAlterado.toFixed(2)) +
        parseFloat(
          parseFloat($($(".campoValor.alterado")[i]).val()).toFixed(2)
        );
    }
    if (valorAlterado > +$("#txt_cred_valor_total").val().replaceAll('.', '').replace(',', '.')) {
      msgAlerta("valor da parcela não pode ser maior que o valor total.");
      $("#btn_dividir_valor").trigger("click");
    } else {
      valorParaRatear = Number($("#txt_cred_valor_total").val().replaceAll('.', '').replace(',', '.')) - valorAlterado;
      let valorRateio = parseFloat(valorParaRatear / qtdeParaRatear).toFixed(2);
      for (let i = 0; i < $(".campoValor").length; i++) {
        if (!$($(".campoValor")[i]).hasClass("alterado")) {
          $($(".campoValor")[i]).val(valorRateio);
        }
      }
    }
  });

  for (let i = 0; i < $(".campoBanco").length; i++) {
    $(`#banco_col_${i}_row_2`).pesquisa(
      `#banco_col_${i}_row_2`,
      "BANCO",
      "NOME_BANCO",
      '/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"cadban", "camposSelect":[ "banco", "nome_banco"], "where": null}',
      "Pesquisa Banco",
      "cadban"
    );
  }

  $(".campoBanco").on("blur", function () {
    for (let i = 0; i < $(".campoBanco").length; i++) {
      if ($($(".campoBanco")[i]).val() == "") {
        $($(".campoBanco")[i]).val($(this).val());
      }
    }
  });

  $(".campoAgencia").on("blur", function () {
    const bLeu = preencheDadosCheque(this);
    if (bLeu) {
      for (let i = 0; i < $(".campoAgencia").length; i++) {
        if ($($(".campoAgencia")[i]).val() == "") {
          $($(".campoAgencia")[i]).val($(this).val());
        }
      }
    }
  });

  $('.campoAgencia').keydown(function (e) {
    if (e.which === 13) {
      e.preventDefault();
      $('.campoAgencia').trigger('blur');
    }
  });

  $(".campoConta").on("blur", function () {
    const bLeu = preencheDadosCheque(this);
    if (bLeu) {
      for (let i = 0; i < $(".campoConta").length; i++) {
        if ($($(".campoConta")[i]).val() == "") {
          $($(".campoConta")[i]).val($(this).val());
        }
      }
    }
  });

  $('.campoConta').keydown(function (e) {
    if (e.which === 13) {
      e.preventDefault();
      $('.campoConta').trigger('blur');
    }
  });

  $(".campoNumero").on("blur", function () {
    const bLeu = preencheDadosCheque(this);
    if (bLeu) {
      if ($(this).val() == "") {
        return;
      }
      for (let i = 0; i < $(".campoNumero").length; i++) {
        if ($($(".campoNumero")[i]).val() == "") {
          const numero = parseInt($(this).val()) + i;
          const qtdeZero = $(this).val().length;
          $($(".campoNumero")[i]).val(ZeroE(qtdeZero, numero.toString()));
        }
      }
    }
  });

  $('.campoNumero').keydown(function (e) {
    if (e.which === 13) {
      e.preventDefault();
      $('.campoNumero').trigger('blur');
    }
  });

  $(".btnCheque").on("click", async function () {
    try {
      try {
        $(this).attr("disabled", "true");
        $.LoadingOverlay("show");
        const posicao = $(this).parents("tr")[0].rowIndex - 1;
        await imprimirCheque(posicao);
      } finally {
        $.LoadingOverlay("hide");
        $(this).removeAttr("disabled");
      }
    } catch (error) {
      msgErro("Erro ao imprimir cheque.");
      $(this).removeAttr("disabled");
    }
  });

  $(".btnLerCheque").on("click", async function () {
    try {
      try {
        $(this).attr("disabled", "true");
        $.LoadingOverlay("show");
        const posicao = $(this).parents("tr")[0].rowIndex - 1;
        await LerCheque(posicao);
      } finally {
        $.LoadingOverlay("hide");
        $(this).removeAttr("disabled");
      }
    } catch (error) {
      msgErro("Erro ao ler cheque.");
      $(this).removeAttr("disabled");
    }
  });

  // async function imprimirCheque(posicao) {
  //   const url = `/ImprimirCheque?`;
  //   const sBanco = pegaChave($(".campoBanco")[posicao]);
  //   const sCidade = await retornaCidade();
  //   const sFavorecido = sessionStorage
  //     .getItem("g_nome_empresa_logada")
  //     .substring(6);
  //   let sValor = $($(".campoValor")[posicao]).val().replace(".", ",");
  //   const sData = moment($($(".campoVencimento")[posicao]).val()).format(
  //     "DD/MM/YYYY"
  //   );
  //   const params = `BANCO=${sBanco}&CIDADE=${sCidade}&FAVORECIDO=${sFavorecido}&VALOR=${sValor}&DATA=${sData}`;
  //   try {
  //     let response = await requisicao_ecf("POST", url, params, "", null);

  //     if (!response) {
  //       msgErro("Não foi possível imprimir o cheque.");
  //       return;
  //     }

  //     if (response.status != 200) {
  //       msgErro("Não foi possível imprimir o cheque.");
  //       return;
  //     }
  //   } catch (error) {
  //     console.error(error);
  //     msgErro("Não foi possível imprimir o cheque.");
  //   }
  // }

  setTimeout(() => {
    $("#tabelaParcelas").DataTable().columns.adjust().draw(false);
  }, 200);
}

$(document).on('blur', '.campoVencimento', async function () {

  const moeda = $('#tabelaCondicoesDePagamento').DataTable().data()[0][1].split('-')[0].trim()
  const tipoMoeda = (await buscaValor('MOEDA', 'FORMA_PAGTO', 'CODMOE', moeda)).FORMA_PAGTO

  if (tipoMoeda == '03' || tipoMoeda == '05' || tipoMoeda == '15') {

    const $input = $(this);

    const dataDigitada = new Date($input.val());
    const dataOriginal = new Date($input.data('original'));

    const valorPadrao = await buscaValoresPadroes('LOJA');

    let diasVencimento =
      valorPadrao?.find(obj => obj.CAMPO === 'DIAS_VENCTO')?.VALOR;

    if (!diasVencimento) return;

    const dataLimite = adicionarDiasUteis(dataOriginal, parseInt(diasVencimento));

    if (dataDigitada > dataLimite) {
      const yyyy = dataLimite.getFullYear();
      const mm = String(dataLimite.getMonth() + 1).padStart(2, '0');
      const dd = String(dataLimite.getDate()).padStart(2, '0');

      $input.val(`${yyyy}-${mm}-${dd}`);
    }
  }
});

function adicionarDiasUteis(dataBase, diasUteis) {
  const data = new Date(dataBase);
  let adicionados = 0;

  while (adicionados < diasUteis) {
    data.setDate(data.getDate() + 1);

    const diaSemana = data.getDay();

    if (diaSemana !== 0 && diaSemana !== 6) {
      adicionados++;
    }
  }

  return data;
}


function adicionarDiasUteis(dataBase, diasUteis) {
  const data = new Date(dataBase);
  let adicionados = 0;

  while (adicionados < diasUteis) {
    data.setDate(data.getDate() + 1);

    const diaSemana = data.getDay();

    if (diaSemana !== 0 && diaSemana !== 6) {
      adicionados++;
    }
  }

  return data;
}


async function retornaBotaoOpcoes() {
  const permiteAlterarPreco = ['2','3'].includes(parametrosVenda[43]);
  const bUsaIntegraçãoITAG = parametrosVenda[60] == 1;
  const bAplicaDescMaxTabPrecoVendaNotAlterar = parametrosVenda[81] == '2';
  const bDevolucao = $(document).find(".devolucao").length > 0;
  const utilizaSomenteBarraLog = (parametrosVenda[46]) == "3";
  return (
    '<div style="text-align:center;"> ' +
    '   <div class="dropdown"> ' +
    '    <button class="btn btn-info btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
    "    </button> " +
    '    <div class="dropdown-menu dropdownVenda"> ' +
    '       <a class="dropdown-item btnInfoAdc" href="">Informações adicionais</a>' +
    '       <div class="dropdown-divider"></div>' +
    `       <a class="dropdown-item btnMotivo ${bDevolucao ? "" : "d-none"}" href="">Motivo</a>` +
    `       <div class="dropdown-divider ${bDevolucao ? "" : "d-none"}"></div>` +
    `       <a class="dropdown-item btnObservacaoItem ${bDevolucao ? "d-none" : ""}" href="">Observação</a>` +
    `       <div class="dropdown-divider ${bDevolucao ? "d-none" : ""}"></div>` +
    `       <a class="dropdown-item btnDesconto ${bAplicaDescMaxTabPrecoVendaNotAlterar ? "d-none" : ""}" href="">Alt. Preço / Desconto</a> ` +
    `       <div class="dropdown-divider ${bAplicaDescMaxTabPrecoVendaNotAlterar ? "d-none" : ""}"></div> ` +
    `${(parametrosVenda[35]) == 1
      ? '       <a class="dropdown-item btnQuantidade" href="">Quantidade</a> ' +
      '       <div class="dropdown-divider"></div>'
      : ""
    }` +
    `${permiteAlterarPreco
      ? '       <a class="dropdown-item btnAlterarPreco" href="">Alterar Preço</a> ' +
      '       <div class="dropdown-divider"></div>'
      : ""
    }` +
    // `${!bUsaIntegraçãoITAG
    //   ?
    `${'<a class="dropdown-item prod_relacionados btnProdutosRelacionados d-none" href="">Produtos Relacionados</a>'}` +
    '       <div class="dropdown-divider prod_relacionados d-none"></div>' +
    `${!utilizaSomenteBarraLog ? '       <a class="dropdown-item btnExcluir" href="">Excluir</a>' : ''}` +
    "    </div>" +
    "  </div>" +
    "</div>"
    //   :
    //   ""
    // }`
  );
}

function retornaBotaoOpcoesCondicao(iTipoMoeda) {
  let botao =
    '<div style="text-align:center;"> ' +
    '   <div class="dropdown"> ' +
    '    <button class="btn btn-info btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
    "      Opções" +
    "    </button> " +
    '    <div class="dropdown-menu"> ';
  if (iTipoMoeda == "1" || iTipoMoeda == "2") {
    // cheque e crediário
    botao =
      `${botao}<a class="dropdown-item btn-alterar-parcelas" href="" >Alterar Parcelas</a>` +
      `<div class="dropdown-divider"></div>`;
  }
  botao =
    `${botao} <a class="dropdown-item btnExcluir" href="">Excluir</a>` +
    `    </div>` +
    `  </div>` +
    `</div>`;
  return botao;
}

function adicionaItens(arrayDeItens) {
  // tratar NaN por garantia, houve caso que tinha desconto nan...
  arrayDeItens[5] = arrayDeItens[5] || 0;
  arrayDeItens[6] = arrayDeItens[6] || 0;

  let table = $('#tabelaItens').DataTable();

  if ((arrayDeItens[35]) || (arrayDeItens[29])) {
    if (arrayDeItens[29]) {
      const newRow = table.row.add(arrayDeItens).draw(false).node();
      $(newRow).addClass('linha-promocao');
    }
    if (arrayDeItens[35]) {
      const newRow = table.row.add(arrayDeItens).draw(false).node();
      $(newRow).addClass('linha-prodRelac');
      $('.prod_relacionados').removeClass('d-none');
    }

  } else {
    table.row.add(arrayDeItens).draw(false);
  }


  // $("#tabelaItens").DataTable().row.add(arrayDeItens).draw(false);
  let $scrollBody = $($("#tabelaItens").DataTable().table().node()).parent();
  $scrollBody.scrollTop($scrollBody.get(0).scrollHeight);
}

function adicionaItensPreco(arrayDeItens) {
  // tratar NaN por garantia, houve caso que tinha desconto nan...
  arrayDeItens[5] = arrayDeItens[5] || 0;
  arrayDeItens[6] = arrayDeItens[6] || 0;

  let table = $('#tabelaEstoquePrecoRegra').DataTable();

  if ((arrayDeItens[35]) || (arrayDeItens[29])) {
    if (arrayDeItens[29]) {
      const newRow = table.row.add(arrayDeItens).draw(false).node();
      $(newRow).addClass('linha-promocao');
    }
    if (arrayDeItens[35]) {
      const newRow = table.row.add(arrayDeItens).draw(false).node();
      $(newRow).addClass('linha-prodRelac');
      $('.prod_relacionados').removeClass('d-none');
    }
  } else {
    table.row.add(arrayDeItens).draw(false);
  }

  // $("#tabelaItens").DataTable().row.add(arrayDeItens).draw(false);
  let $scrollBody = $($("#tabelaEstoquePrecoRegra").DataTable().table().node()).parent();
  $scrollBody.scrollTop($scrollBody.get(0).scrollHeight);
  if (!$('#tabelaEstoquePrecoRegra tbody tr:last-child').hasClass('selected')) {
    $('#tabelaEstoquePrecoRegra tbody tr:last-child').trigger('click');
    $('#tabelaEstoquePrecoRegra').DataTable().context[0].nScrollBody.scrollTo(0, ($('.selected')[0].offsetTop));
  }
}

function adicionaCondicoesDePagamento(arrayCondicoesPagamentos) {
  try {
    $("#tabelaCondicoesDePagamento")
      .DataTable()
      .row.add(arrayCondicoesPagamentos)
      .draw(false);
    let $scrollBody = $(
      $("#tabelaCondicoesDePagamento").DataTable().table().node()
    ).parent();
    $scrollBody.scrollTop($scrollBody.get(0).scrollHeight);
  } catch (error) {
    console.error(error);
  }
}

function listaParcelasCondicao(iOrdem) {
  let arrayParcelasCondicao = [];
  for (
    let index = 0;
    index < $("#tabelaParcelasGeradas").DataTable().rows().count();
    index++
  ) {
    let data = $("#tabelaParcelasGeradas").DataTable().row(index).data();
    if (data[0] == iOrdem) {
      const parcela = {
        CPFSACADO: data[2], // verificar aqui se está pegando do lugar correto
        NOMESACADO: data[1],
        NRCONTA: data[5],
        VENCIMENTO: `${data[7]}T00:00:00Z`,
        BANCO: pegaChave(data[3]),
        NRAGENCIA: data[4],
        NUMERO: data[6],
        VALOR: data[8],
        VALORPAGO: data[8],
      };
      arrayParcelasCondicao.push(parcela);
    }
  }
  return arrayParcelasCondicao;
}

function listaFormaPgto() {
  let arrayCondicoes = [];
  for (
    let index = 0;
    index < $("#tabelaCondicoesDePagamento").DataTable().rows().count();
    index++
  ) {
    const data = $("#tabelaCondicoesDePagamento").DataTable().row(index).data();
    const condicao = {
      CodMoedaECF: "1", // PEGAR DO BANCO
      DescricaoMoeda: $("#tabelaCondicoesDePagamento")
        .DataTable()
        .row(0)
        .data()[1]
        .substring(
          $("#tabelaCondicoesDePagamento")
            .DataTable()
            .row(0)
            .data()[1]
            .indexOf("- ") + 3
        ),
      Valor: data[3],
      ImprimeGR: false,
    };
    arrayCondicoes.push(condicao);
  }
  return arrayCondicoes;
}

async function listaCondicoes() {
  let arrayCondicoes = [];
  for (
    let index = 0;
    index < $("#tabelaCondicoesDePagamento").DataTable().rows().count();
    index++
  ) {
    const data = $("#tabelaCondicoesDePagamento").DataTable().row(index).data();
    const condicao = {
      condiVenda: 0,
      codCondicao: data[9],
      codMoeda: data[8],
      perc_Desconto: data[12],
      perc_Juros: 0,
      valor_Desc: data[13],
      valor_Juros: 0,
      nsu: data[15],
      dados_Tef: "",
      bandeira: data[14],
      antecipacoes: data[11],
      antecipacoesPresente: data[16],
      parcelas: listaParcelasCondicao(data[0]),
      descricaoMoeda: data[1],
      descricaoCondicao: data[2],
      valor: data[3],
      valorPago: data[4],
      valorMoeda: data[7],
      cotacaoMoeda: data[6],
      tipomoeda: data[17],
      adicional: {
        autorizacao: data[18]
      }
    };
    arrayCondicoes.push(condicao);
  }
  return arrayCondicoes;
}

async function listaItensDev(parametroUsaProduto, utilizaBarraLog) {
  let arrayItens = [];
  for (let index = 0; index < $('#tabelaItens').DataTable().rows().count(); index++) {
    const data = $('#tabelaItens').DataTable().row(index).data();
    let itens = {};

    itens.codigo = data[0];
    itens.descricao = data[1];
    itens.barra = data[8];
    itens.cor = data[9];
    itens.desc_Cor = data[11];
    itens.tam = data[10];
    itens.deposito = pegaChave('#txtDeposito', itens.DEPOSITO);
    itens.lote = data[19] == 'P' ? '000000' : data[18]; // verifica se usa material se nao usa lote padrão
    itens.qualidade = data[12];
    itens.promocao = false;
    itens.tipo = data[19];
    itens.codRep = data[20];
    itens.dt_Inclusao = `${formataData(new Date())}T00:00:00Z`;
    itens.quantidade = parseFloat(data[2]);
    // itens.valor = TruncaDecimaisNova(2, data[3]);
    itens.valor = (+quantidadeCasasDecimaisCampo > 2) ? moeda2float(float2moeda(data[3], quantidadeCasasDecimaisCampo))
      : TruncaDecimaisNova(2, data[3]);
    itens.total = TruncaDecimaisNova(2, data[2] * data[3]);
    itens.total_Liq = parseFloat(data[7]);
    itens.valor_Desc = parseFloat(data[6]);
    itens.desconto = itens.total - itens.total_Liq;
    itens.perc_Icms = 0;
    itens.preco_Liq = parseFloat(data[4]);
    itens.perc_Desc = parseFloat(data[5]);
    itens.preco_Custo = 0;
    itens.iD_Estoque = data[13];
    itens.codVenDev = data[14];
    itens.concatenacao = `${data[0]} - ${data[9]} - ${data[10]} - ${data[12]}`;
    itens.presente = data[17];
    itens.lote = data[18];
    itens.unidade = data[21];
    itens.cashback_val = data[23];
    itens.emp_id = data[24];
    itens.motivo = data[25];
    itens.preco_liq_orig = data[26];
    itens.desc_item_orig = data[27];
    itens.preco_bruto_orig = data[28];
    itens.quantidade_orig = data[29];

    arrayItens.push(itens);
  }
  return arrayItens;
};

async function rotinaCliqueConfirmarCFE(bFinalizaVenda = true, codcli, codven) {
  let bErro = false;
  let sErro = [];
  const bAutomatico = parametrosVenda[18];

  if ($('#txtCpfCFe').val() == '') {
    if ((bFinalizaVenda) && ((bAutomatico == 3) || (bAutomatico == 4) || (bAutomatico == 6))) {
      bErro = true;
      sErro.push('Necessário informar um CPF/CNPJ.');
    } else {
      msgAlerta('Necessário informar um CPF/CNPJ.');
      return;
    }
  }

  if ($('#txtNaturezaCFe').val() == '' && $('#txtOperacaoCFe').val() == '') {
    if ((bFinalizaVenda) && ((bAutomatico == 3) || (bAutomatico == 4) || (bAutomatico == 6))) {
      bErro = true;
      sErro.push('Necessário informar uma natureza ou operação fiscal.');
    } else {
      msgAlerta('Necessário informar uma natureza ou operação fiscal.');
      return;
    }
  }

  if (bFinalizaVenda) {
    await RotinaFinalizarVenda(false, true, false, false);
  }

  async function retornaObjetoCfe(sId) {
    try {
      let objeto = await buscaCFEVenda(sId);
      return objeto[0];
    } catch (error) {
      msgErro('Erro ao retornar objeto ');
    }
  }

  try {
    $.LoadingOverlay("show");
    // finaliza venda
    try {
      if (!await testeConexao()) {
        msgAlerta('Não está conectado a Api Local!');
        return;
      }
      let natureza = pegaChave('#txtNaturezaCFe');
      const operacao = pegaChave('#txtOperacaoCFe');
      let cpf = $('#txtCpfCFe').val();
      let obs = $('#txtInfoAdicionaisCFe').val();
      let caixa = pegaChave(sessionStorage.getItem('g_caixa_logado'));
      let codvenda = codven;
      let codcliente = codcli;
      let url = '/Sisplan/cfe/v1/converterVenda?';
      let params = `CNPJ=${cpf}&NATUREZA=${natureza}&MENSAGEM=${obs}&COD_VEN=${codvenda}&CAIXA=${caixa}&CODCLI=${codcliente}&OPERACAO=${operacao}`;
      let response = await requisicao('POST', url, params, '', 30000);

      let jsonStr = await response.json();
      if (response.status != 200) {
        msgErro(jsonStr.mensagem);
        return;
      }
      // pega o objeto para enviar para o sat
      let objeto = await retornaObjetoCfe(jsonStr);

      // transmite pro sat e gera chave
      let bSucesso = await TransmiteCfe(objeto);

      if (bSucesso) {
        setTimeout(() => {
          if (bFinalizaVenda) {
            RotinaFinalizarVenda();
          }

          if (bAutomatico != 5 && bAutomatico != 6) {
            window.location.href = `${BASE_URI}/cfe`;
          } else {
            window.location.reload();
          }
        }, 6000);
      } else {
        toastr.error(
          `Erro ao gerar CFe`,
          '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,
          onHidden() { }
        }
        ).css({
          "margin-top": "20%",
          "width": "500px",
          "max-width": "500px"
        });
      }
    } catch (error) {
      console.error(error);
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

$('#btn_confirmar_cfe').on('click', async function () {
  await rotinaCliqueConfirmarCFE();
});

async function listaItens(parametroUsaProduto, utilizaBarraLog) {

  const empId = getCookie('emp_id');
  let arrayItens = [];
  const utilizaImpressoraFiscal = parametrosVenda[8];
  for (
    let index = 0;
    index < $("#tabelaItens").DataTable().rows().count();
    index++
  ) {
    let data = $("#tabelaItens").DataTable().row(index).data();

    let lote = '';
    if (data[19] == 'P') {
      if (data[18] != '') {
        lote = data[18];
      } else {
        lote = '000000';
      }
    } else {
      lote = data[18];
    }

    let itens = {};
    itens.codigo = data[0];
    itens.descricao = data[1].split(" - ")[1];
    itens.barra = data[9];
    itens.cor = data[10];
    itens.desc_Cor = data[12];
    itens.tam = data[11];
    itens.deposito = pegaChave("#txtDeposito");
    itens.lote = lote;
    itens.qualidade = data[13];
    itens.promocao = data[29];
    itens.tipo = data[19];
    itens.codRep = data[26];
    itens.dt_Inclusao = `${formataData(new Date())}T00:00:00Z`;
    itens.quantidade = parseFloat(data[2]);
    itens.qtde_Conferida = bConferido ? parseFloat(data[2]) : 0;
    itens.valor = (+quantidadeCasasDecimaisCampo > 2) ? moeda2float(float2moeda(data[3], quantidadeCasasDecimaisCampo))
      : TruncaDecimaisNova(2, data[3]);
    // itens.valor = quantidadeCasasDecimaisParametro > 2 ? 
    //                                                    : TruncaDecimaisNova(2, data[3]);

    const soma = +(data[2] * data[3]).toFixed(4);
    const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
    itens.total = utilizaImpressoraFiscal == '1' && maisDeDoisCaracteresDecimal ? mantemDuasCasasDecimais(soma, 3) : TruncaDecimaisNova(2, parseFloat(soma));

    // itens.total = TruncaDecimaisNova(2, data[2] * data[3]);
    itens.total_Liq = TruncaDecimaisNova(2, data[7]);
    itens.valor_Desc = parseFloat(data[6]);
    itens.desconto = TruncaDecimaisNova(2, itens.total - itens.total_Liq <= 0 ? 0 : itens.total - itens.total_Liq);
    itens.perc_Icms = 0;
    itens.preco_Liq = parseFloat(data[4]);
    itens.perc_Desc = parseFloat(data[5]);
    itens.preco_Custo = 0;
    itens.iD_Estoque = data[14];
    itens.codVenDev = data[15];
    itens.concatenacao = `${data[0]} - ${data[10]} - ${data[11]}`;
    itens.presente = data[17];
    itens.ValorDesc_RegraPromo = data[20] != undefined ? data[20] : 0;
    itens.BaseDesc_RegraPromo = data[21] != undefined ? data[21] : 0;
    itens.PercDesc_RegraPromo = data[22] != undefined ? data[22] : 0;
    itens.pedido = data[23];
    itens.ordem_ped = data[24];
    itens.caixa = data[25];
    itens.dt_Inclusao = data[27];
    itens.unidade = data[28];
    itens.valorOld = data[30];
    itens.codRegraPromo = data[31];
    itens.observacao = data[32];
    itens.deposito = data[33];
    itens.tabela = data[34];
    itens.itemRelacionado = data[35];
    itens.lote_orig = data[36];
    itens.qtde_orig = data[37];
    itens.emp_id = empId;
    itens.Valor_IPI = data[38];

    arrayItens.push(itens);
  }
  return arrayItens;
}

async function retornaBarraLog(utilizaBarraLog) {
  const barras = utilizaBarraLog
    ? listaBarrasBipadas
    : [];
  return barras;
}

async function retornaBarraLogEstorno(utilizaBarraLog) {
  const barras = utilizaBarraLog
    ? listaBarrasRemovidas
    : [];
  return barras;
}

async function AplicaDescontoVenda(descontoDeCupom = -1, bSemDescontoItensPromocionais = false, solicitaSenha = true) {
  $.LoadingOverlay("show");
  try {
    const arrayData = $("#tabelaItens").DataTable().data().toArray();

    async function aplicaValoresOriginais(i) {
      arrayData[i][3] = arrayData[i][30];
      arrayData[i][4] = arrayData[i][3];
      arrayData[i][7] = arrayData[i][4] * arrayData[i][2];
      arrayData[i][5] = 0;
      arrayData[i][6] = 0;
    }

    function validaDescontoAplicado() {
      if (bSemDescontoItensPromocionais) {
        return false;
      }

      if (table.column(6, {}).data().sum() > 0) {
        return true;
      }
      return false;
    }

    const descontoMaximoUsuario = await retornaDescontoMaximoUsuario();
    let table = $("#tabelaItens").DataTable();
    let data = table.rows()[0].length;
    let percDesconto = (descontoDeCupom >= 0) ? descontoDeCupom : $("#txtDesconto").val();
    let soma = 0;
    let valor = 0;
    let somaPreco = 0;
    let total = 0;
    let totalQtd = 0;
    let valorDesconto = isNaN(parseFloat($('#txtValDesconto').val())) ? 0 : parseFloat($('#txtValDesconto').val());
    let precoItem = isNaN($('#txtPrecoItem').val()) ? 0 : $('#txtPrecoItem').val();
    const valorTotal = bSemDescontoItensPromocionais ? parseFloat($("#tabelaItens").DataTable().data().filter(item => item[6] == 0).filter(item => !item[29]).map(item => item[7]).sum().toFixed(2))
      : parseFloat(($("#tabelaItens").DataTable().column(7, {}).data().sum()).toFixed(2));
    let TotalDesconto = 0;
    let valorDescontoRatear = isNaN(parseFloat($("#txtValDescontoRateado").val())) ? 0 : parseFloat($("#txtValDescontoRateado").val());
    let percentualDescontoRatear = isNaN(parseFloat($("#txtPercDescontoRateado").val())) ? 0 : parseFloat($("#txtPercDescontoRateado").val());
    const bSenhaSupervisor = parametrosVenda[9];
    let taBomTaBomNaoVouAguentarMais = false;
    const quantidadeItens = bSemDescontoItensPromocionais ? parseFloat($("#tabelaItens").DataTable().data().filter(item => item[6] == 0).filter(item => !item[29]).map(item => item[2]).sum().toFixed(2))
      : parseFloat(($("#tabelaItens").DataTable().column(2, {}).data().sum()).toFixed(2));

    if (parseFloat(percDesconto) > 99 || parseFloat(percentualDescontoRatear) > 99) {
      msgAlerta("Desconto não pode ser maior que 99%");
      return;
    }

    if (parseFloat(percDesconto) < 0 || parseFloat(percentualDescontoRatear) < 0) {
      msgAlerta("Desconto não pode ser menor que 0%");
      return;
    }

    // fazer validacao aquiiiiii
    if (+$('#txtValDescontoRateado').val() > 0) {
      if (Number(valorTotal) > 0) {
        percentualDescontoRatear = (Number(valorDescontoRatear) / Number(valorTotal)) * 100;
        percentualDescontoRatear = Math.round(percentualDescontoRatear * 100) / 100;
      }
    }

    if (+$('#txtValDesconto').val() > 0) {
      if (Number(valorTotal) > 0) {
        const valorDescontoTotal = parseFloat((valorDesconto * quantidadeItens).toFixed(2));
        percDesconto = (Number(valorDescontoTotal) / Number(valorTotal)) * 100;
        percDesconto = Math.round(percDesconto * 100) / 100;
      }
    }

    if ((percDesconto != 0 || valorDesconto != 0 || precoItem != 0 || valorDescontoRatear != 0 || percentualDescontoRatear != 0) && validaDescontoAplicado()) {
      msgAlerta("Existem itens com desconto aplicado, necessário remover os descontos para continuar!");
      return;
    }


    function verificaDescSupervisorEAplica(userSupervisor) {
      verificaDescontoMaximoSupervisor(userSupervisor, callBack);
    }

    const msgSenhaSupervisor = percDesconto != 0 ? `Desconto de ${percDesconto}% aplicado.`
      : percentualDescontoRatear != 0 ? `Desconto de ${percentualDescontoRatear.toFixed(2)}% aplicado.`
        : valorDesconto != 0 ? `Desconto de R$${valorDesconto.toFixed(2)} aplicado.`
          : valorDescontoRatear != 0 ? `Desconto de R$${valorDescontoRatear.toFixed(2)} aplicado.`
            : "";

    const nmrVenda = $('#txt_venda_atual>span').html() == 'Nova' ? 'create' : $('#txt_venda_atual>span').html()

    if ((solicitaSenha) && ((parseFloat(percDesconto) > parseFloat(descontoMaximoUsuario)) ||
      (parseFloat(percentualDescontoRatear) > parseFloat(descontoMaximoUsuario)) && descontoMaximoUsuario > 0)) {
      await senhaSupervisor(
        `Desconto de ${percDesconto != 0 ? percDesconto : percentualDescontoRatear}% no item, máximo do usuário é de ${descontoMaximoUsuario}%.`,
        verificaDescSupervisorEAplica,
        async () => { await callBack(); },
        true,
        undefined, undefined, undefined, false, 'VENDA', nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda, pegaChave('#txtCliente'), parseFloat($('#saldo_geral').text().replace(/R\$\s*/, '').replaceAll('.', '').replace(',', '.')) || 0
      );
    } else {
      if ((solicitaSenha) && bSenhaSupervisor == "1") {
        await senhaSupervisor(
          msgSenhaSupervisor,
          async () => { await callBack(); },
          '', false, undefined, undefined, undefined, false, 'VENDA', nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda, pegaChave('#txtCliente'), parseFloat($('#saldo_geral').text().replace(/R\$\s*/, '').replaceAll('.', '').replace(',', '.')) || 0
        );
      } else {
        await callBack();
      }
    }

    async function callBack() {
      try {
        let exibirMensagem = true;
        for (let i = 0; i < data; i++) {
          if (bSemDescontoItensPromocionais && (arrayData[i][6] != 0 || arrayData[i][29])) {
            continue;
          }
          if (taBomTaBomNaoVouAguentarMais) {
            break;
          }
          if (percDesconto == 0 && valorDesconto == 0 && precoItem == 0 && valorDescontoRatear == 0 && percentualDescontoRatear == 0) {
            if (exibirMensagem) {
              await new Promise((resolve) => {
                msgAlerta('Nenhum desconto aplicado, ao confirmar, os itens receberão seus valores originais. Deseja continuar?', async () => {
                  await aplicaValoresOriginais(i);
                  resolve();
                }, () => { $.LoadingOverlay('hide') });
              });
              exibirMensagem = false;
            } else {
              await aplicaValoresOriginais(i);
            }
          } else if (valorDescontoRatear != 0 || percentualDescontoRatear != 0) {
            function aplicaValorDescontoRateado() {
              try {
                let percentualDesconto = 0;
                if (valorDescontoRatear != 0) {
                  percentualDesconto = parseFloat((valorDescontoRatear / valorTotal) * 100);
                } else {
                  const percentualDescontoRateado = parseFloat((percentualDescontoRatear / quantidadeItens).toFixed(2));
                  percentualDesconto = percentualDescontoRateado;
                  valorDescontoRatear = TruncaDecimaisNova(2, ((percentualDescontoRateado / 100) * valorTotal));
                }

                let preco = 0;

                if (valorDescontoRatear >= valorTotal) {
                  throw new Error(`Valor de desconto não pode ser maior ou igual aos valores dos itens, impossível aplicar o desconto de R$${valorDescontoRatear.toFixed(2)}. O valor original será definido em todos os itens.`);
                }

                let valorOriginal = arrayData[i][3];
                let desconto = 0;
                let valorDescontoThisFunction = 0;

                valorDescontoThisFunction = parseFloat(((valorOriginal * percentualDesconto) / 100).toFixed(2));
                desconto = valorDescontoThisFunction;

                if (desconto >= valorOriginal) {
                  throw new Error(`Valor de desconto não pode ser maior ou igual ao valor do item, impossível aplicar o desconto de R$${valorDescontoRatear.toFixed(2)} no item ${arrayData[1]}. O valor original será definido em todos os itens.`);
                }

                valorDescontoThisFunction *= arrayData[i][2];
                preco = parseFloat((valorOriginal - desconto).toFixed(2));
                TotalDesconto += parseFloat((desconto * arrayData[i][2]).toFixed(2));
                if (i == data - 1) {
                  const diferenca = parseFloat((valorDescontoRatear - TotalDesconto).toFixed(2));
                  if (diferenca != 0) {
                    desconto += (diferenca / arrayData[i][2]);
                    valorDescontoThisFunction += diferenca;
                    preco = parseFloat((valorOriginal - desconto));
                  }
                }

                const total = parseFloat((preco * arrayData[i][2]).toFixed(2)); //[2] = quantidade
                arrayData[i][4] = parseFloat((arrayData[i][3] - desconto).toFixed(2)); //[4]preco_Liq
                arrayData[i][5] = percentualDesconto;
                arrayData[i][6] = valorDescontoThisFunction; //[6]valor_Desc
                arrayData[i][7] = total; //[7]total_liq
              } catch (error) {
                msgAlerta(error.message);
                console.error(error);
                aplicaValoresOriginaisTodosItens();
                taBomTaBomNaoVouAguentarMais = true;
              }
            }

            aplicaValorDescontoRateado();

          } else if (valorDesconto != 0) {
            async function AplicaDescontoItem() {
              let valorOriginal = arrayData[i][3];

              if (valorDesconto == valorTotal) {
                await aplicaValoresOriginais(i);
                return msgAlerta(`Valor de desconto não pode ser o valor integral dos itens, verifique!`)
              }

              soma = valorOriginal - valorDesconto;

              if (valorDesconto > valorTotal || soma < 0) {
                await aplicaValoresOriginais(i);
                return msgAlerta(`Existem valores de desconto maiores que os valores dos itens, impossível aplicar o desconto de R$${valorDesconto.toFixed(2)} no item ${arrayData[i][1]}`)
              }

              total = soma * arrayData[i][2];
              percDesconto = ((valorDesconto * 100)) / valorOriginal;
              arrayData[i][3] = valorOriginal > soma ? arrayData[i][3] : soma;
              arrayData[i][4] = arrayData[i][3] - valorDesconto;
              arrayData[i][5] = total;
              arrayData[i][6] = valorDesconto * arrayData[i][2];
              arrayData[i][7] = total;
            }

            await AplicaDescontoItem();

          } else if (precoItem != 0) {
            if (['2','3'].includes(parametrosVenda[43])) {
              arrayData[i][3] = TruncaDecimaisNova(2, precoItem); // preço orig
            }
            arrayData[i][4] = TruncaDecimaisNova(2, precoItem); // novo preço
            arrayData[i][5] = 0;

            arrayData[i][6] = ($('#txtValDesconto').val() / arrayData[i][3] * 100);
            arrayData[i][7] = parseFloat(parseFloat(arrayData[i][4] * arrayData[i][2]).toFixed(2)); // novo total
          } else {
            valor = table.row(i).data()[3];
            soma = TruncaDecimaisNova(2, parseFloat(valor) - (parseFloat(valor) * percDesconto) / 100);

            total = soma * arrayData[i][2];

            totalQtd = TruncaDecimaisNova(2, total, totalQtd);
            somaPreco = quantidadeCasasDecimaisCampo > 2 ? moeda2float(float2moeda(soma, quantidadeCasasDecimaisCampo))
              : TruncaDecimaisNova(2, soma, somaPreco);

            arrayData[i][4] = somaPreco;
            arrayData[i][7] = totalQtd;
            arrayData[i][5] = percDesconto;
            arrayData[i][6] = TruncaDecimaisNova(2, (valor - soma) * arrayData[i][2]);
          }
        }

        table.clear();
        table.rows.add(arrayData).draw(false);

        table.rows().every(function (rowIdx, tableLoop, rowLoop) {
          const data = this.data();

          if (data[29]) {
            $(this.node()).addClass('linha-promocao');
          }
          if (data[35]) {
            $(this.node()).addClass('linha-prodRelac');
          }
          if (data[6] > 0) {
            // $(`#tabelaItens tbody>tr:eq(${rowIdx}) td:eq(3)`).addClass('textDesconto');
            $($(`#tabelaItens`).DataTable().row(rowIdx).node()).find('td:eq(3)').addClass('textDesconto');
          } else {
            // $(`#tabelaItens tbody>tr:eq(${rowIdx}) td:eq(3)`).removeClass('textDesconto');
            $($(`#tabelaItens`).DataTable().row(rowIdx).node()).find('td:eq(3)').removeClass('textDesconto');
          }
        });

        logDescontoVenda = msgSenhaSupervisor;
      } finally {
        await atualizaTotalVenda();
        atualizaSaldoAPagar();
        atualizaTotaisPagto();
        $('[data-toggle="tooltip"]').tooltip();
        $("#modalDescontoTotal").modal("hide");
        $.LoadingOverlay("hide");
      }
    }
  } catch (error) {
    msgErro("Erro ao aplicar desconto!");
    console.error(error);
  } finally {
    await atualizaTotalVenda();
    atualizaSaldoAPagar();
    atualizaTotaisPagto();
    $('[data-toggle="tooltip"]').tooltip();
    $("#modalDescontoTotal").modal("hide");
    $.LoadingOverlay("hide");
  }
}

$("#btnDescontoTotal").on("click", async function () {
  let total = $("#tabelaItens").DataTable().column(7, {}).data().sum();
  if ($('#txtCupomDesconto').val() !== '') {
    msgAlerta("Venda com cupom de Desconto aplicado, impossível aplicar desconto.");
    return;
  }
  if (parametrosVenda[43] != '0') {
    $("#txtPrecoItem").attr("disabled", false).attr("readonly", false);
  } else {
    $("#txtPrecoItem").attr("disabled", true).attr("readonly", true);
  }
  $("#txtValorTotal").val(total.toFixed(2));
  limpaCamposDescontoEmMassa();
  $("#modalDescontoTotal").modal("show");
});

$('#modalDescontoTotal').on('shown.bs.modal', function () {
  $("#txtDesconto").attr("disabled", false).attr("readonly", false);
  $("#txtValDesconto").attr("disabled", false).attr("readonly", false);
});

$("#btnAplicaDesconto").on("click", async function () {
  $('#txtPrecoItem').trigger('blur');
  const bSemDescontoItensPromocionais = $("#cbSemDescontoItensPromocionais").prop("checked");
  await AplicaDescontoVenda(-1, bSemDescontoItensPromocionais);
});

function limpaCamposDescontoEmMassa() {
  $("#txtDesconto").val("0.00");
  $("#txtValDesconto").val("0.00");
  $("#txtPercDescontoRateado").val("0.00");
  $("#txtValDescontoRateado").val("0.00");
  $("#cbSemDescontoItensPromocionais").prop("checked", false);
}

$("#btnRemoveDesconto").on("click", function () {
  $.LoadingOverlay("show");
  try {
    $("#txtDesconto").val("0.00");
    $("#txtValDesconto").val("0.00");
    $("#txtPercDescontoRateado").val("0.00");
    $("#txtValDescontoRateado").val("0.00");
    aplicaValoresOriginaisTodosItens();
    atualizaTotalVenda();
    const total = $("#tabelaItens").DataTable().column(7, {}).data().sum();
    $("#txtValorTotal").val(total.toFixed(2));
    logDescontoVenda = ''
  } finally {
    $.LoadingOverlay("hide");
  }
})

function aplicaValoresOriginaisTodosItens() {
  $("#tabelaItens").DataTable().data().toArray().forEach((item, i) => {
    item[3] = item[30];
    item[4] = item[3];
    item[7] = item[4] * item[2];
    item[5] = 0;
    item[6] = 0;
    $("#tabelaItens").DataTable().row(i).data(item);
  })
}

async function atualizaTotalVenda() {
  let valorTotal = 0;

  utilizaImpressoraFiscal = parametrosVenda[8];

  $("#tabelaItens")
    .DataTable()
    .data()
    .toArray()
    .forEach((item) => {
      const soma = +(item[3] * item[2]).toFixed(4);
      const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
      valorTotal += utilizaImpressoraFiscal == 1 && maisDeDoisCaracteresDecimal ? mantemDuasCasasDecimais(soma, 3) : TruncaDecimaisNova(2, parseFloat(soma));
    });
  let totalQuantidade = $("#tabelaItens")
    .DataTable()
    .column(2, {})
    .data()
    .sum();
  let totalLiquido = parseFloat($("#tabelaItens").DataTable().column(7, {}).data().sum());

  try {
    let totalAntecipacao =
      $("#tabelaAntecipacoes").length > 0
        ? parseFloat(
          parseFloat(
            $("#tabelaAntecipacoes").DataTable().column(4, {}).data().sum()
          ).toFixed(2)
        )
        : 0;
    let totalAntecipacaoPago =
      $("#tabelaAntecipacoes").length > 0
        ? parseFloat(
          parseFloat(
            $("#tabelaAntecipacoes").DataTable().column(5, {}).data().sum()
          ).toFixed(2)
        )
        : 0;
    let valorTotalItens = $("#tabelaItens")
      .DataTable()
      .column(7, {})
      .data()
      .sum();
    let saldoAntecipacao = totalAntecipacao - totalAntecipacaoPago;
    let saldoGeral = valorTotalItens - saldoAntecipacao;
    if (saldoGeral < 0) {
      saldoGeral = 0;
    }
    $("#credito_cliente").html(
      parseFloat(saldoAntecipacao).toLocaleString("pt-BR", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        currency: "BRL",
      })
    );

    const creditoClienteSaldo = saldoAntecipacao - totalLiquido >= 0 ? saldoAntecipacao - totalLiquido : 0;
    $("#credito_cliente_saldo").html(parseFloat(creditoClienteSaldo).toLocaleString('pt-BR', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: 'BRL'
    }));

    atualizaCreditoConformeUltimaDevolucao();

    $("#saldo_geral").html(
      parseFloat(saldoGeral).toLocaleString("pt-BR", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        currency: "BRL",
      })
    );
  } catch (error) {
    console.error(error);
  }

  $("#subtotal_venda").html(
    parseFloat(totalLiquido).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  totalQuantidade = ArredondarValor(totalQuantidade, 2);

  let total_original = 0;
  let total_desconto = 0;

  const soma = $('#tabelaItens').DataTable().data().toArray().reduce((total, item) => total + parseFloat(item[3] * item[2]), 0);
  const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
  total_original += utilizaImpressoraFiscal == 1 && maisDeDoisCaracteresDecimal ? mantemDuasCasasDecimais(soma, 3) : parseFloat(parseFloat(soma).toFixed(2));

  const tabelaItens = $("#tabelaItens").DataTable().data().toArray();

  for (const item of tabelaItens) {
    total_desconto += TruncaDecimaisNova(2, item[6] * -1);
  }
  // total_desconto = ArredondarValor($('#tabelaItens').DataTable().data().toArray().reduce((total, item) => {
  //   return total + parseFloat(item[6])
  // }, 0), 2) * -1;

  $("#total_desc").html(
    parseFloat(isNaN(total_desconto) || total_desconto > 0 ? 0 : total_desconto).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#total_orig").html(
    parseFloat(isNaN(total_original) ? 0 : total_original).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#total_itens").html(totalQuantidade);

  $("#txtTotalQtde").html(totalQuantidade);

  $("#txtTotalVenda").html(
    parseFloat(valorTotal).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  if ($("#tabelaItens").DataTable().rows()[0].length > 0) {
    const bAplicaDescMaxTabPrecoVendaNotAlterar = parametrosVenda[81] == '2';
    if (!bAplicaDescMaxTabPrecoVendaNotAlterar) {
      $("#btnDescontoTotal").removeClass("d-none");
    }
  }
}

async function atualizaCreditoConformeUltimaDevolucao() {
  const trazerApenasUltimaAntecipacao = parametrosVenda[48] == '1';
  const vendaDevolvida = codven_devolucao;
  if (trazerApenasUltimaAntecipacao && vendaDevolvida != '') {
    const totalDevolvido = $('#tabelaAntecipacoes').DataTable().data().toArray().reduce((total, antecipacao) => total += antecipacao.NRO_CUPOM == vendaDevolvida ? antecipacao.VALOR : 0, 0);
    $("#credito_cliente").html(parseFloat(totalDevolvido).toLocaleString('pt-BR', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: 'BRL'
    }));

    const valorTotalItens = $("#tabelaItens")
      .DataTable()
      .column(7, {})
      .data()
      .sum();
    let saldoGeral = valorTotalItens - totalDevolvido;
    if (saldoGeral < 0) {
      saldoGeral = 0;
    }

    const creditoClienteSaldo = totalDevolvido - valorTotalItens >= 0 ? totalDevolvido - valorTotalItens : 0;
    $("#credito_cliente_saldo").html(parseFloat(creditoClienteSaldo).toLocaleString('pt-BR', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: 'BRL'
    }));

    $("#saldo_geral").html(parseFloat(saldoGeral).toLocaleString('pt-BR', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: 'BRL'
    }));
  }
}

function atualizaTotaisPagto() {
  const paramRetencaoIva = parametrosVenda[105] == 1 ?? false;
  const valRetIva = TruncaDecimaisNova(2, coalesce(parseFloat(pegaValor('#txtTotalRetIva'))));
  let total = $("#tabelaCondicoesDePagamento").DataTable().column(3, {}).data().sum();
  let totalPagamento = $("#tabelaCondicoesDePagamento").DataTable().column(4, {}).data().sum();
  let totalDesconto = $("#tabelaCondicoesDePagamento").DataTable().column(13, {}).data().sum() + $("#tabelaItens").DataTable().column(6, {}).data().sum() + valRetIva;
  let saldo = totalPagamento - total;

  if (paramRetencaoIva) {
    $('#textDescontos').html('Descontos (Retenção IVA):')
  }

  $("#txtTotaisPagamentos").html(
    parseFloat(totalPagamento).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#txtTotaisDesconto").html(
    parseFloat(totalDesconto).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#txtTotaisTroco").html(
    parseFloat(saldo).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#txtTotaisTotal").html(
    parseFloat(total).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  // rotina criada para nelus (novos campos nos totais)

  if (parametrosVenda[58] == '5') {
    let totalAnte = 0;
    $('#tabelaCondicoesDePagamento').DataTable().data().map(item => {
      if (item[11] != null && item[11].length > 0) {
        totalAnte += item[3];
      }
    });

    $("#txtTotaisPagamentos").html(
      parseFloat(totalAnte).toLocaleString("pt-BR", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        currency: "BRL",
      })
    );

    $("#txtTotaisTotal").html(
      parseFloat(total - totalAnte).toLocaleString("pt-BR", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        currency: "BRL",
      })
    );
  }
}

function atualizaSaldoAPagar() {
  const parametroValorIPIVenda = parametrosVenda[102] == 1 ?? false;
  const bAplicaDescMaxTabPrecoVendaNotAlterar = parametrosVenda[81] == '2';
  const valFrete = isNaN(parseFloat($("#txtFrete").val())) ? 0 : parseFloat($("#txtFrete").val());
  const valIPI = parametroValorIPIVenda ? parseFloat($("#txtTotalIPI").val()) : 0;
  const valRetIva = TruncaDecimaisNova(2, coalesce(parseFloat(pegaValor('#txtTotalRetIva'))));
  atualizaExisteValorIPISaldoAPagar(valIPI != 0);
  const saldoItens = parseFloat($("#subtotal_venda").html().replaceAll(".", "").replace(",", ".")) + valFrete + valIPI - valRetIva;
  const valPagtos = $("#tabelaCondicoesDePagamento").DataTable().column(3, {}).data().sum();
  const valDesconto = $("#tabelaCondicoesDePagamento").DataTable().column(13, {}).data().sum();

  let saldo = saldoItens - (valPagtos + valDesconto);
  if (saldo < 0) {
    saldo = 0;
  }

  $("#txtsaldo_a_pagar").html(
    parseFloat(saldo).toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
      currency: "BRL",
    })
  );

  $("#txtValorParcela").val($("#txtsaldo_a_pagar").html().replaceAll(".", "").replace(",", "."));
  $("#txtValorParcela").trigger("change");
  if (saldo == 0) {
    // não deixa mais colocar formas de pagto.
    $("#txtMoeda").prop("disabled", true);
    $("#txtBaixaAntecipacao").prop("disabled", true);
    $("#txtTipoMoeda").prop("disabled", true);
    $("#txtCondicaoDePagamento").prop("disabled", true);
    $("#txtValorParcela").prop("disabled", true);
    $("#txtNrParcelas").prop("disabled", true);
    $("#btn-moeda").prop("disabled", true);
    $("#btn-CondicaoDePagamento").prop("disabled", true);
    $("#txtPercDescontoMoeda").prop("disabled", true);
    $("#txtValorDescontoMoeda").prop("disabled", true);
    $("#txtPercAcrescMoeda").prop("disabled", true);
    $("#txtValorAcrescMoeda").prop("disabled", true);
    $("#txtValorLiquidoMoeda").prop("disabled", true);
    $("#btn-limpa-moeda").prop("disabled", true);
    $("#btn-limpa-condicao").prop("disabled", true);
    $('#txtValorMoedaParcela').prop('disabled', true);
    $('#txtCotacaoMoedaParcela').prop('disabled', true);
  } else {
    // habilita novamente as formas de pagtos.
    $("#txtMoeda").prop("disabled", false);
    $("#txtBaixaAntecipacao").prop("disabled", false);
    $("#txtTipoMoeda").prop("disabled", false);
    $("#txtCondicaoDePagamento").prop("disabled", false);
    $("#txtValorParcela").prop("disabled", false);
    $("#txtNrParcelas").prop("disabled", false);
    $("#btn-moeda").prop("disabled", false);
    $("#btn-CondicaoDePagamento").prop("disabled", false);
    if (!bAplicaDescMaxTabPrecoVendaNotAlterar) {
      $("#txtPercDescontoMoeda").prop("disabled", false);
      $("#txtValorDescontoMoeda").prop("disabled", false);
    }
    $("#txtPercAcrescMoeda").prop("disabled", false);
    $("#txtValorAcrescMoeda").prop("disabled", false);
    $("#txtValorLiquidoMoeda").prop("disabled", false);
    $("#btn-limpa-moeda").prop("disabled", false);
    $("#btn-limpa-condicao").prop("disabled", false);
    $('#txtValorMoedaParcela').prop('disabled', false);
    $('#txtCotacaoMoedaParcela').prop('disabled', false);
  }
}

function confirmExit() {
  return "Deseja realmente sair desta página?";
}

function criaTelaAjuda() {
  $("#pesquisaModalLabel").text("Teclas de atalho");
  $("#pesquisaModalBody").html(
    '<table class="table table-sm table-hover">' +
    "<thead>" +
    "<tr><th>Teclas</th>" +
    "<th>Função</th></tr>" +
    "</thead>" +
    "<tbody>" +
    "<tr><td>F1</td>" +
    "<td>Mostra as teclas de atalho do módulo.</td>" +
    "</tr>" +
    "<tr><td>F2</td>" +
    "<td>Abre cadastro de cliente.</td>" +
    "</tr>" +
    "<tr><td>F4</td>" +
    "<td>Pesquisar nos campos com a lupa.</td>" +
    "</tr>" +
    "<tr><td>F11</td>" +
    "<td>Tela cheia.</td>" +
    "</tr>" +
    "<tr><td>Tab</td>" +
    "<td>Pular para o próximo campo.</td>" +
    "</tr>" +
    "<tr><td>Ctrl + B</td>" +
    "<td>Focar no campo de código de barras.</td>" +
    "</tr>" +
    "<tr><td>Ctrl + Q</td>" +
    "<td>Focar no campo de Quantidade.</td>" +
    "</tr>" +
    "<tr><td>Quantidade <b>*</b> código de barra</td>" +
    "<td>Adiciona n vezes quantidade do mesmo produto bipado. <small>Exemplo: 15*5556448779932</small></td>" +
    "</tr>" +
    "<tr><td><b>-</b> código de barra</td>" +
    "<td>Remove 1 produto dos itens bipados. <small>Exemplo: -5556448779932</small></td>" +
    "</tr>" +
    "<tr><td>ALT + F</td>" +
    "<td>Sair do PDV.</td>" +
    "</tr>" +
    "<tr><td>ALT + S</td>" +
    "<td>Botão confirmar em mensagens de confirmação.</td>" +
    "</tr>" +
    "<tr><td>ALT + N</td>" +
    "<td>Botão cancelar em mensagens de confirmação.</td>" +
    "</tr>" +
    "<tr><td>ALT + F6</td>" +
    "<td>Abre consulta de preços.</td>" +
    "</tr>" +
    "</tbody>" +
    "</table>"
  );
  $("#pesquisaModal").modal("show");
  $("#pesquisaModalSelecionar").hide();
  $("#pesquisaModalConfirmar").hide();
}

async function retornaCondicaoDinheiro() {
  let url = `/sisplan/funcoes/v1/pesquisa?`;
  try {
    let response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"condicao", "camposSelect":[ "min(codcond) codcond", "descricao"], "groupby": ["descricao"], "where": ["1=1"] }`,
      null
    );

    if (!response) {
      return;
    }

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

    return `[${jsonStr.RESULT[0][0].CODCOND}] - ${jsonStr.RESULT[0][0].DESCRICAO}`;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do produto.");
  }
}

async function buscaInfoAdcMaterial(sCodigo) {
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  const pesquisa = {
    tabela: "MATERIAL",
    camposSelect: ["MATERIAL.GRUPO",
      "GRUPO_MA.DESCRICAO DESC_GRUPO",
      "MATERIAL.SUB_GRUPO",
      "SUBGRUPO_MA.DESCRICAO DESC_SUB_GRUPO",
      "MATERIAL.LINHA",
      "TABLIN.DESCRICAO DESC_LINHA",
      "MATERIAL.GRAMATURA",
      "MATERIAL.LARGURA",
      "MATERIAL.UNIDADE",
      "MATERIAL.PESO",
      "MATERIAL.STATUS",
      "SITPROD.DESCRICAO DESC_STATUS"],
    leftjoin: [
      { "tabela": "GRUPO_MA", "condicao": "MATERIAL.GRUPO = GRUPO_MA.CODIGO" },
      { "tabela": "SUBGRUPO_MA", "condicao": "SUBGRUPO_MA.CODIGO = MATERIAL.SUB_GRUPO" },
      { "tabela": "TABLIN", "condicao": "TABLIN.CODIGO = MATERIAL.LINHA" },
      { "tabela": "SITPROD", "condicao": "SITPROD.CODIGO = MATERIAL.STATUS" }
    ],
    where: [`MATERIAL.CODIGO = '${sCodigo}'`]
  };
  try {
    const response = await requisicao(
      "GET",
      url,
      `JSON=${JSON.stringify(pesquisa)}`,
      null
    );

    if (!response) {
      return;
    }

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

    return jsonStr;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do material.");
  }
}

async function buscaInfoAdc(sCodigo, sCor, sTam) {
  const url = `/sisplan/funcoes/v1/pesquisa?`;
  const pesquisa = {
    tabela: "pa_iten",
    camposSelect: ["produto.colecao",
      "colecao.descricao desc_colecao",
      "produto.marca",
      "marca.descricao desc_marca",
      "produto.linha",
      "tablin.descricao desc_linha",
      "produto.grupo",
      "grupo_pa.descricao desc_grupo",
      "produto.etiqueta",
      "etq_prod.descricao desc_etiqueta",
      "pa_iten.barra",
      "pa_iten.barra28",
      "pa_iten.barracli"],
    leftjoin: [
      { "tabela": "produto", "condicao": "produto.codigo = pa_iten.codigo" },
      { "tabela": "tablin", "condicao": "tablin.codigo = produto.linha" },
      { "tabela": "grupo_pa", "condicao": "grupo_pa.codigo = produto.grupo" },
      { "tabela": "colecao", "condicao": "colecao.codigo= produto.colecao" },
      { "tabela": "marca", "condicao": "marca.codigo = produto.marca" },
      { "tabela": "etq_prod", "condicao": "etq_prod.codigo = produto.etiqueta" }
    ],
    where: [`pa_iten.codigo = '${sCodigo}' and pa_iten.cor = '${sCor}' and pa_iten.tam = '${sTam}'`]
  };
  try {
    const response = await requisicao(
      "GET",
      url,
      `JSON=${JSON.stringify(pesquisa)}`,
      null
    );

    if (!response) {
      return;
    }

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

    return jsonStr;
  } catch (error) {
    console.error(error);
    msgErro("Não foi possível buscar os dados do produto.");
  }
}

async function telaInicial() {
  let obrigaGuia = false;
  const bloqueiaAbasInfosEItensVenda = parametrosVenda[80] == "1";
  const numero_venda = window.location.href.split("/").slice(-1).toString();
  if (!$("#GuiaInfoTour").hasClass("d-none")) {
    if ((getCookie('vai_para_aba_itens') != 'true') && ($("#txtGuia").val() == "")) {
      obrigaGuia = true;
    }
  }
  if (bloqueiaAbasInfosEItensVenda && !await validaVendaGerouDeConsignado(numero_venda) && $("#txtCliente").val() != "") {
    fsVenda = $("#fieldset_venda");
    fsPagamento = $("#fieldset_pagamento");
    fsInfo = $("#fieldset_info");

    fsInfo.show();
    fsPagamento.css({
      display: "none",
      position: "relative",
    });

    fsVenda.css({
      display: "none",
      position: "relative",
    });

    fsInfo.css({
      opacity: 1,
    });

    $("#btnVenda").prop("disabled", false);
    $("#btnInfo").prop("disabled", true);
    $("#btnPagamento").prop("disabled", false);
  } else if (($("#tabelaCondicoesDePagamento").DataTable().rows().count() > 0)) {
    fsVenda = $("#fieldset_venda");
    fsPagamento = $("#fieldset_pagamento");
    fsInfo = $("#fieldset_info");

    fsPagamento.css({
      display: "none",
      position: "relative",
    });

    fsInfo.css({
      display: "none",
      position: "relative",
    });

    fsVenda.css({
      opacity: 1,
    });
    fsPagamento.show();
    $("#btnPagamento").prop("disabled", true);
    $("#btnInfo").prop("disabled", false);
    $("#btnVenda").prop("disabled", false);
  } else if (
    $("#txtCliente").val() != "" &&
    $("#txtDeposito").val() != "" &&
    $("#txtTabela").val() != "" &&
    $("#txtVendedor").val() != "" &&
    !obrigaGuia
  ) {
    fsVenda = $("#fieldset_venda");
    fsPagamento = $("#fieldset_pagamento");
    fsInfo = $("#fieldset_info");

    fsPagamento.css({
      display: "none",
      position: "relative",
    });

    fsInfo.css({
      display: "none",
      position: "relative",
    });

    fsVenda.css({
      opacity: 1,
    });
    fsVenda.show();
    $("#btnVenda").prop("disabled", true);
    $("#btnInfo").prop("disabled", false);
    $("#btnPagamento").prop("disabled", false);
    focaCampo();
  } else {
    fsVenda = $("#fieldset_venda");
    fsPagamento = $("#fieldset_pagamento");
    fsInfo = $("#fieldset_info");

    fsInfo.show();
    fsPagamento.css({
      display: "none",
      position: "relative",
    });

    fsVenda.css({
      display: "none",
      position: "relative",
    });

    fsInfo.css({
      opacity: 1,
    });

    $("#btnVenda").prop("disabled", false);
    $("#btnInfo").prop("disabled", true);
    $("#btnPagamento").prop("disabled", false);
  }
  deleteCookie('vai_para_aba_itens');
}

async function corrigeCamposPedido(arrItens, iQtde) {
  const itensFormatados = arrItens.filter((item) => {
    if (iQtde === 'F') {
      return item.qtde_f !== 0;
    } else if (iQtde === 'P') {
      return item.qtde !== 0;
    } else if (iQtde === 'T') {
      return true;
    }
  }).map((item) => ({
    codigo: `<div class="icheck-primary d-inline"><span class="fas fa-times-circle" style="color:#EEAD2D"></span></div>  ${item.codigo}`,
    descricao: item.descricao,
    cor: item.cor,
    descCor: item.descCor,
    tam: item.tam,
    qtde: item.qtde,
    qtde_f: item.qtde_f,
    preco: item.preco,
    tipo: item.tipo,
    id_Estoque: item.id_Estoque,
    qtde_conf: 0,
    barra: item.barra,
    barra28: item.barra28,
    barraCli: item.barraCli,
    ordem: item.ordem_Ped,
    qtde_orig: item.qtde_orig,
    zero: 0,
    qualidade: item.qualidade,
    caixa: item.caixa
  }));
  return itensFormatados;
};

async function imprimirRomaneio(sVenda, sUrl) {
  try {
    $.LoadingOverlay("show");
    let url = `/sisplan/impressao/v1/venda?codven=${sVenda}`;
    try {
      const bImprimeAutomatico = await verificaImprimirAutomatico('Venda');
      const arquivo = await GeraRelatorio(`${url}&`, "GET", undefined, false, 'Venda');

      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(`${sUrl}/relatorios_api/pdf/${arquivo}`, "_blank");
        }
        await limparRelatorios();
      }
    } catch (error) {
      console.error(error);
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function verificaVendaFinalizadaEEnviaWhatsApp(sUrl, codven, tela) {
  try {
    const enviaRomaneioWpp = await CopiaParametro('VENDA', 100);

    if (enviaRomaneioWpp == 2) {
      return;
    }

    if ((String(codven).toUpperCase() == 'CREATE')
      || (String(codven).toUpperCase() == 'CREATE#')
      || (String(codven).toUpperCase() == 'VENDAPENDENTE')
      || (String(codven) == '')) {
      return;
    }
    const bUtilizaWhatsapp = await utilizaWhatsapp();
    if (!bUtilizaWhatsapp) {
      return;
    }

    const empId = getCookie('emp_id');

    const pesquisa = {
      camposSelect: ['VENDA.FECHADA', 'VENDA.VALOR', 'VENDA.CODCLI', 'ENTIDADE.NOME', "VENDA.DEVOLUCAO"],
      tabela: 'VENDA',
      leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = VENDA.CODCLI' }],
      where: [`VENDA.CODVEN = '${codven}' AND VENDA.EMP_ID = ${empId}`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
    const vendaFechada = jsonStr[0].FECHADA == '1';
    const vendaDevolucao = jsonStr[0].DEVOLUCAO == '1';
    const nome = jsonStr[0].NOME;
    const valor = jsonStr[0].VALOR;
    const codcli = jsonStr[0].CODCLI;

    if (nome.indexOf('CONSUMIDOR FINAL') >= 0) {
      return;
    }

    if (vendaFechada || vendaDevolucao) {
      const telefone = await getWhatsapp(codcli);
      if (telefone != '') {
        await enviarRomaneioWpp(codven, telefone, nome, valor, sUrl, tela.toUpperCase());
      }
    }
    return;
  } catch (err) {
    console.error(err);
    return;
  }
}

async function excluiVendaIShopp(codven) {
  try {
    const bIntegracaIShopp = parametrosVenda[68] == 1 || parametrosVenda[68] == 2;
    if (!bIntegracaIShopp) {
      return;
    }

    const empId = getCookie('emp_id');

    const pesquisa = {
      camposSelect: ['VENDA.NR_INTEGRACAO', 'ENTIDADE.CNPJ', 'VENDA.DATA', 'VENDA.VALOR'],
      tabela: 'VENDA',
      leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = VENDA.CODCLI' }],
      where: [`VENDA.CODVEN = '${codven}' AND VENDA.EMP_ID = ${empId}`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));

    let venda = {};
    venda.cnpj = jsonStr[0].CNPJ;
    venda.data = jsonStr[0].DATA;
    venda.valor = jsonStr[0].VALOR;
    venda.nr_integracao = jsonStr[0].NR_INTEGRACAO;

    response = await requisicao_ecf('DELETE', '/ishopp/exclusaovenda?', "", JSON.stringify(venda));

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

async function geraVendaIShopp(codven) {
  try {
    if ((String(codven).toUpperCase() == 'CREATE')
      || (String(codven).toUpperCase() == 'CREATE#')
      || (String(codven).toUpperCase() == 'VENDAPENDENTE')
      || (String(codven) == '')) {
      return;
    }

    const bIntegracaIShopp = parametrosVenda[68] == 1 || parametrosVenda[68] == 2;
    if (!bIntegracaIShopp) {
      return;
    }

    const empId = getCookie('emp_id');
    const empresa = getCookie('empresa');

    const pesquisa = {
      camposSelect: ['VENDA.FECHADA', 'ENTIDADE.CNPJ', 'VENDA.DATA', 'VENDA.VALOR', 'REPRESEN.NOME NOMEREP', 'VENDA.CODREP2', 'ENTIDADE.INTEGRA_SHOPP'],
      tabela: 'VENDA',
      leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = VENDA.CODCLI' },
      { tabela: 'REPRESEN', condicao: 'VENDA.CODREP = REPRESEN.CODREP' }],
      where: [`VENDA.CODVEN = '${codven}' AND VENDA.EMP_ID = ${empId}`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
    const vendaFechada = jsonStr[0].FECHADA == '1';
    const guia = jsonStr[0].CODREP2;

    if ((!vendaFechada) || (jsonStr[0].INTEGRA_SHOPP == 'N')) {
      return;
    }

    if (guia == '') {
      if (parametrosVenda[68] != 2) {
        await gravaVendaIshopp();
      }
    } else {
      await gravaVendaIshopp();
    }

    async function gravaVendaIshopp() {
      let venda = {};
      let valor = 0;
      venda.cnpj = jsonStr[0].CNPJ;
      venda.data = jsonStr[0].DATA;
      // venda.valor = jsonStr[0].VALOR;
      venda.nomerep = jsonStr[0].NOMEREP;
      venda.codven = codven;
      venda.emp_id = empId;
      venda.empresa = empresa;
      venda.condicao = await retornaCondicao(codven, empId);
      venda.condicao.forEach(item => {
        valor += item.valor;
      })
      venda.valor = valor;

      if (vendaFechada) {
        response = await requisicao_ecf('POST', '/ishopp/geravenda?', "", JSON.stringify(venda));

        if (!response) {
          return;
        }

        if (response.status != 200) {
          const retorno = await response.text();
          await msgAguardaConfirmacao(retorno, () => { }, () => { }, true, true, 'Ok');
          return;
        }
      }
    };

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

async function imprimirCheque(posicao) {
  try {
    const empId = getCookie('emp_id');

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

    const cheque = {
      banco: $($('.campoBanco')[posicao]).val().substring(1, $($('.campoBanco')[posicao]).val().indexOf("]")),
      cidade: cidade,
      data: $($(".campoVencimento")[posicao]).val(),
      valor: $($('.campoValor')[posicao]).val()
    };

    if (cheque.banco == '') {
      msgAlerta('Necessário informar o banco.')
      return;
    }

    response = await requisicao_ecf('POST', '/cheque/imprimircheque?', "", JSON.stringify(cheque), 120000);

    if (!response) {
      return;
    }

    if (response.status != 200) {
      const mensagemErro = await response.text();
      msgErro(`Erro ao imprimir cheque. ${mensagemErro}`);
      return;
    }

    response = await response.json();
    insereValor($(".campoBanco")[posicao], response.banco, response.banco);
    $($(".campoAgencia")[posicao]).val(response.agencia);
    $($(".campoConta")[posicao]).val(response.conta);
    $($(".campoNumero")[posicao]).val(response.numero);

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

async function LerCheque(posicao) {
  try {

    let response = await requisicao_ecf('GET', '/cheque/imprimircheque?', "", "", 120000);

    if (!response) {
      msgErro("Não foi possível comunicar com a apiLocal.");
      return;
    }

    if (response.status != 200) {
      const mensagemErro = await response.text();
      msgErro(`Erro ao Ler cheque. ${mensagemErro}`);
      return;
    }

    response = await response.json();
    insereValor($(".campoBanco")[posicao], response.banco, response.banco);
    $($(".campoAgencia")[posicao]).val(response.agencia);
    $($(".campoConta")[posicao]).val(response.conta);
    $($(".campoNumero")[posicao]).val(response.numero);

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

async function geraVendaNetShopping(codven, codGuia) {
  try {
    if ((String(codven).toUpperCase() == 'CREATE')
      || (String(codven).toUpperCase() == 'CREATE#')
      || (String(codven).toUpperCase() == 'VENDAPENDENTE')
      || (String(codven) == '')) {
      return;
    }

    const bIntegracaIShopp = parametrosVenda[69] == 1;
    if (!bIntegracaIShopp) {
      return;
    }

    const empId = getCookie('emp_id');

    const pesquisa = {
      camposSelect: ['VENDA.FECHADA', 'ENTIDADE.CNPJ', 'VENDA.DATA', 'VENDA.VALOR', 'REPRESEN.NOME NOMEREP', 'ENTIDADE.INTEGRA_SHOPP'],
      tabela: 'VENDA',
      leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = VENDA.CODCLI' },
      { tabela: 'REPRESEN', condicao: 'VENDA.CODREP = REPRESEN.CODREP' }],
      where: [`VENDA.CODVEN = '${codven}' AND VENDA.EMP_ID = ${empId}`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
    const vendaFechada = jsonStr[0].FECHADA == '1';
    if ((!vendaFechada) || (jsonStr[0].INTEGRA_SHOPP == 'N')) {
      return;
    }
    let venda = {};
    venda.CPFCNPJCliente = jsonStr[0].CNPJ;
    venda.Guia = codGuia;
    venda.CodVen = codven;
    venda.Emp_Id = empId;
    venda.condicao = await retornaCondicaoNetShopping(codven, empId);

    const param = `JSON=${JSON.stringify(venda)}`;
    if ((vendaFechada) && (venda.condicao.length > 0)) {
      response = await requisicao('POST', '/sisplan/vendas/v1/netshopping?', "", param);

      if (!response) {
        return;
      }

      if (response.status != 200) {
        msgErro("Erro integrar venda com o sistema NetShopping.");
        return;
      }
      let jsonStr = await response.json();
      if (jsonStr.situacao == 'RESTRICAO') {
        await aguardaMsgAlerta(`Restrição: ${jsonStr.situacao}\nDescrição: ${jsonStr.ds_situacao}`, () => { });
        sleep(30000);
      }
      // else { COMENTADO POIS DE INICIO SÓ SERÁ INFORMADO A MENSAGEM QUANDO CONTER ALGUMA RESTRIÇÃO
      //   // jsonStr.condVenda.map(cond => {console.log(cond.cd_movimentacao)}) necessario validar como será retornado a mensagem para o usuário
      //   // mensagem = 
      //   // `Guia: ${jsonStr.cd_guia}\nNome guia: ${jsonStr.nm_guia}\nLiberado compra cheque: ${jsonStr.fl_liberado_compra_cheque}\nLiberado para compra: ${jsonStr.fl_bloqueado_para_compra}\nSaldo: ${jsonStr.saldo.replaceAll('.',',')}`;
      //   // insereValor('#txtCodGuiaIntegracao', jsonStr.cd_guia, jsonStr.nm_guia);
      // }

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

async function retornaCondicaoNetShopping(codven, emp_id) {
  const valorPadrao = await buscaValoresPadroes('LOJA');
  let condicao = valorPadrao?.find(obj => obj.CAMPO === 'MOEDA_NAO_INTEGRANET')?.VALOR || '';

  if (condicao) {
    condicao = ` AND CONDIVENDA.CDMOEDA NOT IN (${condicao})`;
  } else {
    condicao = ''
  }

  let result = [];
  const pesquisa = {
    camposSelect: [
      'ITCONDIVENDA.VALOR', 'RECEBER.AGENCIA_CH', 'MOEDA.TIPO AS TIPO_MOEDA', 'ITCONDIVENDA.CDBANCO', 'ITCONDIVENDA.NRCONTA', 'RECEBER.NUMERO_CH', 'ITCONDIVENDA.NMSACADO',
      'ITCONDIVENDA.CPFSACADO', 'ITCONDIVENDA.VENCIMENTO', 'MOEDA.DESCRICAO DESC_MOEDA'
    ],
    tabela: 'CONDIVENDA',
    innerJoin: [{ tabela: 'MOEDA', condicao: 'MOEDA.CODMOE = CONDIVENDA.CDMOEDA' },
    { tabela: 'ITCONDIVENDA', condicao: 'ITCONDIVENDA.CDCONDIVENDA = CONDIVENDA.CDCONDIVENDA AND ITCONDIVENDA.CDVENDA = CONDIVENDA.CDVENDA AND ITCONDIVENDA.EMP_ID = CONDIVENDA.EMP_ID' }],
    leftJoin: [{ tabela: 'RECEBER', condicao: `RECEBER.NRO_CUPOM = CONDIVENDA.CDVENDA AND RECEBER.STATUS = 'CHEQ' AND RECEBER.NUMERO = ITCONDIVENDA.NRDOCTO AND RECEBER.EMP_ID = CONDIVENDA.EMP_ID AND RECEBER.NRO_CUPOM = ${codven}` }],
    where: [`CONDIVENDA.CDVENDA = '${codven}' AND CONDIVENDA.EMP_ID = ${emp_id} ${condicao}`]
  }
  const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
  jsonStr.map(item => {
    const condicao = {
      valor: item.VALOR,
      tipo_moeda: item.DESC_MOEDA.includes('PIX') ? 4 : item.TIPO_MOEDA,
      banco: String(item.CDBANCO).toString().padStart(3, '0'),
      agencia: item.AGENCIA_CH,
      conta: item.NRCONTA,
      num_cheque: item.NUMERO_CH,
      nmsacado: item.NMSACADO,
      vencimento: item.VENCIMENTO
    };
    result.push(condicao);
  })
  return result;
}

async function retornaCondicao(codven, emp_id) {
  let result = [];
  const pesquisa = {
    camposSelect: [
      'ITCONDIVENDA.VALOR', 'RECEBER.AGENCIA_CH', 'MOEDA.TIPO AS TIPO_MOEDA', 'ITCONDIVENDA.CDBANCO', 'ITCONDIVENDA.NRCONTA', 'RECEBER.NUMERO_CH', 'ITCONDIVENDA.NMSACADO',
      'ITCONDIVENDA.CPFSACADO', 'ITCONDIVENDA.VENCIMENTO'
    ],
    tabela: 'CONDIVENDA',
    innerJoin: [
      { tabela: 'MOEDA', condicao: 'MOEDA.CODMOE = CONDIVENDA.CDMOEDA' },
      { tabela: 'ITCONDIVENDA', condicao: 'ITCONDIVENDA.CDCONDIVENDA = CONDIVENDA.CDCONDIVENDA AND ITCONDIVENDA.CDVENDA = CONDIVENDA.CDVENDA AND ITCONDIVENDA.EMP_ID = CONDIVENDA.EMP_ID' }
    ],
    leftJoin: [{ tabela: 'RECEBER', condicao: `RECEBER.NRO_CUPOM = CONDIVENDA.CDVENDA AND RECEBER.STATUS = 'CHEQ' AND RECEBER.NUMERO = ITCONDIVENDA.NRDOCTO AND RECEBER.EMP_ID = CONDIVENDA.EMP_ID AND RECEBER.NRO_CUPOM = ${codven}` }],
    where: [`CONDIVENDA.CDVENDA = '${codven}' AND CONDIVENDA.EMP_ID = ${emp_id} AND MOEDA.BAIXA_ANTE <> 'S'`]
  }
  const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
  jsonStr.map(item => {
    const condicao = {
      valor: item.VALOR,
      tipo_moeda: item.TIPO_MOEDA,
      cdbanco: item.CDBANCO,
      agencia_ch: item.AGENCIA_CH,
      nrconta: item.NRCONTA,
      numero_ch: item.NUMERO_CH,
      nmsacado: item.NMSACADO,
      cpfsacado: item.CPFSACADO,
      vencimento: item.VENCIMENTO
    };
    result.push(condicao);
  })
  return result;
}

async function enviarRomaneioWpp(sVenda, telefone, nome, valor, sUrl, tela) {
  try {
    const url = `/sisplan/impressao/v1/venda?codven=${sVenda}`;
    try {
      if (telefone == '') {
        return;
      }
      const arquivo = await GeraRelatorio(`${url}&`, "GET", 15000, false, 'Venda');
      const valorFormatado = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(valor);
      const parametrosMensagem = [`VENDA: ${sVenda}`, `EMP_ID: ${getCookie("emp_id")}`];
      const objMsgWpp = [{ CELULAR: telefone, PARAMETROSMENSAGEM: parametrosMensagem.toString(), MENSAGEMPERSONALIZADA: "" }];
      let mensagemPersonalizada = await retornaMsgPersonalizadaWpp(tela, objMsgWpp);
      mensagemPersonalizada = decodeEmoticonsMensagem(mensagemPersonalizada, true);
      let mensagem = `$OLA$ *${nome}*! Obrigado por comprar conosco 🙌 Você efetuou uma compra no valor de *${valorFormatado}*. Segue abaixo uma cópia do relatório da venda *${sVenda}*. Tenha um ótimo dia 😊🎉`;
      if (tela === 'DEVOLUCAO') {
        mensagem = `$OLA$ *${nome}*! Você efetuou uma devolução no valor de *${valorFormatado}*. Segue abaixo uma cópia do relatório da sua devolução *${sVenda}*. Tenha um ótimo dia. 😊`
      }
      const anexosMensagemPersonalizada = await retornaAnexoMsgPersonalizada(tela);
      const anexos = anexosMensagemPersonalizada.map((anexo) => { return anexo.caminhoArquivo });
      if (arquivo != undefined) {
        let enviaArq = false;
        const enviaMsg = await enviarMensagem(telefone, mensagemPersonalizada != "" ? mensagemPersonalizada : mensagem, 'Venda_WEB', sVenda);
        const enviaRomaneioWpp = await CopiaParametro('VENDA', 100);
        if (enviaRomaneioWpp == 0) {
          enviaArq = await enviarMensagem(telefone, '', 'Venda_WEB', sVenda, true, arquivo, anexos);
        };

        // for (let i = 0; i < anexosMensagemPersonalizada.length; i++) {
        //   const terminologiaBase64 = retornaTerminologiaBase64(anexosMensagemPersonalizada[i].arquivo);
        //   if (terminologiaBase64 != "") {
        //     msgAlerta(`O arquivo ${anexosMensagemPersonalizada[i].arquivo} tem um tipo não suportado, os tipos de arquivos aceitos são: .png, .jpg, .jpeg, .mp4, .pdf, .doc, .docx, .xlsx, .xls, .gif, .txt`);
        //     enviaArq = 
        //   } else {

        //   }
        // } DE MOMENTO, RETIRADO, DEPOIS VEJO SOBRE - BRUNO 25/06/2024

        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() {
            },
          }).css({
            "margin-top": "20%",
            width: "500px",
            "max-width": "500px",
          });
        };
        await limparRelatorios();
      }
    } catch (error) {
      console.error(error);
    }
  } finally {
  }
}

async function imprimirCarne(sVenda, sUrl) {
  try {
    $.LoadingOverlay("show");
    let url = `/sisplan/impressao/v1/carne?CODVEN=${sVenda}`;
    try {
      const bImprimeAutomatico = await verificaImprimirAutomatico('Carne');
      let arquivo = await GeraRelatorio(`${url}&`, "GET", 15000, false, 'Carne');
      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(`${sUrl}/relatorios_api/pdf/${arquivo}`, "_blank");
        }
        await limparRelatorios();
      }
    } catch (error) {
      console.error(error);
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function salvarBackupVenda(objeto) {
  try {
    const empId = getCookie("emp_id");
    const hora = new Date()
      .toISOString()
      .slice(0, 19)
      .replaceAll("T", "_")
      .replaceAll(":", "");
    const response = await fetch(
      `../salvar_bkp.php?nome_arquivo=${objeto.codVen}_${empId}_${hora}`,
      {
        method: "POST",
        body: `${JSON.stringify(objeto)}`,
      }
    );

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

async function toastrFinalizarVenda(mensagem, callBack) {
  await toastr
    .success(mensagem, "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,
      async onHidden() {
        await callBack();
      },
    })
    .css({
      "margin-top": "20%",
      width: "500px",
      "max-width": "500px",
    });
}

async function criaTelaInfoAdc(id) {
  sCodigo = {
    Codigo: $("#tabelaItens").DataTable().row(id).data()[0],
    Cor: $("#tabelaItens").DataTable().row(id).data()[10],
    Tam: $("#tabelaItens").DataTable().row(id).data()[11],
    tipo: $("#tabelaItens").DataTable().row(id).data()[19],
  };
  const jsonStr = await buscaInfoAdc(sCodigo.Codigo, sCodigo.Cor, sCodigo.Tam);
  const sColecao = jsonStr.RESULT[0][0].COLECAO;
  const sDescColecao = jsonStr.RESULT[0][0].DESC_COLECAO;
  const sGrupo = jsonStr.RESULT[0][0].GRUPO;
  const sDescGrupo = jsonStr.RESULT[0][0].DESC_GRUPO;
  const sMarca = jsonStr.RESULT[0][0].MARCA;
  const sDescMarca = jsonStr.RESULT[0][0].DESC_MARCA;
  const sEtiqueta = jsonStr.RESULT[0][0].ETIQUETA;
  const sDescEtiqueta = jsonStr.RESULT[0][0].DESC_ETIQUETA;
  const sLinha = jsonStr.RESULT[0][0].LINHA;
  const sDescLinha = jsonStr.RESULT[0][0].DESC_LINHA;
  const sBarra = jsonStr.RESULT[0][0].BARRA;
  const sBarra28 = jsonStr.RESULT[0][0].BARRA28;
  const sBarraCli = jsonStr.RESULT[0][0].BARRACLI;

  $("#pesquisaModalLabel").text("Informações Adicionais");
  $("#pesquisaModalBody").html(
    `${'<table class="table table-sm table-hover">' +
    "<thead>" +
    "<tr><th>Campo</th>" +
    "<th>Descrição</th></tr>" +
    "</thead>" +
    "<tbody>" +
    "<tr><td>Coleção</td>" +
    "<td>"
    }${sColecao} - ${sDescColecao}</td>` +
    `</tr>` +
    `<tr><td>Grupo</td>` +
    `<td>${sGrupo} - ${sDescGrupo}</td>` +
    `</tr>` +
    `<tr><td>Marca</td>` +
    `<td>${sMarca} - ${sDescMarca}</td>` +
    `</tr>` +
    `<tr><td>Etiqueta</td>` +
    `<td>${sEtiqueta} - ${sDescEtiqueta}</td>` +
    `</tr>` +
    `<tr><td>Linha</td>` +
    `<td>${sLinha} - ${sDescLinha}</td>` +
    `</tr>` +
    `<tr><td>Barra</td>` +
    `<td>${sBarra}</td>` +
    `</tr>` +
    `<tr><td>Barra28</td>` +
    `<td>${sBarra28}</td>` +
    `</tr>` +
    `<tr><td>Barra Cliente</td>` +
    `<td>${sBarraCli}</td>` +
    `</tr>` +
    `</tbody>` +
    `</table>`
  );
  $("#pesquisaModal").modal("show");
  $("#pesquisaModalSelecionar").hide();
  $("#pesquisaModalConfirmar").hide();
}

async function criaTelaInfoAdcMaterial(id) {
  sCodigo = {
    Codigo: $("#tabelaItens").DataTable().row(id).data()[0],
  };
  const jsonStr = await buscaInfoAdcMaterial(sCodigo.Codigo);
  $('#btnAbrirCadastro').addClass('d-none');
  const dados = jsonStr.RESULT[0][0];
  const sGrupo = dados.GRUPO;
  const sDescGrupo = dados.DESC_GRUPO;
  const sSubGrupo = dados.SUB_GRUPO;
  const sDescSubGrupo = dados.DESC_SUB_GRUPO;
  const sLinha = dados.LINHA;
  const sDescLinha = dados.DESC_LINHA;
  const sGramatura = dados.GRAMATURA;
  const sLargura = dados.LARGURA;
  const sUnidade = dados.UNIDADE;
  const sPeso = dados.PESO;
  const sStatus = dados.STATUS;
  const sDescStatus = dados.DESC_STATUS;


  $("#pesquisaModalLabel").text("Informações Adicionais");
  $("#pesquisaModalBody").html(
    `${'<table class="table table-sm table-hover">' +
    "<thead>" +
    "<tr><th>Campo</th>" +
    "<th>Descrição</th></tr>" +
    "</thead>" +
    "<tbody>" +
    "<tr><td>Grupo</td>" +
    "<td>"
    }${sGrupo} - ${sDescGrupo}</td>` +
    `</tr>` +
    `<tr><td>SubGrupo</td>` +
    `<td>${sSubGrupo} - ${sDescSubGrupo}</td>` +
    `</tr>` +
    `<tr><td>Linha</td>` +
    `<td>${sLinha} - ${sDescLinha}</td>` +
    `</tr>` +
    `<tr><td>Status</td>` +
    `<td>${sStatus} - ${sDescStatus}</td>` +
    `</tr>` +
    `<tr><td>Gramatura</td>` +
    `<td>${sGramatura}</td>` +
    `</tr>` +
    `<tr><td>Largura</td>` +
    `<td>${sLargura}</td>` +
    `</tr>` +
    `<tr><td>Unidade</td>` +
    `<td>${sUnidade}</td>` +
    `</tr>` +
    `<tr><td>Peso</td>` +
    `<td>${sPeso}</td>` +
    `</tr>` +
    `</tbody>` +
    `</table>`
  );
  $("#pesquisaModal").modal("show");
  $("#pesquisaModalSelecionar").hide();
  $("#pesquisaModalConfirmar").hide();
}

async function criaTelaDesconto(id, bClick = true, bTrocaTabelaPreco = false) {
  const permiteAlterarPreco43 = (parametrosVenda[43]) == 1;
  const utilizaImpressoraFiscal = parametrosVenda[8] == 1;
  if ($('#txtCupomDesconto').val() !== '') {
    msgAlerta("Venda com cupom de Desconto aplicado, impossível aplicar desconto.");
    return;
  }
  let arrDados = $("#tabelaItens").DataTable().row(id).data();
  $("#pesquisaDescontoLabel").text("Alteração de Preço / Desconto");
  $("#txtPercDesconto").attr("disabled", false).attr("readonly", false);
  $("#txtValorDesconto").attr("disabled", false).attr("readonly", false);

  if (bTrocaTabelaPreco) {
    $('#divVendaProdutoDesc').removeClass('d-none');
    try {
      const tabelaDados = arrDados[34];
      const pesquisaParam = {
        tabela: `REGIAO`,
        camposSelect: ['REGIAO.REGIAO', 'REGIAO.DESCRICAO DESC_REGIAO'],
        where: [`REGIAO.REGIAO = '${tabelaDados}'`]
      };

      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
      const descricao = jsonStr[0].DESC_REGIAO;
      $('#txtTabelaDesc').val();
      insereValor('#txtTabelaDesc', tabelaDados, descricao);
      $('#txtDadosEmAlteracao').attr('data-id', id);

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

  }

  if (!permiteAlterarPreco43) {
    $("#txtPrecoDesc").attr("disabled", true).attr("readonly", true);
  } else {
    $("#txtPrecoDesc").attr("disabled", false).attr("readonly", false);

    $("#txtPrecoDesc").unbind("blur");
    $("#txtPrecoDesc").on("blur", function () {
      if ($(this).val() != "" && parseInt($(this).val()) > 0) {
        $("#txtPercDesconto").attr("disabled", true).attr("readonly", true);
        $("#txtValorDesconto").attr("disabled", true).attr("readonly", true);
        CalculaDesconto("#txtPrecoDesc");
      } else {
        $("#txtPercDesconto").attr("disabled", false).attr("readonly", false);
        $("#txtValorDesconto").attr("disabled", false).attr("readonly", false);
        $("#txtPrecoDesc").val($("#txtPrecoOrig").val());
        $("#txtPrecoLiqDesconto").val($("#txtPrecoOrig").val());
        $("#txtTotalLiq").val(TruncaDecimaisNova(2, $("#txtPrecoOrig").val().replaceAll('.', '').replace(',', '.') * $("#txtQuantidadeDesc").val()));
      }
    });
  }

  $("#txtPercDesconto").unbind("blur");
  $("#txtPercDesconto").on("blur", function () {
    if ($(this).val() != "" && parseInt($(this).val()) > 0) {
      $("#txtPrecoDesc").attr("disabled", true).attr("readonly", true);
      $("#txtValorDesconto").attr("disabled", true).attr("readonly", true);
      CalculaDesconto("#txtPercDesconto");
    } else {
      if (!permiteAlterarPreco43) {
        $("#txtPrecoDesc").attr("disabled", true).attr("readonly", true);
      } else {
        $("#txtPrecoDesc").attr("disabled", false).attr("readonly", false);
      }
      $("#txtValorDesconto").attr("disabled", false).attr("readonly", false);
      $("#txtPrecoDesc").val(0);
      $("#txtValorDesconto").val(0);
      $("#txtPrecoDesc").val($("#txtPrecoOrig").val());
      $("#txtPrecoLiqDesconto").val($("#txtPrecoOrig").val());
      const valor = TruncaDecimaisNova(2, $("#txtPrecoOrig").val().replaceAll('.', '').replace(',', '.') * $("#txtQuantidadeDesc").val());
      $("#txtTotalLiq").val(parseFloat(valor).toLocaleString("pt-BR", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2
      }));
    }
  });

  $("#txtValorDesconto").unbind("blur");
  $("#txtValorDesconto").on("blur", function () {
    if ($(this).val() != "" && parseFloat($(this).val().replace(',', '.')) > 0.01) {
      $("#txtPercDesconto").attr("disabled", true).attr("readonly", true);
      $("#txtPrecoDesc").attr("disabled", true).attr("readonly", true);
      CalculaDesconto("#txtValorDesconto");
    } else {
      if (!permiteAlterarPreco43) {
        $("#txtPrecoDesc").attr("disabled", true).attr("readonly", true);
      } else {
        $("#txtPrecoDesc").attr("disabled", false).attr("readonly", false);
      }
      $("#txtPercDesconto").attr("disabled", false).attr("readonly", false);
      $("#txtPercDesconto").val(0);
      $("#txtPrecoDesc").val($("#txtPrecoOrig").val());
      $("#txtPrecoLiqDesconto").val($("#txtPrecoOrig").val());
      const valor = TruncaDecimaisNova(2, parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) * parseFloat($("#txtQuantidadeDesc").val()));
      $("#txtTotalLiq").val(parseFloat(valor).toLocaleString("pt-BR", {
        maximumFractionDigits: 2,
        minimumFractionDigits: 2
      }));
    }
  });

  if (bClick) {
    $("#pesquisaDesconto").modal("show");
  }
  // $("#txtPercDesconto")
  //   .inputmask("numeric", {
  //     min: 0,
  //     max: 99,
  //     positionCaretOnClick: "select",
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });
  // $("#txtPrecoDesc")
  //   .inputmask("numeric", {
  //     min: 0,
  //     positionCaretOnClick: "select",
  //     digits: quantidadeCasasDecimaisCampo,
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });

  // $("#txtValorDesconto")
  //   .inputmask("numeric", {
  //     min: 0,
  //     positionCaretOnClick: "select",
  //     digits: quantidadeCasasDecimaisCampo,
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });

  // $("#txtPercDesconto")
  //   .inputmask("numeric", {
  //     min: 0,
  //     positionCaretOnClick: "select",
  //     digits: quantidadeCasasDecimaisCampo,
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });

  // $("#txtTotalLiq")
  //   .inputmask("numeric", {
  //     min: 0,
  //     positionCaretOnClick: "select",
  //     digits: 2,
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });

  // $("#txtPrecoLiqDesconto")
  //   .inputmask("numeric", {
  //     min: 0,
  //     positionCaretOnClick: "select",
  //     digits: quantidadeCasasDecimaisCampo,
  //   })
  //   .on("focus", function () {
  //     let that = $(this);
  //     setTimeout(function () {
  //       that.select();
  //     }, 1);
  //   });


  $('.maskDesconto').maskMoney({
    decimal: ",",
    thousands: ".",
    precision: quantidadeCasasDecimaisCampo,
  });

  $("#txtProdutoDesc").val(arrDados[1]);
  $("#txtPrecoDesc").val(parseFloat(arrDados[4]).toLocaleString("pt-BR", {
    maximumFractionDigits: quantidadeCasasDecimaisCampo,
    minimumFractionDigits: quantidadeCasasDecimaisCampo
  }));
  $("#txtPrecoOrig").val(parseFloat(arrDados[3]).toLocaleString("pt-BR", {
    maximumFractionDigits: quantidadeCasasDecimaisCampo,
    minimumFractionDigits: quantidadeCasasDecimaisCampo
  }));
  $("#txtQuantidadeDesc").val(parseFloat(arrDados[2]));
  $("#txtPercDesconto").val(parseFloat(arrDados[5]).toLocaleString("pt-BR", {
    maximumFractionDigits: 2,
    minimumFractionDigits: 2
  }));
  $("#txtValorDesconto").val(parseFloat(arrDados[6]).toLocaleString("pt-BR", {
    maximumFractionDigits: quantidadeCasasDecimaisCampo,
    minimumFractionDigits: quantidadeCasasDecimaisCampo
  }));
  $("#txtTotalLiq").val(TruncaDecimaisNova(2, parseFloat(arrDados[7])).toLocaleString("pt-BR", {
    maximumFractionDigits: 2,
    minimumFractionDigits: 2
  }));
  // fazer a tratativa de arredondamento
  const soma = +(arrDados[3]) * parseFloat(arrDados[2]).toFixed(4);
  const maisDeDoisCaracteresDecimal = String(soma).substr(String(soma).indexOf('.') + 1, String(soma).length).length > 2;
  const calculoTotal = utilizaImpressoraFiscal && maisDeDoisCaracteresDecimal ? mantemDuasCasasDecimais(soma, 3) : ArredondarValor(parseFloat(soma), 2);

  $("#txtValBruto").val(parseFloat(calculoTotal).toLocaleString("pt-BR", {
    maximumFractionDigits: quantidadeCasasDecimaisCampo,
    minimumFractionDigits: quantidadeCasasDecimaisCampo
  }));
  $("#txtPrecoLiqDesconto").val(parseFloat(arrDados[4]).toLocaleString("pt-BR", {
    maximumFractionDigits: quantidadeCasasDecimaisCampo,
    minimumFractionDigits: quantidadeCasasDecimaisCampo
  }));

  $("#pesquisaDescontoConfirmar").unbind("click");
  $("#pesquisaDescontoConfirmar").on("click", async function () {
    await eventoClickPesquisaDescontoConfirmar(id);
  });
}

$('#modalItemPreco').on("shown.bs.modal", function () {
  $("#txtItemPrecoNovo").focus();
});

async function criaTelaAlterarPreco(id) {
  try {
    const arrDados = $("#tabelaItens").DataTable().row(id).data();

    $("#txtItemPrecoAtual").val(arrDados[3]);
    $("#txtItemPrecoNovo").val(arrDados[3]);
    $("#txtIdLinhaItemPreco").val(id);
    $("#modalItemPreco").modal("show");
  } catch (error) {
    console.error(error);
  }
}

async function criaTelaQuantidade(id, bDevolucao = false) {
  try {
    let arrDados = $("#tabelaItens").DataTable().row(id).data();

    $("#txtItemQuantidadeAtual").val(arrDados[2]);
    $("#txtItemQuantidade").val(arrDados[2]);
    $("#txtItemQuantidadeDiferenca").val(arrDados[2]);
    $("#txtBarraQuantidadeNova").val(bDevolucao ? arrDados[13] : arrDados[14]);
    if (!bDevolucao) {
      $('#txtDepositoQuantidadeNova').val(arrDados[33]);
    }
    $("#txtItemCodQuantidade").val(arrDados[1]);
    $("#txtIdLinhaItemQuantidade").val(id);
    $("#txtCodigoAlteraQuantidade").val(arrDados[0]);

    $("#txtItemQuantidade").trigger("blur");

    $("#modalQuantidade").modal("show");
  } catch (error) {
    console.error(error);
  }
}

async function criaTelaObservacaoItem(id) {
  try {
    const arrDados = $("#tabelaItens").DataTable().row(id).data();

    $("#txtIdLinha").val(id);
    $("#txtTituloObservacaoItem").html(arrDados[1]);
    $("#txtObservacaoItem").val(arrDados[32]);
    $("#modalObservacaoItem").modal("show");
  } catch (error) {
    console.error(error);
  }
}

async function retornaCodigoItem() {
  try {
    let response;
    let barra = $('#txtBarra').val().indexOf('#') > 0 ? $('#txtBarra').val().substring(0, 6) : $('#txtBarra').val();
    const bBarraLog = await retornaBarraLogLida(barra) == "barra_log";
    if (bBarraLog) {
      barra = await extraiBarra28(barra);
    }
    if ((parametrosVenda[17]) == 0) {
      response = await requisicao(
        "GET",
        "/Sisplan/Funcoes/v1/pesquisa?",
        `JSON={ "tabela":"pa_iten", "camposSelect":["codigo"], "where": ["barra = '${barra}' or barra28 = '${barra}' or barracli = '${barra}' or barra28 = '${barra.substr(0, 6)}'"]}`,
        null
      );
    } else {
      response = await requisicao(
        "GET",
        "/Sisplan/Funcoes/v1/pesquisa?",
        `JSON={ "tabela":"mat_iten", "camposSelect":["codigo"], "where": ["lote = '${barra}'"]}`,
        null
      );
    }
    if (!response) {
      return;
    }
    const jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.RESULT[0].mensagem);
      return;
    }

    return `'${jsonStr.RESULT[0][0].CODIGO}'`;
  } catch (error) {
    console.error(error);
    msgErro("Erro ao Retornar o código do item!");
  }
}

async function tabelaRegraPromocao(jsonStr) {
  try {
    $('#tabelaEstPrecPromo').removeClass('d-none');
    const barra = $('#txtBarra').val();
    const itensRegra = jsonStr.filter(item => item.BARRA === barra || item.BARRA28 === barra || item.BARRACLI === barra);
    const descricaoItem = itensRegra[0].CODIGO + ' - ' + itensRegra[0].DESCRICAO + ' - ' + itensRegra[0].COR + ' - ' + itensRegra[0].DESC_COR + ' - ' + itensRegra[0].TAM;
    const agrupamentoItem = itensRegra[0].CODIGO + ' - ' + itensRegra[0].COR + ' - ' + itensRegra[0].TAM + ' - ' + '1'
    adicionaItensPreco([
      itensRegra[0].CODIGO,
      descricaoItem,
      1,
      itensRegra[0].PRECO,
      itensRegra[0].PRECO,
      0,
      0,
      itensRegra[0].PRECO,
      await retornaBotaoOpcoes(),
      $('#txtBarra').val(),
      itensRegra[0].COR,
      itensRegra[0].TAM,
      itensRegra[0].DESC_COR,
      1,
      0,
      0,
      agrupamentoItem,
      false,
      '',
      'P',
      0,
      0,
      0,
      '',
      '',
      '',
      '',
      `${formataData(new Date())}T00:00:00Z`,
      itensRegra[0].UNI_VENDA,
      itensRegra[0].PRECO_PROMO > 0,
      itensRegra[0].PRECO,
      0,
      '',
      itensRegra[0].DEPOSITO,
      pegaChave('#txtTabelaPrecoProd'),
      false,
      '', //lote orig
      0,
      0 // Valor de IPI do item
    ]);
  } catch (error) {
    console.error(error);
  }
}

async function buscaPreco(bBarra = false) {
  try {
    $.LoadingOverlay("show");
    limpaInfoProdutosPesquisaPreco();
    try {
      let tipo;
      let deposito;

      if ($("#radioMaterialPreco").is(":checked")) {
        tipo = "M";

        deposito = await formataListas($('#txtDepositoProd').val().toString());

        if (deposito == '' && $("#cbTodosDepositos").prop("checked")) {
          deposito = '';
        }

        if (deposito == '' && !$("#cbTodosDepositos").prop("checked")) {
          deposito = pegaChave('#txtDeposito');
        }

      }
      if ($("#radioProdutoPreco").is(":checked")) {
        tipo = "P";

        const filtroDeposito = await buscaDepositoEmpresaUsuario();

        deposito = await formataListas($('#txtDepositoProd').val().toString());

        if (deposito == '') {
          deposito = filtroDeposito;
        }

        if (!deposito) {
          deposito = pegaChave('#txtDeposito')
        }
      }

      const somenteEstoque = $('#cbContemEstoquePreco').prop('checked') ? 'S' : 'N';
      const codigoItem = bBarra ? await retornaCodigoItem() : await formataListas($('#txtCodigoProd').val().toString());
      const tabela = pegaChave("#txtTabelaPrecoProd");
      const prazo = $('#rgPrazoPrecos').val() != '' ? $('#rgPrazoPrecos').val() : '00';
      let dataSet = [];
      const dataSetCols = [];
      let barra = $('#txtBarra').val().indexOf('#') > 0 ? $('#txtBarra').val().substring(0, 6) : $('#txtBarra').val();
      const bBarraLog = await retornaBarraLogLida(barra) == "barra_log";
      if (bBarraLog) {
        barra = await extraiBarra28(barra);
      }
      const grupo = await formataListas($('#txtGrupoMA').val().toString())
      const subGrupo = await formataListas($('#txtSubGrupo').val().toString())
      const linha = await formataListas($('#txtLinhaPreco').val().toString())
      const qualidade = await formataListas($('#txtQualidadePreco').val().toString())
      const loteInterno = await formataListas($('#txtLoteInternoPreco').val().toString())
      const tonalidade = await formataListas($('#txtTonalidadePreco').val().toString())
      const fabricacaoDe = $('#dtFabricacaoDe').val()
      const fabricacaoAte = $('#dtFabricacaoAte').val()

      const descricao = $("#txtDescricaoProd").val();

      let responseCodigo;

      if ($("#tabelaEstPrec").hasClass("d-none")) {
        $("#tabelaEstPrec").removeClass("d-none");
      }

      const params = `tabpreco=${tabela}` +
        `&PRODUTO=${codigoItem}` +
        `&DEPOSITO=${deposito}` +
        `&BARRA=${""}` +
        `&TIPO=${tipo}` +
        `&PRAZO=${prazo}` +
        `&DESCRICAO=${descricao}` +
        `&AGRUPA_ITENS=${false}` +
        `&SOMENTE_ESTOQUE=${somenteEstoque}` +
        `&GRUPO=${grupo}` +
        `&SUB_GRUPO=${subGrupo}` +
        `&LINHA=${linha}` +
        `&QUALIDADE=${qualidade}` +
        `&LOTE_INTERNO=${loteInterno}` +
        `&TONALIDADE=${tonalidade}` +
        `&FABRICACAO_DE=${fabricacaoDe}` +
        `&FABRICACAO_ATE=${fabricacaoAte}`

      let response = await requisicao(
        "GET",
        "/sisplan/vendas/v1/precos?",
        params,
        null
      );

      if (!response) {
        return;
      }

      const jsonStr = await response.json();
      jsonStr.map((item) => {
        if (!item.PRECO) {
          item.PRECO = 0;
        }
      })

      if ((bBarra) && (parametrosVenda[29] == 2)) {
        await tabelaRegraPromocao(jsonStr)
      }

      //PREENCHE QUANTIDADE
      let quantidade = 0
      jsonStr.map((item) => {
        if (item.QTDE) {
          quantidade += item.QTDE
        }
      })
      $('#txtQtdeProduto').text(quantidade)

      if (response.status != 200) {
        msgErro(jsonStr.mensagem);
        $('#txtBarra').val('');
        return;
      }

      const indicePreco = [];
      const indiceQtde = [];
      const indiceDtFabricacao = [];
      dataSet = jsonStr;
      let keys = Object.keys(dataSet[0]);
      for (let k in keys) {
        dataSetCols.push({
          title: keys[k],
          data: keys[k],
        });
        if ((keys[k] == 'PRECO') || (keys[k] == 'PRECO_PROMO')) {
          indicePreco.push(+k);
        } else if (keys[k] == 'QTDE') {
          indiceQtde.push(+k);
        } else if (keys[k] == 'DATA_FABRICACAO') {
          indiceDtFabricacao.push(+k)
        }
      }

      $("#tabelaEstoquePreco").DataTable({
        destroy: true,
        select: true,
        keys: true,
        scrollCollapse: false,
        bPaginate: false,
        scrollY: '200px',
        pageLength: 20,
        paging: true,
        scrollX: 'auto',
        lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, 'Todos']],
        autoWidth: true,
        columns: dataSetCols,
        colReorder: true,
        data: dataSet,
        columnDefs: [
          {
            "render": function (data) {
              return parseFloat(data).toLocaleString("pt-BR", {
                maximumFractionDigits: quantidadeCasasDecimaisCampo,
                minimumFractionDigits: quantidadeCasasDecimaisCampo
              });
            },
            "targets": indicePreco,
            "className": 'pr-4 text-right'
          },
          {
            "targets": indiceQtde,
            "className": 'pr-4 text-right'
          },
          {
            type: 'date-br',
            targets: indiceDtFabricacao,
            render: function (data) {
              if (data != undefined && data != '') {
                x = data.slice(0, 10).split('-');
                hora = data.split(' ')[1]
                if (x[2]) {
                  return `${x[2]}/${x[1]}/${x[0]}`
                } else {
                  return `${x} ${hora} `;
                }
              } else {
                return ''
              }
            }
          }
        ]
      });

      $('#tabelaEstoquePreco_filter').addClass('d-none')
      const colunasInvisiveis = JSON.parse(
        localStorage.getItem("colunasInvisiveisRelatorios")
      );

      $("#tabelaEstoquePreco_wrapper").prepend(
        '<button class="buttonColVis mb-0" id="buttonColVisPreco"><i class="fas fa-cogs"></i></button>'
      );

      $("#buttonColVisPreco").on("click", async function (e) {
        e.preventDefault();
        $('#txtEstoquePrecoControle').val(1)
        $.LoadingOverlay("show");
        $("#modal-ColunasVisiveis").modal("show");
        $.LoadingOverlay("hide");
      });

      $("#buttonColVisPreco").prop("title", "Configurar colunas");

      $("#tabelaEstoquePreco")
        .DataTable()
        .columns()
        .every(function () {
          if (
            colunasInvisiveis.estoquePreco.indexOf(this.dataSrc()) != -1
          ) {
            this.visible(false);
          }
        });

      if (barra != '') {
        if (tipo == "P") {
          const pesquisaProd = {
            tabela: "pa_iten",
            camposSelect: ["PA_ITEN.CODIGO", "PA_ITEN.COR", "PA_ITEN.TAM"],
            where: []
          };
          if (barra != '') {
            pesquisaProd.where = [`1=1 AND (PA_ITEN.BARRA = '${barra}' OR PA_ITEN.BARRA28 = '${barra}' OR PA_ITEN.BARRACLI = '${barra}' OR PA_ITEN.BARRA28 = '${barra.substr(0, 6)}') `];
          }
          if (deposito != '') {
            pesquisaProd.where.push(` PA_ITEN.DEPOSITO IN (${deposito})`);
          }
          responseCodigo = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON=${JSON.stringify(pesquisaProd)}`,
            null
          );
        } else {
          responseCodigo = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"MAT_ITEN", "camposSelect":["MAT_ITEN.CODIGO","MAT_ITEN.COR"], "where": ["MAT_ITEN.LOTE = '${barra}'"]}`,
            null
          );

          responseCodigo = await requisicao(
            "GET",
            "/Sisplan/Funcoes/v1/pesquisa?",
            `JSON={ "tabela":"MAT_ITEN", "camposSelect":["MAT_ITEN.CODIGO","MAT_ITEN.COR"],
                     "where": [" 1=1
                     ${barra != ""
              ? `AND (MAT_ITEN.BARRA = '${$("#txtBarra").val()}')`
              : ""
            }
                      ${deposito != ""
              ? `AND MAT_ITEN.DEPOSITO IN (${deposito})`
              : ""
            }
            "]}`,
            null
          );
        }

        if (!responseCodigo) {
          return;
        }

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

        let posicao = "";

        if (jsonStrCodigo.RESULT[0].length == 0) {
          $("#txtBarra").val("");
          // $("#txtCodigoProd").val("");
          // $("#txtDescricaoProd").val("");
          return;
        }

        let codigo = jsonStrCodigo.RESULT[0][0].CODIGO;
        let cor = jsonStrCodigo.RESULT[0][0].COR;

        for (
          let i = 0;
          i < $("#tabelaEstoquePreco").DataTable().rows().data().length;
          i++
        ) {
          if (tipo == "P") {
            let tam = jsonStrCodigo.RESULT[0][0].TAM;
            if (
              codigo ==
              $("#tabelaEstoquePreco").DataTable().rows().data()[i].CODIGO &&
              tam == $("#tabelaEstoquePreco").DataTable().rows().data()[i].TAM &&
              cor == $("#tabelaEstoquePreco").DataTable().rows().data()[i].COR
            ) {
              posicao = i;
            }
          } else if (
            codigo ==
            $("#tabelaEstoquePreco").DataTable().rows().data()[i].CODIGO &&
            cor == $("#tabelaEstoquePreco").DataTable().rows().data()[i].COR
          ) {
            posicao = i;
          }
        }
        setTimeout(() => {
          $("#tabelaEstoquePreco tbody tr")[posicao].click();
        }, 100);
      }

      // limpaCodigo()
      $("#txtBarra").val("");
    } catch (error) {
      console.error(error);
      msgErro("Não foi possível encontrar o código ou a barra com os dados consultados. Por favor, verifique o código ou a barra do item, o depósito e a tabela de preços!");
      $("#txtBarra").val("");
      // limpaCodigo()
    }

    async function consultaEstoque(codigo, barra, deposito) {
      const response = await requisicao('GET', '/sisplan/vendas/v1/consultaEstoque?', `PRODUTO=${codigo}&DEPOSITO=${deposito}&BARRA=${encodeURIComponent(barra)}`, null);
      const container = document.getElementById('infoEstoque');
      container.innerHTML = '';

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

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


      const agrupado = {};
      jsonStr.forEach(item => {
        const dep = item.DESC_DEPOSITO;
        if (!agrupado[dep]) agrupado[dep] = [];
        agrupado[dep].push(item);
      });


      Object.entries(agrupado).forEach(([deposito, itens]) => {
        const cores = [...new Set(itens.map(i => i.DESC_COR))];

        // 🔹 Ordena tamanhos de acordo com o campo POSICAO (sem perder valores)
        const tamanhoOrdemMap = {};
        itens.forEach(i => {
          if (!(i.TAM in tamanhoOrdemMap) || i.POSICAO < tamanhoOrdemMap[i.TAM]) {
            tamanhoOrdemMap[i.TAM] = i.POSICAO;
          }
        });
        const tamanhos = Object.entries(tamanhoOrdemMap)
          .sort((a, b) => a[1] - b[1])
          .map(([tam]) => tam);

        const tabela = document.createElement('div');
        tabela.className = "mb-5 col-12 col-sm-6";

        tabela.innerHTML = `
            <div class="tabela-grade p-2">
                <table class="table table-bordered text-center mb-0">
                    <thead>
                        <tr>
                            <th></th>
                            ${tamanhos.map(t => `<th>${t}</th>`).join('')}
                        </tr>
                    </thead>
                    <tbody>
                        ${cores.map(cor => `
                            <tr>
                                <th class="text-start">${cor}</th>
                                ${tamanhos.map(tam => {
          const item = itens.find(i => i.DESC_COR === cor && i.TAM === tam);
          return `<td>${item ? item.QUANTIDADE : 0}</td>`;
        }).join('')}
                            </tr>
                        `).join('')}
                    </tbody>
                </table>
            </div>
            <div class="deposito-nome">${deposito}</div>
        `;

        container.appendChild(tabela);
      });
    }

    function limpaCodigo() {
      $("#txtCodigoProd").empty().trigger('change')
      $("#txtCodigoProd").val('');
      $("#txtCodigoProd").attr('data-chave', '');
      $("#txtCodigoProd").attr('data-desc', '');
    }

    $("#tabelaEstoquePreco tbody").on("click", "tr", async function () {
      // $("#tabelaEstoquePreco tbody tr td")[0].click();
      $("#tabelaEstoquePreco")
        .DataTable()
        .$("tr.selected")
        .removeClass("selected");
      $(this).addClass("selected");

      let data = $("#tabelaEstoquePreco").DataTable().row($(this)).data();
      await buscaFotoProdPreco(data.CODIGO);
      $("#txtPrecoProduto").text(
        data.PRECO_PROMO > 0 ? data.PRECO_PROMO : data.PRECO
      );
      // $("#txtQtdeProduto").text(data.QTDE);
      $("#txtDescProduto").text(
        `${data.DESCRICAO.split("-")[0]} - ${data.DESC_COR ? data.DESC_COR : ''} - ${data.TAM}`
      );
      await consultaEstoque(data.CODIGO, data.BARRA, data.DEPOSITO);
    });
  } finally {
    $.LoadingOverlay("hide");
    $(this).focus();
  }
}

function limpaInfoProdutosPesquisaPreco() {
  $('#txtDescProduto').text('Descrição do produto');
  $('#txtPrecoProduto').text('0,00');
  $('#txtQtdeProduto').text('0');
}

async function buscaFotoProdPreco(codigo) {
  try {
    let url = "/Sisplan/Funcoes/v1/FotoItem?";
    let response = await requisicao("GET", url, `codigo=${codigo}`, null);

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (response.status != 200) {
      $("#infoprodimagem").attr(
        "src",
        "<?php echo BASE_URI; ?>/dist/img/prod-1.png"
      );
      return;
    }

    let sBase64 = jsonStr;
    if ($("#tabelaEstoquePreco").DataTable().rows().count() == 0) {
      $("#fotoPrecoProdutoMaterial").attr(
        "src",
        "<?php echo BASE_URI; ?>/dist/img/prod-1.png"
      );
    } else {
      $("#fotoPrecoProdutoMaterial").attr(
        "src",
        `data:image/png;base64,${sBase64.mensagem}`
      );
    }
  } catch (error) {
    console.error(error);
    $("#fotoPrecoProdutoMaterial").attr(
      "src",
      "<?php echo BASE_URI; ?>/dist/img/prod-1.png"
    );
  }
}

$("#pesquisaDesconto").on("shown.bs.modal", function () {
  $("#pesquisaDesconto .modal-body").trigger("click").focus();
});

$("#modalPrecos").on("shown.bs.modal", function () {
  $("#txtBarra").focus();
});

async function focaCampo() {
  const paramFoco = parametrosVenda[21];
  if (paramFoco == 1) {
    $("#txtQuantid").focus();
  }
  if (paramFoco == 2) {
    $("#txtCodigo").focus();
  } else {
    $("#txtCodigo").focus();
  }
}

function validaOrdemBipada(dataFilhos) {
  const ordensUnicas = [...new Set(dataFilhos.map(item => item.ORDEM))];

  const teste = []
  const dataItens = $('#tabelaItens').DataTable().rows().data().toArray().filter((data) => !data[35]);

  dataItens.forEach((it) => {
    return dataFilhos.forEach((itf) => {
      if (itf.CODIGO === it[0]) {
        teste.push({ ordem: itf.ORDEM, codigo: itf.CODIGO })
      }
    })
  })

  const todasOrdensExistem = ordensUnicas.every(ordemUnica =>
    teste.some(item => item.ordem === ordemUnica)
  );

  return todasOrdensExistem

}

async function validaItensRelacionados() {
  const dataTable = $('#tabelaItens').DataTable();
  const dataItensPai = dataTable.rows().data().toArray().filter((data) => data[35]);

  for (let i = 0; i < dataItensPai.length; i++) {
    const codigoPai = dataItensPai[i][0];
    const corPai = dataItensPai[i][10];
    const faixaTamPai = dataItensPai[i][11];

    const url = '/sisplan/produto/v1/valida_produtos_bipados?';
    const response = await requisicao('GET', url, `CODIGO=${codigoPai}&COR=${corPai}&TAM=${faixaTamPai}&`, '', 30000);

    if (!response) {
      return;
    };

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

    const jsonStr = await response.json();

    const todosOsFilhosBipados = validaOrdemBipada(jsonStr);

    if (todosOsFilhosBipados) {
      var rowIndex = dataTable.rows().indexes().filter(function (rowIdx) {
        return dataTable.cell(rowIdx, 0).data() === codigoPai ? true : false;
      });

      if (rowIndex.any()) {
        const rowNode = dataTable.row(rowIndex[0]).node();
        $(rowNode).addClass('linhaAzul');
        $(rowNode).removeClass('linha-prodRelac');
      }

    } else {
      var rowIndex = dataTable.rows().indexes().filter(function (rowIdx) {
        return dataTable.cell(rowIdx, 0).data() === codigoPai ? true : false;
      });

      if (rowIndex.any()) {
        const rowNode = dataTable.row(rowIndex[0]).node();
        $(rowNode).addClass('linha-prodRelac');
        $(rowNode).removeClass('linhaAzul');
      }
    }
  }
}

async function retornaDescontoMaximoMoeda(codMoeda) {
  try {
    if (codMoeda != "") {
      const json = await retornaJsonPesquisaPadrao(
        `{"tabela": "moeda", "camposSelect": ["descmax"], "where": ["codmoe = '${codMoeda}'"] }`
      );
      if (json) {
        return parseFloat(json[0].DESCMAX);
      }
    }

    msgAlerta("Nenhuma moeda selecionada!");
    return;
  } catch (error) {
    console.error(error);
  }
}

async function retornaDescontoMaximoUsuario() {
  try {
    const url = "/sisplan/funcoes/v1/pesquisa?";
    let desconto;
    let usuario;
    if (getCookie("cod_usuario") === "0000") {
      usuario = "SISPLAN";
    } else {
      usuario = getCookie("usuario");
    }
    const response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"acesso_usuarios", "camposSelect": ["desc_max"], "where": ["NOME = '${usuario}'"]}`,
      null
    );

    if (!response) {
      return;
    }

    const jsonStr = await response.json();

    if (
      jsonStr.RESULT[0][0].DESC_MAX != "" &&
      jsonStr.RESULT[0][0].DESC_MAX != null &&
      jsonStr.RESULT[0][0].DESC_MAX != undefined
    ) {
      desconto = jsonStr.RESULT[0][0].DESC_MAX;
    } else {
      desconto = 0;
    }

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

async function retornaValoresDesconto() {
  try {
    const table = $("#tabelaItens").DataTable().rows();
    let somaValorTotalVenda = 0;

    let somaDescontoTotalVenda = $("#tabelaItens")
      .DataTable()
      .column(6, {})
      .data()
      .sum();
    for (let i = 0; i < table[0].length; i++) {
      somaValorTotalVenda += table.data()[i][2] * table.data()[i][3];
    }

    $("#somaDescontoTotalVenda").val(somaDescontoTotalVenda);
    $("#somaValorTotalVenda").val(somaValorTotalVenda);
  } catch (error) {
    console.error(error);
  }
}

async function verificaTotalDescontoUsuario() {
  try {
    const descontoTotalUsuario = await retornaDescontoMaximoUsuario();
    if (descontoTotalUsuario > 0) {
      if ($("#txtPercDescontoMoeda").val() > descontoTotalUsuario) {
        let descontoTotal =
          parseFloat($("#txtPercDescontoMoeda").val()) +
          parseFloat($("#txtPercDescontoMoeda").val());
        const nmrVenda = $('#txt_venda_atual>span').html() == 'Nova' ? 'create' : $('#txt_venda_atual>span').html()
        await senhaSupervisor(
          `Desconto de ${descontoTotal.toFixed(
            2
          )} % na venda, máximo do usuário é de ${descontoMaximoUsuario}%.`,
          verificaDescontoMaximoSupervisor, AplicaDescontoItem, true,
          undefined, undefined, undefined, false,
          'VENDA', nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda, pegaChave('#txtCliente'),
          parseFloat($('#txtValorParcela').val().replace(',', '.')) || 0, parseFloat($('#txtValorLiquidoMoeda').val().replace(',', '.')) || 0, parseFloat($('#txtPercDescontoMoeda').val().replace(',', '.')) || 0, parseFloat($('#txtValorDescontoMoeda').val().replace(',', '.')) || 0, pegaChave('#txtVendedor')
        );
      }
    }
  } catch (error) {
    console.error(error);
  }
}

async function pegaDescontoOutrasMoedas() {
  try {
    const table = $("#tabelaCondicoesDePagamento").DataTable().rows();
    let somaDescontoTotalmMoeda = 0;
    for (let i = 0; i < table[0].length; i++) {
      somaDescontoTotalmMoeda += table.data()[i][13];
    }
    return somaDescontoTotalmMoeda;
  } catch (error) {
    console.error(error);
  }
}

async function verificaUsuarioPodeGravarCondicoes() {
  try {
    const url = `/sisplan/funcoes/v1/pesquisa?`;

    let usuario = "";
    if (getCookie("cod_usuario") === "0000") {
      usuario = "SISPLAN";
    } else {
      usuario = getCookie("usuario");
    }

    const response = await requisicao(
      "GET",
      url,
      `JSON={"tabela": "acesso_usuarios", "camposSelect": ["grava_condicao"], "where": ["NOME = '${usuario}'"] }`,
      null
    );

    if (!response) {
      return false;
    }

    const jsonStr = await response.json();

    if (jsonStr.RESULT[0][0].GRAVA_CONDICAO == "S") {
      return true;
    }
    return false;
  } catch (error) {
    console.error(error);
    return false;
  }
}

async function carregaHistoricoCredito(codcli) {
  const pesquisaParam = {
    tabela: 'ACESSO_TELA',
    camposSelect: [
      'ACESSO_TELA.NUMERO', 'ACESSO_TELA.DT_EMISSAO EMISSAO', 'ACESSO_TELA.DT_AUTORIZACAO AUTORIZACAO', 'ACESSO_TELA.CHAVE',
      'ENTIDADE.NOME', 'ENTIDADE.CNPJ', 'ENTIDADE.CREDITO LIMITE_ATUAL',
      'ACESSO_TELA.VALOR LIMITE_SOLICITADO', 'ACESSO_TELA.MOTIVO', 'ACESSO_TELA.AUTORIZADO',
      'ACESSO_TELA.EMP_ID', 'ENTIDADE.DT_VALID_LIMITE VALIDADE'
    ],
    leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = ACESSO_TELA.CHAVE' }],
    where: [`ACESSO_TELA.CHAVE = '${codcli}'`]
  }
  const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

  if (jsonStr.length == 0) {
    return;
  }

  const keys = Object.keys(jsonStr[0]);
  let dataSetCols = [];

  for (var k in keys) {
    dataSetCols.push({
      'title': keys[k].toUpperCase(),
      'data': keys[k]
    });
  };

  criaDataTablePadrao('#tabela-historico-dup', false, false, false, false, true, true, '300px', jsonStr, dataSetCols, [3, 4, 5, 10], [1, 2, 11], undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);

  setTimeout(() => {
    $("#tabela-historico-dup").DataTable().columns.adjust().draw(false);
  }, 200);
}

async function verificaMoedaCarne(arrayMoeda) {
  let url = `/Sisplan/Funcoes/v1/pesquisa?`;
  let params = `JSON={ "tabela":"moeda", "camposSelect":["CODMOE","IMP_CARNE"], 
                                    "where": ["CODMOE IN (${arrayMoeda.toString()}) AND IMP_CARNE = 'S'"]}`;

  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;
    }
    if (jsonStr.RESULT[0].length == 0) {
      return false;
    }
    if (jsonStr.RESULT[0][0].IMP_CARNE == "S") {
      return true;
    }
    return false;
  } catch (error) {
    console.error(error);
  }
}

async function calculaAcrescimoVenda(
  campoAlterado,
  valorAcrescimo,
  percAcrescimo,
  valorBruto
) {
  try {
    $("#txtPercDescontoMoeda").prop("disabled", true);
    $("#txtValorDescontoMoeda").prop("disabled", true);

    if (campoAlterado === "txtPercAcrescMoeda") {
      valorAcrescimo =
        (valorBruto - parseFloat($("#txtValorDescontoMoeda").val())) *
        (percAcrescimo / 100);
      if (valorAcrescimo != undefined) {
        $("#txtValorAcrescMoeda").val(ArredondarValor(valorAcrescimo, 2));
        $("#txtPercAcrescMoeda").val(ArredondarValor(percAcrescimo, 2));
        $("#txtValorLiquidoMoeda").val(
          ArredondarValor(
            valorBruto -
            parseFloat($("#txtValorDescontoMoeda").val()) +
            valorAcrescimo,
            2
          )
        );
        $("#txtsaldo_a_pagar").html(
          parseFloat($("#txtValorLiquidoMoeda").val()).toLocaleString("pt-BR", {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
            currency: "BRL",
          })
        );
        return;
      }
    }

    if (campoAlterado === "txtValorAcrescMoeda") {
      percAcrescimo =
        (valorAcrescimo / valorBruto -
          parseFloat($("#txtValorDescontoMoeda").val())) *
        100;

      if (valorAcrescimo != undefined) {
        $("#txtValorAcrescMoeda").val(ArredondarValor(valorAcrescimo, 2));
        $("#txtPercAcrescMoeda").val(ArredondarValor(percAcrescimo, 2));
        $("#txtValorLiquidoMoeda").val(
          ArredondarValor(
            valorBruto -
            parseFloat($("#txtValorDescontoMoeda").val()) +
            valorAcrescimo,
            2
          )
        );
        $("#txtsaldo_a_pagar").html(
          parseFloat($("#txtValorLiquidoMoeda").val()).toLocaleString("pt-BR", {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
            currency: "BRL",
          })
        );
        return;
      }
    }
  } catch (error) {
    console.error(error);
    $("#txtPercDescontoMoeda").prop("disabled", false);
    $("#txtValorDescontoMoeda").prop("disabled", false);
  }
}

async function abreCadastroCepVenda() {
  $("#modal-CEP").css("z-index", 99999);
  $("#modal-CEP").modal("show");
  if ($("#modal-cliente").hasClass("modal show")) {
    if (
      $("#txtCep").val() != "" ||
      $("#txtCep").val() != undefined ||
      $("#txtCep").val() != null
    ) {
      $("#txt_Cep").val(
        `${$("#txtCep").val().substr(0, 5)}-${$("#txtCep").val().substr(-3)}`
      );
    }
  }
}

async function possuiTef(venda) {
  const emp_id = getCookie("emp_id");
  const url = `/Sisplan/Funcoes/v1/pesquisa?`;
  const params = `JSON={"tabela":"CONDIVENDA", 
                        "camposSelect":["CONDIVENDA.OPERADOR", "CONDIVENDA.NSU", "CONDIVENDA.TEF_FINALIZACAO", "SUM(ITCONDIVENDA.VALOR) VALOR", "MOEDA.TEF"], 
                        "leftjoin": [{"tabela": "MOEDA", "condicao": "MOEDA.CODMOE = CONDIVENDA.CDMOEDA"},
                                     {"tabela": "ITCONDIVENDA", "condicao": "ITCONDIVENDA.CDCONDIVENDA = CONDIVENDA.CDCONDIVENDA"}],
                        "where": ["CONDIVENDA.CDVENDA = ${venda} AND CONDIVENDA.EMP_ID = ${emp_id}"],
                        "groupBy": ["CONDIVENDA.OPERADOR", "CONDIVENDA.NSU", "CONDIVENDA.TEF_FINALIZACAO", "MOEDA.TEF"]}`;

  try {
    let response = await requisicao("GET", url, params, null);

    if (!response) {
      return false;
    }

    let jsonStr = await response.json();

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

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

    const condicoesTEF = jsonStr.RESULT[0].filter(condicao => condicao.TEF == "S" && (condicao.OPERADO != "" || condicao.NSU != "" || condicao.TEF_FINALIZACAO != ""));

    return condicoesTEF.length > 0 ? condicoesTEF : false;

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

async function verificaECancelaTEF(codven, cupom, tef) {
  try {
    const url = `/tef/cancelartef?`;
    const listaRespostas = [];

    for (let transacaoTEF of tef) {
      const rede = transacaoTEF.OPERADOR;
      const nsu = transacaoTEF.NSU;
      const finalizado = transacaoTEF.TEF_FINALIZACAO;
      const vlvenda = transacaoTEF.VALOR;

      const params = `REDE=${rede}&NSU=${nsu}&FINALIZADO=${finalizado}&NRCUPOM=${cupom}&VALOR=${String(vlvenda).replace(".", ",")}`;

      let response = await requisicao_ecf("GET", url, params, "", 300000);

      if (!response) {
        msgErro(`Não foi possível realizar o cancelamento da transação TEF. NSU: ${nsu}, VALOR: ${vlvenda}`);
        return [false];
      }

      const resp = await response.text();
      if (response.status != 200) {
        mensagemErro = resp != '' ? resp : 'TEF não foi cancelado.'
        msgAlerta(`${mensagemErro} NSU: ${nsu}, VALOR: ${vlvenda}`);
        return [false];
      }

      listaRespostas.push(`${resp}\n`);

    }

    if (listaRespostas.length > 0) {
      return [true, listaRespostas.join(";").replaceAll(";", "")];
    }

    return [true];
  } catch (error) {
    console.error(error);
  }
}

async function RecalculaRegraPromocao(regras, estorno = false, tabela = pegaChave("#txtTabela"), idTabela = '#tabelaItens') {
  let sWhere;
  let sOrderBy;
  if (parametrosVenda[29] == 2) {
    const dataAtual = `${formataData(new Date())}`;
    sWhere = `REGRA_PROMOCAO.DT_INICIAL [MENORQUE] '${dataAtual}' AND REGRA_PROMOCAO.DT_FINAL [MAIORQUE] '${dataAtual}' AND REGRA_PROMOCAO.REGIAO ='${tabela}'`;
    sOrderBy = 'VALOR';
  } else {
    sWhere = `REGRA = '${regras}'`;
    sOrderBy = 'VALOR DESC';
  }
  const data = `${formataData(new Date())} 00:00:00`;
  const url = "/Sisplan/funcoes/v1/pesquisa?";
  const params = `JSON={ "tabela":"REGRA_PROMOCAO", "camposSelect":["REGRA", "SEQ", "VALOR", "DESCONTO", "TIPO", "CAMPO", "CHAVE", "OPERACAO", "MODELO",  "DT_INICIAL", "DT_FINAL", "EMPRESA", "REGIAO" ],
    "where": ["${sWhere}"],
    "orderby": ["${sOrderBy}"]}`;

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

  if (!response) {
    return;
  }

  let jsonRegra = await response.json();

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

  g_regra = jsonRegra.RESULT[0];

  // validacao
  if (parametrosVenda[29] == 2) {
    g_regra = g_regra.filter(function (obj) {
      const empresas = obj.EMPRESA.split(',');
      return empresas.includes(getCookie('emp_id'));
    });
  } else {
    for (let i = 0; i < g_regra.length; i++) {
      if (
        new Date(`${g_regra[i].DT_FINAL.substring(0, 10)} 00:00:00`) <
        new Date(data)
      ) {
        msgAlerta("Data da regra expirada!");
        $("#txtRegraPromocao").val("");
        SaidaCampoRegra();
        desbloqueiaTabela();
        return;
      }
      if (
        new Date(`${g_regra[i].DT_INICIAL.substring(0, 10)} 00:00:00`) >
        new Date(data)
      ) {
        msgAlerta("Data inicial da regra não vigente!");
        $("#txtRegraPromocao").val("");
        SaidaCampoRegra();
        desbloqueiaTabela();
        return;
      }
      if (g_regra[i].REGIAO != tabela) {
        msgAlerta("Tabela de preço não se usa essa regra!");
        $("#txtRegraPromocao").val("");
        SaidaCampoRegra();
        desbloqueiaTabela();
        return;
      }

      if (!g_regra[i].EMPRESA.includes(sessionStorage.getItem("emp_id"))) {
        msgAlerta("Essa empresa não tem acesso a essa regra!");
        $("#txtRegraPromocao").val("");
        SaidaCampoRegra();
        desbloqueiaTabela();
        return;
      }
    }
  }

  if (g_regra) {
    if (($("#tabelaItensRegraPromocao").DataTable().rows().count() > 0) && (parametrosVenda[29] != 2)) {
      if (
        $("#tabelaItensRegraPromocao").DataTable().rows().data()[0][0].REGRA !=
        g_regra[0].REGRA
      ) {
        $("#tabelaItensRegraPromocao").DataTable().rows().clear().draw(false);
        $("#tabelaItensUtilizamRegra").DataTable().rows().clear().draw(false);
        await montaTabelaItensRegra(g_regra);
      }
    } else {
      await montaTabelaItensRegra(g_regra);
    }
    await AplicaRegraPromocao(g_regra, estorno, idTabela);
  }
}

function SaidaCampoRegra() {
  $("#btnRecalcularRegra").trigger("click");
}

function desbloqueiaTabela() {
  $("#txtTabela").prop("disabled", false);
  $("#btn-tabela").prop("disabled", false);
  $("#btn-limpa-tabela").prop("disabled", false);
}

async function montaTabelaItensRegra(regra) {
  try {
    let sWhere;
    if (parametrosVenda[29] == 2) {
      const valores = regra.map(function (obj) { return obj.REGRA }).join(',');
      if (valores == '') {
        return;
      }
      sWhere = `REGRA IN (${valores})`;
    } else {
      sWhere = `REGRA = '${pegaChave('#txtRegraPromocao')}'`;
    }
    const url = '/Sisplan/funcoes/v1/pesquisa?';
    const params = `JSON={ "tabela":"REGRA_PROMOCAOI", "camposSelect": ["REGRA", "CODIGO", "TIPO", "OPERACAO", "VALOR", "COR", "TAM"], "where": ["${sWhere}"]}`;
    const response = await requisicao('GET', url, params, '', 15000);
    let dataSet = [];
    let dataSetCols = [];

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

    dataSet = jsonStr.RESULT;

    let keys = Object.keys(dataSet[0]);

    // keys.map((k) => {
    //   dataSetCols.push({
    //     'title': keys[k],
    //     'data': keys[k]
    //   });
    // });
    for (let k in keys) {
      dataSetCols.push({
        'title': keys[k],
        'data': keys[k]
      });
    }

    let tabelaItensRegraPromocao = $('#tabelaItensRegraPromocao').DataTable();
    tabelaItensRegraPromocao.clear().draw();

    tabelaItensRegraPromocao.rows.add(dataSet).draw();

    // $('#tabelaItensRegraPromocao').DataTable({
    //   paging: false,
    //   filter: false,
    //   info: false,
    //   order: false,
    //   destroy: true,
    //   autowidth: true,
    //   "language": {
    //     "sEmptyTable": "Nenhum registro encontrado",
    //     "sInfo": "_TOTAL_ registros",
    //     "sInfoEmpty": " 0 registros",
    //     "sInfoFiltered": "(Filtrados de MAX registros)",
    //     "sInfoPostFix": "",
    //     "sInfoThousands": ".",
    //     "sLengthMenu": "_MENU_ resultados",
    //     "sLoadingRecords": "Carregando...",
    //     "sProcessing": "Processando...",
    //     "sZeroRecords": "Nenhum registro encontrado",
    //     "sSearch": "Pesquisar",
    //     "oPaginate": {
    //       "sNext": "Próximo",
    //       "sPrevious": "Anterior",
    //       "sFirst": "Primeiro",
    //       "sLast": "Último"
    //     },
    //     "oAria": {
    //       "sSortAscending": ": Ordenar colunas de forma ascendente",
    //       "sSortDescending": ": Ordenar colunas de forma descendente"
    //     }
    //   },
    //   "columns": dataSetCols,
    //   "data": dataSet
    // });

    $('#tabelaItensUtilizamRegra').DataTable({
      paging: false,
      filter: false,
      info: false,
      order: false,
      destroy: true,
      autowidth: true,
    });

    $('#tabelaItensUtilizamRegra').DataTable().rows().clear().draw(false);
    await montaTabelaBrindes(regra);
  } catch (error) {
    console.error(error);
  }
}

async function AplicaRegraPromocao(regra, estorno = false, idTabela) {
  try {
    const itens = $(idTabela).DataTable().rows().data();
    const itensRegra = $("#tabelaItensRegraPromocao").DataTable().rows().data();
    let itensUtilizamRegra = $("#tabelaItensUtilizamRegra").DataTable().rows().data();

    let recordCount = 1;
    if (parametrosVenda[29] == 2) {
      recordCount = regra.length;
    }
    for (let j = 0; j < recordCount; j++) {
      let Quantidade = 0;
      let ValorItens = 0;
      let percDesconto = 0;
      let valorDesconto = 0;
      let itemEncontrado = 0;
      let itemNaoExisteNaRegra = 0;
      let regraP = 0;
      let ItemEstaNaRegra = 0;
      $("#tabelaItensUtilizamRegra").DataTable().clear();
      itensUtilizamRegra = [];
      if (regra[j].MODELO == 1 || regra[j].MODELO == 3) {
        itens.each((item) => {
          if (regra[j].MODELO == 3) {
            itemEncontrado = itensRegra[0].filter(
              (itemRegra) =>
                itemRegra.REGRA === regra[j].REGRA &&
                itemRegra.CODIGO === item[0] &&
                itemRegra.COR === item[10] &&
                itemRegra.TAM === item[11] &&
                item[32] !== 'Brinde'
            )[0];
          } else {
            itemEncontrado = itensRegra[0].filter(
              (itemRegra) => itemRegra.CODIGO === item[0] && itemRegra.REGRA === regra[j].REGRA && item[32] !== 'Brinde'
            )[0];
          }
          if (
            itemEncontrado != undefined &&
            itemEncontrado != null &&
            itemEncontrado != ""
          ) {
            itemNaoExisteNaRegra =
              itensUtilizamRegra.length > 0
                ? itensUtilizamRegra.filter(
                  (itemUtilizaRegra) => itemUtilizaRegra[0] === item[0]
                )[0]
                : true;
            if (itemNaoExisteNaRegra) {
              $("#tabelaItensUtilizamRegra")
                .DataTable()
                .row.add([
                  itemEncontrado.CODIGO,
                  itemEncontrado.COR,
                  itemEncontrado.OPERACAO,
                  itemEncontrado.REGRA,
                  itemEncontrado.TAM,
                  itemEncontrado.TIPO,
                  itemEncontrado.VALOR,
                  item[2],
                  item[31] != 0
                ])
                .draw(false);
            }
            Quantidade += item[2];
            ValorItens += Number(item[7]);
          } else {
            // nao acontece nada feijoada
          }
        });

        // agora vai aplicar a regra nos itens
        if (regra[j].TIPO == "V") {
          if (parametrosVenda[29] == 2) {
            regraP = regra[j].VALOR <= ValorItens ? regra[j] : 0;
          } else {
            regraP = regra.find((regras) => regras.VALOR <= ValorItens);
          }
        } else {
          if (parametrosVenda[29] == 2) {
            if (regra[j].OPERACAO == "=") {
              defineItensAplicarRegra(regra[j], Quantidade);
            }
            regraP = regra[j].VALOR <= Quantidade ? regra[j] : 0;
          } else {
            regraP = regra.find((regras) => regras.VALOR <= Quantidade);
          }
        }

        if (itens.length > 0) {
          itensUtilizamRegra = $("#tabelaItensUtilizamRegra")
            .DataTable()
            .rows()
            .data()
            .toArray();
          itens.each((item, i) => {
            if (regraP.MODELO == 1) {
              itemEncontrado = itensRegra[0].filter(
                (itemVenda) => itemVenda.CODIGO === item[0] && itemVenda.REGRA === regra[j].REGRA
              )[0];
            } else {
              itemEncontrado = itensRegra[0].filter(
                (itemVenda) =>
                  itemVenda.REGRA === regra[j].REGRA &&
                  itemVenda.CODIGO === item[0] &&
                  itemVenda.COR === item[10] &&
                  itemVenda.TAM === item[11]
              )[0];
            }

            if (
              itemEncontrado != undefined &&
              itemEncontrado != null &&
              itemEncontrado != "" &&
              (regraP != 0)
            ) {
              if (itensUtilizamRegra.length > 0) {
                if (regraP.MODELO == 1) {
                  ItemEstaNaRegra = itensUtilizamRegra.filter(
                    (itemExisteNaRegra) =>
                      itemExisteNaRegra[0] == itemEncontrado.CODIGO
                  );
                } else {
                  ItemEstaNaRegra = itensUtilizamRegra.filter(
                    (itemExisteNaRegra) =>
                      itemExisteNaRegra[0] == itemEncontrado.CODIGO &&
                      itemExisteNaRegra[1] == itemEncontrado.COR &&
                      itemExisteNaRegra[4] == itemEncontrado.TAM
                  );
                }
              } else {
                ItemEstaNaRegra = "";
              }
              if (
                ItemEstaNaRegra != undefined &&
                ItemEstaNaRegra != null &&
                ItemEstaNaRegra != ""
              ) {
                if (itemEncontrado.VALOR > 0) {
                  if (itemEncontrado.OPERACAO == "D") {
                    percDesconto = itemEncontrado.VALOR;
                  } else if (item[3] > itemEncontrado.VALOR) {
                    percDesconto = 100 - ((itemEncontrado.VALOR / item[3]) * 100);
                  }
                } else {
                  percDesconto = regraP.DESCONTO;
                }

                if (estorno) {
                  const indexItemUtizaRegra = itensUtilizamRegra.findIndex(itemRegra => itemRegra[0] == item[0] && itemRegra[7] == item[2]);
                  itensUtilizamRegra.splice(indexItemUtizaRegra, 1);
                }

                if ((percDesconto > g_DescCliente) && (item[31] == 0 || item[31] != 0 && item[22] < percDesconto)) {
                  // pega % desconto
                  item[5] = ArredondarValor(percDesconto, 2);
                  valorDesconto = quantidadeCasasDecimaisCampo > 2 ? moeda2float(float2moeda(item[3] * (percDesconto / 100), quantidadeCasasDecimaisCampo))
                    : ArredondarValor(item[3] * (percDesconto / 100), 2);
                  // pega valor Desconto
                  item[6] = valorDesconto * item[2];
                  // ajusta o preco do item
                  item[4] = quantidadeCasasDecimaisCampo > 2 ? moeda2float(float2moeda(item[3] - valorDesconto, quantidadeCasasDecimaisCampo))
                    : ArredondarValor(item[3] - valorDesconto, 2);
                  // ajusta valor total dos itens
                  item[7] = ArredondarValor(item[4] * item[2], 2);
                  item[20] = valorDesconto;
                  item[21] = item[3];
                  item[22] = percDesconto;
                  item[31] = itemEncontrado.REGRA;
                }


                $(idTabela).DataTable().row(i).data(item);
                percDesconto = 0;
              }
            } else {
              if (parametrosVenda[29] != 2) {
                item[4] = item[3];
                item[5] = 0;
                item[6] = 0;
                item[7] = ArredondarValor(item[3] * item[2], 2);
                item[20] = 0;
                item[21] = 0;
                item[22] = 0;
                item[31] = 0;
                $(idTabela).DataTable().row(i).data(item);
              }
            }
          });

          await atualizaTotalVenda();
        }
      } else {
        if (regra[j].MODELO === 4 || regra[j].MODELO === 6) continue;

        itens.each((item) => {
          if (regra[0].MODELO == 3) {
            itemEncontrado = itensRegra[0].filter(
              (itemRegra) =>
                itemRegra.REGRA === regra[j].REGRA &&
                itemRegra.CODIGO === item[0] &&
                itemRegra.COR === item[10] &&
                itemRegra.TAM === item[11]
            )[0];
          } else {
            itemEncontrado = itensRegra[0].filter(
              (itemRegra) => itemRegra.CODIGO === item[0] && itemRegra.REGRA === regra[j].REGRA
            )[0];
          }
          if (
            itemEncontrado != undefined &&
            itemEncontrado != null &&
            itemEncontrado != ""
          ) {
            itemNaoExisteNaRegra =
              itensUtilizamRegra.length > 0
                ? itensUtilizamRegra.filter(
                  (itemUtilizaRegra) => itemUtilizaRegra[0] === item[0]
                )[0]
                : true;
            if (itemNaoExisteNaRegra) {
              $("#tabelaItensUtilizamRegra")
                .DataTable()
                .row.add([
                  itemEncontrado.CODIGO,
                  itemEncontrado.COR,
                  itemEncontrado.OPERACAO,
                  itemEncontrado.REGRA,
                  itemEncontrado.TAM,
                  itemEncontrado.TIPO,
                  itemEncontrado.VALOR,
                  item[2],
                  item[31] != 0
                ])
                .draw(false);
            }
            Quantidade += item[2];
            ValorItens += Number(item[7]);
          } else {
            // nao acontece nada feijoada
          }
        });

        // agora vai aplicar a regra nos itens
        if (regra[j].TIPO == "V") {
          if (parametrosVenda[29] == 2) {
            regraP = regra[j].VALOR <= ValorItens ? regra[j] : undefined;
          } else {
            regraP = regra.filter((regras) => regras.VALOR <= ValorItens);
          }
        } else {
          if (parametrosVenda[29] == 2) {
            regraP = regra[j].VALOR <= Quantidade ? regra[j] : undefined;
          } else {
            regraP = regra.filter((regras) => regras.VALOR <= Quantidade);
          }
        }

        switch (regra[j].OPERACAO) {
          case ">":
            if (regra[j].TIPO && ValorItens > regra[j].VALOR) {
              bCalculaRegra = true;
            } else if (Quantidade > regra[j].VALOR) {
              bCalculaRegra = true;
            }
            break;
          case "<":
            if (regra[j].TIPO && ValorItens > regra[j].VALOR) {
              bCalculaRegra = true;
            } else if (Quantidade > regra[j].VALOR) {
              bCalculaRegra = true;
            }
            break;
          case ">=":
            if (regra[j].TIPO && ValorItens > regra[j].VALOR) {
              bCalculaRegra = true;
            } else if (Quantidade > regra[j].VALOR) {
              bCalculaRegra = true;
            }
            break;
          case "<=":
            if (regra[j].TIPO && ValorItens > regra[j].VALOR) {
              bCalculaRegra = true;
            } else if (Quantidade > regra[j].VALOR) {
              bCalculaRegra = true;
            }
            break;
          case "=":
            if (regra[j].TIPO && ValorItens > regra[j].VALOR) {
              bCalculaRegra = true;
            } else if (Quantidade > regra[j].VALOR) {
              bCalculaRegra = true;
            }
            break;

          default:
            break;
        }
        itensUtilizamRegra = $("#tabelaItensUtilizamRegra")
          .DataTable()
          .rows()
          .data();

        itensUtilizamRegra.each((item, i) => {
          percDesconto = regraP.DESCONTO;

          // pega % desconto
          item[5] = ArredondarValor(percDesconto, 2);
          valorDesconto = ArredondarValor(item[3] * (percDesconto / 100), 2);
          // pega valor Desconto
          item[6] = valorDesconto * item[2];
          // ajusta o preco do item
          item[4] = ArredondarValor(item[3] - valorDesconto, 2);
          // ajusta valor total dos itens
          item[7] = ArredondarValor(item[4] * item[2], 2);
          item[20] = valorDesconto;
          item[21] = item[3];
          item[22] = percDesconto;

          $(idTabela).DataTable().row(i).data(item);
        });
      }
    }
  } catch (error) {
    console.error(error);
  }
}

async function BuscaTiposVenda(id) {
  try {
    const url = "/sisplan/funcoes/v1/pesquisa?";
    let params;
    if (id != "") {
      params = `JSON={ "tabela":"VENDA_TIPO", "camposSelect":["ID", "DESCRICAO", "FECHA_VENDA", "ESTOQUE", "EXCLUSAO_ITEM", "CONSIGNADO", "MOEDA", "TABELA", "VENDA_PENDENTE", "TIPO_DOC_FISCAL"], "where": ["id = ${id}"], "orderby": ["ID"]}`;
    } else {
      params = `JSON={ "tabela":"VENDA_TIPO", "camposSelect":["ID", "DESCRICAO", "FECHA_VENDA", "ESTOQUE", "EXCLUSAO_ITEM", "CONSIGNADO", "MOEDA", "TABELA", "VENDA_PENDENTE", "TIPO_DOC_FISCAL"], "where": null, "orderby": ["ID"]}`;
    }
    const response = await requisicao("GET", url, params);

    if (!response) {
      return;
    }

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

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

async function criaSelectTiposVenda() {
  try {
    let tipoVendaPadrao = '';
    try {
      tipoVendaPadrao = parametrosVenda[71] != undefined ? parametrosVenda[71].substring(1, parametrosVenda[71].indexOf("]")) : '';
    } catch (error) {
      console.error(error)
    }
    const tipos = await BuscaTiposVenda("");
    $("#vendaMovimentaEstoque").prop("checked", true);

    tipos.forEach((tipo) => {
      $("#txtTipoVenda").append(
        `<option value="${tipo.ID}"> [${tipo.ID}] - ${tipo.DESCRICAO}</option>`
      );
    });

    if (tipoVendaPadrao != '') {
      $('#txtTipoVenda').val(tipoVendaPadrao);
    }
  } catch (error) {
    console.error(error);
  }
}

async function ExisteGuiaVendedor(CodRep) {
  const dadosSelect = {
    Tabela: "rep_guia",
    CamposSelect: ["rep_guia.guia"],
    Where: [`rep_guia.codrep = '${CodRep}'`],
  };

  const response = await retornaJsonPesquisaPadrao(
    encodeURIComponent(JSON.stringify(dadosSelect))
  );

  if (!response) {
    return;
  }
  const jsonStr = response;
  if (parseInt(jsonStr.length) <= 0) {
    return false;
  }
  return true;
}

async function validaCondPagto(codCond) {
  if (codCond.trim() == "") {
    return;
  }

  const url = `/sisplan/funcoes/v1/pesquisa?`;
  let validaCond = Boolean;
  try {
    const response = await requisicao(
      "GET",
      url,
      `JSON={ "tabela":"cond_item", "camposSelect":[ "parcela", "prazo"], "where": ["codcond = ${codCond}"] }`,
      null
    );

    if (!response) {
      return;
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
      return false;
    }

    validaCond = jsonStr.RESULT[0].length > 0;

    if (!validaCond) {
      msgAlerta(
        `Prazos não configurados, favor verificar a condição de pagamento. \r\n Código da Condição: ${codCond}`
      );
      $("#btn-limpa-moeda").trigger("click");
    }

    return validaCond;
  } catch (error) {
    return false;
  }
}

async function validaCondicaoMoeda(codMoeda, codCond) {

  if (codCond == "" || codMoeda == "") {
    msgAlerta("Necessário informar uma moeda e uma condição de pagamento!");
    return;
  }

  const url = `/sisplan/funcoes/v1/pesquisa?`;
  try {
    const response = await requisicao("GET", url, `JSON={ "tabela":"COND_MOEDA", "camposSelect":["CODCOND"], "where": ["MOEDA = ${codMoeda}"] }`, null);

    if (!response) {
      return;
    }

    const jsonStr = await response.json();

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

    const itemEncontrado = jsonStr.RESULT[0].filter((item) => item.CODCOND == codCond);

    if (itemEncontrado.length == 0) {
      msgAlerta("Condição não cadastrada na moeda selecionada!");
      return false;
    }
    return true;


  } catch (error) {
    return false;
  }
}

async function imprimirCupomTrocaSemECF(NumeroVenda, tabela, bImpressaoVenda = false) {
  let dadosBackEnd = {};
  let arrayDados = [];
  let cupomUnico = '';


  if (bImpressaoVenda) {
    for (let i = 0; i < tabela.length; i++) {
      if (tabela[i][17] == true) {
        dadosBackEnd = {
          SEL: $(`#cb_itens_troca_${i}`).prop('checked') ? 'S' : 'N',
          VENDA: NumeroVenda,
          ORDEM: +i,
          CODIGO: tabela[i][0],
          DESCRICAO: tabela[i][1],
          COR: tabela[i][10],
          DESC_COR: tabela[i][12],
          TAM: tabela[i][1],
          QTDE: tabela[i][2],
          CUPOMUNICO: true
        };
        arrayDados.push(dadosBackEnd);
      }
    }
  } else {
    for (let i = 0; i < tabela.length; i++) {
      if ($(`#cb_itens_troca_${i}`).prop("checked") == true) {
        dadosBackEnd = {
          SEL: $(`#cb_itens_troca_${i}`).prop('checked') ? 'S' : 'N',
          VENDA: pegaChave("#venda-cupom-troca"),
          ORDEM: +tabela[i][1],
          CODIGO: tabela[i][2],
          DESCRICAO: tabela[i][3],
          COR: tabela[i][4],
          DESC_COR: tabela[i][5],
          TAM: tabela[i][6],
          QTDE: tabela[i][7],
          CUPOMUNICO: $('#inputCupomUnico').prop('checked'),
          DATA_CRIACAO: tabela[i][10],
          DATA_ULTIMA_GRAVACAO: tabela[i][11],
          HORA_ULTIMA_GRAVACAO: tabela[i][44],
          CODCLI: tabela[i][12],
          NOME_CLIENTE: tabela[i][13],
          CNPJ: tabela[i][14],
          NRCAIXA: tabela[i][15],
          DESC_CAIXA: tabela[i][16],
          TABELA: tabela[i][17],
          DESC_TABELA: tabela[i][18],
          PRAZO: tabela[i][19],
          CODREP: tabela[i][20],
          NOME_REPRESENTANTE: tabela[i][21],
          OBSERVACAO: tabela[i][22],
          CODREP_ITENS: tabela[i][23],
          NOME_REPRESENTANTE_ITENS: tabela[i][24],
          TABELA_ITENS: tabela[i][25],
          DESC_TABELA_ITENS: tabela[i][26],
          DEPOSITO: tabela[i][27],
          DESC_DEPOSITO: tabela[i][28],
          DATA_INCLUSAO: tabela[i][29],
          QUALIDADE: tabela[i][31],
          BARRA: tabela[i][32],
          LOTE: tabela[i][33],
          PRECO_LIQ: tabela[i][34],
          OBS: tabela[i][35],
          VALOR: tabela[i][36],
          DESC_ITEM: tabela[i][37],
          VALOR_DESC: tabela[i][38],
          CASHBACK_VAL: tabela[i][39],
          TOTAL: tabela[i][40],
          TOTAL_LIQ: tabela[i][41],
          UNIDADE: tabela[i][30]

        };
        arrayDados.push(dadosBackEnd);
      }
    }
  }

  if (arrayDados.length != 0) {
    const url = `/sisplan/cupom/v1/imprimircupomtroca?`;
    const params = `JSON=${encodeURIComponent(JSON.stringify(arrayDados))}&VENDACUPOM=${NumeroVenda}`;
    const bImprimeAutomatico = await verificaImprimirAutomatico('ImprimirCupom');
    const arquivo = await GeraRelatorio(`${url}${params}&`, 'GET', 120000, false, "ImprimirCupom");
    if (arquivo != undefined) {
      if (!bImprimeAutomatico) {
        window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
      }
      await limparRelatorios();
    }
  }
}

function mantemDuasCasasDecimais(valor, quantidadeCaracteres) {
  if (valor.toString().indexOf('.') > -1) {
    return parseFloat(valor.toString().substring(0, valor.toString().indexOf('.') + quantidadeCaracteres));
  }
  return valor;
}

async function validaRegrasMontadasVenda(bCliente) {
  try {

    if (bCliente) {
      await executaRegraCliente();
    }

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

async function verificaRegrasMontadas(bCliente = true) {

  async function verificaSeExisteRegraParaOtipoDaVenda() {
    try {
      const tipoVenda = $('#txtTipoVenda').val();
      const json = await retornaJsonPesquisaPadrao(`{"tabela": "REGRA_VENDA", "camposSelect": ["VENDA_TIPO"], "where": ["VENDA_TIPO = '${tipoVenda}'"] }`);


      if (json) {
        return true;
      }

      return false;

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

  try {
    const regras = await verificaSeExisteRegraParaOtipoDaVenda();

    if (regras) {

      await validaRegrasMontadasVenda(bCliente);

    }

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

async function executaRegraCliente() {
  try {
    const sCodcli = pegaChave('#txtCliente');
    const tipoVenda = $('#txtTipoVenda').val();
    const url = '/sisplan/regrasmontadasvenda/v1/regrasmontadasvenda?';
    const parametros = window.location.href.split('/');
    const numero_venda = parametros[parametros.length - 1];
    const params = `CODCLI=${sCodcli}&TIPOVENDA=${tipoVenda}&CODVEN=${numero_venda}`;
    const response = await requisicao("GET", url, params, null);

    if (!response) {
      return;
    }

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

    const jsonStr = await response.json();

    if (jsonStr.tipo_msg == 'S') {
      senhaSupervisor(jsonStr.mensagem,
        () => { }, '', false,
        () => { $('#txtCliente').val(''); },
        () => { $('#txtCliente').val(''); },
        () => { $('#txtCliente').val(''); });
      return;
    }

    if (jsonStr.tipo_msg == 'B') {
      msgErro(jsonStr.mensagem);
      $('#txtCliente').val('');
      return;
    }

    if (jsonStr.tipo_msg == 'A') {
      msgAlerta(jsonStr.mensagem);
      return;
    }

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

async function estornaReceberErroCupom(venda) {
  try {
    const url = '/sisplan/vendas/v1/estornarecebererrocupom?';
    const response = await requisicao('POST', url, `CODVENDA=${venda.codVenda}`, `JSON=${encodeURIComponent(JSON.stringify(venda))}`, 30000);
    if ((!response) || (response.status != 200)) {
      return;
    }

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

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

async function permiteVenda(grupo) {
  try {
    const pesquisaParam = {
      tabela: 'GRUPO_MA',
      camposSelect: ['GRUPO_MA.PERMITEVENDA'],
      where: [`GRUPO_MA.CODIGO = '${grupo}'`]
    };

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

    if (jsonStr[0].PERMITEVENDA == 'S') {
      return true;
    } else {
      return false;
    }

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

function adicionaLogVenda(tela, chave, descricao, operacao) {
  const objetoLog = {
    tela,
    chave,
    descricao,
    operacao,
  };

  listaLogsVenda.push(objetoLog);
}

async function gravaLogsVenda(codven) {
  if (listaLogsVenda.length > 0) {
    listaLogsVenda.forEach(async (log) => {
      await rotinaGeraLog(log.tela, codven, log.descricao, log.operacao);
    });
  }

  listaLogsVenda = [];
}

async function buscaVendedorCliente(codCli) {
  try {
    if (($('#txtVendedor').val() != '') || (codCli == '')) {
      return;
    }
    const pesquisaParam = {
      tabela: 'ENTIDADE',
      camposSelect: ['ENTIDADE.CODREP, REPRESEN.NOME'],
      leftJoin: [{ "tabela": "represen", "condicao": "represen.codrep = entidade.codrep" }],
      innerJoin: [{ "tabela": "EMP_VALOR", "condicao": `ENTIDADE.CODREP = EMP_VALOR.VALOR AND EMP_VALOR.TABELA = 'REPRESEN' AND EMP_VALOR.EMP_ID = ${getCookie("emp_id")}` }],
      where: [`ENTIDADE.CODCLI = '${codCli}'`]
    };

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

    if (jsonStr.length <= 0) {
      return;
    }

    if (jsonStr[0].CODREP != '') {
      insereValor('#txtVendedor', jsonStr[0].CODREP, jsonStr[0].NOME);
      $('#txtVendedor').trigger('blur');
    }
    return;
  } catch (error) {
    console.log(error);
  }
}

async function buscaGuiaCliente(codCli, utilizaGuia) {
  try {
    if (($('#txtGuia').val() != '') || (codCli == '') || !["3", "4"].includes(utilizaGuia)) {
      return;
    }

    const url = '/sisplan/vendas/v1/retornaguiacli_com?';
    const filtros = `CODCLI=${codCli}`;
    const response = await requisicao('GET', url, filtros);

    const jsonStrCliCom = await response.json();

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

    if (jsonStrCliCom[0]?.CODREP) {
      insereValor('#txtGuia', jsonStrCliCom[0]?.CODREP, jsonStrCliCom[0]?.NOME);
      $('#txtGuia').trigger('blur');
      return;
    }

    const pesquisaParam = {
      tabela: 'ENTIDADE',
      camposSelect: ['ENTIDADE.CODREP, REPRESEN.NOME'],
      leftJoin: [{ "tabela": "represen", "condicao": "represen.codrep = entidade.codrep" }],
      where: [`ENTIDADE.CODCLI = '${codCli}'`]
    };

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

    if (jsonStr[0].CODREP != '') {
      insereValor('#txtGuia', jsonStr[0].CODREP, jsonStr[0].NOME);
      $('#txtGuia').trigger('blur');
    }
    return;
  } catch (error) {
    console.log(error);
  }
}

async function validaVendaPendente(sCodCli, sNome) {
  try {
    if ((sCodCli != '') && ($('#txt_venda_atual>span').html() == 'Nova')) {
      if (pegaChave('#txtVendedor') != '') {
        const pesquisaParamAtendPendente = {
          tabela: 'VENDA',
          camposSelect: ['VENDA.CODVEN'],
          leftJoin: [{
            tabela: 'VENDA_TIPO',
            condicao: `VENDA.TIPO_VENDA = VENDA_TIPO.ID`
          }],
          where: [`VENDA.CODREP = '${pegaChave('#txtVendedor')}'
            AND VENDA.EMP_ID = ${getCookie('emp_id')}                 
            AND VENDA.CANCELADA = 0 
            AND VENDA.FECHADA = 0 
            AND VENDA.TROCA = 0 
            AND VENDA.DEVOLUCAO = 0 
            AND VENDA.ORCAMENTO = 0
            AND VENDA.ATEND_FINALIZADO is null`]
        };

        const jsonStrAtendPendente = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParamAtendPendente));

        if (jsonStrAtendPendente[0] != undefined) {
          const vendas = [];
          jsonStrAtendPendente.forEach(item => {
            vendas.push(item.CODVEN);
          });

          const callbackCancelarAtendPendente = () => {
            $('#btnVenda').attr('disabled', false);
            $('#btnPagamento').attr('disabled', false);
            $('#btnFinalizar').attr('disabled', false);
            const estaEmOutraAba = $('#fieldset_info').css('display') == 'none';
            if (estaEmOutraAba) {
              $('#btnInfo').trigger('click');
            }
            $('#txtCliente').focus();
          };

          msgAlerta(`Necessário finalizar o atendimento dos consignados (${vendas.join(', ')}), impossível continuar.`, () => {
            const estaEmOutraAba = $('#fieldset_info').css('display') == 'none';
            $('#btnVenda').attr('disabled', false);
            $('#btnPagamento').attr('disabled', false);
            $('#btnFinalizar').attr('disabled', false);
            if (estaEmOutraAba) {
              $('#btnInfo').trigger('click');
            }
            $('#textDescricaoVenda').focus();
            setTimeout(() => {
              $('#txtCliente').focus();
            }, 2000);
          }, callbackCancelarAtendPendente, undefined, callbackCancelarAtendPendente);
          return true;
        }
      }

      const pesquisaParam = {
        tabela: 'VENDA',
        camposSelect: ['VENDA.CODVEN'],
        leftJoin: [{
          tabela: 'VENDA_TIPO',
          condicao: `VENDA.TIPO_VENDA = VENDA_TIPO.ID`
        }],
        where: [`VENDA.CODCLI = '${sCodCli}'
          AND VENDA.EMP_ID = ${getCookie('emp_id')}                 
          AND VENDA.CANCELADA = 0 
          AND VENDA.FECHADA = 0 
          AND VENDA.TROCA = 0 
          AND VENDA.DEVOLUCAO = 0 
          AND VENDA.ORCAMENTO = 0
          AND VENDA_TIPO.CONSIGNADO = 'S'`]
      };

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

      if (jsonStr[0] == undefined) {
        return false;
      }

      if (jsonStr[0].CODVEN != '') {
        localStorage.setItem('@venda.cliente', sCodCli);
        localStorage.setItem('@venda.cliente_nome', sNome);
        localStorage.setItem('@venda.caixa', sessionStorage.getItem("g_caixa_logado"));
        $('#btnVenda').attr('disabled', true);
        $('#btnPagamento').attr('disabled', true);
        $('#btnFinalizar').attr('disabled', true);

        const callbackCancelar = () => {
          $('#btnVenda').attr('disabled', false);
          $('#btnPagamento').attr('disabled', false);
          $('#btnFinalizar').attr('disabled', false);
          const estaEmOutraAba = $('#fieldset_info').css('display') == 'none';
          if (estaEmOutraAba) {
            $('#btnInfo').trigger('click');
          }
          $('#txtCliente').focus();
        };

        msgAlerta(`Cliente já possui consignado pendente número ${jsonStr[0].CODVEN}, impossível continuar.`, () => {
          const estaEmOutraAba = $('#fieldset_info').css('display') == 'none';
          $('#btnVenda').attr('disabled', false);
          $('#btnPagamento').attr('disabled', false);
          $('#btnFinalizar').attr('disabled', false);
          if (estaEmOutraAba) {
            $('#btnInfo').trigger('click');
          }
          $('#textDescricaoVenda').focus();
          setTimeout(() => {
            $('#txtCliente').focus();
          }, 2000);
          window.open(`${BASE_URI}/agrupamento_venda`, "_blank");
        }, callbackCancelar, undefined, callbackCancelar);
        $('#btn-msg-alerta').html('Abrir Agrupamento (ALT + S)');
        return true;
      }
      return false;
    }
  } catch (error) {
    console.log(error);
  }
}

async function verificaMoedasTipoVenda(id) {
  try {
    let moedas = [];
    let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"VENDA_TIPO", "camposSelect":["MOEDA"], "where": ["ID = '${id}'"]}`, null);

    if (!response) {
      return [];
    }

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

    let moedas2 = jsonStr.RESULT[0][0].MOEDA.split(',');
    if (!moedas2[0]) {
      return moedas
    }
    moedas = moedas2.map(moeda => parseInt(moeda.replace(/'/g, ''), 10));

    return moedas;

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

async function buscaLocal(codigo) {
  try {
    let response = await requisicao('GET',
      '/Sisplan/Funcoes/V1/pesquisa?',
      `JSON={ 
                                      "tabela":"PRODUTO", 
                                      "camposSelect":["PRODUTO.LOCAL", "CAD_LOC_ESTOQ.DESCRICAO"], 
                                      "leftjoin": [{ "tabela" : "CAD_LOC_ESTOQ", "condicao" : "CAD_LOC_ESTOQ.CODIGO = PRODUTO.LOCAL" }],
                                      "where": ["PRODUTO.CODIGO = '${codigo}'"]
                                    }`, 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].LOCAL != '' ? '[' + jsonStr.RESULT[0][0].LOCAL + '] - ' + jsonStr.RESULT[0][0].DESCRICAO : '';
    } else {
      return ''
    }
  } catch (error) {
    console.log(error);
  }
}

async function validaVendaGerouDeConsignado(codVen) {
  try {

    if ((codVen == 'create') || (codVen == 'create#') || (codVen == 'vendapendente') || (codVen == 'vendapendente#')) {
      return false;
    }

    const pesquisa = {
      tabela: 'VENDAOBS',
      camposSelect: ["OBSERVACAO"],
      where: [`CODVEN = ${codVen}`, `EMP_ID = ${getCookie("emp_id")}`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisa));
    const observacao = jsonStr[0].OBSERVACAO.toUpperCase();

    if (observacao.indexOf("CONSIGNADO") >= 0) {
      return true;
    }

    return false;

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

async function verificaLimiteCredito(bConsignado = false, bConsigPendente = false) {
  try {
    try {
      $.LoadingOverlay('show');
      const tipoMoeda = pegaChave('#txtTipoMoeda');
      const creditoCliente = bConsignado ? Number($('#txtLimiteCreditoConsignado').val()) : Number($('#txtLimiteCreditoCli').val());
      const emAbertoCliente = bConsignado ? Number($('#txtConsignadoEmAberto').val()) : Number($('#txtVendaEmAberto').val());

      if (bConsigPendente) {
        const total = $('#tabelaItens').DataTable().column(7, {}).data().sum();
        if (total > creditoCliente) {
          msgAlerta(`Crédito do cliente excedido, crédito do cliente: ${creditoCliente + emAbertoCliente}, valor em duplicatas: ${emAbertoCliente}, saldo de crédito: ${creditoCliente}, valor a ser utilizado: ${(total).toFixed(2)}`);
          return false;
        }
        return true;
      } else {
        if (tipoMoeda == '1' || tipoMoeda == '2') {
          const dadosPagamento = $('#tabelaCondicoesDePagamento').DataTable().rows().data().toArray();
          const dadosPagamentoFiltrados = dadosPagamento.filter((pagto) => pagto[17] == '1' || pagto[17] == '2');
          let valorJaLancado = 0;
          if (dadosPagamentoFiltrados.length > 0) {
            for (let i = 0; i < dadosPagamentoFiltrados.length; i++) {
              const pagto = dadosPagamentoFiltrados[i];
              valorJaLancado += pagto[3];
            }
          }

          const valorMoeda = parseFloat($('#txtValorLiquidoMoeda').val());

          if ((valorJaLancado + valorMoeda) > creditoCliente) {
            msgAlerta(`Crédito do cliente excedido, crédito do cliente: ${creditoCliente + emAbertoCliente}, valor em duplicatas: ${emAbertoCliente}, saldo de crédito: ${creditoCliente}, valor a ser utilizado: ${(valorJaLancado + valorMoeda).toFixed(2)}`);
            return false;
          }
          return true;
        }
        return true;
      }
    } catch (error) {
      msgErro('Erro ao validar limite de crédito cliente');
      console.error(error);
      return false;
    }
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function eventoClickPesquisaDescontoConfirmar(id, solicitaSenha = true) {
  const descontoMaximoUsuario = await retornaDescontoMaximoUsuario();
  const tabelaVisivel = !$('#divVendaProdutoDesc').hasClass('d-none');

  if (tabelaVisivel) {
    const tabelaDesc = $('#txtTabelaDesc').val();
    if (tabelaDesc == '') {
      msgErro("Necessário informar uma tabela de preço para continuar.");
      return;
    }

  }

  if (parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.')) <= 0) {
    msgErro("Preço deve ser maior que 0, verifique.");
    return;
  }
  if (parseFloat($("#txtPercDesconto").val().replaceAll('.', '').replace(',', '.')) > 99) {
    msgErro("Perc. de desconto deve ser menor que 99, verifique.");
    return;
  }

  const percDesconto = $("#txtPercDesconto").val().replaceAll('.', '').replace(',', '.');
  const valorDesconto = $("#txtValorDesconto").val().replaceAll('.', '').replace(',', '.');

  async function AplicaDescontoItem() {
    const arrDados = $("#tabelaItens").DataTable().row(id).data();
    arrDados[3] =
      arrDados[3] > parseFloat($("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.'))
        ? arrDados[3]
        : $("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.');
    arrDados[4] = $("#txtPrecoDesc").val().replaceAll('.', '').replace(',', '.');
    arrDados[5] = $("#txtPercDesconto").val().replaceAll('.', '').replace(',', '.');
    arrDados[6] = $("#txtValorDesconto").val().replaceAll('.', '').replace(',', '.');
    arrDados[7] = $("#txtTotalLiq").val().replaceAll('.', '').replace(',', '.');
    if (tabelaVisivel) {
      arrDados[34] = pegaChave('#txtTabelaDesc');
    }

    $("#tabelaItens").DataTable().row(id).data(arrDados).draw(false);
    $("#pesquisaDesconto").modal("hide");
    await atualizaTotalVenda();
    $('[data-toggle="tooltip"]').tooltip();
  }

  const nmrVenda = $('#txt_venda_atual>span').html() == 'Nova' ? 'create' : $('#txt_venda_atual>span').html();
  function verificaDescSupervisorEAplica(userSupervisor) {
    verificaDescontoMaximoSupervisor(userSupervisor, AplicaDescontoItem);
  }
  if ((solicitaSenha) && (parseFloat(percDesconto) > parseFloat(descontoMaximoUsuario) && descontoMaximoUsuario > 0)) {
    await senhaSupervisor(
      `Desconto de ${percDesconto}% no item, máximo do usuário é de ${descontoMaximoUsuario}%.`,
      verificaDescSupervisorEAplica,
      () => {
        AplicaDescontoItem();
      },
      true, undefined, undefined, undefined, false,
      'VENDA', nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda, pegaChave('#txtCliente'),
      parseFloat($('#txtPrecoOrig').val().replace(',', '.')) || 0, parseFloat($('#txtTotalLiq').val().replace(',', '.')) || 0, parseFloat($('#txtPercDesconto').val().replace(',', '.')) || 0, parseFloat($('#txtValorDesconto').val().replace(',', '.')) || 0, pegaChave('#txtVendedor')
    );
  } else {
    let bSenhaSupervisor = parametrosVenda[9];
    if (bSenhaSupervisor == "1" && solicitaSenha) {
      await senhaSupervisor(
        `Desconto de R$ ${valorDesconto} aplicado.`,
        AplicaDescontoItem,
        '', false, undefined, undefined, undefined, false,
        'VENDA', nmrVenda == 'create' ? localStorage.getItem(`SEQUENCIALVENDAPENDENTE`) : nmrVenda, pegaChave('#txtCliente'),
        parseFloat($('#txtPrecoOrig').val().replace(',', '.')) || 0, parseFloat($('#txtTotalLiq').val().replace(',', '.')) || 0, parseFloat($('#txtPercDesconto').val().replace(',', '.')) || 0, parseFloat($('#txtValorDesconto').val().replace(',', '.')) || 0, pegaChave('#txtVendedor')
      );
    } else {
      await AplicaDescontoItem();
    }
  }
}

async function validaParamVenda58() {
  if (parametrosVenda[58] != '4') {
    return;
  }
  let table = $("#tabelaItens").DataTable();
  const totalVenda = parseFloat(($("#txtTotalVenda").html().replaceAll('.', '')).replace(',', '.'));
  const valorAntecipacao = parseFloat($('#txtValorParcela').val());
  const percDesconto = totalVenda == valorAntecipacao ? 100 : parseFloat((valorAntecipacao / totalVenda) * 100);
  let preco = 0;
  let TotalDesconto = 0;

  for (let i = 0; i < table.data().length; i++) {
    arrayData = table.row(i).data();
    let valorOriginal = arrayData[3];
    let desconto = 0;
    let valorDesconto = 0;
    if (percDesconto == 100) {
      desconto = 0.01;
      preco = desconto;
      valorDesconto = (valorOriginal - desconto) * arrayData[2];
      TotalDesconto += desconto * arrayData[2];
      if (i == (table.data().length - 1)) {
        $('#txtValorParcela').val(TotalDesconto);
        $('#txtValorLiquidoMoeda').val(TotalDesconto);
      }
    } else {
      valorDesconto = parseFloat(((valorOriginal * percDesconto) / 100).toFixed(2));
      desconto = valorDesconto;
      valorDesconto *= arrayData[2];
      preco = parseFloat((valorOriginal - desconto).toFixed(2));
      TotalDesconto += parseFloat((desconto * arrayData[2]).toFixed(2));
      if (i == (table.data().length - 1)) {
        const diferenca = parseFloat((valorAntecipacao - TotalDesconto).toFixed(2));
        if (diferenca != 0) {
          desconto += (diferenca / arrayData[2]);
          valorDesconto += diferenca;
          preco = parseFloat((valorOriginal - desconto));
        }
        $('#txtValorParcela').val(0);
        $('#txtValorLiquidoMoeda').val(0);
      }
    }
    const total = parseFloat((preco * arrayData[2]).toFixed(2)); //[2] = quantidade
    arrayData[4] = parseFloat((arrayData[3] - desconto).toFixed(2)); //[4]preco_Liq
    arrayData[5] = total;
    arrayData[6] = valorDesconto; //[6]valor_Desc
    arrayData[7] = total; //[7]total_liq
    $("#tabelaItens").DataTable().row(i).data(arrayData).draw(false);
  }
  await atualizaTotalVenda();
  if (percDesconto == 100) {
    atualizaSaldoAPagar();
  }
  atualizaTotaisPagto();
}

async function cancelaVendaPelaOperadoraTEF() {
  $.LoadingOverlay("show");
  try {
    const obs = "Venda cancelada a partir da operadora TEF.";
    const codVen = $("#txtCodVen").val();

    if (codVen != "") {
      if (!await validaCancelamento(obs, codVen, "")) {
        return;
      }

      const response = await requisicao('POST', '/Sisplan/Vendas/V1/Cancelar?',
        `OBS=${obs}&CODVEN=${codVen}&CONSIG_FINALIZADO=N&MOV_ESTOQUE=S`, '', 90000);

      if (!response) {
        msgAlerta("Não foi possível cancelar a venda.");
        return;
      }

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

      await rotinaGeraLog('VENDA', codVen, 'CANCELAMENTO DA VENDA FOI CONFIRMADO PELO USUÁRIO E EFETUADO PELO CANCELAMENTO DA OPERADORA TEF.', 'Alteração');

      criaMensagemSucesso("Cancelamento efetuado com sucesso!", () => { window.location.reload(); });

    }

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

function defineItensAplicarRegra(regra, qtdeFora) {
  const tabelaItensUtilizamRegra = $("#tabelaItensUtilizamRegra").DataTable().data().toArray().sort(function (a, b) {
    return b[7] - a[7];
  });

  let lista = [];
  let listaRemover = [];
  let listaAux = [];
  let qtde = 0;

  tabelaItensUtilizamRegra.forEach(item => {
    // if (!item[8]) { necessário comentar pois quando havia uma regra por quantidade = 3 e outra = 4, aplicava na 3 quando tinha 3 itens, porém quando bipava o 4 item não entrava nessa rotina, com isso aplicava a regra apenas no ultimo item bipado
    qtde = qtdeFora;
    if (qtde == regra.VALOR) {
      lista.push(item);
    } else if (qtde < regra.VALOR) {
      listaAux.push(item);
    }
    // }
  })

  qtde = 0;
  for (let i = 0; i < listaAux.length; i++) {
    qtde += listaAux[i][7];
    if (qtde == regra.VALOR) {
      let contador = i;
      qtde = 0;
      while (contador > -1) {
        lista.push(listaAux[contador]);
        contador--;
      }
    }
  }

  $('#tabelaItensUtilizamRegra').DataTable().data().toArray().map((item, i) => {
    if (!lista.includes(item)) {
      listaRemover.push(i);
    }
  })

  $('#tabelaItensUtilizamRegra').DataTable().rows(listaRemover).remove().draw();

}

async function buscaAgendamentoGuia(senha) {
  $.LoadingOverlay("show");
  try {
    const url = '/sisplan/vendas/v1/agendamentoguia?';
    const filtros = `SENHA=${senha}`;
    const response = await requisicao('GET', url, filtros);

    if (!response) {
      return;
    }

    const jsonStr = await response.json();

    if (response.status != 200) {
      msgErro(jsonStr.mensagem)
      return;
    }
    insereValor('#txtVendedor', jsonStr[0]?.AGENCIA, jsonStr[0]?.NOME_AGENCIA);
    insereValor('#txtGuia', jsonStr[0]?.GUIA, jsonStr[0]?.NOME_GUIA);
  } catch (error) {
    console.error(error);
    msgErro(`Não foi possível buscar os dados do agendamento: ${error}`);
  } finally {
    $.LoadingOverlay("hide");
  }
}

function adicionaObservacaoTabelaItens(index, observacao) {
  const registro = $("#tabelaItens").DataTable().row(index).data();
  registro[32] = observacao;
}

async function verificaSetoresUsuarioLogado(codUsuario) {
  try {
    let response = await requisicao('GET', '/Sisplan/Funcoes/V1/pesquisa?', `JSON={ "tabela":"ACESSO_USUARIOS", "camposSelect":["CODIGO", "SETORES"], "where": ["CODIGO = '${codUsuario}'"]}`, 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)
  }
}

function buscaItensSemDescontoPromocao() {
  const table = $('#tabelaItens').DataTable();
  const linhas = table.rows().nodes().toArray();
  const linhasSemPromocao = linhas.filter(row => {
    return !$(row).hasClass('linha-promocao') && !$(row).find('.textDesconto').length;
  });
  const itensSemDescontoPromocao = linhasSemPromocao.map(row => table.row(row).data());
  let valorTotal = 0;
  itensSemDescontoPromocao.forEach((item) => {
    const soma = +(item[3] * item[2]).toFixed(4);
    valorTotal += parseFloat(parseFloat(soma).toFixed(2));
  })

  return valorTotal;
}

async function validaBarraDuplicada(barra, deposito) {
  $.LoadingOverlay("show");
  try {
    const url = '/sisplan/vendas/v1/validabarraduplicada?';
    const filtros = `BARRA=${barra}&DEPOSITO=${deposito}`;
    const response = await requisicao('GET', url, filtros);

    if (!response) {
      return false;
    }

    const jsonStr = await response.json();

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

    return jsonStr != 0;
  } catch (error) {
    console.error(error);
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function gravaBrinde() {
  $.LoadingOverlay('show');
  $('#btnGravarBrinde').prop('disabled', true);
  try {
    if (validaGravaBrinde()) {
      return false;
    }

    const url = `/sisplan/vendas/v1/brinde?`;

    const params = `CODVEN=${pegaChave('#txtVendaBrinde')}&CODCLI=${pegaChave('#txtClienteBrinde')}&CODREP=${pegaChave('#txtVendendorBrinde')}&COD_USUARIO=${getCookie('cod_usuario')}&OBS=${$('#txtObservacaoBrinde').val()}`;
    const dados = {
      itens: retornaDadosBrinde()
    };
    const response = await requisicao('POST', url, params, `JSON=${encodeURIComponent(JSON.stringify(dados))}`, 30000);

    if (!response) {
      return false;
    }

    const jsonStr = await response.text();

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

    await criaMensagemSucesso(`Brinde ${jsonStr} cadastrado com sucesso!`, async () => {
      await imprimirBrindeIndividual(jsonStr);
      $('#modal-brinde').modal('hide');
      limpaCamposBrinde();
    });
    numeroBrinde = jsonStr;
    return true;
  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay('hide');
    $('#btnGravarBrinde').prop('disabled', false);
  }
}

function retornaDadosBrinde() {
  const dados = $('#tabelaItensBrinde').DataTable().data().toArray();

  const novoObj = dados.map((item) => {
    return {
      BARRA_LOG: item.BARRA_LOG,
      EMP_ID: item.EMP_ID,
      ID_COR: item.ID_COR,
      ID_DEPOSITO: item.ID_DEPOSITO,
      ID_PRO: item.ID_PRO,
      TABELA: item.TABELA,
      TAM: item.TAM,
      PRECO: item.PRECO,
      QTDE: item.QTDE,
      CODIGO: item.CODIGO,
      COR: item.COR,
      TAM: item.TAM,
      DEPOSITO: item.DEPOSITO,
      QUALIDADE: item.QUALIDADE,
      LOTE: item.LOTE,
      ID_ESTOQUE: item.ID_ESTOQUE,
      TIPO: item.TIPO
    }
  });

  return novoObj;
}

async function montaGridInformacoesBrinde() {
  if ($.fn.DataTable.isDataTable('#tabelaAcessoBrindeInformacoesBrinde')) {
    $('#tabelaAcessoBrindeInformacoesBrinde').DataTable().destroy();
    $('#tabelaAcessoBrindeInformacoesBrinde').empty();
  }

  const titulos = [
    { title: "Código", data: "CODIGO" },
    { title: "Descrição", data: "DESCRICAO" },
    { title: "Desc. Cor", data: "DESC_COR" },
    { title: "Quantidade", data: "QTDE" },
    { title: "Preço", data: "PRECO" },
    { title: "Total", data: "TOTAL" },
  ];

  const indexSelecionado = $('#tabelaAcessoBrinde .selected').index();
  if (indexSelecionado != -1) {
    const nrBrinde = $('#tabelaAcessoBrinde').DataTable().rows(indexSelecionado).data().toArray()[0].BRINDE;
    const pesquisa = {
      camposSelect: ['ITVENDA_BRINDE.CODVEN VENDA', 'SUM(ITVENDA_BRINDE.QTDE) QTDE', 'SUM(ITVENDA_BRINDE.PRECO) PRECO', 'SUM(COALESCE(ITVENDA_BRINDE.QTDE * ITVENDA_BRINDE.PRECO, 0)) TOTAL', `CASE WHEN ITVENDA_BRINDE.TIPO = 'P' THEN PRODUTO.CODIGO ELSE MATERIAL.CODIGO END CODIGO`, `CASE WHEN ITVENDA_BRINDE.TIPO = 'P' THEN PRODUTO.DESCRICAO ELSE MATERIAL.DESCRICAO END DESCRICAO`, 'CADCOR.DESCRICAO DESC_COR', 'ITVENDA_BRINDE.TAM', 'SUM(VENDA.VALOR) VALOR_VENDA'],
      tabela: 'ITVENDA_BRINDE',
      leftJoin: [{ tabela: 'PRODUTO', condicao: 'PRODUTO.ID = ITVENDA_BRINDE.ID_ITEM' },
      { tabela: 'MATERIAL', condicao: 'MATERIAL.ID = ITVENDA_BRINDE.ID_ITEM' },
      { tabela: 'CADCOR', condicao: 'CADCOR.ID = ITVENDA_BRINDE.ID_COR' },
      { tabela: 'VENDA', condicao: 'VENDA.CODVEN = ITVENDA_BRINDE.CODVEN and VENDA.EMP_ID = ITVENDA_BRINDE.EMP_ID' }],
      where: [`ITVENDA_BRINDE.DOCTO = '${nrBrinde}'`],
      groupBy: ['ITVENDA_BRINDE.CODVEN', 'ITVENDA_BRINDE.TIPO', 'PRODUTO.CODIGO', 'MATERIAL.CODIGO', 'PRODUTO.DESCRICAO', 'MATERIAL.DESCRICAO', 'CADCOR.DESCRICAO', 'ITVENDA_BRINDE.TAM']
    };
    try {
      const url = `/sisplan/funcoes/v1/pesquisa?`;
      const response = await requisicao('GET', url, `JSON=${JSON.stringify(pesquisa)}`, null);

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

      const dados = jsonStr.RESULT[0];
      $('#tabelaAcessoBrindeInformacoesBrinde').DataTable({
        bPaginate: false,
        destroy: true,
        search: false,
        filter: false,
        lengthChange: false,
        scrollX: true,
        scrollY: '200px',
        serverside: false,
        order: false,
        autoWidth: true,
        columns: titulos,
        data: dados,
      });

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

}

function limpaCamposBrinde() {
  $('#txtVendaBrinde').val('');
  $('#txtClienteBrinde').val('');
  $('#txtVendendorBrinde').val('');
  if ($.fn.DataTable.isDataTable('#tabelaItensBrinde')) {
    $('#tabelaItensBrinde').DataTable().destroy();
    $('#tabelaItensBrinde').empty();
  }
}


async function buscaBrinde() {
  $.LoadingOverlay('show');
  try {
    if ($("#txtOrdem option").toArray().length > 0) {
      retornaHintRelatorio('btnImprimirBrinde', $("#txtOrdem option").toArray().map(map => { return [map.selected, $(map).attr('nome_prt')] }).filter(filter => filter[0] == true)[0][1])
    }
    const url = `/sisplan/vendas/v1/brinde?`;
    const params = await retornaFiltrosBrinde();
    const response = await requisicao('GET', url, params);

    if (!response) {
      return false;
    }

    const jsonStr = await response.json();

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

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

    const titulos = [
      { title: "Brinde", data: "BRINDE" },
      { title: "Data", data: "DATA" },
      { title: "CodCli", data: "CODCLI" },
      { title: "Cliente", data: "CLIENTE" },
      { title: "Vendedor", data: "VENDEDOR" },
      { title: "Status", data: "STATUS" },
      { title: "Venda", data: "VENDA" },
      { title: "Usuário", data: "USUARIO" },
      { title: "Quantidade", data: "QTDE" },
      { title: "Valor", data: "VALOR" },
      { title: "Fatura", data: "FATURA" },
      { title: "Valor Venda Vinculada", data: "VALOR_VENDA" },
    ];

    $('#tabelaAcessoBrinde').DataTable({
      bPaginate: false,
      destroy: true,
      search: false,
      filter: false,
      info: false,
      lengthChange: false,
      scrollX: true,
      scrollY: '200px',
      serverside: false,
      order: false,
      autoWidth: true,
      columnDefs: [
        {
          targets: [0],
          render: function (data, type, row) {
            return retornaBotaoOpcoesBrinde(data);
          }
        },
        {
          render(data) {
            return parseFloat(data).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            });
          },
          targets: [9, 11],
          "className": 'pr-4 text-right'
        },
        {
          "render": function (data, type, row) {
            var isIE = function () {
              if (/MSIE/i['test'](navigator['userAgent']) == true || /Edge/i['test'](navigator[
                'userAgent']) == true) {
                return true;
              } else {
                return false;
              }
            }
            if (isIE()) {
              x = data.slice(0, 10).split('-');
              return x[2] + "/" + x[1] + "/" + x[0] + data.slice('10');
            } else {
              x = data.slice(0, 10).split('-');
              return x[2] + "/" + x[1] + "/" + x[0] + data.slice('10');
            }
          },
          "targets": [1],
        },
        {
          "targets": [8],
          "className": 'pr-4 text-right'
        }
      ],
      columns: titulos,
      data: jsonStr,
    });

    $('#buttonExcel').removeClass('d-none');
    $('#buttonExcel').prop('title', 'Exportar')
    $('#buttonExcel').on('click', async function () {
      const url = `/sisplan/vendas/v1/brinde?`;
      const filtros = await retornaFiltrosBrinde();
      await exportaCSV(url, filtros, false, null, 'Relatório de Brindes');
    });

    $('#tabelaAcessoBrinde tbody').on('click', 'tr', function () {
      if ($(this).hasClass('selected')) {
        $(this).removeClass('selected');
        $('#titleInfoBrinde').addClass('d-none')
      } else {
        $('#titleInfoBrinde').removeClass('d-none')
        $('#tabelaAcessoBrinde').DataTable().$('tr.selected').removeClass('selected');
        $(this).addClass('selected');
      }
      montaGridInformacoesBrinde();
    });

  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay('hide');
  }
}

function retornaBotaoOpcoesBrinde(data) {
  const retorno = '<div style="text-align:start;"> ' +
    '    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" id="opcoesBrinde" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
    '      ' + data + ' ' +
    '    </button> ' +
    '    <div class="dropdown-menu" style="max-width: 7px;"> ' +
    '    <button class="dropdown-item" type="button" title="Cancelar Brinde" id="btnCancelarBrinde">Cancelar</button>  ' +
    '    <button class="dropdown-item" type="button" title="Imprimir Brinde" id="btnImprimirBrindeIndividual">Imprimir</button>  ' +
    '    <button class="dropdown-item" type="button" title="Gerar NFe" id="btnGerarNFeBrinde">Gerar NFe</button>  ' +
    '</div>';
  '</div>';
  return retorno;
}

async function imprimirBrinde() {
  $.LoadingOverlay('show');
  try {
    const filtros = await retornaFiltrosBrinde();
    const url = `/sisplan/impressao/v1/acessobrinde?`;
    const bImprimeAutomatico = await verificaImprimirAutomatico('AcessoBrinde');
    const ordem = `&TELA_ORDENACAO=AcessoBrinde&ORDEM_ORDENACAO=${$('#txtOrdem').val()}`;
    const arquivo = await GeraRelatorio(`${url}${filtros}${ordem}&`, "GET", 15000, false, 'AcessoBrinde');
    if (arquivo != undefined) {
      if (!bImprimeAutomatico) {
        window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
      }
      await limparRelatorios();
    }
  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function imprimirBrindeIndividual(sNumero) {
  $.LoadingOverlay('show');
  try {
    const filtros = `DOCTO=${sNumero}`;
    const url = `/sisplan/impressao/v1/imprimirbrinde?`;
    const bImprimeAutomatico = await verificaImprimirAutomatico('Brinde');
    const arquivo = await GeraRelatorio(`${url}${filtros}&`, "GET", 15000, false, 'Brinde');
    if (arquivo != undefined) {
      if (!bImprimeAutomatico) {
        window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
      }
      await limparRelatorios();
    }
  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function cancelarBrinde(sNumero, sLancamento) {
  $.LoadingOverlay('show');
  try {
    const url = `/sisplan/vendas/v1/brinde?`;
    const params = `DOCTO=${sNumero}&LANCAMENTO=${sLancamento}`;
    const response = await requisicao('PUT', url, params);

    if (!response) {
      return false;
    }

    const jsonStr = await response.json();

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

    await criaMensagemSucesso(`Brinde ${sNumero} cancelado com sucesso!`);
    await buscaBrinde();
  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function retornaFiltrosBrinde() {
  const codven = pegaChave('#txtAcessoVendaBrinde');
  const codcli = pegaChave('#txtAcessoClienteBrinde');
  const codrep = pegaChave('#txtAcessoVendendorBrinde');
  const docto = pegaChave('#txtAcessoCodigoBrinde');
  const dataDe = $('#txtAcessoDataDeBrinde').val();
  const dataAte = $('#txtAcessoDataAteBrinde').val();
  const ordenacao = await buscaValor('ORDEM_TELA', 'TIPO_ORDENACAO, NOME_ORD_SIST', 'ORDEM', `${$('#txtOrdem').val()}' AND NOME_TELA = 'AcessoBrinde`);


  const params = `CODVEN=${codven}` +
    `&CODCLI=${codcli}` +
    `&CODREP=${codrep}` +
    `&DOCTO=${docto}` +
    `&DATADE=${dataDe}` +
    `&DATAATE=${dataAte}` +
    `&ORDENACAO=${ordenacao.NOME_ORD_SIST}` + `${ordenacao.TIPO_ORDENACAO == 'DESC' ? ':D' : ':A'}`;

  return params
}

async function NFeBrinde() {
  if (validaGravaBrinde()) {
    return;
  }

  $('#txtClienteBrindeNFE').val($('#txtClienteBrinde').val());
  await buscaOperacaoPadraoBrinde();
  $('#modalBrindeNFE').modal('show');
}

async function buscaOperacaoPadraoBrinde() {
  try {
    const valPadrao = await retornaValorCadPadrao('NOTA', 'OPERACAO_BRINDE');
    if (valPadrao) {
      const operacao = `[${valPadrao}] - ${(await buscaValor('OPER_FISCAL', 'DESCRICAO', 'CODIGO', valPadrao)).DESCRICAO}`;
      $('#txtOperacaoBrindeNFE').val(operacao);
    }
  } catch (error) {
    console.log(error);
  }
}

function validaGravaBrinde() {
  if (!$.fn.DataTable.isDataTable('#tabelaItensBrinde')) {
    msgAlerta('Nenhum registro informado, necessário bipar o item de brinde.');
    return true;
  }

  const qtdeRegistros = $('#tabelaItensBrinde').DataTable().rows().count();

  if (qtdeRegistros <= 0) {
    msgAlerta('Nenhum registro informado, necessário bipar o item de brinde.');
    return true;
  }

  if (pegaChave('#txtClienteBrinde') == '') {
    msgAlerta('Necessário informar um cliente.');
    return true;
  }

  if (pegaChave('#txtVendendorBrinde') == '') {
    msgAlerta('Necessário informar um vendedor.')
    return true;
  }

  return false;
}

async function faturaNFeBrinde() {
  $.LoadingOverlay("show");
  try {
    let validacao = true;

    if ($('#txtOperacaoBrindeNFE').val() != '') {
      validacao = $('#txtClienteBrindeNFE').val() != '';
    } else {
      validacao = $('#txtNaturezaBrindeNFE').val() != '' && $('#txtClienteBrindeNFE').val() != '';
    }

    if (validacao || bAcessoBrinde) {
      if (!bAcessoBrinde) {
        if (!await gravaBrinde()) {
          return false;
        }
      }

      let nota = {};
      nota.NATUREZA = $('#txtNaturezaBrindeNFE').val();
      nota.CLIENTE = $('#txtClienteBrindeNFE').val();
      nota.CODVEN = numeroBrinde;
      nota.OPERACAO = $('#txtOperacaoBrindeNFE').val();
      nota.BRINDE = 'S';

      let jsonNota = JSON.stringify(nota);

      parent.abrirEmNovaAbaIFrame('Faturamento Geral', `${BASE_URI}/faturamento/`, btoa(jsonNota))
      $('#modalBrindeNFE').modal('hide');
      $('#modal-brinde').modal('hide');
    } else {
      msgAlerta('Favor preencher os campos para continuar.')
    }
  } catch (error) {
    console.log(error);
  } finally {
    $.LoadingOverlay("hide");
    bAcessoBrinde = false;
  }
}

async function montaTabelaBrindes(regra) {
  try {
    const valores = regra.map(function (obj) { return obj.REGRA }).join(',');
    const params = `REGRA=${valores}`
    const response = await requisicao('GET', '/sisplan/vendas/v1/buscabrinde?', params, undefined, 30000);

    if (!response) {
      return;
    }

    let jsonStr = await response.json();

    let tabelaBrindesPromocao = $('#tabelaBrindesPromocao').DataTable();
    tabelaBrindesPromocao.clear().draw();

    tabelaBrindesPromocao.rows.add(jsonStr).draw();
  } catch (error) {
    console.log(error);
  }
}

async function validaClienteSuframa(codcli) {
  const objPesquisa = {
    tabela: "ENTIDADE",
    camposSelect: ["SUFRAMA"],
    where: [`CODCLI = '${codcli}'`],
  };

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

  if (jsonStr.length == 0) {
    return;
  }

  if (jsonStr[0].SUFRAMA != '') {
    $('#btn-calc-suframa').removeClass('d-none');
  } else {
    $('#btn-calc-suframa').addClass('d-none');
  }
}

async function calculaSuframaVenda() {

  async function retornaDescIcmsSuframa(valCalc, bIcms) {
    if (!bIcms) {
      return 0;
    }

    const objPesquisa = {
      tabela: "UF_EMP",
      camposSelect: ["ALIQUOTA"],
      where: [`CODIGO = 'AM' AND EMP_ID = ${getCookie('emp_id')}`],
    };

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

    if (jsonStr.length == 0) {
      msgAlerta('Alíquota não encontrada para o estado do AM.');
      return;
    }

    const aliqUf = parseFloat(coalesce(jsonStr[0].ALIQUOTA));

    return TruncaDecimaisNova(2, valCalc * (aliqUf / 100));
  };

  async function retornaDescPisCofinsSuframa(valCalc, bPis, bCofins) {
    if (!bPis && !bCofins) {
      return 0;
    }

    const objPesquisa = {
      tabela: "EMPRESA",
      camposSelect: ["EMP_PIS", "EMP_COFINS"],
      where: [`EMP_ID = ${getCookie('emp_id')}`],
    };

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

    if (jsonStr.length == 0) {
      return;
    }

    const aliqPisCofins = parseFloat(bPis ? coalesce(jsonStr[0].EMP_PIS) : 0) + parseFloat(bCofins ? coalesce(jsonStr[0].EMP_COFINS) : 0);

    return TruncaDecimaisNova(2, valCalc * (aliqPisCofins / 100));
  };

  try {
    $.LoadingOverlay('show');

    let bIcms = true;
    let bPis = true;
    let bCofins = true;

    const objPesquisa = {
      tabela: "ENTIDADE",
      camposSelect: ["SUFRAMA_CONF"],
      where: [`CODCLI = '${pegaChave('#txtCliente')}'`],
    };

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

    if (jsonStr.length == 0) {
      return;
    }

    if (jsonStr[0].SUFRAMA_CONF != '') {
      bIcms = jsonStr[0].SUFRAMA_CONF.indexOf('I') != -1;
      bPis = jsonStr[0].SUFRAMA_CONF.indexOf('P') != -1;
      bCofins = jsonStr[0].SUFRAMA_CONF.indexOf('C') != -1;
    }

    const valorTot = parseFloat(coalesce($('#txtValorParcela').val().replace(',', '.')));
    const valDescIcms = await retornaDescIcmsSuframa(valorTot, bIcms);
    const valDescPisCofins = await retornaDescPisCofinsSuframa(valorTot - valDescIcms, bPis, bCofins);
    const valDescTot = valDescIcms + valDescPisCofins;

    $('#txtValorDescontoMoeda').val(valDescTot);
    $('#txtValorDescontoMoeda').trigger('blur');

  } catch {
    $.LoadingOverlay('hide');
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function geraLogDesconto(codven) {
  if (!logDescontoVenda) {
    return;
  }
  $.LoadingOverlay('show')
  try {
    await rotinaGeraLogComBody('VENDA', codven, `Venda ${codven} com ${logDescontoVenda}`, 'Inclusão')
  } catch (error) {
    console.error(error)
    msgAlerta(error.message)
  } finally {
    $.LoadingOverlay('hide')
  }
}


//js do campo contato do modal cadastro de cliente

function desbloqueiaCampos() {
  $('#txtNomeContato').prop('disabled', false);
  $('#txtTelefoneContato').prop('disabled', false);
  $('#txtCelularContato').prop('disabled', false);
  $('#txtCPFCNPJContato').prop('disabled', false);
  $('#zezinho').prop('disabled', false);
  $('#zezinho').prop('readonly', false);
  $('#btnFormataNumero').prop('disabled', false);
  $('#cbMaladireta').prop('disabled', false);
  $('#cbPessoaJuridica').prop('disabled', false);
  $('#cbPessoaFisica').prop('disabled', false);
  $('#btnGravaContato').removeClass('d-none');
  $('#btnCancelarAlteracao').removeClass('d-none');
  $('#btnIncluiContato').addClass('d-none');
  $('#btnExcluirContatoModal').addClass('d-none');
  $('#btnDuplicarContato').addClass('d-none');
  $('#btnAlteraContatoDentroModal').addClass('d-none');
  $('#cbWhatsApp').prop('disabled', false);
  $('#cbEmail').prop('disabled', false);

  $('#selectModificacao2').prop('disabled', false);
  $('#txtObsContatoEntidade').prop('disabled', false);
  $('#txtDoContato').prop('disabled', false);
};

function bloqueiaCampos() {
  $('#txtNomeContato').prop('disabled', true);
  $('#txtTelefoneContato').prop('disabled', true);
  $('#txtCelularContato').prop('disabled', true);
  $('#txtCPFCNPJContato').prop('disabled', true);
  $('#zezinho').prop('disabled', true);
  $('#zezinho').prop('readonly', true);
  $('#btnFormataNumero').prop('disabled', true);
  $('#cbMaladireta').prop('disabled', true);
  $('#cbPessoaJuridica').prop('disabled', true);
  $('#cbPessoaFisica').prop('disabled', true);
  $('#btnGravaContato').addClass('d-none');
  $('#btnCancelarAlteracao').addClass('d-none');
  $('#btnIncluiContato').removeClass('d-none');
  $('#btnExcluirContatoModal').removeClass('d-none');
  $('#btnDuplicarContato').removeClass('d-none');
  $('#btnAlteraContatoDentroModal').removeClass('d-none');
  $('#cbWhatsApp').prop('disabled', true);
  $('#cbEmail').prop('disabled', true);
  $('#txtDoContato').prop('disabled', true);
  $('#txtObsContatoEntidade').prop('disabled', true);
  $('#selectModificacao2').prop('disabled', true);
};

function limpaCampos() {
  $('#txtNomeContato').val('');
  $('#txtTelefoneContato').val('');
  $('#txtCelularContato').val('');
  $('#txtCPFCNPJContato').val('');
  $('#zezinho').val('');
  $('#selectModificacao2').val(0);
  $('#txtObsContatoEntidade').val('');
  $('#txtDoContato').val('');
  $('#cbMalaDireta').prop('checked', true);
  $('#cbPessoaFisica').prop('checked', true);
  $('#cbWhatsApp').prop('checked', false);
  $('#cbEmail').prop('checked', false);
};

function duplicarContato() {
  $('#txtNumeroContato').val('');
  $('#txtNomeContato').prop('disabled', false);
  $('#txtTelefoneContato').prop('disabled', false);
  $('#txtCelularContato').prop('disabled', false);
  $('#txtCPFCNPJContato').prop('disabled', false);
  $('#zezinho').prop('disabled', false);
  $('#zezinho').prop('readonly', false);
  $('#btnFormataNumero').prop('disabled', false);
  $('#cbMaladireta').prop('disabled', false);
  $('#cbPessoaJuridica').prop('disabled', false);
  $('#cbPessoaFisica').prop('disabled', false);
  $('#btnGravaContato').removeClass('d-none');
  $('#btnCancelarAlteracao').removeClass('d-none');
  $('#btnIncluiContato').addClass('d-none');
  $('#btnExcluirContatoModal').addClass('d-none');
  $('#btnDuplicarContato').addClass('d-none');
  $('#btnAlteraContatoDentroModal').addClass('d-none');
  $('#cbWhatsApp').prop('disabled', false);
  $('#cbEmail').prop('disabled', false);
  $('#txtDoContato').prop('disabled', false);
  $('#txtObsContatoEntidade').prop('disabled', false);
  $('#selectModificacao2').prop('disabled', false);
};

var listaDeContatos = [];

async function reservaProduto(idEstoque, qtde) {
  try {
    await requisicao(
      "POST",
      "/sisplan/vendas/v1/reservaproduto?",
      `ID_ESTOQUE=${idEstoque}&QUANTIDADE=${qtde}`
    );
  } catch (error) {
    console.error(error);
  }
}

async function deletaReservaProduto() {
  try {
    await requisicao(
      "DELETE",
      "/sisplan/vendas/v1/deletareserva?",
      ''
    );
  } catch (error) {
    console.error(error);
  }
}

async function moedaContemValorMinimo(moeda) {
  try {
    const pesquisa = {
      camposSelect: ['VALOR_MINIMO'],
      tabela: 'COND_MOEDA',
      where: [`MOEDA = ${moeda} AND VALOR_MINIMO > 0`]
    }

    const response = await requisicao('GET', '/sisplan/funcoes/v1/pesquisa?', `JSON=${JSON.stringify(pesquisa)}`, null);

    if (!response) {
      return false;
    }

    const json = await response.json();

    return json.RESULT[0]?.length > 0;
  } catch (error) {
    console.log(error);
  }
}

async function validaCpfEValorMaximo(cpf) {
  try {
    if (parametrosVenda[101] != 1) {
      return false;
    }

    const pesquisa = await buscaValoresPadroes('LOJA')
    const jsonStr = pesquisa.filter((item) => item.CAMPO == 'VALOR_MAX_NFCE')

    const valor = isNaN(parseFloat(jsonStr[0]?.VALOR.replace(',', '.'))) ? 0 : parseFloat(jsonStr[0]?.VALOR.replace(',', '.'));

    if (valor > 0) {
      const total = $("#tabelaCondicoesDePagamento").DataTable().column(3, {}).data().sum();
      if ((total > valor) && ((cpf == '000.000.000-00') || (cpf == '00.000.000/0000-00') || (!valida_cpf_cnpj(cpf)))) {
        await aguardaMsgAlerta(`Venda com valor total superior a ${valor.toFixed(2)} (Valor definido nos valores padrões) e CPF/CNPJ inválido. Necessário alterar o cliente ou informar um CPF/CNPJ válido!`, () => { });
        return true;
      }
    }

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

function atualizaTotalIPI(valorIPI) {
  $("#txtTotalIPI").val(valorIPI);
  $("#txtTotalIPI").html(parseFloat(valorIPI).toLocaleString("pt-BR", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
    currency: "BRL"
  }));
}

function atualizaValoresComIPI(valorIPI, bRemover = false) {
  atualizaValorParcelaComIPI(valorIPI, bRemover);
  atualizaValorLiquidoComIPI(valorIPI, bRemover);
  atualizaSaldoAPagarComIPI(valorIPI, bRemover);
}

function atualizaValorParcelaComIPI(valorIPI, bRemover = false) {
  const valorParcela = parseFloat($("#txtValorParcela").val());
  const valorCalculado = bRemover ? TruncaDecimaisNova(2, valorParcela - valorIPI)
    : TruncaDecimaisNova(2, valorParcela + valorIPI);
  $("#txtValorParcela").val(valorCalculado);
}

function atualizaValorLiquidoComIPI(valorIPI, bRemover = false) {
  const valorLiquido = parseFloat($("#txtValorLiquidoMoeda").val());
  const valorCalculado = bRemover ? TruncaDecimaisNova(2, valorLiquido - valorIPI)
    : TruncaDecimaisNova(2, valorLiquido + valorIPI);
  $("#txtValorLiquidoMoeda").val(valorCalculado);
}

function atualizaSaldoAPagarComIPI(valorIPI, bRemover = false) {
  const saldoAPagar = parseFloat($("#txtsaldo_a_pagar").html().replaceAll(".", "").replace(",", "."));
  const valorCalculado = bRemover ? TruncaDecimaisNova(2, saldoAPagar - valorIPI)
    : TruncaDecimaisNova(2, saldoAPagar + valorIPI);
  $("#txtsaldo_a_pagar").html(parseFloat(valorCalculado).toLocaleString("pt-BR", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
    currency: "BRL"
  }));
  // atualizaExisteValorIPISaldoAPagar(!bRemover);
}

function atualizaExisteValorIPISaldoAPagar(bExiste) {
  $("#txtsaldo_a_pagar").prop("bExisteValorIPI", bExiste);
}

function rotinaAplicaValorIPIItensVenda(listaItensValorIPI) {
  listaItensValorIPI.forEach(item => {
    const registro = $("#tabelaItens").DataTable().row(item.indexVenda).data();
    registro[38] = item.valorIPI;
  })
}

async function rotinaAplicaValorIPI(bAtualizaValores = true) {
  $.LoadingOverlay("show");
  try {
    const listaItensVendaValorIPI = await retornaValorIPIItensVenda();
    rotinaAplicaValorIPIItensVenda(listaItensVendaValorIPI);
    const valorTotalIPI = listaItensVendaValorIPI.reduce((valorIPI, item) => valorIPI + (item.valorIPI || 0), 0);
    atualizaTotalIPI(valorTotalIPI);
    if (bAtualizaValores) {
      atualizaValoresComIPI(valorTotalIPI);
      atualizaExisteValorIPISaldoAPagar(true);
    }
  } finally {
    $.LoadingOverlay("hide");
  }
}

function rotinaRemoveValorIPI() {
  const valorIPI = $("#txtTotalIPI").val();
  atualizaValoresComIPI(valorIPI, true);
}

function AtualizaVendedorItens() {
  try {
    const vendedor = pegaChave('#txtVendedor');
    if (vendedor == '') return;

    const tabela = $('#tabelaItens').DataTable();
    const dados = tabela.data().toArray();
    const qtdeVendedor = new Set(dados.map(row => row[26]));

    if (qtdeVendedor?.size > 1) {
      msgAlerta('Existe mais de um vendedor vinculado aos itens da venda, o vendedor dos itens não será alterado.');
      return;
    }

    dados.forEach((row) => {
      row[26] = vendedor;
    });

    tabela.clear().rows.add(dados).draw();
  } catch (error) {
    console.log(error);
  }
}

async function rotinaAplicaValorRetencaoIva() {
  $.LoadingOverlay("show");
  try {
    const listaItensVendaValorRet = await retornaValorIPIItensVenda();
    const totalIva = listaItensVendaValorRet.reduce((valRet, item) => valRet + (item.val_iva || 0), 0);
    const percRet = await buscaValor('ENTIDADE', 'PERC_IR_RET', 'CODCLI', pegaChave('#txtCliente'));

    const totalRet = (totalIva * percRet.PERC_IR_RET) / 100;

    $('#txtTotalRetIva').val(totalRet);
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function retornaParcelaArredondamento(codigoMoeda) {
  const url = "/sisplan/operadoratef/v1/parcelaarredondamento?";
  try {
    const response = await requisicao("GET", url, `CODIGO_MOEDA=${codigoMoeda}`, undefined, 60000);

    if (!response) {
      throw new Error();
    }

    const retorno = await response.text();
    if (response.status != 200) {
      const erro = await response.json();
      throw new Error(erro.mensagem);
    }

    return retorno;

  } catch (error) {
    console.error("Não foi possível buscar a parcela do arredondamento. " + error.message);
  }

}

async function buscaFuncionario() {
  const codUsuario = getCookie('cod_usuario');
  try {
    const pesquisaParam = {
      tabela: 'ACESSO_USUARIOS',
      camposSelect: ['ACESSO_USUARIOS.CODFUN', 'PESSOAL.NOME'],
      leftJoin: [{
        tabela: 'PESSOAL',
        condicao: 'PESSOAL.CODIGO = ACESSO_USUARIOS.CODFUN'
      }],
      where: [`ACESSO_USUARIOS.CODIGO = '${codUsuario}'`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

    return jsonStr.length > 0 ? jsonStr[0].CODFUN : codUsuario;

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

async function RotinaFaturarVenda(numeroVenda, natureza, cliente, operacao, bAgrup = false, dadosAdd = '') {
  const bNFEAut = parametrosVenda[20] == 3;
  const empFat = pegaChave(parametrosVenda[111]);
  $.LoadingOverlay("show");
  try {
    const codUsuario = await buscaFuncionario();
    let params = `CODVEN=${numeroVenda}&NATUREZA=${natureza}&CLIENTE=${cliente}&OPERACAO=${operacao}&COD_USUARIO=${codUsuario}`

    if (bNFEAut && (empFat != '') && !bAgrup) {
      params += `&EMPRESA=${empFat}`;
    }

    const response = await requisicao('POST', '/Sisplan/Vendas/V1/faturarvenda?', params, dadosAdd, 300000);

    if (!response) {
      return;
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.mensagem);
      return false;
    }
    return jsonStr;
  } catch (error) {
    msgErro('Erro ao faturar venda.');
    console.error(error);
    return false;
  } finally {
    $.LoadingOverlay("hide");
  }
}

async function rotinaTransmiteNota(sFatura, sSerie, bAgrup = false) {
  $.LoadingOverlay("show");
  try {
    const bNFEAut = parametrosVenda[20] == 3;
    const empFat = pegaChave(parametrosVenda[111]);
    const usaCertificadoA3 = await CopiaParametro("FATURAMENTO", 2) == '1';
    const _url = '/sisplan/nfe/v1/gerarnfe?';
    let _params = `SERIE=${sSerie}&FATURA=${sFatura}&FINALIDADE=${0}&JUSTIFICATIVA=${''}&TIPO_TRANSMISSAO=${0}&CERTA3=${usaCertificadoA3 ? '1' : '0'}`;

    if (bNFEAut && (empFat != '') && !bAgrup) {
      _params += `&EMPRESA=${empFat}`;
    }

    const response = await requisicao('POST', _url, _params, null, 60000);

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

    if (usaCertificadoA3 && (response.status == 200)) {
      const xml = await response.text();
      const loteNfe = await retornaLoteNfe();
      const empClasse = await retornaInformacaoEmpresa();

      // TRANSMITE NA API LOCAL
      const responseLocal = await requisicao_ecf('POST', '/nfe/gerar?', `CLASSEEMPRESA=${JSON.stringify(empClasse)}&LOTE=${loteNfe}`, xml, 120000);
      if (responseLocal.status != 200) {
        const mensagemErro = await responseLocal.text();
        return [false, mensagemErro];
      }
      const retornoNota = await responseLocal.json();

      // FINALIZA TRANSMISSÃO NA API WEB
      const reponseApiWeb = await requisicao(
        'POST',
        '/sisplan/nfe/v1/finalizanfe?',
        `FATURA=${sFatura}&SERIE=${sSerie}&TIPO_TRANSMISSAO=${0}`,
        JSON.stringify(retornoNota),
        60000
      );
      if (!response) {
        return [false, 'Sem comunicação coma a API WEB'];
      }
      if (reponseApiWeb.status != 200) {
        const mensagemRetorno = await reponseApiWeb.json();
        return [false, mensagemRetorno.mensagem];
      }
      return [true, true];
    }
    return [true, true];    
  } catch (error) {
    console.log(error); 
  } finally {
    $.LoadingOverlay("hide");
  }
}

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"], 
      "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: ');
  }
}

async function retornaLoteNfe() {
  try {
    const url = `/sisplan/nfe/v1/finalizanfe?`;
    const response = await requisicao('GET', url, '', null);
    if (!response) {
      return;
    }
    const lote = await response.text();
    if (response.status != 200) {
      return;
    }
    return lote;
  } catch (error) {
    console.error(error);
  }
}

async function imprimirNfe(fatura, serie) {
  const bNFEAut = parametrosVenda[20] == 3;
  const empFat = pegaChave(parametrosVenda[111]);

  let url = `/sisplan/nfe/v1/imprimirnfe?FATURA=${fatura}&SERIE=${serie}`;

  if (bNFEAut && (empFat != '')) {
    url += `&EMPRESA=${empFat}`;
  }

  try {
    const bImprimeAutomatico = await verificaImprimirAutomatico('NFE');
    var arquivo = await GeraRelatorio(url + '&', 'PUT', 15000, false, 'NFE');
    if (arquivo != undefined) {
      if (!bImprimeAutomatico) {
        window.open(BASE_URI + '/relatorios_api/pdf/' + arquivo, '_blank');
      }
      await limparRelatorios();
    }
  } catch (error) {
    console.error(error);
  }
}

async function verificaAPIPagamentoPOS() {
  $.LoadingOverlay('show');
  try {
    const url = `/sisplan/integracaopos/v1/apipagamentopos?`;
    const response = await requisicao('GET', url, '', null);
    if (!response) {
      return;
    }
    const result = await response.text();
    if (response.status != 200) {
      return false;
    }
    return result !== '';   
  } catch (error) {
    console.error(error);
    return false;
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function adicionaTerminais() {
  $.LoadingOverlay('show');
  try {
    const url = `/sisplan/integracaopos/v1/buscaterminais?`;
    const response = await requisicao('GET', url, 'FILTRA_EMP=S', null);
    if (!response) {
      return;
    }
    const jsonStr = await response.json();
    if (response.status != 200) {
      return false;
    }
    $("#txtTerminalPagamento").empty();
    jsonStr.map((terminal) => {
      $("#txtTerminalPagamento").append(new Option(terminal.terminalId, terminal.id, null, terminal.active));
    });
  } catch (error) {
    console.error(error); 
  } finally {
    $.LoadingOverlay('hide');
  }
};

async function adicionaLinksPagamento() {
  $.LoadingOverlay('show');
  try {
    const url = `/sisplan/integracaopos/v1/gatewaysloja?`;
    const response = await requisicao('GET', url, 'FILTRA_EMP=S', null);
    if (!response) {
      return;
    }
    const jsonStr = await response.json();
    if (response.status != 200) {
      return false;
    }
    $("#txtLinkPagamento").empty();
    jsonStr.map((terminal) => {
      $("#txtLinkPagamento").append(new Option(terminal.merchantAccount, terminal.id, null));
    });
  } catch (error) {
    console.error(error); 
  } finally {
    $.LoadingOverlay('hide');
  }
};

async function atualizaTerminalPagamentoCaixa(idTerminal, caixa) {
  $.LoadingOverlay('show');
  try {
    const url = `/sisplan/integracaopos/v1/atualizaterminalcaixa?`;
    const response = await requisicao('PUT', url, `ID=${idTerminal}&CAIXA=${caixa}`, null);
    if (!response) {
      return;
    }
    if (response.status != 200) {
      return false;
    }
  } catch (error) {
    console.error(error);
  } finally {
    $.LoadingOverlay('hide');
  }
};

async function geraLinkPagamento(codven, codCli, nomeCliente) {
  return new Promise(async (resolve, reject) => {
    $.LoadingOverlay('show');
    try {    
      if ($.fn.DataTable.isDataTable('#tblLinksPagamento')) {
        $('#tblLinksPagamento').DataTable().destroy();
        $('#tblLinksPagamento').empty();
      }

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

      const url = `/sisplan/integracaopos/v1/pagamentolink?`;
      const idLink = sessionStorage.getItem('g_id_link_caixa');

      const response = await requisicao('POST', url, `IDLINK=${idLink}&CODVEN=${codven}`, null);
      if (!response) return;

      const jsonStr = await response.json();

      if (response.status != 200) {
        msgAlerta('Não foi possível gerar link de pagamento. ' + jsonStr.mensagem);
        return reject(jsonStr);
      }

      
      const numero = await getWhatsapp(codCli);
      $('#txtNumeroCelular').val(numero);
      
      const jsonAtivos = jsonStr.filter(link => ['pendente', 'ativo', 'concluído', 'expirado'].includes(link.status));
      const jsonInativos = jsonStr.filter(link => !['pendente', 'ativo', 'concluído', 'expirado'].includes(link.status));

      jsonAtivos.forEach((item, index) => {
        item.acao = botaoAcaoLink(++index);
        item.link = `<input type="text" class="form-control" value="${item.paymentLinkUrl}" readonly onclick="this.select()" style="min-width: 460px">`;
        item.condicao = `${item.condicao} - ${item.descCondicao}`;
        item.moeda = `${item.moeda} - ${item.descMoeda}`;
      });
      
      jsonInativos.forEach((item, index) => {
        item.acao = botaoAcaoLink(++index, true);
        item.link = `<input type="text" class="form-control" value="${item.paymentLinkUrl}" readonly onclick="this.select()" style="min-width: 460px">`;
        item.condicao = `${item.condicao} - ${item.descCondicao}`;
        item.moeda = `${item.moeda} - ${item.descMoeda}`;
      });

      const colunasItens = [
        { title: 'Ação', data: 'acao' },
        { title: 'Link', data: 'link' },
        { title: 'ID', data: 'id' },
        { title: 'Status', data: 'status' },
        { title: 'Valor', data: 'valor' },
        { title: 'Moeda', data: 'moeda' },
        { title: 'Condição', data: 'condicao' },
        { title: 'Nr. Parcelas', data: 'parcelas' },
        { title: 'Data de Criação', data: 'dataCadastro' },
        { title: 'Tempo Pendente', data: 'tempoPendente' },
        { title: 'Data Aprovação', data: 'dataAprovacao' },
        { title: 'Data Cancelamento', data: 'dataCancelamento' },
        { title: 'Data Estorno', data: 'dataEstorno' },
        { title: 'Data Expiração', data: 'dataExpiracao' },
      ]

      $('#tblLinksPagamento').DataTable({
        search: false,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        paging: false,
        "data": jsonAtivos,
        "columns": colunasItens,
        autoWidth: false,
        "colReorder": true,
        "columnDefs": [{
          "targets": [8, 10, 11, 12, 12+1],
          "render": function (data) {
            if ((data) && (data != '1899-12-30T00:00:00.000Z')) {
              let partes = data.split(' ');
              
              if (partes.length === 1) {
                partes = data.split('T');
              }

              const dataParte = partes[0];
              const horaParte = partes[1] || '00:00:00';
              const x = dataParte.split('-');
              return `${x[2]}/${x[1]}/${x[0]} ${horaParte.split('.')[0]}`;
            }
            return '';
          }
        },
        {
          render(data) {
            return parseFloat(data).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            });
          },
          targets: [4],
          "className": 'pr-4 text-right'
        },
        {
          targets: [2],
          visible: false,
        },
        {
          targets: [3],
          render: function (data) {
            let color = '';

            switch (data) {
              case 'pendente': color = '#0d6efd'; break;
              case 'concluído': color = '#198754'; break;
              case 'cancelado': color = '#dc3545'; break;
              case 'estornado': color = '#ffc107'; break;
              case 'expirado': color = '#6f42c1'; break;
            }

            return `<span style="color:${color}"><strong>${data}</strong></span>`;
          }
        },
        {
          targets: '_all',
          className: 'text-nowrap'
        }]
      });

      $('#tblLinksPagamentoInativos').DataTable({
        search: false,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        paging: false,
        "data": jsonInativos,
        "columns": colunasItens,
        autoWidth: false,
        "colReorder": true,
        "columnDefs": [{
          "targets": [8, 10, 11, 12, 12+1],
          "render": function (data) {
            if ((data) && (data != '1899-12-30T00:00:00.000Z')) {
              let partes = data.split(' ');
              
              if (partes.length === 1) {
                partes = data.split('T');
              }

              const dataParte = partes[0];
              const horaParte = partes[1] || '00:00:00';
              const x = dataParte.split('-');
              return `${x[2]}/${x[1]}/${x[0]} ${horaParte.split('.')[0]}`;
            }
            return '';
          }
        },
        {
          render(data) {
            return parseFloat(data).toLocaleString("pt-BR", {
              maximumFractionDigits: 2,
              minimumFractionDigits: 2
            });
          },
          targets: [4],
          "className": 'pr-4 text-right'
        },
        {
          targets: [3],
          render: function (data) {
            let color = '';

            switch (data) {
              case 'pendente': color = '#0d6efd'; break;
              case 'concluído': color = '#198754'; break;
              case 'cancelado': color = '#dc3545'; break;
              case 'estornado': color = '#ffc107'; break;
              case 'expirado': color = '#6f42c1'; break;
            }

            return `<span style="color:${color}"><strong>${data}</strong></span>`;
          }
        },
        {
          targets: [2],
          visible: false,
        },
        {
          targets: '_all',
          className: 'text-nowrap'
        }]
      });

      $.LoadingOverlay('hide');
      $.LoadingOverlay('hide');

      // cancelar link
      $('#tblLinksPagamento')
      .on('click', '#btn-cancelar-link', async function (event) {
        event.preventDefault();

        const tabela = $('#tblLinksPagamento').DataTable();
        const linha = tabela.row($(this).closest('tr'));
        const dados = linha.data();

        const id = dados.id;

        $.LoadingOverlay('show');

        try {
          const url = `/sisplan/integracaopos/v1/cancelapagamentolink?`;
          const response = await requisicao(
            'POST',
            url,
            `ID=${encodeURIComponent(id)}`,
            null
          );

          if (!response) return;

          const jsonStr = await response.json();

          if (response.status != 200) {
            msgAlerta('Não foi possível cancelar o link de pagamento. ' + jsonStr.mensagem);
            return;
          }

          criaMensagemSucesso('Link de pagamento cancelado com sucesso.');
          linha.remove().draw();
        } catch (error) {
          console.error(error);
        } finally {
          $.LoadingOverlay('hide');
        }
      });

      $("#btnWppLinkPagamento").off("click").on("click", async function() {
        $.LoadingOverlay("show");
        try {
          // const codCli = data.CLIENTE.split(' - ')[0];
          // const nomeCliente = data.CLIENTE.split(' - ')[1];
          const celular = $('#txtNumeroCelular').val();

          const inputs = $('#tblLinksPagamento tbody input');

          for (const input of inputs) {
            const linkPagamento = $(input).val();

            if (!linkPagamento) continue;

            await enviaWhatsAppPix(
              codCli,
              nomeCliente,
              celular,
              linkPagamento,
              'LINK_PAGAMENTO'
            );
          }
        } finally {
          $.LoadingOverlay("hide");
        }
      });

      $('#btn-fechar-link')
        .off('click')
        .on('click', function () {
          $('#modalLinkPagamento').modal('hide');
          resolve(true);
        });

      $('#modalLinkPagamento').modal({
        backdrop: 'static',
        keyboard: false
      });

    } catch (error) {
      console.error(error);
      reject(error);
    } finally {
      $.LoadingOverlay('hide');
    }
  });
}

function botaoAcaoLink(index, btnDisable = false) {
  return `<div style="text-align:center;">
            <div class="dropdown">
              <button class="btn btn-info btn-sm dropdown-toggle btnOpcoesLink" 
                type="button" data-toggle="dropdown" ${btnDisable ? 'disabled' : ''}>
                ${index}
              </button>
              <div class="dropdown-menu"> 
                <a id="btn-cancelar-link" class="dropdown-item" href="">Cancelar Link</a>
              </div>
            </div>
          </div>`
}

async function processaPagamentoPOS(jsonVenda, bCartao = true, bRetry = false) {
  $.LoadingOverlay('show');
  try {
    if ((!bPrimeiraCondicaoPagamento) && (!bRetry)) {
      await msgAguardaConfirmacao('Deseja efetuar o próximo pagamento?', () => { }, () => { }, false, true);  
    }

    if (!bRetry) atualizarStatusPagamento(jsonVenda, bCartao);

    let obj = jsonVenda;
    if (typeof jsonVenda === 'object') {
      obj = JSON.stringify(jsonVenda);
    }
    const url = `/sisplan/integracaopos/v1/pagamentoterminal?`;
    const idTerminal = sessionStorage.getItem('g_id_terminal_caixa');
    const response = await requisicao('POST', url, `IDTERMINAL=${idTerminal}&CARTAO=${bCartao}`, obj, 1500000);
    if (!response) {
      await rotinaGeraLog("TVENDALOJA", $("#txtCodVen").val(), "Erro ao comunicar com a API de integração com terminais POS", "Inclusão");
      await msgAguardaConfirmacao('Erro ao comunicar com a API de integração com terminais POS, verifique o terminal e clique em sim para tentar novamente.', () => { }, () => { }, false, true);
      return await processaPagamentoPOS(jsonVenda, bCartao, true);
    }

    if (response.status != 200) {
      const jsonStr = await response.json();
      console.error(jsonStr.mensagem);
      await msgAguardaConfirmacao('Não foi possível efetuar o pagamento no terminal, verifique o terminal e clique em sim para tentar novamente.', () => { }, () => { }, false, true);
      return await processaPagamentoPOS(jsonVenda, bCartao, true);
    }      
    atualizarStatusPagamento(jsonVenda, bCartao, true);
    bPrimeiraCondicaoPagamento = false;
    await verificaSeTemOutroPagamentoParaProcessar(jsonVenda, bCartao);
    return true;
  } catch (error) {
    console.error(error);
  } finally {
    $.LoadingOverlay('hide');
  } 
}

async function verificaSeTemOutroPagamentoParaProcessar(obj, bCartao) {
  const tipoProcurado = bCartao ? 3 : 5;
  
  const forma = obj.formaPagamento.find(fp =>
    fp.tipo === tipoProcurado &&
    fp.tpIntegracao === 1 &&
    fp.statusPagamentoPOS !== 'C'
  );
  
  if (forma) {
    await processaPagamentoPOS(obj, bCartao);
  }
}

function atualizarStatusPagamento(obj, bCartao, bConcluido = false) {
  if (bConcluido) {
    const forma = obj.formaPagamento.find(fp => fp.statusPagamentoPOS === 'A');

    if (forma) {
      forma.statusPagamentoPOS = 'C'; // Concluído
    }
    return
  }

  const tipoProcurado = bCartao ? 3 : 5;

  const forma = obj.formaPagamento.find(fp =>
    fp.tipo === tipoProcurado &&
    fp.tpIntegracao === 1 &&
    fp.statusPagamentoPOS !== 'C'
  );

  if (forma) {
    forma.statusPagamentoPOS = 'A'; // A processar
  }
}


async function gerarCotacao() {
  $.LoadingOverlay('show');
  try {
    if ($.fn.DataTable.isDataTable('#tabelaCotacaoGoFrete')) {
      $('#tabelaCotacaoGoFrete').DataTable().destroy();
      $('#tabelaCotacaoGoFrete').empty();
    }
    const jsonCotacao = await montaJsonCotacao();
    const response = await requisicao('POST', '/sisplan/integracaocotacaofrete/v1/fazercotacaogofrete?', '', JSON.stringify(jsonCotacao), 30000);
    if (!response) {
      msgErro('Não foi possível gerar a cotação, tente novamente.');
      return;
    }
    const jsonStr = await response.json();
    if (response.status != 200) {
      msgErro(jsonStr.mensagem);
      return; 
    }
    jsonStr.forEach(function (item) {
        item.SEL = botaoSelecionarGrid();
    }); 

    const colunasItens = [
      { title: 'Sel', data: 'SEL' },
      { title: 'Código', data: 'CODIGO' },
      { title: 'Nome', data: 'NOME' },
      { title: 'Descrição', data: 'DESCRICAO' },
      { title: 'Fantasia', data: 'FANTASIA' },
      { title: 'Prazo', data: 'PRAZO' },
      { title: 'Valor frete', data: 'VALOR_FRETE' },
      { title: 'Valor ICMS', data: 'VALOR_ICMS' },
      { title: 'Aliq. ICMS', data: 'ALIQ_ICMS' },
      { title: 'CNPJ', data: 'CNPJ' },
      { title: 'Cod. tabela', data: 'COD_TABELA' }
    ]

    $('#tabelaCotacaoGoFrete').DataTable({
      search: false,
      filter: false,
      order: [],
      sort: true,
      destroy: true,
      paging: false,
      "autoWidth": true,
      "data": jsonStr,
      "columns": colunasItens,
      autoWidth: true,
      "colReorder": true,
      "columnDefs": [{
        render(data) {
          return parseFloat(data).toLocaleString("pt-BR", {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2
          });
        },
        targets: [6, 7, 8],
        "className": 'pr-4 text-right'
      },
      {
        targets: [5, 10],
        "className": 'pr-4 text-right'
      }]
    });

    $('#tabelaCotacaoGoFrete').off('click', 'tr').on('click', 'tr', async function () {
      const table = $('#tabelaCotacaoGoFrete').DataTable();

      const $checkbox = $(this).find('.checkCotacao');

      if ($(this).hasClass('selected')) {
          $(this).removeClass('selected');
          $checkbox.prop('checked', false);
      } else {
          table.$('tr.selected').removeClass('selected')
              .find('.checkCotacao').prop('checked', false);

          $(this).addClass('selected');
          $checkbox.prop('checked', true);
      }
    });
  } catch (error) {
    console.error(error);  
  } finally {
    $.LoadingOverlay('hide');
  }
}

async function montaJsonCotacao() {
  const jsonCotacao = {};
  const dadosTabela = $('#tabelaItens').DataTable().data().toArray();
  
  jsonCotacao.CepOrigem = (await buscaValor('EMPRESA', 'EMP_CEP', 'EMP_PAT', pegaChave('#txtEmpresaOrigemCotacao'))).EMP_CEP;
  jsonCotacao.CodCli = pegaChave('#txtCliente');
  jsonCotacao.Cnpj = $('#txtCNPJ').val();
  jsonCotacao.EmpCnpj = (await buscaValor('EMPRESA', 'EMP_CNPJ', 'EMP_PAT', pegaChave('#txtEmpresaOrigemCotacao'))).EMP_CNPJ;
  jsonCotacao.Itens = dadosTabela.map(data => ({
    Codigo: data[0],
    Tipo: data[19],
    Quantidade: parseFloat(data[2]),
    ValorTotal: TruncaDecimaisNova(2, data[7])
  }));

  return jsonCotacao;
}

function botaoSelecionarGrid() {
  return (
    '<div class="form-check">' +
    '<input type="checkbox" class="align-self-center checkCotacao" value"">' +
    '</div>'
  );
};

async function validaObsAntecipacao(idTable = '#tabelaAntecipacoes') {
  if (parametrosVenda[119] != 1) return true;

  try {
    const duplicatas =$(idTable).DataTable().data().toArray().filter(item => item.VALOR_PAGO > 0).map(item => `'${item.DUPLICATA}'`);
    if (duplicatas.length > 0) {
      const empId = getCookie("emp_id");
      const params = {
        tabela: "HIST_FINAN",
        camposSelect: ["OBS", "NUMERO"],
        where: [
          `NUMERO IN (${duplicatas.join(",")}) AND EMP_ID = ${empId}`,
        ],
      };

      const response = await retornaJsonPesquisaPadrao(JSON.stringify(params));

      if (!response) {
        return false;
      }

      if (response.length > 0) {
        const mensagem = response.map(item => `${item.NUMERO}: ${item.OBS}`).join('.\n')
        let bloqueio = false;
        await msgAguardaConfirmacao(`Observação da antecipação: ${mensagem}. Deseja Continuar ?`, () => { bloqueio = true }, () => { bloqueio = false });
        if (!bloqueio) {
          const table = $(idTable).DataTable();

          const novosDados = table.data().toArray().map(item => ({
              ...item,
              VALOR_PAGO: 0,
              VALOR_UTILIZADO: 0
          }));

          table.clear();
          table.rows.add(novosDados);
          table.draw(false);
          if (idTable === '#tabelaAntecipacoes') {
            $('#txtMoeda').trigger('focusout');
            $('#txtMoeda').focus();
          } else {
            $('#txtValorAntecipacao').html($('#txtValorParcela').val());
          }
        }
        return bloqueio;
      }
      return true;
    }
  } catch (error) {
    console.log(error);
  }
}