$('#tutorial').on('click', function () {
  $(document).ready(async function () {
    const driver = new Driver({
      doneBtnText: 'Sair',
      closeBtnText: 'Fechar',
      nextBtnText: 'Próximo',
      prevBtnText: 'Anterior',
      allowClose: false,
      animate: true,
      onNext: (Element) => {
        if ((Element.node.id == 'avancar1')) {
          $('#avancar1').trigger('click');
        } else if ((Element.node.id == 'avancar2')) {
          $('#avancar2').trigger('click');
        };
      },
      onPrevious: (Element) => {
        if ((Element.node.id == 'voltar3')) {
          $('#voltar3').trigger('click');
        } else if ((Element.node.id == 'voltar2')) {
          $('#voltar2').trigger('click');
        };
      }
    });

    driver.defineSteps([{
      element: '.dadosGerais',
      popover: {
        title: 'Dados Gerais',
        description: 'Aqui estão os dados gerais.',
        position: 'top'
      }
    },
    {
      element: '.dadosCores',
      popover: {
        title: 'Cores',
        description: 'Aqui estão as cores.',
        position: 'top'
      }
    },
    {
      element: '.divResumo',
      popover: {
        title: 'Quantidade setores',
        description: 'Tabela com o resumo das quantidades de cada setor/parte.',
        position: 'top'
      }
    },
    {
      element: "#btnVoltar",
      popover: {
        title: "Botão Voltar",
        description:
          "Ao clicar nesse botão você retorna para a tela de consulta.",
        position: "left",
      },
    },
    {
      element: '#avancar1',
      popover: {
        title: 'Botão Avançar',
        description: 'Clique aqui para ir para a próxima aba.',
        position: 'left'
      }
    },
    {
      element: '#voltar2',
      popover: {
        title: 'Botão para Voltar',
        description: 'Clique aqui para voltar a aba anterior.',
        position: 'top'
      }
    },
    {
      element: '.divDadosMov',
      popover: {
        title: 'Dados da Movimentação',
        description: 'Aqui estão os dados a serem informados para fazer a movimentação.',
        position: 'top'
      }
    },
    {
      element: '#txtParte',
      popover: {
        title: 'Campo Parte',
        description: 'Informar a parte a ser movimentada.',
        position: 'top'
      }
    },
    {
      element: '#txtSetor',
      popover: {
        title: 'Campo Setor',
        description: 'Informar o setor a ser movimentado.',
        position: 'top'
      }
    },
    {
      element: '#txtEmpresaDestino',
      popover: {
        title: 'Campo Empresa Destino',
        description: 'Informar a empresa destino a ser movimentada.',
        position: 'top'
      }
    },
    {
      element: '#avancar2',
      popover: {
        title: 'Botão Avançar',
        description: 'Clique aqui para avançar para a próxima aba.',
        position: 'top'
      }
    },
    {
      element: '#voltar3',
      popover: {
        title: 'Botão para Voltar',
        description: 'Clique aqui para voltar a aba anterior.',
        position: 'top'
      }
    },
    {
      element: '#formcard3',
      popover: {
        title: 'Grade',
        description: 'Grade para ser informado as quantidades a serem movimentadas.',
        position: 'top'
      }
    },
    {
      element: '#btnGravar',
      popover: {
        title: 'Botão Gravar',
        description: 'Clique aqui para movimentar as quantidades informadas.',
        position: 'left'
      }
    }
    ]);
    driver.start();
  });
});

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

  $('#msform').validate({
    debug: false,
    ignore: "",
    rules: {
      txtParte: {
        required: true,
      },
      txtSetor: {
        required: true,
      },
      txtEmpresaDestino: {
        required: true,
      },
      txtQualidade: {
        required: true,
      },
      txtTipoBaixa: {
        required: true,
      },
      txtDeposito: {
        required: true,
      },
      txtProximoSetor: {
        required: true,
      }
    },
    messages: {
      txtParte: {
        required: "Informe a parte."
      },
      txtSetor: {
        required: "Informe um setor."
      },
      txtEmpresaDestino: {
        required: "Informe a empresa destino."
      },
      txtQualidade: {
        required: "Informe uma qualidade."
      },
      txtTipoBaixa: {
        required: "Informe um Tipo de Baixa."
      },
      txtDeposito: {
        required: "Informe um Depósito."
      },
      txtProximoSetor: {
        required: "Informe um setor."
      }
    },
    errorElement: 'span',
    errorPlacement(error, element) {
      error.addClass('invalid-feedback');
      element.closest('.form-group').append(error);
    },
    highlight(element) {
      $(element).addClass('is-invalid');
    },
    unhighlight(element) {
      $(element).removeClass('is-invalid');
    }
  });

  let dadosConsumo;
  let dadosConsumoOF;
  let listaBarrasBipadasEPC = [];
  let listaBarrasForamBipadasEPC = [];
  let barrasLidas = [];
  let barrasLog = [];
  const parametrosOP = await BuscaParametrosOrdemProducao();
  const bPermiteQtdeFracionada = parametrosOP[2].VALOR == '1';
  const integracaoEPC = await CopiaParametro('EXPEDICAO', 7);
  const bBarraLog = await CopiaParametro('SISTEMA', 0);
  let listaBarrasBipadas = [];

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

  $('body').keydown(function (e) {
    const keyCode = e.keyCode || e.which
    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);
    }
  });

  function pegarDataAtual() {
    let dataAtual = new Date();
    const dia = dataAtual.getDate();
    const mes = dataAtual.getMonth() + 1;
    const ano = dataAtual.getFullYear();

    const dataFormatada = `${ano}-${mes.toString().padStart(2, '0')}-${dia.toString().padStart(2, '0')}`;

    return dataFormatada;
  }

  const dataAtual = pegarDataAtual();


  $('#account').css('cursor', 'pointer');
  $('#payment').css('cursor', 'pointer');

  let queryString = window.location.href;
  let parametros = queryString.split('/');
  let ordemproducao = parametros[parametros.length - 1];

  let contaFs = 1;
  $('#account').on('click', function () {
    if (contaFs == 2) {
      $('#voltar2').trigger('click');
    }
  });

  $('#payment').on('click', function () {
    if (contaFs == 1) {
      $('#avancar1').trigger('click');
    } else if (contaFs == 3) {
      $('#voltar3').trigger('click');
    }
  });

  $('#confirm').on('click', function () {
    if (contaFs == 2) {
      $('#avancar2').trigger('click');
    }
  });

  $('#btnVoltar').on('click', async function () {
    await deletaRegistro("MOVIMENTACAOFACCAO", getCookie("usuario"), ordemproducao);
    window.location.href = `${BASE_URI}/movimentacaofaccao`;
  });

  $("#btnGravar").click(async function () {
    $.LoadingOverlay('show');
    try {
      if ($('#txtDtRetorno').val() < dataAtual) {
        msgAlerta('Data de retorno menor que a data atual.');
        return
      } else if (pegaChave('#txtSetor') === pegaChave('#txtProximoSetor')) {
        msgAlerta('Setor e Próximo Setor não podem ser iguais, verifique.');
        return
      }

      await validaMovimentacao();
      await movimentaOF();
    } catch (error) {
      console.error(error);
      msgErro(`Não foi possível fazer a movimentação: ${error.message}`);
    } finally {
      $.LoadingOverlay('hide');
    }
  });

  $(".next").click(async function () {
    let liberado = true;
    let finalizado = false;

    if ($(this).attr("id") == "avancar1") {
      liberado = !$('#avancar1').prop('disabled');
      finalizado = $('#avancar1').prop('disabled');
    }

    if (liberado) {
      contaFs += 1;
      currentFs = $(this).parent().parent();
      nextFs = $(this).parent().parent().next();

      $("#progressbar li").eq($("fieldset").index(nextFs)).addClass("active");

      nextFs.show();
      currentFs.animate(
        {
          opacity: 0,
        },
        {
          step(now) {
            opacity = 1 - now;

            currentFs.css({
              display: "none",
              position: "relative",
            });
            nextFs.css({
              opacity,
            });
          },
          duration: 600,
        }
      );
    } else {
      if (!finalizado) {
        msgAlerta('Necessário informar os campos obrigatórios!');
      }
    }
  });

  $(".previous").click(function () {
    contaFs -= 1;

    currentFs = $(this).parent().parent();
    previousFs = $(this).parent().parent().prev();
    $("#progressbar li")
      .eq($("fieldset").index(currentFs))
      .removeClass("active");
    previousFs.show();
    currentFs.animate(
      {
        opacity: 0,
      },
      {
        step(now) {
          opacity = 1 - now;
          currentFs.css({
            display: "none",
            position: "relative",
          });
          previousFs.css({
            opacity,
          });
        },
        duration: 600,
      }
    );
  });

  await BuscaDadosOF(ordemproducao);

  async function BuscaDadosOF(Numero) {
    try {
      $.LoadingOverlay('show');
      try {
        const params = `NUMERO=${Numero}&PENDENTE=N`
        const response = await requisicao('GET', '/buscaordemproducao?', params, undefined, 120000);

        if (!response) {
          return;
        }

        let jsonStr = await response.json();
        jsonStr = jsonStr.resultado[0];
        $("#txtNumeroOrdem").val(Numero);
        document.querySelector("#dadosMovimentacao").innerHTML = `Dados da Movimentação da OF: ${Numero}`

        $('#txtPedido').val(jsonStr.pedido);
        $("#txtProgramacao").val(jsonStr.programacao);
        insereValor("#txtProduto", jsonStr.codigo, jsonStr.descricao);
        $("#txtDtCadastro").val(jsonStr.dtCadastro != undefined ? jsonStr.dtCadastro.slice(0, 10) : 0);
        $("#txtDtInicio").val(jsonStr.dtInicio != undefined ? jsonStr.dtInicio.slice(0, 10) : 0);
        $("#txtDtFim").val(jsonStr.dtFim != undefined ? jsonStr.dtFim.slice(0, 10) : 0);
        $("#txtObs").val(jsonStr.observacao);
        setarDataAtual('txtDtProducao');
        setarDataAtual('txtDtRetorno');
        await buscaCores(jsonStr.cores);
        CriaPesquisasTela();
        await habilitaAvancar(Numero);
        await adicionaPartes(jsonStr.partes);
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar os dados ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  $('#cbPartes').on('change', async function () {
    await buscaResumo($(this).val());
  });

  $('#txtDepositoConsumoSubProduto').on('focusout', async function () {
    if (pegaChave(this) != '') {
      await buscaReservaSubProduto();
    }
  })

  $('#txtDepositoConsumoOF').on('focusout', async function () {
    if (pegaChave(this) != '') {
      await buscaConsumosOF();
    }
  })

  async function adicionaPartes(partes) {
    let componente = $('#cbPartes');

    partes.forEach(parte => {
      componente.append($('<option>', {
        value: parte.codigo,
        text: `${parte.codigo} - ${parte.descricao}`
      }))
    })
    await buscaResumo($('#cbPartes').val())
    insereValor('#txtParte', partes[0].codigo, partes[0].descricao);
    $('#txtParte').trigger('focusout');
  }

  async function buscaResumo(parte) {
    try {
      $.LoadingOverlay('show');
      try {
        const params = `NUMERO=${$('#txtNumeroOrdem').val()}&PARTE=${parte}`;
        const response = await requisicao('GET', '/buscaresumoprod?', params, undefined, 120000);

        if (!response) {
          return;
        }

        let jsonStr = await response.json();
        if (jsonStr.resultado) {
          jsonStr = jsonStr.resultado;

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

          if (jsonStr.length == 0) {
            msgAlerta('Não foi possivel buscar o resumo da ordem de produção.');
            return;
          }

          const colunasItens = [
            { title: "Setor", data: "cod_Setor" },
            { title: "Desc. Setor", data: "setor" },
            { title: "Qtde Orig.", data: "orig" },
            { title: "Qtde", data: "qtde" },
            { title: "Qtde Segunda", data: "segunda" },
            { title: "Qtde Incompleta", data: "incompleta" },
            { title: "Qtde Perdida", data: "perdida" },
            { title: "Qtde Saldo", data: "saldo" }
          ];

          $('#tabelaResumo').DataTable({
            search: false,
            filter: false,
            order: [],
            sort: true,
            scrollX: true,
            destroy: true,
            colReorder: true,
            paging: false,
            "createdRow": function (row, data, dataIndex) {
              if (data.cor === 'verde') {
                $('td', row).css('color', '#75BE25')
              } else if (data.cor === 'vermelho') {
                $('td', row).css('color', 'red')
              } else if (data.cor === 'azul') {
                $('td', row).css('color', '#2195f0')
              }
            },
            "autoWidth": true,
            "data": jsonStr,
            "columns": colunasItens,
            autoWidth: true,
            columnDefs: [{
              targets: 0,
              // searchable: false
            },
            {
              "targets": [2, 3, 4, 5, 6, 7],
              "className": 'pr-4 text-right'
            }]
          });
        }
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar os dados ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  function CriaPesquisasTela() {
    $('#txtParte').autocompleta(1, `JSON={
      "tabela": "FACCAO",
      "camposSelect": ["TIPO_APL.CODIGO CHAVE", "TIPO_APL.DESCRICAO"],
      "innerJoin": [{ "tabela": "TIPO_APL", "condicao": "FACCAO.PARTE = TIPO_APL.CODIGO" }],
      "where": ["FACCAO.NUMERO = '${$('#txtNumeroOrdem').val()}'"],
      "groupBy": ["TIPO_APL.CODIGO", "TIPO_APL.DESCRICAO"]
    }`);

    $('#btn-Parte').pesquisa_serverside(['#txtParte'], ['TIPO_APL.CODIGO'], ['TIPO_APL.DESCRICAO'], `{
      "tabela":"FACCAO",
      "camposSelect": ["TIPO_APL.CODIGO", "TIPO_APL.DESCRICAO"],
      "innerJoin": [{"tabela": "TIPO_APL", "condicao": "FACCAO.PARTE = TIPO_APL.CODIGO" }],
      "where": ["FACCAO.NUMERO = '${$('#txtNumeroOrdem').val()}'"],
      "groupBy": ["TIPO_APL.CODIGO", "TIPO_APL.DESCRICAO"]
    }`, 'Pesquisa Parte');

    $('#btn-limpa-Parte').on('click', function () {
      $('#txtParte').val('');
      $('#txtSetor').val('');
      $('#txtProximoSetor').val('');
    });

    $('#txtEmpresaDestino').autocompleta(1, `JSON={
      "tabela": "ENTIDADE",
      "camposSelect": ["ENTIDADE.CODCLI CHAVE", "ENTIDADE.NOME DESCRICAO"],
      "where": ["ENTIDADE.TIPO_ENTIDADE LIKE '[PERCENTUAL]T[PERCENTUAL]'"]
    }`);

    $('#btn-EmpresaDestino').pesquisa_serverside(['#txtEmpresaDestino'], ['ENTIDADE.CODCLI'], ['ENTIDADE.NOME'], `{
      "tabela": "ENTIDADE",
      "camposSelect": ["ENTIDADE.CODCLI", "ENTIDADE.NOME"],
      "where": ["ENTIDADE.TIPO_ENTIDADE LIKE '[PERCENTUAL]T[PERCENTUAL]'"]
    }`, 'Pesquisa Entidade');

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

    $('#txtCelulaDestino').autocompleta(1, `JSON={
      "tabela": "CELULA",
      "camposSelect": ["CELULA.CODIGO CHAVE", "CELULA.DESCRICAO"],
      "where": null
    }`);

    $('#btn-CelulaDestino').pesquisa_serverside(['#txtCelulaDestino'], ['CELULA.CODIGO'], ['CELULA.DESCRICAO'], `{
      "tabela": "CELULA",
      "camposSelect": ["CELULA.CODIGO", "CELULA.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Celula');

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

    $('#txtParte').on("focusout", async function () {
      $('#txtSetor').unbind('autocompleta');
      $('#btn-Setor').unbind('pesquisa_serverside');

      if ($(this).val() == '') {
        $('#txtSetor').val('');
        $('#txtProximoSetor').val('');
      } else {
        const sWhere = bPermiteQtdeFracionada ? "(FACCAO.QT_ORIG_NUM > (FACCAO.QUANT_NUM [SOMA] FACCAO.QUANT_I_NUM [SOMA] FACCAO.QUANT_2_NUM [SOMA] FACCAO.QUANT_F_NUM))" : "(FACCAO.QT_ORIG > (FACCAO.QUANT [SOMA] FACCAO.QUANT_I [SOMA] FACCAO.QUANT_2 [SOMA] FACCAO.QUANT_F))";
        $('#txtSetor').autocompleta(1, `JSON={ 
          "tabela": "FACCAO", 
          "camposSelect": ["FACCAO.OP CHAVE", "CADFLUXO.DESCRICAO"],
          "leftJoin": [
            {"tabela": "CADFLUXO", "condicao": "CADFLUXO.CODIGO = FACCAO.OP"},
            {"tabela": "FAC_SETOR", "condicao": "FAC_SETOR.SETOR = FACCAO.OP AND FAC_SETOR.NUMERO = FACCAO.NUMERO AND FAC_SETOR.PARTE = FACCAO.PARTE"}
          ], 
          "where": [
            "FACCAO.NUMERO = '${$('#txtNumeroOrdem').val()}'",
            "FACCAO.PARTE = '${pegaChave(this)}'",
            "${sWhere}"
          ],
          "groupBy": ["FACCAO.OP", "CADFLUXO.DESCRICAO"]
        }`);

        const sWhereBtn = bPermiteQtdeFracionada ? "(FACCAO.QT_ORIG_NUM > (FACCAO.QUANT_NUM + FACCAO.QUANT_I_NUM + FACCAO.QUANT_2_NUM + FACCAO.QUANT_F_NUM))" : "(FACCAO.QT_ORIG > (FACCAO.QUANT + FACCAO.QUANT_I + FACCAO.QUANT_2 + FACCAO.QUANT_F))";
        $('#btn-Setor').pesquisa_serverside(['#txtSetor'], ['FACCAO.OP'], ['CADFLUXO.DESCRICAO'], `{
          "tabela": "FACCAO", 
          "camposSelect": ["FACCAO.OP", "CADFLUXO.DESCRICAO", "FAC_SETOR.ORDEM"],
          "leftJoin": [
            {"tabela": "CADFLUXO", "condicao": "CADFLUXO.CODIGO = FACCAO.OP"},
            {"tabela": "FAC_SETOR", "condicao": "FAC_SETOR.SETOR = FACCAO.OP AND FAC_SETOR.NUMERO = FACCAO.NUMERO AND FAC_SETOR.PARTE = FACCAO.PARTE"}
          ], 
          "where": [
            "FACCAO.NUMERO = '${$('#txtNumeroOrdem').val()}'",
            "FACCAO.PARTE = '${pegaChave(this)}'",
            "${sWhereBtn}"
          ],
          "groupBy": ["FACCAO.OP", "CADFLUXO.DESCRICAO", "FAC_SETOR.ORDEM"],
          "orderBy": ["FAC_SETOR.ORDEM"]
        }`, 'Pesquisa Setor');

        await buscaSetor();
      }
    });

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

    $('#txtSetor').on("focusout", async function () {
      $('#txtBarra').val('')
      $('#txtBarraEstorno').val('')
      $('#txtBarraEstorno').val('')
      $('#cbBaixaPorBarra').prop('checked', false)
      $('#txtProximoSetor').unbind('autocompleta');
      $('#btn-Setor').unbind('pesquisa');

      const setor = pegaChave(this);
      const parte = pegaChave('#txtParte');

      if ((setor != '') && (parte != '')) {
        await buscaMovimento(setor, parte);
        await consultaEmpresa(setor, parte, $('#cbMovimento').val());
        await validaUltimoSetor(setor, parte);
      }

      if (setor != '') {
        await validaCamposFuncionario(setor);
      }

      if ($(this).val() == '') {
        $('#txtProximoSetor').val('');
      } else {
        $('#txtProximoSetor').autocompleta(1, `JSON={ 
          "tabela": "FAC_SETOR", 
          "camposSelect": ["FAC_SETOR.SETOR CHAVE", "CADFLUXO.DESCRICAO"],
          "innerJoin": [{"tabela": "CADFLUXO", "condicao": "CADFLUXO.CODIGO = FAC_SETOR.SETOR"}], 
          "where": [
            "FAC_SETOR.NUMERO = '${$('#txtNumeroOrdem').val()}'",
            "FAC_SETOR.PARTE = '${pegaChave('#txtParte')}'",
            "FAC_SETOR.ORDEM_ORIG > (SELECT MAX(FACSETOR.ORDEM_ORIG) FROM [FAC_SETOR] FACSETOR WHERE FACSETOR.NUMERO = '${$('#txtNumeroOrdem').val()}' AND FACSETOR.PARTE = '${pegaChave('#txtParte')}' AND FACSETOR.SETOR = '${pegaChave(this)}')"
          ],
          "groupBy": ["FAC_SETOR.SETOR", "CADFLUXO.DESCRICAO", "FAC_SETOR.ORDEM_ORIG"],
          "orderBy": ["FAC_SETOR.ORDEM_ORIG DESC"],
          "limit": 1 
        }`);

        $("#btn-ProximoSetor").pesquisa(
          "#txtProximoSetor",
          "SETOR",
          "DESCRICAO",
          `/sisplan/funcoes/v1/pesquisa?JSON={
            "tabela": "FAC_SETOR", 
            "camposSelect": ["FAC_SETOR.SETOR", "CADFLUXO.DESCRICAO"],
            "innerJoin": [{"tabela": "CADFLUXO", "condicao": "CADFLUXO.CODIGO = FAC_SETOR.SETOR"}], 
            "where": [
              "FAC_SETOR.NUMERO = '${$('#txtNumeroOrdem').val()}'",
              "FAC_SETOR.PARTE = '${pegaChave('#txtParte')}'",
              "FAC_SETOR.ORDEM_ORIG > (SELECT MAX(FACSETOR.ORDEM_ORIG) FROM [FAC_SETOR] FACSETOR WHERE FACSETOR.NUMERO = '${$('#txtNumeroOrdem').val()}' AND FACSETOR.PARTE = '${pegaChave('#txtParte')}' AND FACSETOR.SETOR = '${pegaChave(this)}')"
            ],
            "groupBy": ["FAC_SETOR.SETOR", "CADFLUXO.DESCRICAO", "FAC_SETOR.ORDEM_ORIG"],
            "orderBy": ["FAC_SETOR.ORDEM_ORIG"],
            "limit": 1 
          }`,
          "Pesquisa Setor",
          "setor"
        );
      }
      await buscaItensMovimentacao();
      await buscaProximoSetor();
    });

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

    componenteFiltro('qualidade', false, false, 'Qualidade2')

    $('#txtQualidade').autocompleta(1, `JSON={
      "tabela": "TABQUL",
      "camposSelect": ["TABQUL.CODIGO CHAVE", "TABQUL.DESCRICAO"],
      "where": null
    }`);

    $('#btn-Qualidade').pesquisa_serverside(['#txtQualidade'], ['TABQUL.CODIGO'], ['TABQUL.DESCRICAO'], `{
      "tabela": "TABQUL",
      "camposSelect": ["TABQUL.CODIGO", "TABQUL.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Qualidade');

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

    $('#txtTipoBaixa').autocompleta(1, `JSON={
      "tabela": "TABBAI",
      "camposSelect": ["TABBAI.CODIGO CHAVE", "TABBAI.DESCRICAO"],
      "where": null
    }`);

    $('#btn-TipoBaixa').pesquisa_serverside(['#txtTipoBaixa'], ['TABBAI.CODIGO'], ['TABBAI.DESCRICAO'], `{
      "tabela": "TABBAI",
      "camposSelect": ["TABBAI.CODIGO", "TABBAI.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Tipo de Baixa');

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

    $('#txtDeposito').autocompleta(1, `JSON={
      "tabela": "DEPOSITO",
      "camposSelect": ["DEPOSITO.CODIGO CHAVE", "DEPOSITO.DESCRICAO"],
      "where": null
    }`);

    $('#btn-Deposito').pesquisa_serverside(['#txtDeposito'], ['DEPOSITO.CODIGO'], ['DEPOSITO.DESCRICAO'], `{
      "tabela": "DEPOSITO",
      "camposSelect": ["DEPOSITO.CODIGO", "DEPOSITO.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Depósito');

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

    $('#txtTipoBaixaConsumoSubProduto').autocompleta(1, `JSON={
      "tabela": "TABBAI",
      "camposSelect": ["TABBAI.CODIGO CHAVE", "TABBAI.DESCRICAO"],
      "where": null
    }`);

    $('#btn-TipoBaixaConsumoSubProduto').pesquisa_serverside(['#txtTipoBaixaConsumoSubProduto'], ['TABBAI.CODIGO'], ['TABBAI.DESCRICAO'], `{
      "tabela": "TABBAI",
      "camposSelect": ["TABBAI.CODIGO", "TABBAI.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Tipo de Baixa');

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

    $('#txtDepositoConsumoSubProduto').autocompleta(1, `JSON={
      "tabela": "DEPOSITO",
      "camposSelect": ["DEPOSITO.CODIGO CHAVE", "DEPOSITO.DESCRICAO"],
      "where": null
    }`);

    $('#btn-DepositoConsumoSubProduto').pesquisa_serverside(['#txtDepositoConsumoSubProduto'], ['DEPOSITO.CODIGO'], ['DEPOSITO.DESCRICAO'], `{
      "tabela": "DEPOSITO",
      "camposSelect": ["DEPOSITO.CODIGO", "DEPOSITO.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Depósito');

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

    $('#txtFuncionario').autocompleta(1, `JSON={
      "tabela": "PESSOAL",
      "camposSelect": ["PESSOAL.CODIGO CHAVE", "PESSOAL.NOME DESCRICAO"],
      "where": null
    }`);

    $('#btn-Funcionario').pesquisa_serverside(['#txtFuncionario'], ['PESSOAL.CODIGO'], ['PESSOAL.NOME'], `{
      "tabela": "PESSOAL",
      "camposSelect": ["PESSOAL.CODIGO", "PESSOAL.NOME"],
      "where": null
    }`, 'Pesquisa Funcionário');

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

    $('#txtMotivo').autocompleta(1, `JSON={
      "tabela": "MENSAGEM",
      "camposSelect": ["MENSAGEM.CODMEN CHAVE", "MENSAGEM.DESCRICAO"],
      "where": null
    }`);

    $('#btn-Motivo').pesquisa_serverside(['#txtMotivo'], ['MENSAGEM.CODMEN'], ['MENSAGEM.DESCRICAO'], `{
      "tabela": "MENSAGEM",
      "camposSelect": ["MENSAGEM.CODMEN", "MENSAGEM.DESCRICAO"],
      "where": null
    }`, 'Pesquisa Motivo');

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

    $('#txtDepositoConsumoOF').autocompleta(1, `JSON={
          "tabela": "DEPOSITO",
          "camposSelect": ["DEPOSITO.CODIGO CHAVE", "DEPOSITO.DESCRICAO"],
          "where": null
        }`);

    $('#btn-DepositoConsumoOF').pesquisa_serverside(['#txtDepositoConsumoOF'], ['DEPOSITO.CODIGO'], ['DEPOSITO.DESCRICAO'], `{
          "tabela": "DEPOSITO",
          "camposSelect": ["DEPOSITO.CODIGO", "DEPOSITO.DESCRICAO"],
          "where": null
        }`, 'Pesquisa Depósito');

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

  async function buscaCores(cores) {
    $.LoadingOverlay("show");
    try {
      if ($.fn.DataTable.isDataTable('#tabelaCores')) {
        $('#tabelaCores').DataTable().destroy();
        $('#tabelaCores').empty();
      }

      if (cores.length == 0) {
        msgAlerta('Não foi possivel buscar as cores da ordem de produção.');
        return;
      }

      const colunasItens = [
        { title: "Cor", data: "cor" },
        { title: "Descrição", data: "descricao" }
      ];

      $('#tabelaCores').DataTable({
        search: false,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        colReorder: true,
        paging: false,

        "autoWidth": true,
        "data": cores,
        "columns": colunasItens,
        autoWidth: true
      });
    } catch (error) {
      console.log(error)
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  $('#cbMovimento').on('change', async function () {
    const setor = pegaChave('#txtSetor');
    const parte = pegaChave('#txtParte');
    if ((setor != '') && (parte != '')) {
      await consultaEmpresa(setor, parte, $('#cbMovimento').val());
      await buscaItensMovimentacao();
    }
  });

  $('#modal-baixa-consumo-subproduto').on('show.bs.modal', async function () {
    await buscaDeposito('txtDepositoConsumoSubProduto');
    await buscaTipoBaixa('txtTipoBaixaConsumoSubProduto');
    await buscaReservaSubProduto();
  });

  $('#modal-baixa-consumo-of').on('show.bs.modal', async function () {
    if ($.fn.DataTable.isDataTable('#tabelaConsumosOF')) {
      await sleep(200);
      $("#tabelaConsumosOF").DataTable().columns.adjust().draw(false);
    }
  });

  $('#btnConfirmarConsumosProduto').on('click', async function () {
    try {
      await validaBaixaConsumoSubProduto();
      await baixaConsumosSubProduto();
      $('#modal-baixa-consumo-subproduto').modal('hide');
      await baixaConsumosOF();
    } catch (error) {
      msgErro(`Não foi possível fazer a baixa dos consumos dos subprodutos: ${error.message}`);
    }
  });

  $('#btnConfirmarConsumosOF').on('click', async function () {
    try {
      await validaBaixaConsumoOF();
      await gravaConsumosOF();
      $('#modal-baixa-consumo-of').modal('hide');
      await gravarMovimentacaoOF();
    } catch (error) {
      msgErro(`Não foi possível fazer a baixa dos consumos da OF: ${error.message}`);
    }
  });

  async function buscaMovimento(setor, parte) {
    try {
      $.LoadingOverlay('show');
      try {
        const params = `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${setor}&PARTE=${parte}`;
        const response = await requisicao('GET', '/buscamovimentofaccao?', params, undefined, 120000);

        if (!response) {
          return;
        }

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

        let componente = $('#cbMovimento');
        componente.empty();
        if (jsonStr.length > 1) componente.append($('<option>', { value: '', text: 'Movimenta Inteira' }));

        jsonStr.forEach(parte => {
          componente.append($('<option>', {
            value: parte.movimento,
            text: parte.movimento
          }))
        })
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar os movimentos do setor ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  async function consultaEmpresa(setor, parte, movimento) {
    try {
      $.LoadingOverlay('show');
      try {
        let where = ''
        where += `1 = 1 `
        where += $('#txtNumeroOrdem').val() ? ` AND FACCAO.NUMERO = '${$('#txtNumeroOrdem').val()}'` : '';
        where += setor ? ` AND FACCAO.OP = '${setor}'` : '';
        where += parte ? ` AND FACCAO.PARTE = '${parte}'` : '';
        where += movimento ? ` AND FACCAO.MOV = '${movimento}'` : '';
        const dadosSelect = {
          tabela: 'FACCAO',
          camposSelect: ['FACCAO.CODCLI', 'ENTIDADE.NOME'],
          leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = FACCAO.CODCLI' }],
          where: [where],
          groupBy: ['FACCAO.CODCLI', 'ENTIDADE.NOME']
        };

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

        if (!retornoSelect) {
          msgAlerta('Não foi possível buscar os dados da empresa.');
          return;
        }

        insereValor('#txtEmpresa', retornoSelect[0].CODCLI, retornoSelect[0].NOME);
        insereValor('#txtEmpresaDestino', retornoSelect[0].CODCLI, retornoSelect[0].NOME);
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar a empresa ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  async function buscaItensMovimentacao() {
    try {
      $.LoadingOverlay('show');
      try {
        if ((pegaChave('#txtParte' == '')) || (pegaChave('#txtSetor') == '')) {
          return;
        }

        const params = `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${pegaChave('#txtSetor')}&PARTE=${pegaChave('#txtParte')}&MOVIMENTO=${$('#cbMovimento').val()}&CODCLI=${pegaChave('#txtEmpresa')}&NAO_ZERAR=N&BPENDENTE=true&BSETORANTERIOR=true`;
        const response = await requisicao('GET', '/buscaitensmovfaccao?', params, undefined, 120000);

        if (!response) {
          return;
        }

        let jsonStr = await response.json();
        if (!jsonStr.resultado) {
          msgAlerta('Não foi possível buscar os itens. Verifique se o setor a ser movimentado ainda está pendente.');
          return;
        }
        jsonStr = jsonStr.resultado[0];

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

        const titulos = [
          { title: "Codigo", data: "CODIGO" },
          { title: "Cor", data: "COR" },
          { title: "Desc. Cor", data: "DESC_COR" },
          { title: "Tam", data: "TAM" },
          { title: "Quant_Orig.", data: "QUANT_ORIG" },
          { title: "Saldo", data: "SALDO_CALC" },
          { title: "Quant.", data: "QUANT" },
          { title: "Segunda", data: "QUANT_SEGUNDA" },
          { title: "Incomp.", data: "QUANT_INCOMPLETA" },
          { title: "Perdida", data: "QUANT_PERDIDA" },
          { title: "Saldo", data: "SALDO" },
          { title: "Identificador", data: "IDENTIFICADOR" }
        ];

        const codigo = jsonStr.codigo;
        let jsonObject;

        let i = 0;
        jsonObject = jsonStr.gradeCores.reduce(function (result, gradeCor) {
          let tamanhosRenomeados = extrairRenomearTamanhos(gradeCor.tamanhos);
          tamanhosRenomeados.forEach(function (tamanhoRenomeado, index) {
            result.push({
              CODIGO: codigo,
              COR: gradeCor.cor,
              DESC_COR: gradeCor.descricao,
              TAM: tamanhoRenomeado.TAM,
              QUANT_ORIG: tamanhoRenomeado.QUANT_ORIG,
              SALDO_CALC: `<input type="number" min="0" class="input-default focus form-control campoSaldo text-right" id="SALDO${i}" value="${tamanhoRenomeado.SALDO}" disabled>`,
              QUANT: `<input type="number" min="0" class="input-default focus form-control campoQuant camposGrade text-right" id="QUANT${i}" value="${tamanhoRenomeado.QUANT}">`,
              QUANT_SEGUNDA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdeSegunda text-right" id="QUANT_SEGUNDA${i}" value="${tamanhoRenomeado.QUANT_SEGUNDA}">`,
              QUANT_PERDIDA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdePerdidas text-right" id="QUANT_PERDIDA${i}" value="0">`,
              QUANT_INCOMPLETA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdeIncompletas text-right" id="QUANT_INCOMPLETA${i}" value="0">`,
              SALDO: tamanhoRenomeado.SALDO,
              IDENTIFICADOR: tamanhoRenomeado.IDENTIFICADOR
            });
            i++;
          });
          return result;
        }, []);

        $("#tabelaItens").DataTable({
          destroy: true,
          filter: false,
          paging: false,
          autoWidth: false,
          columns: titulos,
          data: jsonObject,
          columnDefs: [
            {
              targets: [10, 11],
              visible: false,
            },
            {
              "targets": [4, 5, 6, 7, 8, 9],
              "className": 'pr-4 text-right',
              width: '160px',
              minWidth: '160px'
            },
          ]
        });

        if (!bPermiteQtdeFracionada) {
          $('.camposGrade').on('focusout', async function () {
            let inputValue
            if ($(this).val() == '') {
              inputValue = 0
              $(this).val(0)
            } else {
              inputValue = $(this).val()
            }
            if (!Number.isInteger(parseFloat(inputValue))) {
              msgAlerta('Permitido apenas números inteiros!');
              $(this).val(0);
            }
            const inputId = $(this).attr('id');
            const numeroId = inputId.match(/\d+/)[0];
            const saldo = $("#tabelaItens").DataTable().data().toArray()[numeroId].SALDO;
            const quant = isNaN(parseInt($(`#QUANT${numeroId}`).val())) ? 0 : parseInt($(`#QUANT${numeroId}`).val());
            const segunda = isNaN(parseInt($(`#QUANT_SEGUNDA${numeroId}`).val())) ? 0 : parseInt($(`#QUANT_SEGUNDA${numeroId}`).val());
            const incompleta = isNaN(parseInt($(`#QUANT_INCOMPLETA${numeroId}`).val())) ? 0 : parseInt($(`#QUANT_INCOMPLETA${numeroId}`).val());
            const perdida = isNaN(parseInt($(`#QUANT_PERDIDA${numeroId}`).val())) ? 0 : parseInt($(`#QUANT_PERDIDA${numeroId}`).val());
            const novoSaldo = (saldo - quant - segunda - incompleta - perdida).toFixed(0);
            const qtdeOrig = $('#tabelaItens').DataTable().row($(`#${$(this).attr('id')}`).closest('tr').index()).data().QUANT_ORIG
            const permiteQtdeMaior = await baixaMaiorQueSaldo()
            let sair = false
            if (novoSaldo < 0) {
              if (!(permiteQtdeMaior)) {
                $(`#QUANT${numeroId}`).val(quant)
                $(`#QUANT_SEGUNDA${numeroId}`).val(segunda)
                $(`#QUANT_INCOMPLETA${numeroId}`).val(incompleta)
                $(`#QUANT_PERDIDA${numeroId}`).val(perdida)
                $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida + parseFloat($(this).val()))
                $(this).val(0)
                return msgAlerta('Saldo não pode ser negativo, verfique!')
              } else {
                if (inputId == `QUANT${numeroId}`) {
                  await msgAguardaConfirmacao(`Qtde de saldo é ${saldo} e a qtde digitada é ${quant}. Deseja Continuar?`, () => { }, () => {
                    $(`#QUANT${numeroId}`).val(quant)
                    $(`#QUANT_SEGUNDA${numeroId}`).val(segunda)
                    $(`#QUANT_INCOMPLETA${numeroId}`).val(incompleta)
                    $(`#QUANT_PERDIDA${numeroId}`).val(perdida)
                    $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida + parseFloat($(this).val()))
                    $(this).val(0)
                    sair = true
                  })
                  if (sair) {
                    return
                  }
                }
              }
            }
            $(`#SALDO${numeroId}`).val(novoSaldo);
          });
        } else {
          $('.camposGrade').on('focusout', async function () {
            const inputId = $(this).attr('id');
            const numeroId = inputId.match(/\d+/)[0];
            const saldo = $("#tabelaItens").DataTable().data().toArray()[numeroId].SALDO;
            const quant = isNaN(parseFloat($(`#QUANT${numeroId}`).val())) ? 0 : parseFloat($(`#QUANT${numeroId}`).val());
            const segunda = isNaN(parseFloat($(`#QUANT_SEGUNDA${numeroId}`).val())) ? 0 : parseFloat($(`#QUANT_SEGUNDA${numeroId}`).val());
            const incompleta = isNaN(parseFloat($(`#QUANT_INCOMPLETA${numeroId}`).val())) ? 0 : parseFloat($(`#QUANT_INCOMPLETA${numeroId}`).val());
            const perdida = isNaN(parseFloat($(`#QUANT_PERDIDA${numeroId}`).val())) ? 0 : parseFloat($(`#QUANT_PERDIDA${numeroId}`).val());
            const novoSaldo = formatarValor((saldo - quant - segunda - incompleta - perdida).toFixed(2));
            const qtdeOrig = $('#tabelaItens').DataTable().row($(`#${$(this).attr('id')}`).closest('tr').index()).data().QUANT_ORIG
            const permiteQtdeMaior = await baixaMaiorQueSaldo()
            let sair = false

            if (novoSaldo < 0) {
              if (!(permiteQtdeMaior)) {
                $(`#QUANT${numeroId}`).val(quant)
                $(`#QUANT_SEGUNDA${numeroId}`).val(segunda)
                $(`#QUANT_INCOMPLETA${numeroId}`).val(incompleta)
                $(`#QUANT_PERDIDA${numeroId}`).val(perdida)
                $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida + parseFloat($(this).val()))
                $(this).val(0)
                return msgAlerta('Saldo não pode ser negativo, verfique!')
              } else {
                if (inputId == `QUANT${numeroId}`) {
                  await msgAguardaConfirmacao(`Qtde de saldo é ${saldo} e a qtde digitada é ${quant}. Deseja Continuar?`, () => { }, () => {
                    $(`#QUANT${numeroId}`).val(quant)
                    $(`#QUANT_SEGUNDA${numeroId}`).val(segunda)
                    $(`#QUANT_INCOMPLETA${numeroId}`).val(incompleta)
                    $(`#QUANT_PERDIDA${numeroId}`).val(perdida)
                    $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida + parseFloat($(this).val()))
                    $(this).val(0)
                    sair = true
                  })
                  if (sair) {
                    return
                  }
                }
              }
            }


            $(`#SALDO${numeroId}`).val(novoSaldo);
          });
        }

        $('.camposGrade').trigger('focusout');

        $('.qtdeSegunda, .qtdePerdidas').on('blur', function () {
          validaHabilitarMotivoQual2()
        })
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar os movimentos do setor ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  $('#Itens').html('<div><div style="text-align:start;"> ' +
    '    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" style="font-size: smaller;" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ' +
    '      ' + $('#Itens').html() + ' ' +
    '    </button> ' +
    '    <div class="dropdown-menu"> ' +
    '       <button class="dropdown-item" type="button" title="Saldo Perdido" id="btnSaldoPerdido">Marcar saldo como Perdido </button>     ' +
    '       <button class="dropdown-item" type="button" title="Saldo Segunda" id="btnSaldoSegunda">Marcar saldo como Segunda </button>     ' +
    '       <button class="dropdown-item" type="button" title="Saldo Incompleta" id="btnSaldoIncompleta">Marcar saldo como Incompleta </button>  ' +
    '       <button class="dropdown-item" type="button" title="Zerar Quantidades" id="btnZerarQuantidades">Zerar Quantidades </button>  ' +
    '    </div>'
  )

  $('#btnSaldoPerdido').on('click', async function () {
    await marcaSaldoPerdido();
    validaHabilitarMotivoQual2()
  });

  $('#btnSaldoSegunda').on('click', async function () {
    await marcaSaldoSegunda();
    validaHabilitarMotivoQual2()
  });

  $('#btnSaldoIncompleta').on('click', async function () {
    await marcaSaldoIncompleta();
    validaHabilitarMotivoQual2()
  });

  $('#btnZerarQuantidades').on('click', function () {
    zeraQuantidades()
    validaHabilitarMotivoQual2()
  })

  async function marcaSaldoPerdido() {
    const tabelaItens = $('#tabelaItens').DataTable().rows().data();
    tabelaItens.map((item, i) => {
      const saldo = parseFloat($(`#SALDO${i}`).val())
      if (saldo) {
        $(`#SALDO${i}`).val(0)
      }
      let qtdePerdida = parseFloat($(`#QUANT_PERDIDA${i}`).val())
      qtdePerdida = qtdePerdida + saldo;
      $(`#QUANT_PERDIDA${i}`).val(qtdePerdida)
    })
  }

  async function marcaSaldoSegunda() {
    const tabelaItens = $('#tabelaItens').DataTable().rows().data();
    tabelaItens.map((item, i) => {
      const saldo = parseFloat($(`#SALDO${i}`).val())
      if (saldo) {
        $(`#SALDO${i}`).val(0)
      }
      let qtdeSegunda = parseFloat($(`#QUANT_SEGUNDA${i}`).val())
      qtdeSegunda = qtdeSegunda + saldo;
      $(`#QUANT_SEGUNDA${i}`).val(qtdeSegunda)
    })
  }

  async function marcaSaldoIncompleta() {
    const tabelaItens = $('#tabelaItens').DataTable().rows().data();
    tabelaItens.map((item, i) => {
      const saldo = parseFloat($(`#SALDO${i}`).val())
      if (saldo) {
        $(`#SALDO${i}`).val(0)
      }
      let qtdeIncompleta = parseFloat($(`#QUANT_INCOMPLETA${i}`).val())
      qtdeIncompleta = qtdeIncompleta + saldo;
      $(`#QUANT_INCOMPLETA${i}`).val(qtdeIncompleta)
    })
  }

  function zeraQuantidades() {
    try {
      $('#tabelaItens').DataTable().data().toArray().forEach((e, i) => {
        $(`#SALDO${i}`).val(e.QUANT_ORIG)
        $(`#QUANT${i}`).val('0')
        $(`#QUANT_SEGUNDA${i}`).val('0')
        $(`#QUANT_PERDIDA${i}`).val('0')
        $(`#QUANT_INCOMPLETA${i}`).val('0')
      })
    } catch (e) {
      msgErro('Ocorreu um erro ao zerar as quantidades, tente novamente.')
    }
  }

  $('#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();
  });

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

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

  $('#cbBaixaPorBarra').on('click', async function () {
    const bBarra = isChecked(this);
    const ordem = (await buscaValor('FAC_SETOR', 'ORDEM', `PARTE = '${pegaChave('#txtParte')}' AND SETOR = '${pegaChave('#txtSetor')}' AND NUMERO`, $('#txtNumeroOrdem').val())).ORDEM;
    if (bBarra) {
      if (ordem == 99) {
        $('.inputEpc').removeClass('d-none')
      }
      $('#divBarra').removeClass('d-none');
    } else {
      $('#divBarra').addClass('d-none');
    }
    $('.campoQuant').prop('disabled', bBarra);
    $('.campoQuant').val(0);
    $('.campoQuant').trigger('blur');
  })

  //ANTIGO QUE USA CLASS PARA FAZER O CONTROLE DOS INPUTS
  // $('#cbBaixaPorBarra').on('click', function () {
  //   let btnHasClass = $('#txtBarra').hasClass('d-none')
  //   $('.classBarra').prop('disabled', !btnHasClass)
  //   $('.campoQuant').prop('disabled', btnHasClass)
  //   $('.campoQuant').val(0)
  //   $('.campoQuant').trigger('blur')
  // })

  $('#txtBarra').on('blur', async function () {
    if (pegaValor(this) != '') {
      await saidaBarra();
    }
    $(this).focus()
  });

  $('#txtBarraEstorno').on('blur', async function () {
    $.LoadingOverlay('show');
    try {
      let barra = $('#txtBarraEstorno').val();

      if (!barra) {
        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(false, barra, barraLog);
      $(this).focus()
    } catch (error) {
      console.log(error);
    } finally {
      $.LoadingOverlay('hide');
    }
  })

  function validaHabilitarMotivoQual2() {
    try {
      const itensSegunda = $('.qtdeSegunda').toArray();
      let qtde = 0;

      itensSegunda.forEach(function (e) {
        qtde += parseFloat($(e).val())
      })

      if (qtde === 0) {
        const itensPerdidas = $('.qtdePerdidas').toArray()
        itensPerdidas.forEach(function (e) {
          qtde += parseFloat($(e).val())
        })
      }

      if (qtde > 0) {
        $('.divMotivo').removeClass('d-none');
        if ($('#txtProximoSetor').prop('disabled')) {
          $('.divQualidade').removeClass('d-none');
        }
      } else {
        $('.divMotivo').addClass('d-none');
        $('.divQualidade').addClass('d-none');
      }
    } catch (e) {

    }
  }

  function formatarValor(valor) {
    const partes = valor.toString().split(".");
    if (partes[1] !== "00" && partes.length > 1) {
      return valor;
    } else {
      return partes[0];
    }
  }

  function extrairRenomearTamanhos(tamanhos) {
    return tamanhos.map(function (tamanho) {
      return {
        TAM: tamanho.tam,
        QUANT: tamanho.quant,
        QUANT_INCOMPLETA: tamanho.quant_I,
        QUANT_ORIG: tamanho.quant_Orig,
        QUANT_SEGUNDA: tamanho.quant_2,
        QUANT_PERDIDA: tamanho.quant_F,
        SALDO: tamanho.saldo,
        IDENTIFICADOR: tamanho.identificador
      };
    });
  }

  async function validaUltimoSetor(setor, parte) {
    const ordem = await buscaValor('FAC_SETOR', 'ORDEM', `PARTE = '${parte}' AND SETOR = '${setor}' AND NUMERO`, $('#txtNumeroOrdem').val());
    if (ordem.ORDEM == '99') {
      $('.ultimoSetor').removeClass('d-none');
      $('#txtProximoSetor').prop('disabled', true);
      $('#btn-ProximoSetor').prop('disabled', true);
      $('#btn-limpa-ProximoSetor').prop('disabled', true);
      $('#txtProximoSetor').prop('required', false);
      insereValor('#txtQualidade', '1', '1');
      const response = await requisicao('GET', '/buscatipobaixamovfaccao?', '', undefined, 120000);
      if (response) {
        const jsonStr = await response.json();
        insereValor('#txtTipoBaixa', jsonStr.mensagem, jsonStr.mensagem);
      }

      buscaDeposito('txtDeposito');
    } else {
      $('.ultimoSetor').addClass('d-none');
      $('#txtProximoSetor').prop('disabled', false);
      $('#btn-ProximoSetor').prop('disabled', false);
      $('#btn-limpa-ProximoSetor').prop('disabled', false);
      $('#txtProximoSetor').prop('required', true);
    }
  }

  async function validaMovimentacao() {
    let validator = $("#msform").validate();
    let liberado = true;
    validator.element("#txtParte");
    validator.element("#txtSetor");
    validator.element("#txtEmpresaDestino");

    if (!$('.ultimoSetor').hasClass('d-none')) {
      validator.element("#txtQualidade");
      validator.element("#txtTipoBaixa");
      validator.element("#txtDeposito");
      if (!(validator.element("#txtParte") && validator.element("#txtSetor") && validator.element("#txtEmpresaDestino") && validator.element("#txtQualidade")
        && validator.element("#txtTipoBaixa") && validator.element("#txtDeposito"))) {
        liberado = false;
      }
    } else {
      validator.element("#txtProximoSetor");
      if (!(validator.element("#txtParte") && validator.element("#txtSetor") && validator.element("#txtEmpresaDestino") && validator.element("#txtProximoSetor"))) {
        liberado = false;
      }
    }

    if (!liberado) {
      throw new Error('Necessário informar os campos obrigatórios!');
    }

    const baixaMaior = await buscaValor('CADFLUXO', 'BAIXAMAIOR', 'CODIGO', pegaChave('#txtSetor'));
    let bContemQtde = false;
    $("#tabelaItens").DataTable().data().toArray().forEach((item, index) => {
      if ((parseFloat($(`#QUANT_SEGUNDA${index}`).val()) > 0) || (parseFloat($(`#QUANT_PERDIDA${index}`).val()) > 0) ||
        (parseFloat($(`#QUANT${index}`).val()) > 0) || (parseFloat($(`#QUANT_INCOMPLETA${index}`).val()) > 0)) {
        bContemQtde = true;
      }

      if (baixaMaior.BAIXAMAIOR != 'S') {
        if ((parseFloat($(`#QUANT${index}`).val()) + parseFloat($(`#QUANT_SEGUNDA${index}`).val()) + parseFloat($(`#QUANT_INCOMPLETA${index}`).val()) +
          parseFloat($(`#QUANT_PERDIDA${index}`).val())) > item.SALDO) {
          throw new Error('Quantidades informadas maiores que o saldo disponível, verifique.');
        }
      }
    })

    if (!bContemQtde) {
      throw new Error('Nenhuma quantidade informada, impossível continuar.');
    }
    const movFaccao = retornaObjeto();
    const response = await requisicao('POST', '/sisplan/movimentacaofaccao/v1/validarmovimentofaccao?', `CODUSUARIO=${getCookie('cod_usuario')}`, JSON.stringify(movFaccao), 120000);

    if (!response) {
      return;
    }

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

    const itens = $('.qtdeSegunda').toArray();
    let qtde = 0;

    itens.forEach(function (e) {
      qtde += parseFloat($(e).val())
    })

    if (qtde > 0 && $('#txtProximoSetor').prop('disabled') && pegaChave('#txtQualidade2') == '') {
      throw new Error('Existem quantidades de segunda qualidade porém o campo Qualidade 2 está em branco, impossível continuar.');
    }
  }

  function retornaObjeto() {
    try {
      const movFaccao = {};
      movFaccao.CodCli = pegaChave('#txtEmpresa');
      movFaccao.Numero = $('#txtNumeroOrdem').val();
      movFaccao.Codigo = pegaChave('#txtProduto');
      movFaccao.Parte = pegaChave('#txtParte');
      movFaccao.Setor = pegaChave('#txtSetor');
      movFaccao.SetorDestino = pegaChave('#txtProximoSetor');
      movFaccao.Mov = $('#cbMovimento').val();
      movFaccao.GradeCores = retornaGradeCores();
      movFaccao.Terceiro = pegaChave('#txtEmpresaDestino');
      movFaccao.DtR = pegaValor('#txtDtRetorno');
      movFaccao.DtS = pegaValor('#txtDtProducao');
      movFaccao.Funcionario = pegaChave('#txtFuncionario');
      movFaccao.CelulaDestino = pegaChave('#txtCelulaDestino');
      movFaccao.Deposito = pegaChave('#txtDeposito');
      movFaccao.Qualidade = pegaChave('#txtQualidade');
      movFaccao.TipoBaixa = pegaChave('#txtTipoBaixa');
      movFaccao.Qualidade2 = pegaChave('#txtQualidade2');
      movFaccao.Caixa = $('#txtCaixa').val();
      movFaccao.Maquina = $('#txtMaquina').val();
      movFaccao.Pedido = $('#txtPedido').val();
      movFaccao.Programacao = $('#txtProgramacao').val();
      movFaccao.Motivo = pegaChave('#txtMotivo');
      movFaccao.Observacao = $('#txtObs').val();
      return movFaccao;
    } catch (error) {
      console.log('Rotina retornaObjeto ' + error);
    }
  }

  function retornaGradeCores() {
    try {
      let MovCor = [];
      let MovTam = [];
      const maxIndex = $("#tabelaItens").DataTable().data().count() - 1;
      let retorno = {};
      let cor = '';
      $("#tabelaItens").DataTable().data().toArray().forEach((item, index) => {
        if (cor == item.COR) {
          MovTam.push(retornaTamanhos(item, index));
          retorno.Tamanhos = MovTam;
          if (maxIndex == index) {
            MovCor.push(retorno);
          }
        } else {
          if (index != 0) {
            retorno.Tamanhos = MovTam;
            MovCor.push(retorno);
          }
          retorno = {};
          MovTam = [];
          retorno.Cor = item.COR;
          retorno.Descricao = item.DESC_COR;
          MovTam.push(retornaTamanhos(item, index));
          if (maxIndex == index) {
            retorno.Tamanhos = MovTam;
            MovCor.push(retorno);
          }
        }
        cor = item.COR;
      });
      return MovCor;
    } catch (error) {
      console.log('Rotina retornaGradeCores ' + error);
    }
  }

  function retornaTamanhos(item, index) {
    const MovTam = {};
    try {
      MovTam.Tam = item.TAM;
      MovTam.Identificador = item.IDENTIFICADOR;
      MovTam.Quant = $(`#QUANT${index}`).val();
      MovTam.Quant_I = $(`#QUANT_INCOMPLETA${index}`).val();
      MovTam.Quant_Orig = item.QUANT_ORIG;
      MovTam.Quant_F = $(`#QUANT_PERDIDA${index}`).val();
      MovTam.Quant_2 = $(`#QUANT_SEGUNDA${index}`).val();
      MovTam.Saldo = item.SALDO;
      return MovTam;
    } catch (error) {
      console.log('Rotina retornaTamanhos ' + error);
    }
  }

  async function validaCamposFuncionario(setor) {
    try {
      const params = `SETOR=${setor}`
      const response = await requisicao('GET', '/usafuncionariomov?', params);

      if (!response) {
        return;
      }

      if (response.status == 200) {
        let jsonStr = await response.json();
        if (jsonStr.mensagem == 'S') {
          $('.habilitaFunc').removeClass('d-none');
        } else {
          $('.habilitaFunc').addClass('d-none');
        }
      }
    } catch (error) {
      console.log('Rotina validaCamposFuncionario ' + error)
    }
  }

  function validaMotivo() {
    let bMotivo = false;
    $("#tabelaItens").DataTable().data().toArray().some((item, index) => {
      if ((parseFloat($(`#QUANT_SEGUNDA${index}`).val()) > 0) || (parseFloat($(`#QUANT_PERDIDA${index}`).val()) > 0)) {
        bMotivo = true;
        return true;
      }
    })

    if (bMotivo) {
      let validator = $("#msform").validate();
      validator.element("#txtMotivo");
      if (!(validator.element("#txtMotivo"))) {
        throw new Error('Necessário informar o Motivo!');
      }
    }
  }

  async function baixaConsumo() {
    $.LoadingOverlay('show');
    try {
      const params = `SETOR=${pegaChave('#txtSetor')}`;
      const response = await requisicao('GET', '/baixaconsumoprodutofaccao?', params);

      if (!response) {
        return;
      }

      if (response.status == 200) {
        let jsonStr = await response.json();
        if (jsonStr.mensagem == 'S') {
          const lancamento = await proximoLancamento();
          $('#txtLancamento').val(lancamento);
          const params = retornaObjeto();
          const responseSubProduto = await requisicao('POST', '/buscasubprodutosfaccao?', '', JSON.stringify(params));

          if (!responseSubProduto) {
            throw new Error('Não foi possível buscar os subprodutos para baixa.');
          }

          if (responseSubProduto.status == 200) {
            dadosConsumo = await responseSubProduto.json();
            dadosConsumo = dadosConsumo.resultado;
            dadosConsumo.lancamento = $('#txtLancamento').val();
            dadosConsumo.numero = $('#txtNumeroOrdem').val();
          }

          $('#modal-baixa-consumo-subproduto').modal('show');
        } else {
          await baixaConsumosOF();
        }
      } else {
        await baixaConsumosOF();
      }
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  async function buscaDeposito(componente) {
    const responseDeposito = await requisicao('GET', '/buscadepositomovfaccao?', `NUMERO=${$('#txtNumeroOrdem').val()}`, undefined, 120000);
    if (responseDeposito) {
      const jsonStr = await responseDeposito.json();
      insereValor(`#${componente}`, jsonStr.mensagem, jsonStr.mensagem);
    }
  }

  async function buscaTipoBaixa(componente) {
    const responseDeposito = await requisicao('GET', '/consumotipobaixapadrao?');
    if (responseDeposito) {
      const jsonStr = await responseDeposito.json();
      insereValor(`#${componente}`, jsonStr.mensagem, jsonStr.mensagem);
    }
  }

  async function movimentaOF() {
    await baixaConsumo();
  }

  async function buscaReservaSubProduto() {
    const response = await requisicao('POST', '/buscareservasubprodutosfaccao?', `DEPOSITO=${pegaChave('#txtDepositoConsumoSubProduto')}`, JSON.stringify(dadosConsumo));
    if (response) {
      if (response.status != 200) {
        throw new Error('Não foi possível buscar os dados da reserva dos subprodutos');
      }

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

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

      if (!dadosConsumo.dados > 0) {
        return;
      }

      const colunasItens = [
        { title: "Codigo", data: "codigo" },
        { title: "Descricao", data: "descricao" },
        { title: "Cor", data: "cor" },
        { title: "DescCor", data: "descCor" },
        { title: "Tam", data: "tam" },
        { title: "Quantidade", data: "quantidade" },
        { title: "Estoque.", data: "estoque" },
        { title: "Baixado", data: "baixado" },
        { title: "Reservado", data: "reservado" }
      ];

      $("#tabelaConsumosProduto").DataTable({
        destroy: true,
        filter: false,
        paging: false,
        autoWidth: true,
        columns: colunasItens,
        data: dadosConsumo.dados,
        columnDefs: [
          {
            "targets": [5, 6, 7, 8],
            "className": 'pr-4 text-right'
          }
        ]
      });
    }
  }

  async function validaBaixaConsumoSubProduto() {
    if (pegaChave('#txtDepositoConsumoSubProduto') == '') {
      throw new Error('Necessário informar um depósito, impossível continuar.')
    }

    if (pegaChave('#txtTipoBaixaConsumoSubProduto') == '') {
      throw new Error('Necessário informar um Tipo Baixa, impossível continuar.')
    }

    await buscaReservaSubProduto();

    let bBaixa = false;
    let bAguardar = true;
    let bAbortar = false;
    if (!dadosConsumo.dados) {
      return;
    }
    dadosConsumo.dados.forEach(item => {
      item.tipoBaixa = pegaChave('#txtTipoBaixaConsumoSubProduto');
      if (item.baixado >= item.quantidade) {
        bBaixa = true;
      }
    })

    if (bBaixa) {
      await msgAlerta('SubProduto já Possui Baixa Superior/Igual a Necessidade. Deseja realmente continuar?', () => { bAguardar = false },
        () => {
          bAbortar = true;
          bAguardar = false;
        }
      );

      while (bAguardar) {
        await sleep(500);
      }

      if (bAbortar) {
        throw new Error('Processo abortado.');
      }
    }
  }

  async function validaBaixaConsumoOF() {
    if (pegaChave('#txtDepositoConsumoOF') == '') {
      throw new Error('Necessário informar um depósito, impossível continuar.')
    }

    await buscaConsumosOF();
  }

  async function baixaConsumosSubProduto() {
    $.LoadingOverlay('show');
    try {
      const response = await requisicao('POST', '/gravarconsumosubproduto?', '', JSON.stringify(dadosConsumo));
      if (response) {
        if (response.status != 200) {
          const jsonStr = await response.json();
          throw new Error('Não foi possível gravar a baixa dos subprodutos ' + jsonStr.mensagem);
        }
      }
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  async function gravaConsumosOF() {
    $.LoadingOverlay('show');
    try {
      const dados = {};
      dados.dados = dadosConsumoOF;
      dados.numero = $('#txtNumeroOrdem').val();
      dados.lancamento = $('#txtLancamento').val();
      dados.cliente = pegaChave('#txtEmpresa');
      dados.deposito = pegaChave('#txtDepositoConsumoOF');

      const response = await requisicao('POST', '/gravarconsumosfaccao?', '', JSON.stringify(dados));
      if (response) {
        if (response.status != 200) {
          const jsonStr = await response.json();
          throw new Error('Não foi possível gravar a baixa dos consumos da OF ' + jsonStr.mensagem);
        }
      }
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  async function baixaConsumosOF() {
    const params = `SETOR=${pegaChave('#txtSetor')}`;
    const response = await requisicao('GET', '/baixaconsumofaccao?', params);

    if (!response) {
      return;
    }

    if (response.status == 200) {
      let jsonStr = await response.json();
      if (jsonStr.mensagem == 'S') {
        if ($('#txtLancamento').val() == '') {
          const lancamento = await proximoLancamento();
          $('#txtLancamento').val(lancamento);
        }
        await buscaConsumosOF();
        $('#modal-baixa-consumo-of').modal('show');
      } else {
        await gravarMovimentacaoOF();
      }
    }

  }

  async function proximoLancamento() {
    const responseLancamento = await requisicao('POST', '/proximolancamentofaccao?');

    if (!responseLancamento) {
      throw new Error('Não foi possível gerar o próximo lançamento.');
    }

    if (responseLancamento.status == 200) {
      const lancamento = await responseLancamento.json();
      if (!lancamento.mensagem) {
        throw new Error('Não foi possível gerar o próximo lançamento.');
      }

      return lancamento.mensagem;
    } else {
      throw new Error('Não foi possível gerar o próximo lançamento.');
    }
  }

  async function buscaConsumosOF() {
    const params = `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${pegaChave('#txtSetor')}&PARTE=${pegaChave('#txtParte')}&DEPOSITO=${pegaChave('#txtDepositoConsumoOF')}`
    const response = await requisicao('GET', '/buscarofconsumos?', params);

    if (!response) {
      throw new Error('Não foi possível buscar os consumos da OF.');
    }

    if (response.status == 200) {
      const jsonStr = await response.json();
      dadosConsumoOF = jsonStr.resultado;

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

      if (!dadosConsumoOF > 0) {
        return;
      }

      const colunasItens = [
        { title: "Codigo", data: "codigo" },
        { title: "Descricao", data: "descricao" },
        { title: "Cor", data: "cor" },
        { title: "DescCor", data: "descricaoCor" },
        { title: "Baixar", data: "baixar" },
        { title: "Consumo", data: "consumo" },
        { title: "Estoque", data: "estoque" },
        { title: "Baixado", data: "baixado" },
        { title: "Reservado", data: "reserva" },
        { title: "Deposito", data: "deposito" },
        { title: "Lote", data: "lote" }
      ];

      $("#tabelaConsumosOF").DataTable({
        destroy: true,
        filter: false,
        paging: false,
        scrollX: true,
        autoWidth: true,
        columns: colunasItens,
        data: dadosConsumoOF,
        columnDefs: [
          {
            "targets": [4, 5, 6, 7, 8],
            "className": 'pr-4 text-right'
          }
        ]
      });
    } else {
      throw new Error('Não foi possível buscar os consumos da OF.');
    }
  }

  async function gravarMovimentacaoOF() {
    const params = `CODUSUARIO=${getCookie('cod_usuario')}&SISPLANWEB=1&LANCAMENTO=${$('#txtLancamento').val()}`;
    const dados = retornaObjeto();
    const response = await requisicao('POST', '/movimentarfaccao?', params, JSON.stringify(dados));

    if (response) {
      const jsonStr = await response.json();
      if (response.status != 200) {
        throw new Error('Não foi possível movimentar a OF ' + jsonStr.mensagem.mensagem);
      }

      if (jsonStr.mensagem.codigo == 0) {
        await criaMensagemSucesso(`OF movimentada com sucesso!`, async () => { await callbackOfMovimentada() });
      } else {
        throw new Error('Não foi possível movimentar a OF ' + jsonStr.mensagem.mensagem);
      }
    }
  }

  async function callbackOfMovimentada() {
    const fac500_8 = await buscaParametroERP('FAC', '500', '8', '1')
    if (fac500_8 == 'S') {
      await msgAguardaConfirmacao('Deseja imprimir os dados da movimentação?', async () => {
        $.LoadingOverlay('show')
        try {
          const objEnvio = {
            NUMERO: $('#txtNumeroOrdem').val(),
            PRODUTO: pegaChave('#txtProduto'),
            PARTE: pegaChave('#txtParte'),
            CODFACCAO: pegaChave('#txtEmpresaDestino'),
            DESCFACCAO: pegaDescricao('#txtEmpresaDestino'),
            CODSETOR: pegaChave('#txtProximoSetor'),
            DESCSETOR: pegaDescricao('#txtProximoSetor'),
            SAIDA: $('#txtDtProducao').val(),
          }
          localStorage.setItem('objenviorelfaccao', JSON.stringify(objEnvio));

          parent.document.querySelector('#menu_relfaccao .nav-link').click();

          window.location.href = `${BASE_URI}/movimentacaofaccao/${$('#txtNumeroOrdem').val()}`;
        } catch (error) {
          console.error(error)
          msgAlerta(error.message)
        } finally {
          $.LoadingOverlay('hide')
        }
      }, async () => {
        window.location.href = `${BASE_URI}/movimentacaofaccao/${$('#txtNumeroOrdem').val()}`;
      })
    } else {
      window.location.href = `${BASE_URI}/movimentacaofaccao/${$('#txtNumeroOrdem').val()}`;
    }
  }

  async function buscaSetor() {
    const params = `NUMERO=${$('#txtNumeroOrdem').val()}&PARTE=${pegaChave('#txtParte')}`;
    const response = await requisicao('GET', '/buscasetorfaccao?', params);

    if (response) {
      const jsonStr = await response.json();
      if (response.status != 200) {
        throw new Error('Não foi possível buscar o setor ' + jsonStr.mensagem);
      }

      if (jsonStr.resultado) {
        insereValor('#txtSetor', jsonStr.resultado[0].codigo, jsonStr.resultado[0].descricao);
        $('#txtSetor').trigger('focusout');
        await buscaProximoSetor();
      }
    }
  }

  async function buscaProximoSetor() {
    const params = `NUMERO=${$('#txtNumeroOrdem').val()}&PARTE=${pegaChave('#txtParte')}&SETOR=${pegaChave('#txtSetor')}`;
    const response = await requisicao('GET', '/buscaproximosetorfaccao?', params);

    if (response) {
      const jsonStr = await response.json();
      if (response.status != 200) {
        throw new Error('Não foi possível buscar o setor ' + jsonStr.mensagem);
      }

      if (jsonStr.resultado) {
        insereValor('#txtProximoSetor', jsonStr.resultado[0].codigo, jsonStr.resultado[0].descricao);
      }
    }
  }

  async function habilitaAvancar(numero) {
    $.LoadingOverlay('show');
    try {
      let campos = 'AND (FACCAO.QT_ORIG > (FACCAO.QUANT [SOMA] FACCAO.QUANT_I [SOMA] FACCAO.QUANT_2 [SOMA] FACCAO.QUANT_F))';
      if (bPermiteQtdeFracionada) {
        campos = 'AND (FACCAO.QT_ORIG_NUM > (FACCAO.QUANT_NUM [SOMA] FACCAO.QUANT_I_NUM [SOMA] FACCAO.QUANT_2_NUM [SOMA] FACCAO.QUANT_F_NUM))';
      }
      const dadosSelect = {
        tabela: 'FACCAO',
        camposSelect: ['FACCAO.NUMERO'],
        where: [`FACCAO.NUMERO = '${numero}' ${campos}`],
        groupBy: ['FACCAO.NUMERO']
      };

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

      if (!retornoSelect) {
        msgAlerta('Não foi possível buscar os dados da empresa.');
        return;
      }

      const habilita = retornoSelect[0] == undefined;
      $('#avancar1').prop('disabled', habilita);
      if (habilita) {
        $('#avancar1').attr('title', 'OF já finalizada.');
      }
    } catch (error) {
      console.error(error);
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  $('#tabelaItens').on('input', 'input[type="number"]', function () {
    var valor = $(this).val();

    if (valor < 0) {
      $(this).val(0);
    }
  });

  async function saidaBarra(bBipar = true, bEstornoEpc = false) {
    $.LoadingOverlay('show');
    try {
      let barra = $('#txtBarra').val()

      if (!barra) {
        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);

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

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

      async function bipaBarra(indices) {
        let retorno = 0;

        const tabelaItens = $('#tabelaItens').DataTable().rows().data();
        let bEncontrou = false;
        tabelaItens.map((item, i) => {
          if (item.COR === cor && item.TAM === tam && item.CODIGO === codigo) {
            bEncontrou = true;
            let saldo = parseFloat($(`#SALDO${i}`).val());
            let quant = parseFloat($(`#QUANT${i}`).val());
            if (!biparEstornar) {
              if (saldo >= item.QUANT_ORIG) {
                throw msgAlerta('Saldo não pode ser negativo, verifique!');
              }
              $(`#SALDO${i}`).val(saldo += 1);
              $(`#QUANT${i}`).val(quant -= 1);
              retorno = 0;
              removeBarraLogLida(barraLog);
              estornaBarraBipadaEPC();
            } else {
              if ($(`#SALDO${i}`).val() == 0) {
                throw msgAlerta('Nenhum saldo para a barra lida, verifique!');
              }
              if (!addBarraLogLida(barraLog)) {
                retorno = 6;
              } else {
                $(`#SALDO${i}`).val(saldo -= 1);
                $(`#QUANT${i}`).val(quant += 1);
                addBarraLida(barra);
                adicionaBarraBipadaEPC();
                retorno = 0;
              }
            }
          }
        })

        if (!bEncontrou) {
          throw msgAlerta('Nenhum item encontrado para a barra lida, verifique!');
        }

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

      const params = `BARRA=${encodeURIComponent(barra)}&ESTORNO=${!biparEstornar ? 'S' : 'N'}`;
      const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/retornadadosbarra?', params);

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

      if (!jsonStr.length) {
        if (jsonStr.codigo != 200) {
          throw msgAlerta(jsonStr.mensagem);
        }

        throw msgAlerta('Nenhum item encontrado para a barra lida, verifique!');
      }

      const cor = jsonStr[0].COR;
      const tam = jsonStr[0].TAM;
      const codigo = jsonStr[0].CODIGO;
      if (jsonStr[0].BARRA_LOG == 'S') {
        if (!biparEstornar) {
          if (!await estornaBarraBipada(barra)) {
            msgAlerta('Barra não encontrada!');
            return;
          }
        } else if (!await barraJaEstaBipada(barra, biparEstornar)) {
          await adicionaBarraBipada({
            codigo: codigo,
            cor: cor,
            tam: tam,
            barra: barra,
          });
        } else {
          return;
        }
      }

      const retorno = await bipaBarra(jsonStr);
      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');
    }
  };

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

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

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

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

  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 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 adicionaBarraBipada(objItem) {
    try {
      listaBarrasBipadas.push(objItem);
    } catch (error) {
      console.error(error);
    }
  }

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

  async function estornaBarraBipada(sBarra) {
    if (!listaBarrasBipadas.find(item => item.barra == sBarra)) {
      return false;
    }
    listaBarrasBipadas = [...listaBarrasBipadas.filter(item => item.barra !== sBarra)];
    return true;
  }

  async function baixaMaiorQueSaldo() {
    try {
      const pesquisa = {
        tabela: "CADFLUXO",
        camposSelect: ["BAIXAMAIOR"],
        where: [`CODIGO = '${pegaChave('#txtSetor')}'`]
      };

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

      if (jsonStr && jsonStr.length <= 0) {
        return false;
      } else if (jsonStr[0].BAIXAMAIOR == 'S') {
        return true
      } else {
        return false
      }
    } catch (error) {
      console.error(error)
      msgAlerta(error.message)
    }
  }

  $('#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 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 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 movimentaçã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 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: [
            "BARRA",
            "BARRACLI",
            "BARRA28",
            "ID",
            `'${item.EPC}' EPC`
          ],
          where: [`CODIGO = '${item.CODIGO}' AND COR = '${item.COR}' AND TAM = '${item.TAMANHO}'`],
        };

        const json = await retornaJsonPesquisaPadrao(JSON.stringify(dadosBarraEPC));
        if ((json) && (json.length > 0)) {
          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);
    }
  }
});