$('#tutorial').on('click', function () {
  $('#geral-tab').trigger('click');
  $(document).ready(async function () {
    const driver = new Driver({
      doneBtnText: 'Sair',
      closeBtnText: 'Fechar',
      nextBtnText: 'Próximo',
      prevBtnText: 'Anterior',
      allowClose: false
    });

    driver.defineSteps([
      {
        element: '#tutoPedido',
        popover: {
          title: 'Dados do Pedido',
          description: 'Insira um pedido para iniciar a expedição do mesmo.',
          position: 'bottom'
        }
      }, {
        element: '#divProduto',
        popover: {
          title: 'Tabela de Itens',
          description: 'Aqui serão carregados os itens do pedido após digitar o número.',
          position: 'bottom'
        }
      }, {
        element: '#barraBipar',
        popover: {
          title: 'Campo Barra',
          description: 'Campo de bipagem de barra, para realizar a conferência.',
          position: 'bottom'
        }
      }, {
        element: '#btnMais',
        popover: {
          title: 'Botão Estornar',
          description: 'Ao clicar nesse botão, as barras bipadas serão para estornar os itens do grid.',
          position: 'bottom'
        }
      }, {
        element: '#btnGravar',
        popover: {
          title: 'Botão Gravar',
          description: 'Ao clicar nesse botão, a expedição será gravada.',
          position: 'left'
        }
      }
    ]);
    driver.start();
  });
});

$(document).ready(async function () {

  let listaBarrasBipadasEPC = [];
  let listaBarrasForamBipadasEPC = [];
  const bTransmiteNota = ['1', '2'].includes(await CopiaParametro('FATURAMENTO', 1));
  const bUsaCertificadoA3 = (await CopiaParametro('FATURAMENTO', 2)) == 1;
  const bFaturaParcial = (await CopiaParametro('EXPEDICAO', 0)) == 1;
  const bNaoPermiteParcial = (await CopiaParametro('EXPEDICAO', 0)) == 2;
  const bNaoFatura = (await CopiaParametro('EXPEDICAO', 0)) == 3;
  const somAtivo = localStorage.getItem('@prodEntrada.somAtivo') ?? 'false';
  const layoutNFE = await CopiaParametro('EXPEDICAO', 3) == 0 ? 'NFE' : 'NFESimplificada';
  const bVolumeManual = (await CopiaParametro('EXPEDICAO', 5)) == 1;
  const bControlaEstoque = (await CopiaParametro('EXPEDICAO', 6)) == 1;
  const integracaoEPC = await CopiaParametro('EXPEDICAO', 7);
  const bEnviaEmail = ['1', '3'].includes(await CopiaParametro('FATURAMENTO', 7));
  const bEmailTransp = await CopiaParametro("FATURAMENTO", 9) == '1';
  const bBarraLog = await CopiaParametro('SISTEMA', 0);
  const PedidoBloqueado = await CopiaParametro('EXPEDICAO', 11);
  const bBuscaCondPagto = (await CopiaParametro('EXPEDICAO', 8)) == 1;

  let visualizaBarra = Boolean;
  let barrasLidas = [];
  let barrasLog = [];
  let idInterval;
  let validaEstoqueBip = false;

  const colunasTabelaItens = [
    { title: "Código", data: "codigo" },
    { title: "Descrição", data: "descricao" },
    { title: "Cor", data: "cor" },
    { title: "Desc. Cor", data: "descCor" },
    { title: "Tam", data: "tam" },
    { title: "Qualidade", data: "qualidade" },
    { title: "Qtde", data: "qtde" },
    { title: "Barra", data: "barra" },
    { title: "Barra28", data: "barra28" },
    { title: "BarraCli", data: "barraCli" },
    { title: "Ordem", data: "ordem" },
    { title: "Qtde F.", data: "qtdeF" },
    { title: "Lote", data: "lote" },
    { title: "Local", data: "local" },
    { title: "Reserva", data: "reserva" },
    { title: "Baixados", data: "baixados" },
    { title: "Bloqueio", data: "bloqueio" },
    { title: "Id Item Ped.", data: "idItemPed" },
    { title: "Posição", data: "posicao" },
    { title: "Id Reserva", data: "idReserva" },
    { title: "Id PaIten", data: "idPaIten" },
    { title: "End. Local", data: "endLocal" },
    { title: "Desc. End. Local", data: "descEndLocal" },
    { title: "Qtde Conf.", data: "QTDE_CONF" },
    { title: "Qtde Est.", data: "QTDE_EST" }
  ];

  if ((integracaoEPC != '0') && (integracaoEPC != '3')) {
    $('.divRFID').removeClass("d-none");
  } else if (integracaoEPC == '3') {
    $('#btnRFID').removeClass("d-none");
  }

  if (bNaoFatura) {
    $('#btnNfe').addClass('d-none');
  }

  validaCampoVolume();
  adicionaPesquisaAutocompleta();
  focaCampoPedido();
  validaSomBipagem();
  validaCookiePedcli();

  await buscaFuncionario();
  await validaEdicao();
  await vencimentoCertificado();
  await buscaEspecieEmpresa();

  $('#txtPedido').on('blur', async function () {
    const pedido = $('#txtPedido').val();

    if ((pedido == '') || (pedido.split('')[0] == '[')) {
      return;
    }

    $.LoadingOverlay('show');
    try {

      const pesquisaParam = {
        tabela: 'PEDIDO',
        camposSelect: [
          'PEDIDO.CODCLI', 'ENTIDADE.NOME', 'PEDIDO.DEPOSITO', 'DEPOSITO.DESCRICAO', 'PEDIDO.OPERACAO',
          'PEDIDO.NATUREZA', 'PEDIDO.BLOQUEIO', 'PEDIDO.FINANCEIRO', 'SITPROD.BLOQ_FAT', 'SITPROD.BLOQ_EXPEDICAO'
        ],
        leftJoin: [
          { tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = PEDIDO.CODCLI' },
          { tabela: 'DEPOSITO', condicao: 'DEPOSITO.CODIGO = PEDIDO.DEPOSITO' },
          { tabela: 'SITPROD', condicao: 'SITPROD.CODIGO = PEDIDO.STATUS' }
        ],
        where: [`PEDIDO.NUMERO = '${pedido}'`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Número de pedido não existe, favor verificar.');
        $('#txtPedido').val('');
        return;
      }

      if ((jsonStr[0].OPERACAO == 0) && (jsonStr[0].NATUREZA == '')) {
        msgAlerta('Pedido não possui operação ou natureza cadastrada, favor verificar.');
        $('#txtPedido').val('');
        return;
      }

      if (PedidoBloqueado == '1' || PedidoBloqueado == '3') {
        if ((jsonStr[0].BLOQUEIO == 0)) {
          msgAlerta('Pedido está bloqueado no comercial, favor verificar.');
          $('#txtPedido').val('');
          return;
        }
      }

      if (PedidoBloqueado == '2' || PedidoBloqueado == '3') {
        if ((jsonStr[0].FINANCEIRO == 0)) {
          msgAlerta('Pedido está bloqueado no financeiro, favor verificar.');
          $('#txtPedido').val('');
          return;
        }
      }

      if (jsonStr[0].BLOQ_EXPEDICAO == 'S') {
        msgAlerta('Pedido com status bloqueado para expedição, favor verificar.');
        $('#txtPedido').val('');
        return;
      }

      if (jsonStr[0].BLOQ_FAT == 'S') {
        msgAlerta('Pedido com status bloqueado para faturamento, favor verificar.');
        $('#txtPedido').val('');
        return;
      }

      if (await pedidoCancelado(pedido)) {
        msgAlerta('Pedido cancelado ou já faturado, impossível expedir.');
        $('#txtPedido').val('');
        return;
      }

      if (await pedidoExpedido(pedido) && bNaoFatura) {
        msgAlerta('Pedido já expedido, impossível continuar.');
        $('#txtPedido').val('');
        return;
      }

      insereValor('#txtPedido', pedido, jsonStr[0].NOME);
      insereValor('#txtCliente', jsonStr[0].CODCLI, jsonStr[0].NOME);
      insereValor('#txtDeposito', jsonStr[0].DEPOSITO, jsonStr[0].DESCRICAO);

      // if (await liberarRegistro('EXPEDICAO', pedido) == false) {
      //   msgAlerta('Pedido está sendo alterado.', null, null, () => { window.location.href = 'create' }, () => { window.location.href = 'create' });
      //   return;
      // }

      await buscaPedidoComSemReserva();
      await buscaPedcli(pedido);
      $('#txtBarra').focus();
    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      atualizaTotais();
      atualizaVolumes();
      $.LoadingOverlay('hide');
    }
  });

  $('#txtPedidoBusca').on('blur', async function () {
    const pedido = $('#txtPedidoBusca').val();

    if ((pedido == '') || (pedido.split('')[0] == '[')) {
      return;
    }

    $.LoadingOverlay('show');
    try {

      const pesquisaParam = {
        tabela: 'PEDIDO',
        camposSelect: ['ENTIDADE.NOME'],
        leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = PEDIDO.CODCLI' }],
        where: [`PEDIDO.NUMERO = '${pedido}'`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Número de pedido não existe, favor verificar.');
        $('#txtPedidoBusca').val('');
        return;
      }

      insereValor('#txtPedidoBusca', pedido, jsonStr[0].NOME);

      await buscaNotaPedido();

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

  $('#txtBarra').on('blur', async function () {
    await saidaBarra();
  });

  $('#txtBarraEstorno').on('blur', async function () {
    try {
      let barra = $('#txtBarraEstorno').val();
      if (barra == '') {
        return;
      }
      if (($('#modal-warning').data('bs.modal') || {})._isShown == true) {
        $('#txtBarraEstorno').val('');
        return;
      }

      let barra28 = '';
      let barraLog = false;
      if ((bBarraLog == '1') || (bBarraLog == '2')) {
        barra28 = await extraiBarra28(barra);
        if (barra28 && (barra28 != '')) {
          barraLog = barra;
          barra = barra28;
        }
      }

      if (!barraLog && (bBarraLog == '2')) {
        msgAlerta('Necessário bipar uma BarraLog.', undefined, undefined, () => { $('#txtBarra').val('').focus() });
        $('#txtBarra').val('').focus();
        return;
      }

      await confereBarra(false, barra, barraLog);
    } finally {
      atualizaTotais();
    }
  });

  $('#txtBarra').on('keydown', async function (event) {
    if ((event.key == 'Enter')) {
      $('#txtBarra').trigger('blur');
      $('#txtBarra').focus();
    }
  });

  $('#txtBarraEstorno').on('keydown', async function (event) {
    if ((event.key == 'Enter')) {
      $('#txtBarraEstorno').trigger('blur');
      $('#txtBarraEstorno').focus();
    }
  });

  $('#txtQtde').on('keypress', function (event) {
    var regex = new RegExp("^[0-9]+$");
    var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
    if (!regex.test(key)) {
      event.preventDefault(); return false;
    }
  });

  $('#txtQtde').on('blur', function () {
    if ($('#txtQtde').val() == '') {
      $('#txtQtde').val('1');
    }
  });

  $('#txtPedido').on('keydown', async function (event) {
    if ((event.key == 'Enter')) {
      $('#txtPedido').trigger('blur');
    }
  });

  $('#txtPedidoBusca').on('keydown', async function (event) {
    if ((event.key == 'Enter')) {
      $('#txtPedidoBusca').trigger('blur');
    }
  });

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

  $('#btnMais').on('click', function () {
    $('#barraBipar').addClass('d-none');
    $('#barraEstorno').removeClass('d-none');
    $('#txtBarraEstorno').focus();
  });

  $('#btnMenos').on('click', function () {
    $('#barraEstorno').addClass('d-none');
    $('#barraBipar').removeClass('d-none');
    $('#txtBarra').focus();
  });

  $('#btnDesistir').on('click', function () {
    msgAlerta('Deseja mesmo abandonar essa expedição? Todos os itens conferidos serão perdidos.', abandonaExpedicao)
  });

  $('#btnGravar').on('click', async function () {
    if ($('#txtPedido').val() == '') {
      msgAlerta('Nenhum pedido informado.')
      return;
    };
    await gravaDados();
  });

  $('#txtReserva').on('change', async function () {
    $('#tabelaItens').DataTable().rows().remove().draw();
    const pedido = $('#txtPedido').attr('data-chave');
    const deposito = $('#txtDeposito').attr('data-chave');
    await buscaPedidoComReserva(pedido, $('#txtReserva').val(), deposito);
  });

  $('#btnVoltar').on('click', function () {
    window.location.href = `${BASE_URI}/expedicao`;
  });

  $('#btnMaisInfo').on('click', () => {
    $('#modal-infos').modal('show')
  });

  $('#btnNfe').on('click', () => {
    $('#modal-nfe').modal('show')
  });

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

  $('#modal-nfe').on('hidden.bs.modal', function (_) {
    limpaCamposNota();
  });

  $('#btnImprimir').on('click', async function () {
    const fatura = pegaValor('#txtFatura');
    const serie = pegaValor('#txtSerie');
    const chave = pegaValor('#txtChave');

    if (fatura == '' || serie == '') {
      msgAlerta('Nenhuma nota selecionada, favor verificar.');
      return;
    }

    if (chave == '') {
      msgAlerta('Nota não transmitida, impossível imprimir');
      return;
    }

    await imprimeNotaModal(fatura, serie);
  });

  $('#btnTelaCheia').on('click', function (e) {
    abreTelaCheia();
  });

  $('#btnTelaReduzida').on('click', function (e) {
    fechaTelaCheia();
  });

  $('body').keydown(function (e) {
    const keyCode = e.keyCode || e.which
    if (((window.event.which === 13) || (window.event.which === 9)) && (getCookie('expedicao_tela_cheia') == 'true')) {
      abreTelaCheia();
    }
    if (window.event.which === 113) {
      fechaTelaCheia();
    } else if ((e.altKey && keyCode == 49) && (integracaoEPC != '0') && (integracaoEPC != '3') && (!$('#btn-iniciar-epc').prop('disabled'))) { //Alt + 1 inicia leitura rfid
      e.preventDefault();
      $('#btn-iniciar-epc').trigger('click');
    } else if ((e.altKey && keyCode == 50) && (integracaoEPC != '0') && (integracaoEPC != '3') && (!$('#btn-parar-epc').prop('disabled'))) { //Alt + 2 para leitura rfid
      e.preventDefault();
      $('#btn-parar-epc').trigger('click');
    } else if ((keyCode == 13) && (integracaoEPC != '0') && (integracaoEPC != '3') && (!$('#btn-parar-epc').prop('disabled'))) { //Alt + 2 para leitura rfid
      e.preventDefault();
      setTimeout(() => {
        $('#btn-parar-epc').trigger('click');
      }, 5000);
    }
  });

  $('#checkPedcli').on('change', function () {
    setCookie('usa_pedcli_expedicao', isChecked('#checkPedcli') ? 'S' : 'N', 30);
    if (isChecked('#checkPedcli')) {
      $('#linhaPedcli').removeClass('d-none');
    } else {
      $('#linhaPedcli').addClass('d-none');
    }
  });

  $('#txtCaixa').on('blur', async function () {
    const caixa = $(this).val();

    if (caixa == '') {
      return;
    }

    await editaExpedicao(caixa);

    $('#txtCaixa').prop('disabled', true);
  });

  function abreTelaCheia(executaCloseFullScreen = true) {
    try {
      const elem = document.querySelector('body');

      $('body').addClass('sidebar-collapse');
      $('#btnTelaCheia').addClass('d-none');
      $('#btnTelaReduzida').removeClass('d-none');

      if (executaCloseFullScreen) {
        if (elem.requestFullscreen) {
          elem.requestFullscreen();
        } else if (elem.mozRequestFullScreen) {
          elem.mozRequestFullScreen();
        } else if (elem.webkitRequestFullscreen) {
          elem.webkitRequestFullscreen();
        } else if (elem.msRequestFullscreen) {
          elem.msRequestFullscreen();
        }

        setCookie('expedicao_tela_cheia', true, 30);
      }

    } finally {
      if ($.fn.DataTable.isDataTable("#tabelaItens")) {
        $("#tabelaItens").DataTable().columns.adjust().draw(false);
      }
    }
  };

  function fechaTelaCheia(executaCloseFullScreen = true) {
    try {
      $('body').removeClass('sidebar-collapse');
      $('#btnTelaCheia').removeClass('d-none');
      $('#btnTelaReduzida').addClass('d-none');

      if (executaCloseFullScreen) {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        }
        else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        }
        else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen();
        }
        else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        }

        setCookie('expedicao_tela_cheia', false, 30);
      }

    } finally {
      if ($.fn.DataTable.isDataTable("#tabelaItens")) {
        $("#tabelaItens").DataTable().columns.adjust().draw(false);
      }
    }
  };

  function validaCookiePedcli() {
    $('#checkPedcli').prop('checked', getCookie('usa_pedcli_expedicao') == 'S');
    if (getCookie('usa_pedcli_expedicao') == 'S') {
      $('#linhaPedcli').removeClass('d-none');
    } else {
      $('#linhaPedcli').addClass('d-none');
    }
  }

  async function abandonaExpedicao() {
    await deletaRegistro('EXPEDICAO', getCookie('usuario'), pegaChave('#txtPedido'));

    if ($(window.location.href.split('/')).get(-1) != 'create') {
      window.location.href = 'create';
    }

    $('#txtCaixa').val('');
    $('#txtPedido').val('');
    $('#txtReserva').val('');
    $('#txtDeposito').val('');
    $('#txtCliente').val('');
    $('#txtTotal').val('0');
    $('#txtConferidas').val('0');
    $('#txtSaldo').val('0');
    $('#txtPedido').prop('disabled', false);
    $('#txtPedido').prop('readonly', false);
    $('#btnPedido').prop('disabled', false);
    if ($.fn.DataTable.isDataTable('#tabelaItens')) {
      $('#tabelaItens').DataTable().rows().remove().draw();
    };
    $('#btnDesistir').addClass('d-none');
    $('#btnVoltar').removeClass('d-none');
    $('#txtReserva').empty();
    $('#txtCaixa').prop('disabled', false);

    escondeBloqueiaCampos(false);
    clearInterval(idInterval);

    barrasLidas = [];
    listaBarrasForamBipadasEPC = [];
    idInterval = null;

    $('#timerExp').text('00:00').addClass('d-none');

    focaCampoPedido();
  };

  function focaCampoPedido() {
    $('#txtPedido').focus();
  };

  function validaCampoVolume() {
    if (bVolumeManual) {
      $('#divCliente').addClass('col-2');
      $('#divCliente').removeClass('col-3');
      $('#divVolumes').removeClass('d-none');
    }
  };

  function validaSomBipagem() {
    $('.somAtivo').on('click', function () {
      $(this).addClass('d-none');
      localStorage.setItem("@prodEntrada.somAtivo", false);
      $('.somInativo').removeClass('d-none');
    });

    $('.somInativo').on('click', function () {
      $(this).addClass('d-none');
      localStorage.setItem("@prodEntrada.somAtivo", true);
      $('.somAtivo').removeClass('d-none');
    });

    if (somAtivo == 'true') {
      $($('.somInativo')[0]).trigger('click');
    }
  };

  function addBarraLida(sBarra) {
    if (!barrasLidas.includes(sBarra)) {
      barrasLidas.push(sBarra);
    }
  };

  async function addBarraLogLida(barraLog) {
    if (!barraLog) {
      return true;
    }

    if (!barrasLog.includes(barraLog)) {
      if (!await validaBarraLogLiberada(barraLog.replace('#', '[HASHTAG]'))) {
        return false;
      }
      barrasLog.push(barraLog);
      return true;
    } else {
      return false;
    }
  };

  function removeBarraLogLida(barraLog) {
    if (barrasLog.includes(barraLog) && barraLog) {
      barrasLog.splice(barrasLog.indexOf(barraLog), 1);
    }
  };

  function validaGravar() {
    let qtdeBipada = 0;

    $('#tabelaItens').DataTable().rows().data().map(item => {
      qtdeBipada += item.QTDE_CONF;
    });

    if (qtdeBipada == 0) {
      return false;
    }
    return true;
  };

  function validaExpedicaoParcial() {
    const qtdeBipada = $('#tabelaItens').DataTable().column(23, {}).data().sum();
    const qtdeTotal = $('#tabelaItens').DataTable().column(6, {}).data().sum();

    if (qtdeBipada != qtdeTotal) {
      return true;
    }
    return false;
  };

  function escondeBloqueiaCampos(bReserva) {
    if (bReserva) {
      $('#divReserva').removeClass('d-none');
      $('#divDeposito').removeClass('col-4');
      $('#divDeposito').addClass('col-2');
      $('#txtCaixa').prop('disabled', true);
      return;
    }
    $('#divReserva').addClass('d-none');
    $('#divDeposito').addClass('col-4');
    $('#divDeposito').removeClass('col-2');
  };

  function bloqueiaCampos() {
    $('#txtPedido').prop('disabled', true);
    $('#txtPedido').prop('readonly', true);
    $('#btnPedido').prop('disabled', true);
    $('#btnDesistir').removeClass('d-none');
    $('#btnVoltar').addClass('d-none');
    $('#txtCaixa').prop('disabled', true);
  };

  function bloqueiaCamposVisualizacao() {
    $('#txtPedido').prop('disabled', true);
    $('#txtPedido').prop('readonly', true);
    $('#btnPedido').prop('disabled', true);
    $('#txtFuncionario').prop('disabled', true);
    $('#txtFuncionario').prop('readonly', true);
    $('#btnFuncionario').prop('disabled', true);
    $('#btnAFuncionario').prop('disabled', true);
    $('#txtFuncionario').prop('disabled', true);
    $('#txtObservacao').prop('readonly', true);
    $('#txtObservacao').prop('disabled', true);
    $('#btnGravar').addClass('d-none');
    $('#btnDesistir').addClass('d-none');
    $('#divQtde').addClass('d-none');
    $('#barraBipar').addClass('d-none');
    $('.escondeEdicao').addClass('d-none');
    $('#txtCaixa').prop('disabled', true);
  };

  function addReservasSelect(arrReservas) {
    arrReservas.map((item) => {
      $("#txtReserva").append(new Option(item.RESERVA, item.RESERVA));
    });
  };

  function corrigeCamposJson(arrItens) {
    let itensFormatados = [];
    arrItens.map((item) => {
      itensFormatados.push({
        codigo: `<div class="icheck-primary d-inline"><span class="fas fa-times-circle mr-1" title="Aguardando Bipagem" style="color:#EEAD2D"></span></div>  ` + item.CODIGO,
        descricao: item.DESCRICAO,
        cor: item.COR,
        descCor: item.DESCCOR,
        tam: item.TAM,
        qualidade: item.QUALIDADE,
        qtde: item.QTDE,
        barra: item.BARRA,
        barra28: item.BARRA28,
        barraCli: item.BARRACLI,
        ordem: item.ORDEM,
        qtdeF: item.QTDE_F,
        lote: item.LOTE,
        local: item.LOCAL,
        reserva: item.RESERVA,
        baixados: item.BAIXADOS,
        bloqueio: item.BLOQUEIO,
        idItemPed: item.IDITEMPED,
        posicao: item.POSICAO,
        idReserva: item.IDRESERVA,
        idPaIten: item.IDPAITEN,
        endLocal: item.ENDLOCAL,
        descEndLocal: item.DESC_END_LOCAL,
        QTDE_CONF: item.QTDE_CONF,
        QTDE_EST: item.QTDE_EST
      });
    });
    return itensFormatados;
  };

  function retornaClassePedido3() {
    let arrItens = [];
    let bTudoBipado = true;

    $('#tabelaItens').DataTable().data().map((item) => {
      const itPedido = {
        CODIGO: item.codigo.split('</div>  ')[1],
        COR: item.cor,
        QTDE: item.QTDE_CONF,
        QTDEF: item.qtdeF,
        PESOL: 0,
        PESO: 0,
        TAM: item.tam,
        ORDEM: item.ordem,
        DEPOSITO: pegaChave('#txtDeposito'),
        QUALIDADE: item.qualidade,
        DATA: `${new Date().toJSON().slice(0, 10)}T00:00:00Z`,
        IDPAITEN: item.idPaIten,
        DESCRICAO: item.descricao,
        DESCCOR: item.descCor,
        IDPEDITEN: item.idItemPed,
        QTDEDIST: 0,
        SEQCAIXA: 0,
        IDRESERVA: item.idReserva,
        BARRA28: item.barra28,
        BARRA: item.barra,
        BARRACLI: item.barraCli,
        FUNCIONARIO: pegaChave('#txtFuncionario'),
        ENDLOCAL: item.endLocal,
        DESCENDLOCAL: item.descEndLocal
      }
      if (itPedido.QTDE > 0) {
        arrItens.push(itPedido);
      }
      if (item.qtde > item.QTDE_CONF) {
        bTudoBipado = false;
      }
    });

    return {
      EXPLOJAWEB: true,
      NUMERO: pegaChave('#txtPedido'),
      CAIXA: $('#txtCaixa').val(),
      RESERVA: $('#txtReserva').val() > 0 ? $('#txtReserva').val() : 0,
      DEPOSITO: pegaChave('#txtDeposito'),
      FUNCIONARIO: pegaChave('#txtFuncionario'),
      BARRASLIDAS: barrasLidas,
      BARRASLOG: barrasLog,
      ITENS: arrItens,
      FATURAR: bFaturaParcial ? bFaturaParcial : bTudoBipado,
      TUDOBIPADO: bTudoBipado,
      VOLUMES: pegaValor('#txtVolumes') > 0 ? pegaValor('#txtVolumes') : '1',
      EPC: retornaCodigosGravacaoEPC(pegaChave('#txtPedido'), integracaoEPC != '0'),
      ESPECIE: pegaValor('#txtEspecie') != '' ? pegaValor('#txtEspecie') : 'VOLUME'
    }
  };

  function retornaHoraMinSeg(totalSegundos) {
    function retornaHMSstring(num) {
      return (num < 10 ? '0' : '') + num;
    }

    let horas = Math.floor(totalSegundos / 3600);
    totalSegundos = totalSegundos % 3600;

    let minutos = Math.floor(totalSegundos / 60);
    totalSegundos = totalSegundos % 60;

    let segundos = Math.floor(totalSegundos);

    horas = retornaHMSstring(horas);
    minutos = retornaHMSstring(minutos);
    segundos = retornaHMSstring(segundos);

    return (minutos + ':' + segundos);
  };

  function iniciaTimer() {
    $('#timerExp').removeClass('d-none');
    let segundosCorridos = 0;
    idInterval = setInterval(function () {
      segundosCorridos += 1;
      $('#timerExp').html("<i class=\"fas fa-stopwatch\"></i>" + retornaHoraMinSeg(segundosCorridos));
    }, 1000);
  };

  function limpaCamposNota(bPedido = false, bNota = false) {
    if (!bPedido) {
      $('#txtPedidoBusca').val('');
    }
    if (!bNota) {
      $('#txtNota').val('');
    }
    $('#txtFatura').val('');
    $('#txtSerie').val('');
    $('#txtChave').val('');
    $('#txtProtocolo').val('');
    $('#txtDtEmissao').val('');
  };

  async function imprimeNotaModal(sFatura, sSerie) {
    let url = layoutNFE == 'NFE' ? '/sisplan/nfe/v1/imprimirnfe?' : '/sisplan/nfe/v1/imprimirnfesimplificada?';
    url += `FATURA=${sFatura}&SERIE=${sSerie}`;
    try {
      $.LoadingOverlay("show");
      try {
        const bImprimeAutomatico = await verificaImprimirAutomatico(layoutNFE);
        var arquivo = await GeraRelatorio(url + '&', 'PUT', 15000, false, layoutNFE);
        if (arquivo != undefined) {
          if (!bImprimeAutomatico) {
            window.open(BASE_URI + '/relatorios_api/pdf/' + arquivo, '_blank');
          }
          await limparRelatorios();
        }
      } catch (error) {
        console.error(error);
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  };

  async function buscaNotaPedido() {
    limpaCamposNota(true);

    const pedido = $('#txtPedidoBusca').attr('data-chave');

    $.LoadingOverlay('show');
    try {
      const pesquisaParam = {
        tabela: 'NOTAITEN',
        camposSelect: ['NOTA.FATURA', 'NOTA.SERIE', 'NOTA.DT_EMISSAO', 'NOTA.PROTOCOLO_NFE', 'NOTA.CHAVE_NFE'],
        leftJoin: [{ tabela: 'NOTA', condicao: 'NOTA.FATURA = NOTAITEN.FATURA AND NOTA.SERIE = NOTAITEN.SERIE' }],
        where: [`NOTAITEN.PEDIDO = '${pedido}'`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Nenhuma nota encontrada, favor verificar.');
        $('#txtPedidoBusca').val('');
        return;
      }

      insereValor('#txtNota', jsonStr[0].FATURA, jsonStr[0].SERIE);
      insereValor('#txtFatura', jsonStr[0].FATURA);
      insereValor('#txtSerie', jsonStr[0].SERIE);
      insereValor('#txtChave', jsonStr[0].CHAVE_NFE);
      insereValor('#txtProtocolo', jsonStr[0].PROTOCOLO_NFE);
      insereValor('#txtDtEmissao', jsonStr[0].DT_EMISSAO);

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

  async function buscaPedidoNota() {
    limpaCamposNota(false, true);

    const nota = $('#txtNota').attr('data-chave');

    $.LoadingOverlay('show');
    try {
      const pesquisaParam = {
        tabela: 'NOTA',
        camposSelect: ['NOTA.FATURA', 'NOTA.SERIE', 'NOTAITEN.PEDIDO', 'ENTIDADE.NOME', 'NOTA.DT_EMISSAO', 'NOTA.PROTOCOLO_NFE', 'NOTA.CHAVE_NFE'],
        leftJoin: [
          { tabela: 'NOTAITEN', condicao: 'NOTA.FATURA = NOTAITEN.FATURA AND NOTA.SERIE = NOTAITEN.SERIE' },
          { tabela: 'ENTIDADE', condicao: 'NOTA.CODCLI = ENTIDADE.CODCLI' }
        ],
        where: [`NOTA.FATURA = '${nota}'`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Nenhuma nota encontrada, favor verificar.');
        $('#txtPedidoBusca').val('');
        return;
      }

      insereValor('#txtPedidoBusca', jsonStr[0].PEDIDO, jsonStr[0].NOME);
      insereValor('#txtFatura', jsonStr[0].FATURA);
      insereValor('#txtSerie', jsonStr[0].SERIE);
      insereValor('#txtChave', jsonStr[0].CHAVE_NFE);
      insereValor('#txtProtocolo', jsonStr[0].PROTOCOLO_NFE);
      insereValor('#txtDtEmissao', jsonStr[0].DT_EMISSAO);

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

  async function pedidoCancelado(sPedido) {
    const pesquisaParam = {
      tabela: 'PED_ITEN',
      camposSelect: ['CODIGO'],
      where: [`NUMERO = '${sPedido}' AND QTDE > 0`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

    return !(jsonStr.length > 0)
  };

  async function pedidoExpedido(sPedido) {
    const pesquisaParam = {
      tabela: 'PED_RESERVA',
      camposSelect: ['SUM(QTDE) QTDE'],
      where: [`NUMERO = '${sPedido}'`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

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

    if (jsonStr[0].QTDE == 0) {
      return true;
    }

    return false;
  };

  async function pedidoSemCondPagto(sPedido) {
    // validação parametro
    if (!bBuscaCondPagto) {
      return false;
    }

    // validação se possui operação
    const operacao = (await buscaValor('PEDIDO', ['OPERACAO'], 'NUMERO', sPedido)).OPERACAO;
    if ((operacao == '') || (operacao == '0')) {
      return false;
    }

    // validação se regra gera duplicata
    const pesquisaParam = {
      tabela: 'REGRA_FISCAL',
      camposSelect: ['DUPLI'],
      where: [`COD_OPER = ${operacao} AND DUPLI = 'S'`]
    }
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
    if (jsonStr.length == 0) {
      return false;
    }

    // validação se possui cond_pagto
    const pesquisaParamPed = {
      tabela: 'COND_PAGTO',
      camposSelect: ['NUMERO'],
      where: [`NUMERO = '${sPedido}' AND TIPO = 'P'`]
    }
    const jsonStrPed = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParamPed));
    return !(jsonStrPed.length > 0)
  };

  async function validaGravacao() {
    let bTudoBipado = true;

    $('#tabelaItens').DataTable().data().map((item) => {
      if (item.qtde > item.QTDE_CONF) {
        bTudoBipado = false;
      }
    });

    if (bTudoBipado) {
      clearInterval(idInterval);
      await gravaDados();
    };
  };

  async function validaEdicao() {
    try {
      const caixaBase = $(window.location.href.split('/')).get(-1);

      if (caixaBase == 'create') {
        return;
      };

      $('#divCaixa').removeClass('d-none');

      const caixa = atob(caixaBase).split(',');

      if (caixa[1] == 'true') {
        await editaExpedicao(caixa[0]);
      } else {
        await visualizaCaixa(caixa[0]);
      }
    } finally {
      atualizaTotais();
    }
  };

  function validaTotalExpedido() {
    $('#tabelaItens').DataTable().rows().data().map((item, index) => {
      if (item.qtde == item.QTDE_CONF) {
        item.codigo = item.codigo.replace('times-circle', 'check-circle').replace('#EEAD2D', 'green').replace("Aguardando Bipagem", "Barra Bipada");
        $('#tabelaItens').DataTable().row(index).data(item).draw(false);
      }
    })
  };

  function criaTabelaItens(data, columns) {
    if (visualizaBarra) {
      criaDataTablePadrao('#tabelaItens', false, false, false, false, true, true, '400px', data, colunasTabelaItens, [10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24], [], [], [], {}, 2, '', '', false, [], [6, 11, 23]);
    } else {
      criaDataTablePadrao('#tabelaItens', false, false, false, false, true, true, '400px', data, colunasTabelaItens, [7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24], [], [], [], {}, 2, '', '', false, [], [6, 11, 23]);
    }
  };

  function atualizaVolumes() {
    let qtdeVol = Math.floor(pegaValor('#txtTotal') > 50);
    if (qtdeVol == 0) {
      qtdeVol = 1;
    }
    if (bVolumeManual) {
      insereValor('#txtVolumes', qtdeVol);
    }
  };

  function atualizaTotais() {
    if (!$.fn.DataTable.isDataTable('#tabelaItens')) {
      return;
    };

    const total = $("#tabelaItens").DataTable().column(6, {}).data().sum();
    const conferidas = $("#tabelaItens").DataTable().column(23, {}).data().sum();
    const saldo = total - conferidas;

    insereValor('#txtTotal', total);
    insereValor('#txtConferidas', conferidas);
    insereValor('#txtSaldo', saldo);
  };

  async function confereBarra(biparEstornar, barra, barraLog = false) {
    try {

      async function bipaBarra(arrIndices) {
        const indice = arrIndices[0];
        const qtde = + $('#txtQtde').val();
        let retorno = 0;

        const dadosItem = $('#tabelaItens').DataTable().row(indice).data();

        if (((dadosItem.QTDE_CONF + (qtde)) <= dadosItem.qtde) && biparEstornar) {
          if (validaEstoqueBip && ((dadosItem.QTDE_CONF + qtde) > dadosItem.QTDE_EST)) {
            retorno = 5;
          } else if (!await addBarraLogLida(barraLog)) {
            retorno = 6;
          } else {
            dadosItem.QTDE_CONF += qtde;
            addBarraLida(barra);
            if (dadosItem.QTDE_CONF == dadosItem.qtde) {
              dadosItem.codigo = dadosItem.codigo.replace('times-circle', 'check-circle').replace('#EEAD2D', 'green').replace("Aguardando Bipagem", "Barra Bipada");
            }
            retorno = 0;
            await adicionaBarraBipadaEPC();
          }
        } else if (biparEstornar && (dadosItem.QTDE_CONF < dadosItem.qtde)) {
          retorno = 1;
        } else if (biparEstornar) {
          retorno = 2;
        } else if (!biparEstornar && ((dadosItem.QTDE_CONF - qtde) >= 0)) {
          dadosItem.codigo = dadosItem.codigo.replace('check-circle', 'times-circle').replace('green', '#EEAD2D').replace("Aguardando Bipagem", "Barra Bipada");
          dadosItem.QTDE_CONF -= qtde;
          removeBarraLogLida(barraLog);
          retorno = 0;
          await estornaBarraBipadaEPC();
        } else if (!biparEstornar && ((dadosItem.QTDE_CONF - qtde) < 0) && (qtde > 1)) {
          retorno = 3;
        } else {
          retorno = 4;
        }

        $('#tabelaItens').DataTable().row(indice).data(dadosItem).draw(false);
        $($('#tabelaItens tbody tr')[indice]).click();
        $('#tabelaItens').DataTable().context[0].nScrollBody.scrollTo(0, ($('.selected')[0].offsetTop));

        if ((arrIndices.length > 1) && (retorno != 0)) {
          arrIndices.shift();
          return await bipaBarra(arrIndices);
        } else {
          return retorno;
        }
      }

      const dados = $('#tabelaItens').DataTable().rows().data();
      let indices = [];
      dados.map((item, idx) => { if (item.barra == barra || item.barra28 == barra || item.barraCli == barra) { indices.push(idx) } });

      if (indices.length == 0) {
        msgAlerta('Nenhuma barra localizada.\r\nBarra lida: ' + $(`#txtBarra${biparEstornar ? '' : 'Estorno'}`).val());
        SomAlerta(BASE_URI, true);
        return;
      }

      if (barraLog) {
        $('#txtQtde').val('1');
      }

      const retorno = await bipaBarra(indices);
      switch (retorno) {
        case 0: {
          SomAlerta();
          break;
        }
        case 1: {
          msgAlerta('Impossível bipar quantidade maior do que há de pendente.');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 2: {
          msgAlerta('Quantidade total do item já conferida');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 3: {
          msgAlerta('Impossível estornar quantidade maior do que a conferida.');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 4: {
          msgAlerta('Toda a quantidade já foi estornada.');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 5: {
          msgAlerta('Estoque insuficiente para o item bipado.');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 6: {
          msgAlerta('Barra Log já lida, impossível ler novamente.');
          SomAlerta(BASE_URI, true);
          break;
        }
      }

    } finally {
      $(`#txtBarraEstorno`).val('');
      $(`#txtBarra`).val('');
      $(`#txtBarra${biparEstornar ? '' : 'Estorno'}`).focus();
      $('#txtQtde').val('1');
    }
  };

  async function buscaFuncionario() {
    const codUsuario = getCookie('cod_usuario');
    try {
      const pesquisaParam = {
        tabela: 'ACESSO_USUARIOS',
        camposSelect: ['ACESSO_USUARIOS.CODFUN', 'PESSOAL.NOME', 'ACESSO_USUARIOS.VISUALIZA_BARRA_EXP'],
        leftJoin: [{ tabela: 'PESSOAL', condicao: 'PESSOAL.CODIGO = ACESSO_USUARIOS.CODFUN' }],
        where: [`ACESSO_USUARIOS.CODIGO = '${codUsuario}'`]
      }
      const jsonStr = (await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam)))[0];

      visualizaBarra = jsonStr.VISUALIZA_BARRA_EXP == 'S';

      if (jsonStr.CODFUN == '') {
        return;
      }

      insereValor('#txtFuncionario', jsonStr.CODFUN, jsonStr.NOME);

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

  async function buscaPedidoComSemReserva() {
    const pedido = $('#txtPedido').attr('data-chave');
    const deposito = $('#txtDeposito').attr('data-chave');

    if (await pedidoSemCondPagto(pedido)) {
      msgAlerta('Sistema está com parâmetro configurado para buscar condições de pagamento porém não existe nenhuma informada para este pedido (COND_PAGTO), favor verificar.');
      $('#txtPedido').val('');
      return;
    }

    const pesquisaParam = {
      tabela: 'PED_RESERVA',
      camposSelect: ['RESERVA'],
      where: [`NUMERO = '${pedido}' AND QTDE > 0`],
      groupby: ['RESERVA']
    };

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

    validaEstoqueBip = bControlaEstoque;

    if (!validaEstoqueBip) {
      const depFatNeg = (await buscaValor('DEPOSITO', 'FAT_ESTOQUE_NEG', 'CODIGO', pegaChave('#txtDeposito'))).FAT_ESTOQUE_NEG;
      validaEstoqueBip = depFatNeg == 'N';
    }

    if (buscaReserva.length == 0) {
      escondeBloqueiaCampos(false);
      await buscaPedidoSemReserva(pedido);
    } else {
      escondeBloqueiaCampos(true);
      addReservasSelect(buscaReserva);
      await buscaPedidoComReserva(pedido, $('#txtReserva').val(), deposito);
      await validaReservaPedido(pedido);
    }

    if ((integracaoEPC != '0') && (integracaoEPC != '3')) {
      $('#btn-iniciar-epc').trigger('click');
    }
  };

  async function buscaPedcli(sPedido) {

    const pesquisaParam = {
      tabela: 'PEDIDO',
      camposSelect: ['PED_CLI'],
      where: [`NUMERO = '${sPedido}'`]
    };

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

    if (jsonStr.length == 0) {
      return;
    }
    insereValor('#txtPedcli', jsonStr[0].PED_CLI);
  };

  async function validaReservaPedido(sPedido) {
    $.LoadingOverlay('show');
    try {
      const pesquisaParam = {
        tabela: 'PEDIDO3',
        camposSelect: ['CAIXA'],
        where: [`NUMERO = '${sPedido}' AND RESERVA = 0 AND (NOTAFISCAL = '' OR NOTAFISCAL IS NULL)`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

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

      insereValor('#txtCaixa', jsonStr[0].CAIXA);
    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $.LoadingOverlay('hide');
    }
  };

  async function editaExpedicao(sCaixa) {
    $.LoadingOverlay('show');
    try {
      const pesquisaParam = {
        tabela: 'PED_ITEN',
        camposSelect: [
          'PED_ITEN.NUMERO', 'PED_ITEN.CODIGO', 'PRODUTO.DESCRICAO', 'PED_ITEN.COR', 'CADCOR.DESCRICAO DESCCOR', 'PED_ITEN.TAM', 'PED_ITEN.QUALIDADE', 'PA_ITEN.LOTE',
          'PED_ITEN.QTDE', 'PA_ITEN.BARRA', 'PA_ITEN.BARRA28', 'PA_ITEN.BARRACLI', '1 ORDEM', 'PED_ITEN.QTDE_F', 'PA_ITEN.LOCAL', '0 RESERVA',
          '0 BAIXADOS', `'0' BLOQUEIO`, 'PED_ITEN.ID IDITEMPED', '0 POSICAO', '0 IDRESERVA', 'PA_ITEN.ID IDPAITEN', 'PRODUTO.LOCAL ENDLOCAL',
          'CAD_LOC_ESTOQ.DESCRICAO DESC_END_LOCAL', 'COALESCE(PEDIDO3.QTDE, 0) QTDE_CONF', 'PEDIDO.DEPOSITO', 'PEDIDO.CODCLI', 'ENTIDADE.NOME', 'DEPOSITO.DESCRICAO DESC_DEPOSITO',
          'PA_ITEN.QUANTIDADE QTDE_EST'
        ],
        leftJoin: [
          { tabela: 'PEDIDO3', condicao: `PED_ITEN.NUMERO = PEDIDO3.NUMERO AND PED_ITEN.CODIGO = PEDIDO3.CODIGO AND PED_ITEN.COR = PEDIDO3.COR AND PED_ITEN.TAM = PEDIDO3.TAM AND PED_ITEN.DEPOSITO = PEDIDO3.DEPOSITO AND PED_ITEN.QUALIDADE = PEDIDO3.QUALIDADE AND PEDIDO3.CAIXA = '${sCaixa}'` },
          { tabela: 'PA_ITEN', condicao: 'PA_ITEN.CODIGO = PED_ITEN.CODIGO AND PA_ITEN.COR = PED_ITEN.COR AND PA_ITEN.TAM = PED_ITEN.TAM AND PA_ITEN.DEPOSITO = PED_ITEN.DEPOSITO AND PA_ITEN.TIPO = PED_ITEN.QUALIDADE' },
          { tabela: 'CADCOR', condicao: 'CADCOR.COR = PED_ITEN.COR' },
          { tabela: 'PRODUTO', condicao: 'PRODUTO.CODIGO = PED_ITEN.CODIGO' },
          { tabela: 'CAD_LOC_ESTOQ', condicao: 'CAD_LOC_ESTOQ.CODIGO = PRODUTO.LOCAL' },
          { tabela: 'PEDIDO', condicao: 'PEDIDO.NUMERO = PED_ITEN.NUMERO' },
          { tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = PEDIDO.CODCLI' },
          { tabela: 'DEPOSITO', condicao: 'DEPOSITO.CODIGO = PEDIDO.DEPOSITO' }
        ],
        where: [`PED_ITEN.NUMERO IN (SELECT NUMERO FROM [PEDIDO3] WHERE CAIXA = '${sCaixa}') AND PED_ITEN.QTDE > 0`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Caixa com quantidade total já faturada ou número incorreto.', null, null, () => { window.location.href = 'create'; });
        return;
      };

      insereValor('#txtCaixa', sCaixa);
      insereValor('#txtPedido', jsonStr[0].NUMERO, jsonStr[0].NOME);
      insereValor('#txtCliente', jsonStr[0].CODCLI, jsonStr[0].NOME);
      insereValor('#txtDeposito', jsonStr[0].DEPOSITO, jsonStr[0].DESC_DEPOSITO);

      let itensFormatados = corrigeCamposJson(jsonStr);

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

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

      criaTabelaItens(itensFormatados, dataSetCols);
      validaTotalExpedido();
      bloqueiaCampos();

    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $.LoadingOverlay('hide');
      if ($.fn.DataTable.isDataTable('#tabelaItens')) {
        $("#tabelaItens").DataTable().columns.adjust().draw(false);
      }

      if (((integracaoEPC != '0') && (integracaoEPC != '3')) || (integracaoEPC == '3')) {
        setTimeout(() => {
          $('#btn-iniciar-epc').trigger('click');
        }, 1500);
        setTimeout(() => {
          $('#btn-parar-epc').trigger('click');
        }, 6500);
      }
    }
  };

  async function visualizaCaixa(sCaixa) {
    $.LoadingOverlay('show');
    try {
      const pesquisaParam = {
        tabela: 'PEDIDO3',
        camposSelect: [
          'PEDIDO3.NUMERO', 'PEDIDO3.CODIGO', 'PRODUTO.DESCRICAO', 'PEDIDO3.COR', 'CADCOR.DESCRICAO DESCCOR', 'PEDIDO3.TAM', 'PEDIDO3.QUALIDADE', 'PA_ITEN.LOTE',
          '(PEDIDO3.QTDE_F [SOMA] PEDIDO3.QTDE) QTDE', 'PA_ITEN.BARRA', 'PA_ITEN.BARRA28', 'PA_ITEN.BARRACLI', '1 ORDEM', 'PEDIDO3.QTDE_F', 'PA_ITEN.LOCAL', '0 RESERVA',
          '0 BAIXADOS', `'0' BLOQUEIO`, 'PED_ITEN.ID IDITEMPED', '0 POSICAO', '0 IDRESERVA', 'PA_ITEN.ID IDPAITEN', 'PRODUTO.LOCAL ENDLOCAL',
          'CAD_LOC_ESTOQ.DESCRICAO DESC_END_LOCAL', '(PEDIDO3.QTDE_F [SOMA] PEDIDO3.QTDE) QTDE_CONF', 'PEDIDO.DEPOSITO', 'PEDIDO.CODCLI', 'ENTIDADE.NOME', 'DEPOSITO.DESCRICAO DESC_DEPOSITO'
        ],
        leftJoin: [
          { tabela: 'PA_ITEN', condicao: 'PA_ITEN.CODIGO = PEDIDO3.CODIGO AND PA_ITEN.COR = PEDIDO3.COR AND PA_ITEN.TAM = PEDIDO3.TAM AND PA_ITEN.DEPOSITO = PEDIDO3.DEPOSITO AND PA_ITEN.TIPO = PEDIDO3.QUALIDADE' },
          { tabela: 'PED_ITEN', condicao: 'PED_ITEN.NUMERO = PEDIDO3.NUMERO AND PED_ITEN.CODIGO = PEDIDO3.CODIGO AND PED_ITEN.COR = PEDIDO3.COR AND PED_ITEN.TAM = PEDIDO3.TAM AND PED_ITEN.DEPOSITO = PEDIDO3.DEPOSITO AND PED_ITEN.QUALIDADE = PEDIDO3.QUALIDADE' },
          { tabela: 'CADCOR', condicao: 'CADCOR.COR = PEDIDO3.COR' },
          { tabela: 'PRODUTO', condicao: 'PRODUTO.CODIGO = PEDIDO3.CODIGO' },
          { tabela: 'CAD_LOC_ESTOQ', condicao: 'CAD_LOC_ESTOQ.CODIGO = PRODUTO.LOCAL' },
          { tabela: 'PEDIDO', condicao: 'PEDIDO.NUMERO = PEDIDO3.NUMERO' },
          { tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = PEDIDO.CODCLI' },
          { tabela: 'DEPOSITO', condicao: 'DEPOSITO.CODIGO = PEDIDO.DEPOSITO' }
        ],
        where: [`PEDIDO3.CAIXA = '${sCaixa}'`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Caixa não encontrada.', null, null, () => { window.location.href = 'create'; });
        return;
      };

      insereValor('#txtCaixa', sCaixa);
      insereValor('#txtPedido', jsonStr[0].NUMERO, jsonStr[0].NOME);
      insereValor('#txtCliente', jsonStr[0].CODCLI, jsonStr[0].NOME);
      insereValor('#txtDeposito', jsonStr[0].DEPOSITO, jsonStr[0].DESC_DEPOSITO);

      jsonStr.map((item) => {
        item.QTDE_EST = 0;
      });

      let itensFormatados = corrigeCamposJson(jsonStr);

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

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

      criaTabelaItens(itensFormatados, dataSetCols);
      validaTotalExpedido();
      bloqueiaCamposVisualizacao();

    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $.LoadingOverlay('hide');
      if ($.fn.DataTable.isDataTable('#tabelaItens')) {
        $("#tabelaItens").DataTable().columns.adjust().draw(false);
      }
    }
  };

  async function buscaPedidoSemReserva(pedido) {
    try {
      const pesquisaParam = {
        tabela: 'PED_ITEN',
        camposSelect: [
          'PED_ITEN.CODIGO', 'PRODUTO.DESCRICAO', 'PED_ITEN.COR', 'CADCOR.DESCRICAO DESCCOR', 'PED_ITEN.TAM', 'PA_ITEN.TIPO QUALIDADE',
          'PED_ITEN.QTDE QTDE', 'PA_ITEN.BARRA', 'PA_ITEN.BARRA28', 'PA_ITEN.BARRACLI', '1 ORDEM', `COALESCE(PEDIDO3.CAIXA, '') CAIXA`,
          'COALESCE(PEDIDO3.QTDE_F, 0) QTDE_F', 'PA_ITEN.LOTE', 'PA_ITEN.LOCAL', '0 RESERVA', '0 BAIXADOS', `'0' BLOQUEIO`, 'PED_ITEN.ID IDITEMPED',
          '0 POSICAO', '0 IDRESERVA', 'PA_ITEN.ID IDPAITEN', 'PRODUTO.LOCAL ENDLOCAL', 'CAD_LOC_ESTOQ.DESCRICAO DESC_END_LOCAL', 'COALESCE(PEDIDO3.QTDE, 0) QTDE_CONF',
          'PA_ITEN.QUANTIDADE QTDE_EST', 'SUM(COALESCE(PED_RESERVA.QTDE, 0)) QTDE_RESERVADA'
        ],
        leftJoin: [
          { tabela: 'PEDIDO', condicao: 'PEDIDO.NUMERO = PED_ITEN.NUMERO' },
          { tabela: 'PEDIDO3', condicao: 'PEDIDO3.NUMERO = PED_ITEN.NUMERO AND PEDIDO3.CODIGO = PED_ITEN.CODIGO AND PEDIDO3.COR = PED_ITEN.COR AND PEDIDO3.TAM = PED_ITEN.TAM AND PEDIDO3.DEPOSITO = PEDIDO.DEPOSITO AND PEDIDO3.QUALIDADE = PED_ITEN.QUALIDADE' },
          { tabela: 'PA_ITEN', condicao: `PA_ITEN.CODIGO = PED_ITEN.CODIGO AND PA_ITEN.COR = PED_ITEN.COR AND PA_ITEN.TAM = PED_ITEN.TAM AND PA_ITEN.DEPOSITO = PEDIDO.DEPOSITO  AND PA_ITEN.TIPO = '1'` },
          { tabela: 'PED_RESERVA', condicao: 'PED_RESERVA.NUMERO <> PED_ITEN.NUMERO AND PED_RESERVA.CODIGO = PED_ITEN.CODIGO AND PED_RESERVA.COR = PED_ITEN.COR AND PED_RESERVA.TAM = PED_ITEN.TAM AND PED_RESERVA.DEPOSITO = PEDIDO.DEPOSITO AND PED_RESERVA.QUAL = PED_ITEN.QUALIDADE' },
          { tabela: 'CADCOR', condicao: 'CADCOR.COR = PED_ITEN.COR' },
          { tabela: 'PRODUTO', condicao: 'PRODUTO.CODIGO = PED_ITEN.CODIGO' },
          { tabela: 'CAD_LOC_ESTOQ', condicao: 'CAD_LOC_ESTOQ.CODIGO = PRODUTO.LOCAL' }
        ],
        where: [`PED_ITEN.NUMERO = '${pedido}' AND PED_ITEN.QTDE > 0`],
        groupBy: [
          'PED_ITEN.CODIGO', 'PRODUTO.DESCRICAO', 'PED_ITEN.COR', 'CADCOR.DESCRICAO', 'PED_ITEN.TAM', 'PA_ITEN.TIPO',
          'PED_ITEN.QTDE', 'PA_ITEN.BARRA', 'PA_ITEN.BARRA28', 'PA_ITEN.BARRACLI', 'PEDIDO3.CAIXA',
          'PEDIDO3.QTDE_F', 'PA_ITEN.LOTE', 'PA_ITEN.LOCAL', 'PED_ITEN.ID',
          'PA_ITEN.ID', 'PRODUTO.LOCAL', 'CAD_LOC_ESTOQ.DESCRICAO', 'PEDIDO3.QTDE',
          'PA_ITEN.QUANTIDADE'
        ]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

      if (jsonStr.length == 0) {
        msgAlerta('Pedido não possui quantidades pendendes para expedir.');
        await abandonaExpedicao();
        return;
      };

      jsonStr.map(item => {
        item.QTDE_EST -= item.QTDE_RESERVADA;
        if (item.CAIXA != '') {
          $('#txtCaixa').val(item.CAIXA);
        }
      });

      let itensFormatados = corrigeCamposJson(jsonStr);

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

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

      criaTabelaItens(itensFormatados, dataSetCols);
      validaTotalExpedido();
      bloqueiaCampos();

    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $.LoadingOverlay('hide');
      if ($.fn.DataTable.isDataTable('#tabelaItens')) {
        $("#tabelaItens").DataTable().columns.adjust().draw(false);
      }
    }
  };

  async function verificaBuscaEpc(sPedido) {
    try {
      const response = await requisicao('GET', '/sisplan/pedido3/v1/itensepc?', `NUMERO=${sPedido}`, null);

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

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

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

      // função não finalizada

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

  async function buscaPedidoComReserva(pedido, reserva, deposito) {
    $.LoadingOverlay('show');
    try {
      const response = await requisicao('GET', '/expedicao?', `NUMERO=${pedido}&DEPOSITO=${deposito}&RESERVA=${reserva}&WEB=true`, null);

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

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

      jsonStr.map((item) => {
        // item.qtde -= item.baixados;
        item.qtdeF = item.baixados;
        item.QTDE_CONF = 0;
        item.codigo = `<div class="icheck-primary d-inline"><span class="fas fa-times-circle mr-1" title="Aguardando Bipagem" style="color:#EEAD2D"></span></div>  ` + item.codigo;
        item.QTDE_EST = item.qtde_est;
        delete item.qtde_est;
        delete item.qtdeOriginal;
      });

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

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

      criaTabelaItens(jsonStr, dataSetCols);

    } catch (error) {
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $.LoadingOverlay('hide');
      $("#tabelaItens").DataTable().columns.adjust().draw(false);
      $('#txtPedido').prop('disabled', true);
      $('#txtPedido').prop('readonly', true);
      $('#btnPedido').prop('disabled', true);
      $('#btnDesistir').removeClass('d-none');
      $('#btnVoltar').addClass('d-none');
    }
  };

  async function gravaDados() {

    if (!validaGravar()) {
      msgAlerta('Nenhum item bipado, favor verificar.');
      return;
    }

    if (bBuscaCondPagto && !bNaoFatura && validaExpedicaoParcial()) {
      msgAlerta('Configurado para buscar condições de pagamento do pedido, impossível realizar expedição parcial. Necessário bipar todos os itens.');
      return;
    }

    if (bNaoPermiteParcial && validaExpedicaoParcial()) {
      msgAlerta('Necessário bipar todos os itens para realizar a expedição, favor verificar.');
      return;
    }

    if ($('#btnGravar').prop('disabled')) {
      return;
    }

    $('#btnGravar').prop('disabled', true);
    $('#btn-iniciar-epc').prop('disabled', true);
    $('#btn-parar-epc').prop('disabled', true);

    const pedido3 = retornaClassePedido3();

    const registroLiberado = await verificarRegistro('EXPEDICAO', pedido3.NUMERO);
    if (!registroLiberado) {
      return;
    }
    await liberarRegistro('EXPEDICAO', pedido3.NUMERO);

    if (bNaoFatura) {
      pedido3.FATURAR = false;
      setTimeout(async () => {
        await realizaFaturamentoExpedicao(pedido3);
      }, 200);
    } else {
      setTimeout(async () => {
        if (!pedido3.FATURAR) {
          msgAlerta('Deseja faturar essa expedição?', async function () { pedido3.FATURAR = true; await realizaFaturamentoExpedicao(pedido3) }, async function () { await realizaFaturamentoExpedicao(pedido3) });
        } else {
          await realizaFaturamentoExpedicao(pedido3);
        }
      }, 200);
    }

    $('#btnGravar').prop('disabled', false);
    $('#btn-iniciar-epc').prop('disabled', false);
    $('#btn-parar-epc').prop('disabled', false);
  };

  async function realizaFaturamentoExpedicao(pedido3) {
    $.LoadingOverlay('show');
    try {
      const response = await requisicao('POST', '/expedicao?', '', JSON.stringify(pedido3), 900000);

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

      if (response.status != 200) {
        msgAlerta(jsonStr.mensagem.mensagem, null, null, () => { window.location.href = 'create' }, () => { window.location.href = 'create' });
        return;
      }

      if (!pedido3.TUDOBIPADO) {
        await imprimeExpPendente(pedido3.NUMERO);
      }

      let relogarTela = true;

      if (bTransmiteNota && jsonStr.resultado.faturar) {
        if (await transmiteNota(jsonStr.resultado.fatura, jsonStr.resultado.serie)) {
          if (bEnviaEmail) {
            await enviaEmail(jsonStr.resultado.fatura, jsonStr.resultado.serie);
          }
          if (bEmailTransp) {
            await enviaEmailTransp(jsonStr.resultado.fatura, jsonStr.resultado.serie);
          }
          await imprimeSigep(jsonStr.resultado.fatura, jsonStr.resultado.serie);
          await imprimeNota(jsonStr.resultado.fatura, jsonStr.resultado.serie);
        } else {
          relogarTela = false;
        }
      }

      if (relogarTela) {
        await criaMensagemSucesso('Expedição realizada com sucesso.', () => { window.location.href = 'create' });
      }

    } catch (error) {
      $('#btnGravar').prop('disabled', false);
      $('#btn-iniciar-epc').prop('disabled', false);
      $('#btn-parar-epc').prop('disabled', false);
      console.error(error);
      $.LoadingOverlay('hide');
    } finally {
      $('#btnGravar').prop('disabled', false);
      $('#btn-iniciar-epc').prop('disabled', false);
      $('#btn-parar-epc').prop('disabled', false);
      $.LoadingOverlay('hide');
    }
  };

  async function enviaEmail(sFatura, sSerie) {

    try {
      try {
        $.LoadingOverlay("show");
        const response = await requisicao('POST', '/sisplan/nfe/v1/enviaremail?', `FATURA=${sFatura}&SERIE=${sSerie}&CODUSUARIO=${getCookie('cod_usuario')}`, null, 300000);
        if (!response) {
          return;
        }
        const jsonStr = await response.json();
        if (response.status != 200) {
          msgErro(jsonStr.mensagem)
          return;
        }
        await msgSucesso(jsonStr.mensagem);
      } catch (error) {
        console.error(error);
        msgErro('Erro ao enviar e-mail para cliente.');
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  };

  async function enviaEmailTransp(sFatura, sSerie) {
    const url = '/sisplan/nfe/v1/enviaremailtransp?';
    try {
      try {
        $.LoadingOverlay("show");
        const response = await requisicao('POST', url, `FATURA=${sFatura}&SERIE=${sSerie}&CODUSUARIO=${getCookie('cod_usuario')}`, null, 300000);
        if (!response) {
          return;
        }
        const jsonStr = await response.json();
        if (response.status != 200) {
          msgErro(jsonStr.mensagem)
          return;
        }
        await msgSucesso(jsonStr.mensagem);
      } catch (error) {
        console.error(error);
        msgErro('Erro ao enviar e-mail para transportadora.');
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  }

  async function transmiteNota(sFatura, sSerie) {
    const responseTransmissao = await requisicao('POST', '/Sisplan/NFE/v1/GerarNFE?', `SERIE=${sSerie}&FATURA=${sFatura}&FINALIDADE=${0}&JUSTIFICATIVA=${''}&TIPO_TRANSMISSAO=${0}&CERTA3=${bUsaCertificadoA3 ? '1' : '0'}`, null, 120000);

    if (responseTransmissao.status != 200) {
      jsonStr = await responseTransmissao.json();
      msgAlerta(jsonStr.mensagem, null, null, () => { window.location.href = 'create' }, () => { window.location.href = 'create' });
      return false;
    }

    if (bUsaCertificadoA3 && (responseTransmissao.status == 200)) {
      const xml = await responseTransmissao.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();
        msgAlerta(mensagemErro, null, null, () => { window.location.href = 'create' }, () => { window.location.href = 'create' });
        return false;
      }
      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 (!reponseApiWeb) {
        return false;
      }
      if (reponseApiWeb.status != 200) {
        const mensagemRetorno = await reponseApiWeb.json();
        msgAlerta(mensagemRetorno.mensagem, null, null, () => { window.location.href = 'create' }, () => { window.location.href = 'create' });
        return false;
      }
    };
    return true;
  };

  async function imprimeNota(sFatura, sSerie) {
    let url = layoutNFE == 'NFE' ? '/sisplan/nfe/v1/imprimirnfe?' : '/sisplan/nfe/v1/imprimirnfesimplificada?';
    url += `FATURA=${sFatura}&SERIE=${sSerie}`;
    try {
      const bImprimeAutomatico = await verificaImprimirAutomatico(layoutNFE);
      const arquivo = await GeraRelatorio(url + '&', 'PUT', 15000, false, layoutNFE);
      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(BASE_URI + '/relatorios_api/pdf/' + arquivo, '_blank');
        }
        await limparRelatorios();
        window.location.href = 'create';
      }
    } catch (error) {
      console.error(error);
      window.location.href = 'create';
    }
  };

  async function imprimeSigep(sFatura, sSerie) {
    try {
      $.LoadingOverlay('show');
      try {
        const url = `/sisplan/impressao/v1/imprimiretiqsigep?`;
        const filtros = `FATURA=${sFatura}&SERIE=${sSerie}`;
        const bImprimeAutomatico = await verificaImprimirAutomatico('EtiquetaSigep');
        const arquivo = await GeraRelatorio(`${url}${filtros}&`, 'GET', 100000, false, 'EtiquetaSigep');
        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 imprimeExpPendente(sPedido) {
    try {
      $.LoadingOverlay('show');
      try {
        const url = `/sisplan/impressao/v1/exppendente?`;
        const filtros = `PEDIDO=${sPedido}`;
        const bImprimeAutomatico = await verificaImprimirAutomatico('ExpPendente');
        const arquivo = await GeraRelatorio(`${url}${filtros}&`, 'GET', 100000, false, 'ExpPendente');
        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 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"], 
        "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 buscaEspecieEmpresa() {
    try {
      const pesquisaParam = {
        tabela: 'EMPRESA',
        camposSelect: ['EMP_ESPECIE'],
        where: [`EMP_ID = ${getCookie('emp_id')}`]
      }
      const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

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

      insereValor('#txtEspecie', jsonStr[0].EMP_ESPECIE);
    } catch (error) {
      console.error(error);
    }
  };

  function adicionaPesquisaAutocompleta() {
    $('#btnPedido').pesquisa_serverside(
      ['#txtPedido', '#txtDeposito', '#txtCliente'],
      ['PEDIDO.NUMERO', 'PEDIDO.DEPOSITO', 'PEDIDO.CODCLI'],
      ['ENTIDADE.NOME', 'DEPOSITO.DESCRICAO', 'ENTIDADE.NOME', 'PEDIDO.PED_CLI'],
      `{"tabela":"PEDIDO", 
        "camposSelect":[ "PEDIDO.NUMERO", "PEDIDO.DEPOSITO", "PEDIDO.CODCLI", "ENTIDADE.NOME", "DEPOSITO.DESCRICAO", "PEDIDO.PED_CLI"], 
        "leftjoin": [ 
          {"tabela": "ENTIDADE", "condicao": "ENTIDADE.CODCLI = PEDIDO.CODCLI"},
          {"tabela": "DEPOSITO", "condicao": "DEPOSITO.CODIGO = PEDIDO.DEPOSITO"}
        ],
        "where": null
       }`,
      'Pesquisa Pedido',
      buscaPedidoComSemReserva
    );

    $('#txtFuncionario').autocompleta(1, `JSON={ "tabela":"PESSOAL", "camposSelect":["CODIGO CHAVE, NOME DESCRICAO"], "where": null }`);
    $('#btnFuncionario').pesquisa('#txtFuncionario', "CODIGO", "NOME", `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"PESSOAL", "camposSelect":["CODIGO", "NOME"], "where": null}`, "Pesquisa Funcionário", "PESSOAL");
    $('#btnAFuncionario').on('click', function () { $('#txtFuncionario').val(''); });

    $('#btnPedidoBusca').pesquisa_serverside(
      ['#txtPedidoBusca'], ['PEDIDO.NUMERO'], ['ENTIDADE.NOME'],
      `{"tabela":"PEDIDO", 
        "camposSelect":[ "PEDIDO.NUMERO", "PEDIDO.DEPOSITO", "PEDIDO.CODCLI", "ENTIDADE.NOME", "DEPOSITO.DESCRICAO"], 
        "leftjoin": [ 
          {"tabela": "ENTIDADE", "condicao": "ENTIDADE.CODCLI = PEDIDO.CODCLI"},
          {"tabela": "DEPOSITO", "condicao": "DEPOSITO.CODIGO = PEDIDO.DEPOSITO"}
        ],
        "where": null
       }`,
      'Pesquisa Pedido',
      buscaNotaPedido
    );
    $('#btnAPedidoBusca').on('click', function () { limpaCamposNota(); });

    $('#btnNota').pesquisa_serverside(
      ['#txtNota', '#txtaaaaaa'],
      ['FATURA', 'DT_EMISSAO'],
      ['SERIE', 'DT_EMISSAO'],
      `{"tabela":"nota", "camposSelect":[ "FATURA", "SERIE", "DT_EMISSAO" ], "where": null}`,
      'Pesquisa Nota',
      buscaPedidoNota
    );
    $('#txtNota').autocompleta(3, `JSON={ "tabela":"NOTA", "camposSelect":["FATURA CHAVE, SERIE DESCRICAO"], "where": [] }`, undefined, undefined, undefined, buscaPedidoNota);
    $('#btnANota').on('click', function () { limpaCamposNota(); });

    $('#txtVolumes').maskMoney({
      decimal: '.',
      thousands: '',
      precision: 0,
    });
  };

  $('#btn-iniciar-epc').on('click', async function () {
    try {
      $('#btn-iniciar-epc').prop('disabled', true);
      $('#btn-parar-epc').prop('disabled', false);
      $('#btnIniciarEPCConferencia').prop('disabled', true);
      $('#btnPararEPCConferencia').prop('disabled', true);
      epcVenda = true;
      await iniciarEPC();
    } catch (error) {
      console.error(error)
    }
  })

  $('#btn-parar-epc').on('click', async function () {
    try {
      $('#btn-iniciar-epc').prop('disabled', false);
      $('#btn-parar-epc').prop('disabled', true);
      $('#btnIniciarEPCConferencia').prop('disabled', false);
      $('#btnPararEPCConferencia').prop('disabled', false);
      await pararEPC();
    } catch (error) {
      console.error(error)
    }
  })

  async function iniciarEPC() {
    $.LoadingOverlay("show");
    try {
      const url = '/epc/inicia?';
      const response = await requisicao_ecf('POST', url, `INTEGRACAO=${integracaoEPC}`);

      if ((!response) || (response.status != 200)) {
        msgAlerta('Erro ao iniciar a leitura RFID!');
      }

    } catch (error) {
      console.error('Erro ao iniciar a leitura RFID', error);
    } finally {
      $.LoadingOverlay("hide");
    }
  }

  async function pararEPC() {
    $.LoadingOverlay("show");
    try {
      const url = '/epc/para?';
      const response = await requisicao_ecf('PUT', url, `INTEGRACAO=${integracaoEPC}`);

      if ((!response) || (response.status != 200)) {
        msgAlerta('Erro ao parar a leitura RFID!');
      }

      await retornaCodigosEPC();

    } catch (error) {
      console.error('Erro ao parar a leitura RFID', error);
    } finally {
      $.LoadingOverlay("hide");
    }
  }

  async function retornaCodigosEPC(estorno = false, listaEPC) {
    $.LoadingOverlay("show");
    try {
      const url = '/epc/retorna?';
      const response = await requisicao_ecf('GET', url, `INTEGRACAO=${integracaoEPC}`);

      if ((!response) || (response.status != 200)) {
        msgAlerta('Erro ao retornar codigos da leitura RFID!')
      }
      listaBarrasForamBipadasEPC = JSON.parse(await response.text());

      if (integracaoEPC == '2') {
        listaBarrasForamBipadasEPC = listaBarrasForamBipadasEPC.data.epcs;
      }

      if (listaBarrasForamBipadasEPC.length == 0) {
        msgAlerta('Nenhum código bipado!');
        return;
      }

      if (!estorno) {
        if (await barraJaEstaBipadaEPC()) {
          estorno = true;
        }
      }

      if (listaBarrasForamBipadasEPC.length > 0) {
        await retornaProdutosEPC(estorno ? listaEPC : listaBarrasForamBipadasEPC, estorno);
      }

    } catch (error) {
      console.error('Erro ao retornar codigos da leitura RFID', error);
    } finally {
      $.LoadingOverlay("hide");
    }
  }

  async function barraJaEstaBipadaEPC(sCodigoEPC) {
    try {
      // aqui ele pega os que foram bipados e compara com os que estão na tabela itens para nao bipar 2x
      const barrasLidas = listaBarrasForamBipadasEPC.filter((barrasBipadas) => listaBarrasBipadasEPC.includes(barrasBipadas));

      if (barrasLidas.length > 0) {
        // aqui ele pega só os que foram bipados e joga pra variavel global
        listaBarrasForamBipadasEPC = listaBarrasForamBipadasEPC.filter((barrasBipadas) => !listaBarrasBipadasEPC.includes(barrasBipadas));
        msgAlerta(`RFID ${barrasLidas.join(', ')} já lido nesta expedição, o mesmo será estornado.`);
        await limpaEPCSBipados(barrasLidas)
        return true;
      }

      return false;

    } catch (error) {
      console.error('barra_EPC', error);
      msgErro('Erro ao processar barra EPC.');
    }
  }

  async function retornaProdutosEPC(codigos, estorno = false) {

    async function retornaIdEPC(codigos) {
      const codigosWhere = codigos.map((codigo) => "'" + codigo + "'");
      const pesquisaIdEPC = {
        tabela: "EPC",
        camposSelect: [
          "EPC",
          "ID",
          "PERMITE_MOVIMENTACAO",
        ],
        where: [`EPC IN (${codigosWhere.toString()})`],
      };

      const json = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaIdEPC));


      await verificaSeTodosEPCsExistem(codigos, json);

      return json;
    }

    async function verificaSeTodosEPCsExistem(codigos, retornos) {
      try {
        const codigosRetornados = retornos.map((codigo) => codigo.EPC);
        const codigoNaoExiste = codigos.filter((codigo, i) => !codigosRetornados.includes(codigo));

        if (codigoNaoExiste.length > 0) {
          msgAlerta(`Codigos: ${JSON.stringify(codigoNaoExiste)} não existem ou estão desativado na base de dados, faça a bipagem manual`)
        }

      } catch (error) {
        console.error('Erro verificar codigos RFID', error);
      }
    }

    async function retornaDadosProdutoEPC(dadosEPC) {
      const ids = dadosEPC.map((dado) => "'" + dado.ID + "'");

      const pesquisaDadosProdutosEPC = {
        tabela: "EPC_PRODUTO",
        camposSelect: [
          "EPC_PRODUTO.CODIGO",
          "EPC_PRODUTO.COR",
          "EPC_PRODUTO.TAMANHO",
          "EPC.EPC",
        ],
        leftjoin: [{
          tabela: "EPC",
          condicao: "EPC_PRODUTO.ID_EPC = EPC.ID"
        }],
        where: [`EPC_PRODUTO.ID_EPC IN (${ids.toString()})`],
      };

      const json = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaDadosProdutosEPC));

      return json;
    }

    try {
      const dadosEPC = await retornaIdEPC(codigos);
      const naoPermiteMovimentacao = dadosEPC.filter((dadoEPC) => dadoEPC.PERMITE_MOVIMENTACAO != 'S');
      const permiteMovimentacao = dadosEPC.filter((dadoEPC) => dadoEPC.PERMITE_MOVIMENTACAO == 'S');
      if (permiteMovimentacao.length > 0) {
        const produtos = await retornaDadosProdutoEPC(permiteMovimentacao);
        await bipaEPC(produtos, estorno);
      }
      naoPermiteMovimentacao.length > 0 && msgAlerta(`Codigos: ${naoPermiteMovimentacao.map((dado) => `${dado.EPC},`)} não existem ou estão desativados na base de dados, faça a bipagem manual!`);

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

  async function limpaEPCSBipados(barras) {
    try {
      await retornaCodigosEPC(true, barras);
      listaBarrasBipadasEPC = listaBarrasBipadasEPC.filter((barrasBipadas) => !barras.includes(barrasBipadas));
      listaBarrasForamBipadasEPC = [];
    } catch (error) {
      console.error('Erro ao limpar a leitura RFID', error);
    }
  }

  async function bipaEPC(itensEPC, estorno) {

    async function retornaBarrasEPC(itens) {
      const sDeposito = pegaChave("#txtDeposito");
      const arrayBarras = [];
      await Promise.all(itens.map(async (item) => {

        const dadosBarraEPC = {
          tabela: "PA_ITEN",
          camposSelect: [
            "PA_ITEN.BARRA",
            "PA_ITEN.BARRACLI",
            "PA_ITEN.BARRA28",
            "PA_ITEN.ID",
            `'${item.EPC}' EPC`,
            "COALESCE(BARRA_LOG.BARRA, '') BARRALOG"
          ],
          leftjoin: [{
            tabela: "BARRA_LOG",
            condicao: `BARRA_LOG.EPC = '${item.EPC}'`
          }],
          where: [`PA_ITEN.CODIGO = '${item.CODIGO}' AND PA_ITEN.COR = '${item.COR}' AND PA_ITEN.TAM = '${item.TAMANHO}' AND PA_ITEN.DEPOSITO = '${sDeposito}' `],
        };

        const json = await retornaJsonPesquisaPadrao(JSON.stringify(dadosBarraEPC));
        if ((json) && (json.length > 0)) {
          if (json[0].BARRALOG != '') {
            arrayBarras.push({
              BARRA: json[0].BARRALOG,
              IDITEM: json[0].ID,
              EPC: json[0].EPC
            });
          } else if (json[0].BARRA != '') {
            arrayBarras.push({
              BARRA: json[0].BARRA,
              IDITEM: json[0].ID,
              EPC: json[0].EPC
            });
          } else if (json[0].BARRACLI != '') {
            arrayBarras.push({
              BARRA: json[0].BARRACLI,
              IDITEM: json[0].ID,
              EPC: json[0].EPC
            });
          } else if (json[0].BARRA28 != '') {
            arrayBarras.push({
              BARRA: json[0].BARRA28,
              IDITEM: json[0].ID,
              EPC: json[0].EPC
            });
          } else {
            arrayBarras.push({
              BARRA: '',
              IDITEM: json[0].ID,
              EPC: json[0].EPC
            });
          }
        } else {
          msgAlerta(`Não existe barra para esse RFID: ${item.EPC}`);
        }
      }));

      return arrayBarras
    }

    try {
      const barrasEPC = await retornaBarrasEPC(itensEPC);

      async function processarBarras() {
        for (const barra of barrasEPC) {
          $('#txtQtde').val(1);
          $('#txtBarra').val(barra.BARRA);
          $('#txtCodigoEPC').val(barra.EPC);
          await saidaBarra(!estorno, estorno);
          await sleep(200);
        }
      }

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

  async function estornaBarraBipadaEPC() {
    if (integracaoEPC != '0') {
      const sBarra = $('#txtCodigoEPC').val();
      try {
        listaBarrasBipadasEPC = [...listaBarrasBipadasEPC.filter(item => item.barra !== sBarra)];
        $('#txtCodigoEPC').val('');
      } catch (error) {
        console.error(error);
      }
    }
  }

  async function adicionaBarraBipadaEPC() {
    if (integracaoEPC != '0') {
      const codigoEPC = $('#txtCodigoEPC').val();
      try {
        if (codigoEPC != '') {
          listaBarrasBipadasEPC.push(codigoEPC);
          return true;
        }
        $('#txtCodigoEPC').val('');
      } catch (error) {
        console.error(error);
      }
    }
  }

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

  async function saidaBarra(bBipar = true, bEstornoEpc = false) {
    try {
      let barra = $('#txtBarra').val();
      if (barra == '') {
        return;
      }
      if ($('#txtPedido').val() == '') {
        $('#txtBarra').val('');
        return;
      }
      if ((($('#modal-warning').data('bs.modal') || {})._isShown == true) && (!bEstornoEpc)) {
        $('#txtBarra').val('');
        return;
      }

      let barraLog = false;
      let barra28 = '';
      if ((bBarraLog == '1') || (bBarraLog == '2')) {
        barra28 = await extraiBarra28(barra);
        if (barra28 && (barra28 != '')) {
          barraLog = barra;
          barra = barra28;
        }
      }

      if (!barraLog && (bBarraLog == '2')) {
        msgAlerta('Necessário bipar uma BarraLog.', undefined, undefined, () => { $('#txtBarra').val('').focus() });
        $('#txtBarra').val('').focus();
        return;
      }

      await confereBarra(bBipar, barra, barraLog);
      await validaGravacao();
      if (!idInterval) {
        iniciaTimer();
      };
    } finally {
      atualizaTotais();
    }
  }

  async function buscaEPCApiSisplan() {
    $.LoadingOverlay('show');
    $('#btnRFID').prop('disabled', true);
    try {
      const pedido = pegaChave('#txtPedido');
      const deposito = pegaChave('#txtDeposito');
      const reserva = $('#divReserva').hasClass('d-none') ? '' : $('#txtReserva').val();
      if (pedido == '') {
        msgAlerta('Necessário informar um número de pedido');
      }

      let response = await requisicao('GET', '/sisplan/epc/v1/buscaepcexpedicaoapisisplan?', `NUMERO=${pedido}&DEPOSITO=${deposito}${(reserva != '') ? ('&RESERVA=' + reserva) : ''}`, null, 30000);

      const jsonStr = await response.json();

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

      let barra;
      for (const epc of jsonStr) {
        if (epc.BARRA != '') {
          barra = epc.BARRA;
        } else if (epc.BARRA28 != '') {
          barra = epc.BARRA28;
        } else if (epc.BARRACLI != '') {
          barra = epc.BARRACLI;
        }
        $('#txtQtde').val(1);
        $('#txtBarra').val(barra);
        $('#txtCodigoEPC').val(epc.EPC);

        await saidaBarra();
        await sleep(200);
      }

    } catch (error) {
      console.log(error)
    } finally {
      $('#btnRFID').prop('disabled', false);
      $.LoadingOverlay('hide');
    }
  }

  validaBordaCampo("#barraBipar");

  function validaBordaCampo(idBarra) {
    if ($("#txtCodigoEPC").is("[hidden]")) {
      $(idBarra).addClass("arredondarCantos")
    } else {
      $(idBarra).removeClass("arredondarCantos")
    };
  };
});