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

  const url = window.location.href
  const id = url.split('/')[url.split('/').length - 1]

  const params = new URLSearchParams(id);

  const ordemproducao = params.get("NUMERO");
  const recarregar = params.get("RECARREGAR") === 'S';

  if (!recarregar && !await liberarRegistro('MOVIMENTOFACCAO', ordemproducao)) {
    window.location.href = '../movimentacaofaccao';
  }

  componenteFiltro('maquina', false, false, 'Maquina')

  let dadosConsumo;
  let dadosConsumoOF;
  let listaBarrasBipadasEPC = [];
  let barrasLidas = [];
  let barrasLog = [];
  let objEnfesto = {}
  let arrDefeito = []
  let arrReprovado = []
  let ultimoRegistroBipado = {}
  const parametrosOP = await BuscaParametrosOrdemProducao();
  const bPermiteQtdeFracionada = parametrosOP[2].VALOR == '1';
  const integracaoEPC = await CopiaParametro('EXPEDICAO', 7);
  const bBarraLog = await CopiaParametro('SISTEMA', 0);
  const bUsaLocal = await CopiaParametro('SISTEMA', 4) == '1';
  const bLancaDefeito = parametrosOP[5].VALOR == '1';
  const bConfirmacaoTamanho = parametrosOP[6].VALOR == '1';
  let listaBarrasBipadas = [];
  let carregouDadosNaoSalvos = false
  const validarOfsFilhasPendentes = parametrosOP[9]?.VALOR == '1' ?? false
  const selecionarLotesAoBaixarConsumos = parametrosOP[10]?.VALOR == '1' ?? false
  let bloqueiaSaida = false;

  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;
  }

  if (bUsaLocal) {
    $('#divLocalSubProduto').removeClass('d-none')
    $('#divLocalConsumos').removeClass('d-none')
    $('#containerLocalBaixaConsumos').removeClass('d-none')
  }
  const dataAtual = pegarDataAtual();

  let enfestoCount = 1;
  const ENFESTO_OFFSET = 4;

  const columnsEnfesto = [
    { data: "codigo", title: "Código" },
    { data: "cor", title: "Cor" },
    { data: "desc_cor", title: "Desc. Cor" },
    { data: "tam", title: "Tam" },
    { data: "enfesto_1", title: "Enfesto 1" },
    { data: "enfesto_2", title: "Enfesto 2", visible: false },
    { data: "enfesto_3", title: "Enfesto 3", visible: false },
    { data: "enfesto_4", title: "Enfesto 4", visible: false },
    { data: "enfesto_5", title: "Enfesto 5", visible: false },
    { data: "enfesto_6", title: "Enfesto 6", visible: false },
    { data: "enfesto_7", title: "Enfesto 7", visible: false },
    { data: "enfesto_8", title: "Enfesto 8", visible: false },
    { data: "enfesto_9", title: "Enfesto 9", visible: false },
    { data: "enfesto_10", title: "Enfesto 10", visible: false }
  ];

  criaDataTablePadrao('#tabelaEnfesto', false, false, false, false, true, true, '250px', null, columnsEnfesto, [], [], [], []);

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

  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);
    await excluirRegistroExpiracao("MOVIMENTOFACCAO", ordemproducao, false);
    await deletaDadosDigitados()
    removerRegistroParaLiberarSessionStorage('movimentacaofaccao')
    window.location.href = `${BASE_URI}/movimentacaofaccao`;
  });

  async function validaObrigaLaudo() {
    if (contaFs == 2 && (await buscaValor('CADFLUXO', 'OBRIGA_LAUDO', 'CODIGO', pegaChave('#txtSetor'))).OBRIGA_LAUDO == 'S') {
      if (!await Existe('FAC_DEFEITO', ['NUMERO', 'SETOR'], [$('#txtNumeroOrdem').val(), pegaChave('#txtSetor')])) {
        msgAlerta('Inspeção de qualidade obrigatória neste setor. Verifique, por favor.');
        return false
      }
    }

    return true
  }

  async function validarDatas(numero, setor, parte, movimento) {
    const retorno = new Date($('#txtDtRetorno').val()).setHours(0, 0, 0, 0)

    const where = [`NUMERO = '${numero}'`, `OP = '${setor}'`, `PARTE = '${parte}'`]
    if (movimento) {
      where.push(`MOV = ${movimento}`)
    }

    const pesquisa = {
      tabela: "FACCAO",
      camposSelect: ["DT_S", "MOV"],
      where,
      groupBy: ["DT_S", "MOV"],
    };

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

    if (!jsonStr || jsonStr.length === 0) {
      throw new Error('Não foi possível validar as datas.')
    }

    if (movimento) {
      const envio = new Date(jsonStr[0].DT_S ?? 0).setHours(0, 0, 0, 0)
      if (retorno < envio) {
        throw new Error(`Data de retorno menor que a data de envio. Data de envio: ${formataDataBonita(jsonStr[0].DT_S ?? '')}`);
      }
    } else {
      const registroEncontrado = jsonStr.find((it) => {
        const envio = new Date(it.DT_S ?? 0).setHours(0, 0, 0, 0)
        return retorno < envio
      })

      if (registroEncontrado) {
        throw new Error(`Data de retorno menor que a data de envio.\nData de envio: ${formataDataBonita(registroEncontrado.DT_S ?? '')}\nMovimento: ${registroEncontrado.MOV}`);
      }
    }
  }

  $("#btnGravar").click(async function () {
    $.LoadingOverlay('show');
    try {
      $('#btnGravar').attr('disabled', true)
      const numeroOf = $('#txtNumeroOrdem').val()
      const usuario = getCookie('usuario')
      const setor = pegaChave('#txtSetor')
      const parte = pegaChave('#txtParte')
      rotinaGeraLog('MOV_FACCAO_WEB', numeroOf, `USUARIO ${usuario} CLICOU NO GRAVAR PARA MOVIMENTAR OF. NUMERO: ${numeroOf} - SETOR: ${setor}`, 'Movimentação')
      if (!await validaObrigaLaudo()) return

      await validarDatas(numeroOf, setor, parte, $('#cbMovimento').val())

      if (pegaChave('#txtSetor') === pegaChave('#txtProximoSetor')) {
        return msgAlerta('Setor e Próximo Setor não podem ser iguais, verifique.');
      }

      await validaMovimentacao();

      if ($('#cbHabilitaQtdeOf').is(':checked') && contaFs == 2) {
        await new Promise((resolve, reject) => {
          ModalAtualizaQuantidade.carregar({
            numero: numeroOf,
            setor,
            parte,
            movimento: $('#cbMovimento').val(),
            cliente: pegaChave('#txtEmpresa'),
            bPermiteQtdeFracionada,
            permiteQtdeMaior: $('#cbBaixaMaior').is(':checked'),
            resolve,
            reject,
          })
          ModalAtualizaQuantidade.abrir()
          $.LoadingOverlay('hide')
        })
      }
      if ($('#cbHabilitaQtdeOf').is(':checked') && $('#tabelaItens').DataTable().data().toArray().some(item => item.ALTEROUQTDE == 'S')) {
        await atualizaQtdeOf()
      }


      if ((await buscaValor('CADFLUXO', 'MOV_PARTES', 'CODIGO', pegaChave('#txtSetor'))).MOV_PARTES == 'S') {
        await executarRotinaFacAbreSetor();
      }
      rotinaGeraLog('MOV_FACCAO_WEB', numeroOf, `DADOS FORAM VALIDADOS PARA MOVIMENTACAO DE OF. USUARIO: ${usuario} - NUMERO: ${numeroOf} - SETOR: ${setor}`, 'Movimentação')

      await movimentaOF();
    } catch (error) {
      console.error(error);
      if (error && error.message) {
        msgErro(`Não foi possível fazer a movimentação: ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
      await deletaDadosDigitados()
      $('#btnGravar').attr('disabled', false)
    }
  })

  async function validarOfsPendentes(numero, parte, setor) {
    try {
      $.LoadingOverlay('show')
      const response = await requisicao('GET', `/sisplan/movimentacaofaccao/v1/ofspendentes?`, `NUMERO=${numero}&PARTE=${parte}&SETOR=${setor}`, '', 3600000)

      const dados = await response.json()
      if (!dados) {
        return
      }

      const { mensagem, resultado } = dados
      if (mensagem?.codigo !== 200) {
        throw mensagem?.mensagem
      }

      if (resultado && resultado.length) {
        const texto = resultado.map((item) => `\nNúmero: ${item.numero}\nParte: ${item.parte} - ${item.descParte}`)

        msgErro(`Existem ordens de produção filhas pendentes, impossível continuar.${texto.join('\n')}`)

        return false
      }

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

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

    if ($(this).attr("id") == "avancar1") {
      if (validarOfsFilhasPendentes) {
        const dadosValidados = await validarOfsPendentes($('#txtNumeroOrdem').val(), pegaChave('#txtParte'), pegaChave('#txtSetor'))
        if (!dadosValidados) {
          return
        }
      }
      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,
        }
      );

      $('#txtSetor').focus()
      $('#txtSetor').trigger('blur')

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

    } else {
      if (!finalizado) {
        msgAlerta('Necessário informar os campos obrigatórios!');
      }
    }
  });

  function getMaxEnfestoCol(data) {
    let max = 1;
    data.forEach(item => {
      for (let i = 10; i >= 1; i--) {
        if (item[`enfesto_${i}`] !== undefined && item[`enfesto_${i}`] != 0) {
          if (i > max) max = i;
          break;
        }
      }
    });
    return max;
  }

  async function buscaEnfesto() {
    const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/enfesto?', `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${$('#txtSetor').val()}`, '', 120000);

    if (!response) {
      return;
    }

    let jsonStr = await response.json();
    if (objEnfesto.length) {
      return objEnfesto.map((item) => ({
        codigo: item.codigo,
        cor: item.cor,
        desc_cor: item.desc_cor,
        tam: item.tamanho,
        enfesto_1: item.enfesto_1 ? item.enfesto_1 : 0,
        enfesto_2: item.enfesto_2 ? item.enfesto_2 : 0,
        enfesto_3: item.enfesto_3 ? item.enfesto_3 : 0,
        enfesto_4: item.enfesto_4 ? item.enfesto_4 : 0,
        enfesto_5: item.enfesto_5 ? item.enfesto_5 : 0,
        enfesto_6: item.enfesto_6 ? item.enfesto_6 : 0,
        enfesto_7: item.enfesto_7 ? item.enfesto_7 : 0,
        enfesto_8: item.enfesto_8 ? item.enfesto_8 : 0,
        enfesto_9: item.enfesto_9 ? item.enfesto_9 : 0,
        enfesto_10: item.enfesto_10 ? item.enfesto_10 : 0,
      }))
    } else if (!jsonStr.resultado) {
      const tabela = $('#tabelaItens').DataTable().data()
      return tabela.map((item) => ({
        codigo: item.CODIGO,
        cor: item.COR,
        desc_cor: item.DESC_COR,
        tam: item.TAM,
        enfesto_1: 0,
        enfesto_2: 0,
        enfesto_3: 0,
        enfesto_4: 0,
        enfesto_5: 0,
        enfesto_6: 0,
        enfesto_7: 0,
        enfesto_8: 0,
        enfesto_9: 0,
        enfesto_10: 0,
      }))
    } else {
      return jsonStr.resultado.map((item, i) => ({
        codigo: item.codigo,
        cor: item.cor,
        desc_cor: item.desc_cor,
        tam: item.tamanho,
        enfesto_1: item.enfesto_1 ? item.enfesto_1 : 0,
        enfesto_2: item.enfesto_2 ? item.enfesto_2 : 0,
        enfesto_3: item.enfesto_3 ? item.enfesto_3 : 0,
        enfesto_4: item.enfesto_4 ? item.enfesto_4 : 0,
        enfesto_5: item.enfesto_5 ? item.enfesto_5 : 0,
        enfesto_6: item.enfesto_6 ? item.enfesto_6 : 0,
        enfesto_7: item.enfesto_7 ? item.enfesto_7 : 0,
        enfesto_8: item.enfesto_8 ? item.enfesto_8 : 0,
        enfesto_9: item.enfesto_9 ? item.enfesto_9 : 0,
        enfesto_10: item.enfesto_10 ? item.enfesto_10 : 0,
      }))
    }
  }

  $('#modal-enfesto').on('show.bs.modal', async function () {
    if ($.fn.DataTable.isDataTable('#tabelaEnfesto')) {
      $('#tabelaEnfesto').DataTable().destroy();
      $('#tabelaEnfesto').empty();
    }

    const data = await buscaEnfesto() || [];

    enfestoCount = getMaxEnfestoCol(Array.isArray(data) ? data : data.toArray());
    enfestoCria = enfestoCount;

    const table = $('#tabelaEnfesto').DataTable({
      search: false,
      filter: false,
      order: [],
      sort: true,
      info: false,
      scrollX: true,
      destroy: true,
      colReorder: true,
      paging: false,
      autoWidth: true,
      data: data,
      columns: columnsEnfesto,
      rowCallback: function (row, rowData) {
        for (let i = 1; i <= enfestoCount; i++) {
          const colIndex = ENFESTO_OFFSET + (i - 1);
          let $td = $(row).find('td').eq(colIndex);

          if ($td.find('input.campoEnfesto').length === 0) {
            let $input = $('<input>', {
              type: 'number',
              min: 0,
              id: `txtEnfesto_${i}_${row._DT_RowIndex}`,
              class: 'input-default focus form-control text-right campoEnfesto',
              value: rowData[`enfesto_${i}`] || 0,
              // disabled: true,
              focus: function () {
                if ($(this).val() == '0' || $(this).val() == '') $(this).val('');
              }
            }).css({ width: '80px', 'box-sizing': 'border-box', margin: '0 2px' });
            $input.on('change blur', function () {
              if ($(this).val() == '0' || $(this).val() == '') {
                $(this).val('0');
              }
              let valor = $(this).val() || 0;
              rowData[`enfesto_${i}`] = parseFloat(valor);
            });

            $td.empty().append($input);
          } else {
            $td.find('input.campoEnfesto').val(rowData[`enfesto_${i}`] || 0);
          }
        }

        // $(row).find('.campoEnfesto').attr('disabled', true);
      }
    });

    for (let i = 1; i <= enfestoCount; i++) {
      table.column(ENFESTO_OFFSET + (i - 1)).visible(true);
    }

    $("#tabelaEnfesto").DataTable().columns.adjust().draw(false);
  });

  $('#btnIncluirEnfesto').on('click', function () {
    if (enfestoCount >= 10) {
      msgAlerta('Não é possível criar mais de 10 enfestos.');
      return;
    }

    enfestoCount++;

    const table = $('#tabelaEnfesto').DataTable();
    const colIndex = ENFESTO_OFFSET + (enfestoCount - 1);

    table.column(colIndex).visible(true);
    table.columns.adjust().draw(false);

    // $('#tabelaEnfesto').find('td:visible .campoEnfesto').attr('disabled', false);

    $('#btnGravarEnfesto').removeClass('d-none');
    $('#btnDesistirEnfesto').removeClass('d-none');
  });

  $('#btnDesistirEnfesto').on('click', function () {
    $('#btnDesistirEnfesto').addClass('d-none')
    $('#btnGravarEnfesto').addClass('d-none')
    $('#btnIncluirEnfesto').removeClass('d-none')
    $('#btnFecharEnfesto').removeClass('d-none')

    // $('.campoEnfesto').attr('disabled', true)
  })

  function BuscaDadosEnfesto() {
    const tabela = $('#tabelaEnfesto').DataTable()

    const retorno = tabela.data().map((item) => ({
      numero: $('#txtNumeroOrdem').val(),
      setor: pegaChave('#txtSetor'),
      codigo: item.codigo,
      cor: item.cor,
      desc_cor: item.desc_cor,
      tamanho: item.tam,
      enfesto_1: item.enfesto_1,
      enfesto_2: item.enfesto_2,
      enfesto_3: item.enfesto_3,
      enfesto_4: item.enfesto_4,
      enfesto_5: item.enfesto_5,
      enfesto_6: item.enfesto_6,
      enfesto_7: item.enfesto_7,
      enfesto_8: item.enfesto_8,
      enfesto_9: item.enfesto_9,
      enfesto_10: item.enfesto_10,
    }))

    return retorno
  }

  $('#btnGravarEnfesto').on('click', async function () {
    objEnfesto = BuscaDadosEnfesto().toArray()
    $('#modal-enfesto').modal('hide')
  })

  function callBackVoltar(el) {
    contaFs -= 1;

    const currentFs = $(el).parent().parent();
    const previousFs = currentFs.prev();

    $("#progressbar li")
      .eq($("fieldset").index(currentFs))
      .removeClass("active");

    previousFs.show();

    currentFs.animate(
      { opacity: 0 },
      {
        step(now) {
          const opacity = 1 - now;
          currentFs.css({
            display: "none",
            position: "relative",
          });
          previousFs.css({ opacity });
        },
        duration: 600,
      }
    );
    $('#divBarra').addClass('d-none');
    listaBarrasBipadas = [];
    barrasLog = [];
    barrasLidas = [];
    carregouDadosNaoSalvos = true
  }

  $(".previous").click(function () {
    const el = this
    const total = $('.campoQuant').toArray().reduce((soma, el) => soma + (Number(el.value) || 0), 0);

    if ($('#cbBaixaPorBarra').is(':checked') && total > 0) {
      msgAguardaConfirmacao('Já existem itens bipados. Ao confirmar, a quantidade bipada será perdida. Deseja continuar?', () => { callBackVoltar(el) }, () => { })
    } else {
      callBackVoltar(el)
    }
  });

  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} - (Pressione F7 para esconder/mostrar campos)`

        $('#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}`
      }))
    })
    insereValor('#txtParte', partes[0].codigo, partes[0].descricao);
    $('#txtParte').trigger('focusout');
    await buscaResumo($('#cbPartes').val())
  }

  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;
          }

          let 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 Expurga", data: "expurga" },
            { title: "Qtde Saldo", data: "saldo" }
          ];

          colunasItens = colunasItens.filter(item => item !== false);

          $('#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,
            scrollY: '350px',
            columnDefs: [{
              targets: 0,
              // searchable: false
            },
            {
              "targets": [2, 3, 4, 5, 6, 7, 8],
              "className": 'pr-4 text-right'
            }]
          });
        }
      } catch (error) {
        console.error(error);
        msgErro(`Não foi possível buscar os dados ${error.message}`);
      }
    } finally {
      $.LoadingOverlay('hide');
    };
  }

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

      let setor = ''
      if (pegaChave('#txtSetor') != '') {
        setor = pegaChave('#txtSetor')
      } else {
        let tabela = $('#tabelaResumo').DataTable()
        let dados = tabela.data()
        if (dados.length > 0) {
          let ultimo = dados[dados.length - 1];
          setor = ultimo.cod_Setor;
        }
      }

      try {
        if ((pegaChave('#txtParte' == ''))) {
          return;
        }

        const params = `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${setor}&PARTE=${pegaChave('#txtParte')}&MOVIMENTO=${$('#cbMovimento').val()}&CODCLI=${pegaChave('#txtEmpresa')}&NAO_ZERAR=N&BPENDENTE=true&BSETORANTERIOR=true&MOSTRA_GRADE=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('#tabelaGrade')) {
          $('#tabelaGrade').DataTable().destroy();
          $('#tabelaGrade').empty();
        };

        const titulos = [
          { title: "Codigo", data: "CODIGO" }, //1
          { title: "Cor", data: "COR" }, //2
          { title: "Desc. Cor", data: "DESC_COR" }, //3
          { title: "Tam", data: "TAM" }, //4
          { title: "Quant_Orig.", data: "QUANT_ORIG" }, //5
          { title: "Saldo", data: "SALDO_CALC" }, //6
          { title: "Quant.", data: "QUANT" }, //7
          { title: "Segunda", data: "QUANT_SEGUNDA" }, //8
          { title: "Incomp.", data: "QUANT_INCOMPLETA" }, //9
          { title: "Perdida", data: "QUANT_PERDIDA" }, //10
          { title: "Saldo", data: "SALDO" }, //11
          { title: "Identificador", data: "IDENTIFICADOR" }, //12
          { title: "Alterou Qtde", data: "ALTEROUQTDE" }, //13
          { title: "Expurga", data: "QTDE_EXPURGA" } //14
        ];

        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: tamanhoRenomeado.SALDO,
              QUANT: 0,
              QUANT_SEGUNDA: tamanhoRenomeado.QUANT_SEGUNDA,
              QUANT_PERDIDA: 0,
              QUANT_INCOMPLETA: 0,
              SALDO: tamanhoRenomeado.SALDO,
              IDENTIFICADOR: tamanhoRenomeado.IDENTIFICADOR,
              ALTEROUQTDE: 'N',
              QTDE_EXPURGA: 0,
            });
            i++;
          });
          return result;
        }, []);

        const [
          { ESCONDE_SEGUNDA: escondeSegunda },
          { ESCONDE_INCOMPLETA: escondeIncompleta },
          { ESCONDE_PERDIDA: escondePerdida },
          { LANCA_EXPURGA: lancaExpurga }
        ] = await Promise.all([
          buscaValor('CADFLUXO', 'ESCONDE_SEGUNDA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'ESCONDE_INCOMPLETA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'ESCONDE_PERDIDA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'LANCA_EXPURGA', 'CODIGO', pegaChave('#txtSetor'))
        ])

        let indices = []

        if (escondeSegunda === 'S') indices.push(7)
        if (escondeIncompleta === 'S') indices.push(8)
        if (escondePerdida === 'S') indices.push(9)
        if (lancaExpurga === 'N') indices.push(13)

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

        addBlurCamposGrade()

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

  $('#cbMostrarGrade').on('click', async function () {
    if ($(this).is(':checked')) {
      $('#divTabelaResumo').addClass('d-none');
      $('#divTabelaGrade').removeClass('d-none');
      await buscaGradeMovimentacao()
    } else {
      $('#divTabelaResumo').removeClass('d-none');
      $('#divTabelaGrade').addClass('d-none');
    }
  })

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

    const retornaColunas = (campos) => {
      let dataSetCols = [];

      let keys = Object.keys(campos[0]);
      dataSetCols.push({
        'title': 'SEL',
        'data': 'SEL',
        'width': '15px'
      });

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

      return dataSetCols
    }

    componenteFiltro('defeito', false, false)

    $('#cbBaixaPorBarra').on('click', async function () {
      $('#btn-parar-epc').attr('disabled', !$('#btn-parar-epc').prop('disabled'))
      $('#btn-iniciar-epc').attr('disabled', !$('#btn-iniciar-epc').prop('disabled'))
      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');
      // calcularTotais()

      await carregaDadosArquivo()
    })

    $('#txtSetor').on("focusout", async function () {
      $.LoadingOverlay('show')
      try {
        await validaObrigaLaudo()
        $('#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 (validarOfsFilhasPendentes) {
          const dadosValidados = await validarOfsPendentes($('#txtNumeroOrdem').val(), parte, setor)
          if (!dadosValidados) {
            callBackVoltar($('#voltar2'))
            return
          }
        }

        await buscaProximoSetor();

        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();

        if (await habilitaQtdeOf() && contaFs == 2) {
          // if (await abreModalAlteraQtde()) {
          // $('#cbHabilitaQtdeOf').prop('checked', true)
          // } else {
          // $('#cbHabilitaQtdeOf').prop('checked', true)
          // }
          // } else {
          $('#cbHabilitaQtdeOf').prop('disabled', false)
        }
        const baixaMaior = (await buscaValor('CADFLUXO', 'BAIXAMAIOR', 'CODIGO', pegaChave('#txtSetor'))).BAIXAMAIOR == 'S'
        if (baixaMaior) {
          $('#cbBaixaMaior').prop('checked', true)
        }

        const naoGeraPagamento = (await buscaValor('CADFLUXO', 'REPROVA_PAGAMENTO', 'CODIGO', pegaChave('#txtSetor'))).REPROVA_PAGAMENTO
        if (naoGeraPagamento) {
          $('#divReprovarPagamento').removeClass('d-none')
        }


        const habilitaEnfesto = (await buscaValor('CADFLUXO', 'HAB_ENFESTO_MOV', 'CODIGO', pegaChave('#txtSetor'))).HAB_ENFESTO_MOV
        const usaBarra = (await buscaValor('CADFLUXO', 'USA_BARRA_FAC', 'CODIGO', pegaChave('#txtSetor'))).USA_BARRA_FAC == "S"
        if (habilitaEnfesto == 'S' && $('#payment').hasClass('active')) {
          $('#modal-enfesto').modal('show')
        }

        if (usaBarra) {
          if (integracaoEPC != '0' || integracaoEPC != '3') {
            $('#btn-iniciar-epc').prop('disabled', true)
          }

          $('#cbBaixaPorBarra').prop('checked', true)
          $('#cbBaixaPorBarra').prop('disabled', true)
          setTimeout(() => {
            $('#cbBaixaPorBarra').trigger('click')
          }, 200)
        } else {
          $('#cbBaixaPorBarra').prop('checked', false)
          $('#cbBaixaPorBarra').prop('disabled', false)
        }
        
      } finally {
        $.LoadingOverlay('hide')
      }
    });

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

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

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

    $('#btnLimpaDeposito2').on('click', function () {
      $('#txtDeposito2').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('');
    });

    componenteFiltro('local', false, false, 'LocalConsumoOF');
    componenteFiltro('local', false, false, 'LocalSubProduto');
  }

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

    if (setor != '') {
      const usaBarra = (await buscaValor('CADFLUXO', 'USA_BARRA_FAC', 'CODIGO', setor)).USA_BARRA_FAC

      if (usaBarra == 'S') {
        $('#cbBaixaPorBarra').prop('checked', true)
        $('#cbBaixaPorBarra').prop('disabled', true)
        setTimeout(() => {
          $('#cbBaixaPorBarra').trigger('click')
        }, 200)
      } else {
        $('#cbBaixaPorBarra').prop('checked', false)
        $('#cbBaixaPorBarra').prop('disabled', false)
      }
    }
  });

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

  $('#modal-baixa-consumo-subproduto').on('hidden.bs.modal', async function () {
    $('#btnGravar').attr('disabled', false)
  });

  $('#modal-baixa-consumo-of').on('hidden.bs.modal', async function () {
    $('#btnGravar').attr('disabled', false)
  });

  $('#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 {
      $(this).prop('disabled', true)
      $.LoadingOverlay('show');
      if (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}`);
    } finally {
      $.LoadingOverlay('hide');
      $(this).prop('disabled', false)
    }
  });

  $('#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) {
    $.LoadingOverlay('show');
    try {
      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 {
        const selectProFluxo = {
          tabela: 'PRO_FLUXO_SETOR',
          camposSelect: ['ENTIDADE.CODCLI', 'ENTIDADE.NOME'],
          leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = PRO_FLUXO_SETOR.TERCEIRO' }],
          where: [
            `PRO_FLUXO_SETOR.CODIGO = '${pegaChave('#txtProduto')}'`,
            `PRO_FLUXO_SETOR.PARTE = '${parte}'`,
            `PRO_FLUXO_SETOR.SETOR = '${pegaChave('#txtProximoSetor')}'`,
          ],
          groupBy: ['ENTIDADE.CODCLI', 'ENTIDADE.NOME']
        };

        const retornoProFluxo = await retornaJsonPesquisaPadrao(JSON.stringify(selectProFluxo));

        if (retornoProFluxo.length > 0 && retornoProFluxo[0].CODCLI != '') {
          insereValor('#txtEmpresaDestino', retornoProFluxo[0].CODCLI, retornoProFluxo[0].NOME);
        }

        let where = ''
        const having = []
        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}'` : '';
        if (bPermiteQtdeFracionada) {
          having.push('SUM(FACCAO.QT_ORIG_NUM - (FACCAO.QUANT_NUM [SOMA] FACCAO.QUANT_2_NUM [SOMA] FACCAO.QUANT_I_NUM [SOMA] FACCAO.QUANT_F_NUM)) > 0')

        } else {
          having.push('SUM(FACCAO.QT_ORIG - (FACCAO.QUANT [SOMA] FACCAO.QUANT_2 [SOMA] FACCAO.QUANT_I [SOMA] FACCAO.QUANT_F)) > 0')
        }
        const dadosSelect = {
          tabela: 'FACCAO',
          camposSelect: ['FACCAO.CODCLI', 'ENTIDADE.NOME'],
          leftJoin: [{ tabela: 'ENTIDADE', condicao: 'ENTIDADE.CODCLI = FACCAO.CODCLI' }],
          where: [where],
          groupBy: ['FACCAO.CODCLI', 'ENTIDADE.NOME'],
          having,
        };

        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);
        if (retornoProFluxo.length <= 0 || retornoProFluxo[0].CODCLI == '') 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');
    };
  }

  function calcularTotais() {
    let totalQuantOrig = 0
    let totalSaldo = 0
    let totalQuant = 0
    let totalSegunda = 0
    let totalIncompleta = 0
    let totalPerdida = 0
    let totalExpurga = 0

    $('#tabelaItens').DataTable().rows().every(function () {
      const row = $(this.node());
      const quantOrig = safeParseFloat(this.data()?.QUANT_ORIG) ?? 0
      const saldo = safeParseFloat(row.find('.campoSaldo').val()) ?? 0
      const quant = safeParseFloat(row.find('.campoQuant').val()) ?? 0
      const segunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0
      const incompleta = safeParseFloat(row.find('.qtdeIncompletas').val()) ?? 0
      const expurga = safeParseFloat(row.find('.qtdeExpurga').val()) ?? 0
      const perdida = safeParseFloat(row.find('.qtdePerdidas').val()) ?? 0

      totalQuantOrig += quantOrig
      totalSaldo += saldo
      totalQuant += quant
      totalSegunda += segunda
      totalIncompleta += incompleta
      totalPerdida += perdida
      totalExpurga += expurga
    })

    $('#txtTotalQuantOrig').val($('#tabelaResumo').DataTable().data()[$('#tabelaResumo').DataTable().data().length - 1].orig)
    $('#txtTotalSaldo').val(totalSaldo)
    $('#txtTotalQuant').val(totalQuant)
    $('#txtTotalSegunda').val(totalSegunda)
    $('#txtTotalIncompleta').val(totalIncompleta)
    $('#txtTotalPerdida').val(totalPerdida)
    $('#txtTotalExpurga').val(totalExpurga)
  }

  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" },
          { title: "Alterou Qtde", data: "ALTEROUQTDE" },
          { title: "Expurga", data: "QTDE_EXPURGA" }
        ];

        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) {
            const identificador = tamanhoRenomeado.IDENTIFICADOR;
            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${identificador}" value="${tamanhoRenomeado.SALDO}" disabled style="min-width: 70px; max-width: 150px">`,
              QUANT: `<input type="number" min="0" class="input-default focus form-control campoQuant camposGrade text-right" id="QUANT${identificador}" value="${tamanhoRenomeado.QUANT}" style="min-width: 70px; max-width: 150px">`,
              QUANT_SEGUNDA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdeSegunda text-right" id="QUANT_SEGUNDA${identificador}" value="${tamanhoRenomeado.QUANT_SEGUNDA}" style="min-width: 70px; max-width: 150px">`,
              QUANT_PERDIDA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdePerdidas text-right" id="QUANT_PERDIDA${identificador}" value="0" style="min-width: 70px; max-width: 150px">`,
              QUANT_INCOMPLETA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdeIncompletas text-right" id="QUANT_INCOMPLETA${identificador}" value="0" style="min-width: 70px; max-width: 150px">`,
              SALDO: tamanhoRenomeado.SALDO,
              IDENTIFICADOR: tamanhoRenomeado.IDENTIFICADOR,
              ALTEROUQTDE: 'N',
              QTDE_EXPURGA: `<input type="number" min="0" class="input-default focus form-control camposGrade qtdeExpurga text-right" id="QTDE_EXPURGA${identificador}" value="0" style="min-width: 70px; max-width: 150px">`,
            });
            i++;
          });
          return result;
        }, []);

        const [
          { ESCONDE_SEGUNDA: escondeSegunda },
          { ESCONDE_INCOMPLETA: escondeIncompleta },
          { ESCONDE_PERDIDA: escondePerdida },
          { LANCA_EXPURGA: lancaExpurga }

        ] = await Promise.all([
          buscaValor('CADFLUXO', 'ESCONDE_SEGUNDA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'ESCONDE_INCOMPLETA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'ESCONDE_PERDIDA', 'CODIGO', pegaChave('#txtSetor')),
          buscaValor('CADFLUXO', 'LANCA_EXPURGA', 'CODIGO', pegaChave('#txtSetor'))
        ])

        let indices = []

        if (escondeSegunda === 'S') indices.push(7)
        if (escondeIncompleta === 'S') indices.push(8)
        if (escondePerdida === 'S') indices.push(9)
        if (lancaExpurga === 'N') indices.push(13)

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

        addBlurCamposGrade()

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

  const opcaoZerarQuantidades = bBarraLog === '0' ? '       <button class="dropdown-item" type="button" title="Zerar Quantidades" id="btnZerarQuantidades">Zerar Quantidades </button>  ' : ''

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

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

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

  async function marcaSaldoPerdido() {
    const table = $('#tabelaItens').DataTable();
    table.rows().every(function () {
      const row = $(this.node());
      const saldo = parseFloat(row.find('.campoSaldo').val())
      if (saldo) {
        row.find('.campoSaldo').val(0)
      }
      let qtdePerdida = parseFloat(row.find('.qtdePerdidas').val())
      qtdePerdida = qtdePerdida + saldo;
      row.find('.qtdePerdidas').val(qtdePerdida)
    })
    calcularTotais()
  }

  async function marcaSaldoSegunda() {
    const table = $('#tabelaItens').DataTable();
    table.rows().every(function () {
      const row = $(this.node());
      const saldo = parseFloat(row.find('.campoSaldo').val())
      if (saldo) {
        row.find('.campoSaldo').val(0)
      }
      let qtdeSegunda = parseFloat(row.find('.qtdeSegunda').val())
      qtdeSegunda = qtdeSegunda + saldo;
      row.find('.qtdeSegunda').val(qtdeSegunda)
    })
    calcularTotais()
  }

  async function marcaSaldoIncompleta() {
    const table = $('#tabelaItens').DataTable();
    table.rows().every(function () {
      const row = $(this.node());
      const saldo = parseFloat(row.find('.campoSaldo').val())
      if (saldo) {
        row.find('.campoSaldo').val(0)
      }
      let qtdeIncompleta = parseFloat(row.find('.qtdeIncompletas').val())
      qtdeIncompleta = qtdeIncompleta + saldo;
      row.find('.qtdeIncompletas').val(qtdeIncompleta)
    })
    calcularTotais()
  }

  async function marcaSaldoExpurga() {
    const table = $('#tabelaItens').DataTable();
    table.rows().every(function () {
      const row = $(this.node());
      const saldo = parseFloat(row.find('.campoSaldo').val())
      if (saldo) {
        row.find('.campoSaldo').val(0)
      }
      let qtdeExpurga = parseFloat(row.find('.qtdeExpurga').val())
      qtdeExpurga = qtdeExpurga + saldo;
      row.find('.qtdeExpurgas').val(qtdeExpurga)
    })
    calcularTotais()
  }

  function zeraQuantidades() {
    try {
      const table = $('#tabelaItens').DataTable();
      table.rows().every(function () {
        const item = this.data();
        const row = $(this.node());
        row.find('.campoSaldo').val(item.QUANT_ORIG)
        row.find('.campoQuant').val('0')
        row.find('.qtdeSegunda').val('0')
        row.find('.qtdePerdidas').val('0')
        row.find('.qtdeIncompletas').val('0')
        row.find('.qtdeExpurga').val('0')
      })
      calcularTotais()
    } 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');
    }
  });

  $('#txtBarra').on('keydown', async function (event) {
    if ((event.key == 'Enter')) {
      $('#txtBarra').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) != '') {
      $('#inputQueVaiReceberFocoParaOFocoNaoIrParaOQtdeSegunda').focus();
      await saidaBarra();
    }
    // $(this).focus()
  });

  $('#txtBarraEstorno').on('blur', async function () {
    $.LoadingOverlay('show');
    try {
      $('#inputQueVaiReceberFocoParaOFocoNaoIrParaOQtdeSegunda').focus();
      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')) {
          $('.divQualidade2').removeClass('d-none');
        }
      } else {
        $('.divMotivo').addClass('d-none');
        $('.divQualidade2').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,
        QTDE_EXPURGA: tamanho.qtde_expurga,
      };
    });
  }

  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);
      $('#txtProximoSetor').val('')
      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;
    const table = $("#tabelaItens").DataTable();
    table.rows().every(function () {
      const item = this.data();
      const row = $(this.node());

      if ($('#cbHabilitaQtdeOf').is(':checked')) {
        if (row.find('.campoSaldo').val() != 0) {
          throw new Error('Existem Itens com Saldo Pendente. Impossível Atualizar Quantidades da OF.')
        }
      }

      if ((parseFloat(row.find('.qtdeSegunda').val()) > 0) || (parseFloat(row.find('.qtdePerdidas').val()) > 0) ||
        (parseFloat(row.find('.campoQuant').val()) > 0) || (parseFloat(row.find('.qtdeIncompletas').val()) > 0) ||
        (parseFloat(row.find('.qtdeExpurga').val()) > 0)) {
        bContemQtde = true;
      }

      if (baixaMaior.BAIXAMAIOR != 'S') {
        if ((parseFloat(row.find('.campoQuant').val()) + parseFloat(row.find('.qtdeSegunda').val()) + parseFloat(row.find('.qtdeIncompletas').val()) +
          parseFloat(row.find('.qtdePerdidas').val()) + parseFloat(row.find('.qtdeExpurga').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), 3600000);

    if (!response) {
      return;
    }

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

    if ($('#cbSegundaQualidade').is(':checked')) {
      if (!$('#txtQualidade2').val()) {
        throw new Error('Necessário informar a segunda qualidade')
      }
      if (!$('#txtDeposito2').val()) {
        throw new Error('Necessário informar o depósito da segunda qualidade')
      }
    }

    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('#txtDeposito2') != '' ? pegaChave('#txtDeposito2') : pegaChave('#txtDeposito');
      movFaccao.Qualidade = pegaChave('#txtQualidade');
      movFaccao.TipoBaixa = pegaChave('#txtTipoBaixa');
      movFaccao.Qualidade2 = pegaChave('#txtQualidade2');
      movFaccao.Caixa = $('#txtCaixa').val();
      movFaccao.Maquina = pegaChave('#txtMaquina')
      movFaccao.Pedido = $('#txtPedido').val();
      movFaccao.Programacao = $('#txtProgramacao').val();
      movFaccao.Motivo = pegaChave('#txtMotivo');
      movFaccao.Observacao = $('#txtObs').val();
      movFaccao.Enfesto = objEnfesto;
      movFaccao.BarrasLog = barrasLog;
      movFaccao.Defeito = arrDefeito;
      movFaccao.Reprovado = arrReprovado;

      return movFaccao;
    } catch (error) {
      console.log('Rotina retornaObjeto ' + error);
    }
  }

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

  function retornaTamanhos(item, row) {
    const MovTam = {};
    try {
      MovTam.Tam = item.TAM;
      MovTam.Identificador = item.IDENTIFICADOR;
      MovTam.Quant = row.find('.campoQuant').val();
      MovTam.Quant_I = row.find('.qtdeIncompletas').val();
      MovTam.Quant_Orig = item.QUANT_ORIG;
      MovTam.Quant_F = row.find('.qtdePerdidas').val();
      MovTam.Quant_2 = row.find('.qtdeSegunda').val();
      MovTam.Qtde_Expurga = row.find('.qtdeExpurga').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;
    const table = $("#tabelaItens").DataTable();
    table.rows().every(function () {
      const row = $(this.node());
      if ((parseFloat(row.find('.qtdeSegunda').val()) > 0) || (parseFloat(row.find('.qtdePerdidas').val()) > 0)) {
        bMotivo = true;
        return false;
      }
    })

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

  async function baixaConsumo() {
    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();
        }

        if (dadosConsumo.dados) {
          const itensComConsumo = dadosConsumo.dados?.map(item => {
            const registro = $("#tabelaItens").DataTable().data().toArray().find(t =>
              t.COR == item.corProd &&
              t.TAM == item.tam
            );

            const quantOrig = registro ? registro.QUANT_ORIG : 0;

            return {
              ...item,
              consumo: item.consumoUni * quantOrig
            };
          });
          dadosConsumo.dados = itensComConsumo

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

  async function buscaDeposito(componente) {
    const idDepConsSubProduto = (await buscaValor('CADFLUXO', 'ID_DEP_CONS_SUB_PROD', 'CODIGO', pegaChave('#txtSetor'))).ID_DEP_CONS_SUB_PROD

    if (idDepConsSubProduto && componente != 'txtDeposito') {
      const DepConsSubProduto = (await buscaValor('DEPOSITO', 'CODIGO', 'ID', idDepConsSubProduto)).CODIGO
      insereValor('#txtDepositoConsumoSubProduto', DepConsSubProduto, {
        tabela: 'DEPOSITO',
        campoBusca: 'DESCRICAO',
        campoWhere: 'CODIGO',
        valorWhere: DepConsSubProduto
      });
    } else {
      const responseDeposito = await requisicao('GET', '/buscadepositomovfaccao?', `NUMERO=${$('#txtNumeroOrdem').val()}&SETOR=${pegaChave('#txtSetor')}`, 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: "Consumo", data: "consumo" },
        { 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 bSemEstoque = false;
    let bAguardar = true;
    let bAbortar = false;
    if (!dadosConsumo.dados) {
      return;
    }
    dadosConsumo.dados.forEach(item => {
      item.tipoBaixa = pegaChave('#txtTipoBaixaConsumoSubProduto');
      if (item.baixado >= item.consumo) {
        bBaixa = true;
      }
      if (item.quantidade > item.estoque) {
        bSemEstoque = true;
      }
    })

    if (bBaixa) {
      await msgAlerta('SubProduto já Possui Baixa Superior/Igual a Necessidade. \n\nConfirmar: realizar a baixa dos consumos do subproduto. \nCancelar: continuar sem realizar a baixa do subproduto.', () => { bAguardar = false },
        () => {
          bAbortar = true;
          bAguardar = false;
        }
      );

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

      if (bAbortar) {
        await rotinaGeraLog('MOVIMENTACAO DE TERCEIROS', $('#txtNumeroOrdem').val(), 'Usuário optou por prosseguir com a movimentação sem realizar a baixa dos consumos do subproduto.', 'Movimentação');

        return false
      }
    }

    if (bSemEstoque) {
      bAguardar = true
      bAbortar = false
      switch ((await buscaValor('DEPOSITO', 'FAT_ESTOQUE_NEG', 'CODIGO', pegaChave('#txtDepositoConsumoSubProduto'))).FAT_ESTOQUE_NEG) {
        case 'M': {
          await msgAlerta('Estoque insuficiente para realizar a baixa. Deseja continuar?', () => { bAguardar = false },
            () => {
              bAbortar = true;
              bAguardar = false;
            }
          );

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

          if (bAbortar) {
            throw new Error('Processo Abortado')
          }
        }
          break;
        case 'N': {
          throw new Error('Estoque insuficiente para realizar a baixa. Impossível continuar!')
        }

        default:
          break;
      }
    }

    return true
  }

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

    await buscaConsumosOF();
  }

  async function baixaConsumosSubProduto() {
    dadosConsumo.dados.forEach(item => {
      item.local = pegaChave('#txtLocalSubProduto')
    })
    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);
      }
    }
  }

  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');
      dados.local = pegaChave('#txtLocalConsumoOF');

      const response = await requisicao('POST', '/gravarconsumosfaccao?', '', JSON.stringify(dados), 150000);
      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() {
    if (selecionarLotesAoBaixarConsumos) {
      const parametros = retornaObjeto()
      const dadosBaixa = await ModalBaixaConsumos.buscar(parametros.Numero, parametros.Parte, parametros.Setor, '', parametros.Codigo, parametros.GradeCores)
      if (!!dadosBaixa.setor?.baixaConsumosSetor) {
        await new Promise((resolve, reject) => {
          ModalBaixaConsumos.carregar({
            deposito: {
              codigo: dadosBaixa.setor.depositoBaixa,
              descricao: dadosBaixa.setor.descDepositoBaixa,
            },
            consumos: dadosBaixa.consumos,
            estoque: dadosBaixa.estoque,
            numero: parametros.Numero,
            parte: parametros.Parte,
            setor: parametros.Setor,
            codigo: parametros.Codigo,
            grade: parametros.GradeCores,
            lancamento: $('#txtLancamento').val(),
            cliente: pegaChave('#txtEmpresa'),
            produto: pegaChave('#txtProduto'),
            resolve,
            reject,
          })
          ModalBaixaConsumos.abrir()
          $.LoadingOverlay('hide')
        })

        $.LoadingOverlay('show')
        gravarMovimentacaoOF()

        return
      }
    }

    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);
        }

        const idDepConsSetor = (await buscaValor('CADFLUXO', 'ID_DEP_CONS_SETOR', 'CODIGO', pegaChave('#txtSetor'))).ID_DEP_CONS_SETOR
        if (idDepConsSetor) {
          const DepConsSetor = (await buscaValor('DEPOSITO', 'CODIGO', 'ID', idDepConsSetor)).CODIGO
          insereValor('#txtDepositoConsumoOF', DepConsSetor, {
            tabela: 'DEPOSITO',
            campoBusca: 'DESCRICAO',
            campoWhere: 'CODIGO',
            valorWhere: DepConsSetor
          });
        }
        await buscaConsumosOF();

      } 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 dados = retornaObjeto()
    const response = await requisicao('POST', '/buscarofconsumos?', params, JSON.stringify(dados));

    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?.filter(item => Number(item.baixar) > 0);

      if (!dadosConsumoOF || dadosConsumoOF.length === 0) {
        $('#modal-baixa-consumo-of').modal('hide');
        await gravarMovimentacaoOF();
        return;
      }

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

      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'
          }
        ]
      });
      $('#modal-baixa-consumo-of').modal('show');
    } else {
      throw new Error('Não foi possível buscar os consumos da OF.');
    }
  }

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

      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);
        }
      }
    } finally {
      $.LoadingOverlay('hide')
    }
  }

  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/NUMERO=${$('#txtNumeroOrdem').val()}&RECARREGAR=S`;
        } catch (error) {
          console.error(error)
          msgAlerta(error.message)
        } finally {
          $.LoadingOverlay('hide')
        }
      }, async () => {
        window.location.href = `${BASE_URI}/movimentacaofaccao/NUMERO=${$('#txtNumeroOrdem').val()}&RECARREGAR=S`;
      })
    } else {
      window.location.href = `${BASE_URI}/movimentacaofaccao/NUMERO=${$('#txtNumeroOrdem').val()}&RECARREGAR=S`;
    }
  }

  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() {
    try {
      const params = `NUMERO=${$('#txtNumeroOrdem').val()}&PARTE=${pegaChave('#txtParte')}&SETOR=${pegaChave('#txtSetor')}&CONSIDERA_ORDEM=true`;
      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);
        }
        const resultado = jsonStr.resultado?.[0];

        if (resultado) {
          insereValor('#txtProximoSetor', resultado.codigo, resultado.descricao);
          const dataProducao = $('#txtDtProducao').val()
          const dataAtual = dataProducao ? new Date(dataProducao) : new Date()
          const dataAtualSemHoras = new Date(dataAtual.getUTCFullYear(), dataAtual.getUTCMonth(), dataAtual.getUTCDate())
          setarDataPraFrente('txtDtRetorno', dataAtualSemHoras, resultado.dias);
          MovimentacaoFaccao.diasProximoSetor = resultado.dias
        }

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

  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 verificaBarraLogBipada(barra) {
    try {
      const url = `/sisplan/movimentacaofaccao/v1/barrasloglidas?`;
      const params = `&BARRA=${encodeURIComponent(barra)}` +
        `&NUMERO=${$('#txtNumeroOrdem').val()}` +
        `&SETOR_ANT=${pegaChave('#txtSetor')}` +
        `&SETOR=${pegaChave('#txtProximoSetor')}` +
        `&PARTE=${pegaChave('#txtParte')}` +
        `&MOV=${$('#cbMovimento').val() == '' ? '0' : $('#cbMovimento').val()}`;

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

      if (!response) {
        return;
      }

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

      return jsonStr.resultado
    } catch (error) {
      msgAlerta(error.message);
    }
  }

  async function saidaBarraEPC() {
    $.LoadingOverlay('show');
    try {
      const listaEPCs = epc.listaBarrasForamBipadasEPC;
      if (listaEPCs.length === 0) {
        return;
      }

      const sDeposito = pegaChave("#txtDeposito");
      const sNumero = $('#txtNumeroOrdem').val();
      const biparEstornar = $('#barraEstorno').hasClass('d-none');

      const params = new URLSearchParams({
        DEPOSITO: sDeposito,
        NUMERO: sNumero,
        ESTORNO: biparEstornar ? 'N' : 'S',
        TIPO: 'P'
      });

      const listaFormatada = listaEPCs.map(epc => `'${epc}'`).join(',');
      const response = await requisicao('POST', '/sisplan/epc/v1/detalhes?', params.toString(), listaFormatada);

      if (!response || response.status !== 200) {
        throw new Error('Erro ao buscar os detalhes dos EPC!');
      }

      const detalhes = await response.json();
      const epcsPermitidos = detalhes.filter(e => e.PERMITE_MOVIMENTACAO === 'S');
      const epcsNegados = detalhes.filter(e => e.PERMITE_MOVIMENTACAO !== 'S' || e.BARRALOG_LIDA === 'S');

      if (epcsNegados.length > 0) {
        msgAlerta(`EPCs: ${epcsNegados.map(e => e.EPC).join(', ')} não existem, estão desativados ou já foram lidos, faça a bipagem manual!`);
      }

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

      let barrasLogJaLidasSet = new Set();
      let facBarrasExistentesSet = new Set();
      const barrasLogParaValidar = epcsPermitidos.filter(e => e.BARRA_LOG).map(e => e.BARRA_LOG);

      if (barrasLogParaValidar.length > 0 && biparEstornar) {
        const [facBarras, lidas] = await Promise.all([
          retornaJsonPesquisaPadrao(JSON.stringify({
            tabela: 'FAC_BARRA',
            camposSelect: ['BARRA'],
            where: [`BARRA IN (${barrasLogParaValidar.map(b => `'${b.replace(/#/g, '[HASHTAG]')}'`).join(',')})`]
          })),
          retornaJsonPesquisaPadrao(JSON.stringify({
            tabela: 'BARRA_LOG',
            camposSelect: ['BARRA'],
            where: [`BARRA IN (${barrasLogParaValidar.map(b => `'${b.replace(/#/g, '[HASHTAG]')}'`).join(',')})`, `LIDA = 'S'`]
          }))
        ]);

        facBarrasExistentesSet = new Set((facBarras || []).map(b => b.BARRA));
        barrasLogJaLidasSet = new Set((lidas || []).map(b => b.BARRA));
      }

      const table = $('#tabelaItens').DataTable();
      const bSegunda = $('#cbSegundaQualidade').is(':checked');

      for (const itemEPC of epcsPermitidos) {
        const cor = itemEPC.COR;
        const tam = itemEPC.TAM;
        const codigo = itemEPC.CODIGO;
        const barra = itemEPC.BARRA_LOG || itemEPC.BARRA;
        const barraLog = itemEPC.BARRA_LOG ? barra : false;

        if (biparEstornar && barraLog) {
          if (facBarrasExistentesSet.has(barraLog)) continue;
          if (barrasLogJaLidasSet.has(barraLog)) continue;
          if (barrasLog.some(it => it.barra === barraLog)) continue;
        }

        const index = table.rows().indexes().toArray().find(idx => {
          const item = table.row(idx).data();
          const row = $(table.row(idx).node());

          if (
            item.COR != cor ||
            item.TAM != tam ||
            item.CODIGO != codigo
          ) {
            return false;
          }

          const saldo = parseFloat(row.find('.campoSaldo').val());
          const quant = safeParseFloat(row.find('.campoQuant').val()) ?? 0
          const quantSegunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0
          const quantIncompleta = safeParseFloat(row.find('.qtdeIncompletas').val()) ?? 0
          const quantPerdida = safeParseFloat(row.find('.qtdePerdidas').val()) ?? 0
          const qtdeExpurga = safeParseFloat(row.find('.qtdeExpurga').val()) ?? 0

          if (biparEstornar) {
            return !isNaN(saldo) && saldo > 0;
          } else {
            return (quant > 0) || (quantSegunda > 0) || (quantIncompleta > 0) || (quantPerdida > 0) || (qtdeExpurga > 0)
          }
        });

        if (index === undefined) continue;

        const row = $(table.row(index).node());
        const itemData = table.row(index).data();
        let saldo = parseFloat(row.find('.campoSaldo').val());
        let quant = bSegunda ? parseFloat(row.find('.qtdeSegunda').val()) : parseFloat(row.find('.campoQuant').val());

        if (biparEstornar) {
          row.find('.campoSaldo').val(saldo - 1);
          if (bSegunda) {
            row.find('.qtdeSegunda').val(quant + 1);
          } else {
            row.find('.campoQuant').val(quant + 1);
          }

          addBarraLida(barra);
          if (barraLog) {
            if (bLancaDefeito && pegaChave('#txtDefeito')) {
              arrDefeito.push({ defeito: pegaChave('#txtDefeito'), barraLog: barraLog, ...itemEPC })
            }
            barrasLog.push({
              barra: barraLog,
              codigo,
              cor,
              tam,
              idFaccao: itemData.IDENTIFICADOR,
            });

            if ($('#cbReprovarPagamento').is(':checked')) {
              preenchePagamento(itemEPC, barraLog, itemData.IDENTIFICADOR)
            }
            await adicionaBarraBipada(itemEPC, barraLog);
          } else {
            await adicionaBarraBipada(itemEPC, barraLog);
          }
        } else {
          row.find('.campoSaldo').val(saldo + 1);
          if (bSegunda) {
            row.find('.qtdeSegunda').val(quant - 1);
          } else {
            row.find('.campoQuant').val(quant - 1);
          }

          removeBarraLogLida(barraLog, itemEPC);
          await estornaBarraBipada(barra);
        }
      }

      calcularTotais();
      salvaDadosDigitados();
      SomAlerta();

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

  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;
      }

      if ((bBarraLog == '1') || (bBarraLog == '2')) {
        if (await verificaBarraLogBipada(barra)) {
          throw new Error('Barra já foi bipada na movimentação desse setor. Impossível continuar.')
        }
      }

      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) {
      msgAlerta(error.message || 'Não foi possível bipar a barra')
    } finally {
      $.LoadingOverlay('hide');
    }
  }

  $('#cbSegundaQualidade').on('click', function () {
    if ($('#cbSegundaQualidade').is(':checked')) {
      // $('#divSegundaQualidade').removeClass('d-none');
      $('.divQualidade2').removeClass('d-none');
      $('.qtdeSegunda').attr('disabled', true);
      $('.divDeposito2').removeClass('d-none');
      $('.divMotivo').removeClass('d-none');

      if (bLancaDefeito) {
        $('#txtDefeito').val('')
        $('#divDefeito').removeClass('d-none');
      }
    } else {
      // $('#divSegundaQualidade').addClass('d-none');
      $('.divQualidade2').addClass('d-none');
      $('.qtdeSegunda').attr('disabled', false);
      $('.divDeposito2').addClass('d-none');
      $('.divMotivo').addClass('d-none');

      $('#txtQualidade2').val('')
      $('#txtDeposito2').val('')

      if (bLancaDefeito) {
        $('#txtDefeito').val('')
        $('#divDefeito').addClass('d-none');
      }
    }
  })

  function retornaFocoBarras(biparEstornar) {
    if (biparEstornar) {
      $('#txtBarra').focus()
    } else {
      $('#txtBarraEstorno').focus()
    }
  }

  function validarQtdeBipadaAMais(dadosTabela, itemBipado, barra, retornoBipaBarra, registrosEncontrados) {
    try {
      const itemEncontrado = dadosTabela.find((it) => it.codigo === itemBipado.codigo && it.cor === itemBipado.cor && it.tam === itemBipado.tam && it.identificador === itemBipado.identificador)

      if (!itemEncontrado) {
        return
      }

      let diferenca = 0

      if (itemBipado.segundaQualidade) {
        diferenca = Math.abs(itemBipado.qtdeSegundaAtualizada - itemEncontrado.qtdeSegunda)
      } else {
        diferenca = Math.abs(itemBipado.qtdeAtualizada - itemEncontrado.qtde)
      }

      if (diferenca > 1) {
        if (itemBipado.segundaQualidade) {
          itemEncontrado.inputQtdeSegunda.val(itemEncontrado.qtdeSegunda)
        } else {
          itemEncontrado.inputQtde?.val(itemEncontrado.qtde)
        }
        itemEncontrado.inputSaldo.val(itemEncontrado.saldo)

        msgErro('Inconsistência nas quantidades, favor bipar novamente a última barra.')
        removeBarraLogLida(barra)
        listaBarrasBipadas = listaBarrasBipadas.filter((it) => it.barra_log !== barra && it.barra !== barra)

        const bodyLog = {
          tela: 'MOVIMENTACAO FACCAO',
          descricao: `INCONSISTENCIA NAS QUANTIDADES BIPADAS - CODIGO: ${itemEncontrado.codigo}, COR: ${itemEncontrado.cor}, TAM: ${itemEncontrado.tam}, BARRA: ${barra}, RETORNO BIPA BARRA: ${retornoBipaBarra}, REGISTROS ENCONTRADOS: ${registrosEncontrados}`,
          chave: $('#txtNumeroOrdem').val(),
          operacao: 'Movimentação',
        }

        requisicao(
          "POST",
          "/sisplan/log/v1/geralog?",
          'POSSUIBODY=S',
          `JSON=${JSON.stringify(bodyLog)}`
        );
      }
    } finally {
      calcularTotais()
    }
  }

  async function confereBarra(biparEstornar, barra, barraLog = false) {
    try {
      const tabelaDados = $('#tabelaItens').DataTable()

      const dadosTabela = tabelaDados.data().toArray().map((_, index) => {
        const rowApi = tabelaDados.row(index)
        const item = rowApi.data()
        const row = $(rowApi.node())

        const identificador = item.IDENTIFICADOR
        const codigo = item.CODIGO
        const cor = item.COR
        const tam = item.TAM
        const qtde = safeParseFloat(row.find('.campoQuant').val()) ?? 0
        const qtdeSegunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0
        const saldo = safeParseFloat(row.find('.campoSaldo').val()) ?? 0
        const inputQtde = row.find('.campoQuant')
        const inputQtdeSegunda = row.find('.qtdeSegunda')
        const inputSaldo = row.find('.campoSaldo')

        return {
          identificador,
          codigo,
          cor,
          tam,
          qtde,
          qtdeSegunda,
          saldo,
          inputQtde,
          inputQtdeSegunda,
          inputSaldo,
        }
      })

      let voltaFocoBarra = true
      let qtde = 0
      let qtdeSegunda = 0
      const bSegunda = $('#cbSegundaQualidade').is(':checked');
      let identificador = 0

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

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

        table.rows().every(function () {
          const row = $(this.node());
          row.css('background-color', 'transparent');
          row.css('color', 'var(--font-color)');
          row.find('.campoSaldo').css('color', 'var(--font-color)');
          row.find('.campoQuant').css('color', 'var(--font-color)');
        });

        const index = table.rows().indexes().toArray().find(idx => {
          const item = table.row(idx).data();
          const row = $(table.row(idx).node());

          if (
            item.COR != cor ||
            item.TAM != tam ||
            item.CODIGO != codigo
          ) {
            return false;
          }

          const saldo = parseFloat(row.find('.campoSaldo').val());
          const quant = safeParseFloat(row.find('.campoQuant').val()) ?? 0
          const quantSegunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0
          const quantIncompleta = safeParseFloat(row.find('.qtdeIncompletas').val()) ?? 0
          const quantPerdida = safeParseFloat(row.find('.qtdePerdidas').val()) ?? 0
          const qtdeExpurga = safeParseFloat(row.find('.qtdeExpurga').val()) ?? 0

          if (biparEstornar) {
            return !isNaN(saldo) && saldo > 0;
          } else {
            return (quant > 0) || (quantSegunda > 0) || (quantIncompleta > 0) || (quantPerdida > 0) || (qtdeExpurga > 0)
          }
        });

        if ((!index) && (index !== 0) && (!$('#cbBaixaMaior').is(':checked'))) {
          throw new Error('Item sem saldo disponível para a barra lida. Verifique!');
        }

        if (!index && (index !== 0)) {
          throw new Error('Nenhum item encontrado. Verifique!');
        }

        const rowApi = table.row(index);
        const item = rowApi.data();
        const row = $(rowApi.node());
        identificador = item.IDENTIFICADOR

        row.css('background-color', 'transparent');
        row.css('color', 'var(--font-color)');
        row.find('.campoSaldo').css('color', 'var(--font-color)');
        row.find('.campoQuant').css('color', 'var(--font-color)');

        row.get(0).scrollIntoView({ behavior: 'smooth', block: 'center' });

        let quant = 0;
        let saldo = parseFloat(row.find('.campoSaldo').val());

        if (bSegunda) {
          quant = parseFloat(row.find('.qtdeSegunda').val());
        } else {
          quant = parseFloat(row.find('.campoQuant').val());
        }

        if (!biparEstornar) {
          if (saldo >= item.QUANT_ORIG && !$('#cbBaixaMaior').is(':checked')) {
            throw new Error('Saldo não pode ser negativo, verifique!');
          }

          row.find('.campoSaldo').val(saldo += 1);

          if (bSegunda) {
            row.find('.qtdeSegunda').val(quant -= 1);
          } else {
            row.find('.campoQuant').val(quant -= 1);
          }

          retorno = 0;
          removeBarraLogLida(barraLog, objGravacaoBarraLog);
          // estornaBarraBipadaEPC();
          calcularTotais()

        } else {
          if ((row.find('.campoSaldo').val() == 0) && !$('#cbBaixaMaior').is(':checked')) {
            throw new Error('Nenhum saldo para a barra lida, verifique!');
          }

          if (!await addBarraLogLida(barraLog, objGravacaoBarraLog, codigo, cor, tam, identificador)) {
            retorno = 6;
          } else {
            if (bConfirmacaoTamanho) {
              if (
                (ultimoRegistroBipado.tamanho && ultimoRegistroBipado.tamanho !== item.TAM) ||
                (ultimoRegistroBipado.cor && ultimoRegistroBipado.cor !== item.COR)
              ) {
                $('#txtBarra').trigger('focusout');
                voltaFocoBarra = false;
                retorno = 7

                msgAlertaHtml(
                  `<span class="text-lg">
                      Tamanho anterior: <b class="destaque-em-vermelho">${ultimoRegistroBipado.tamanho}</b><br>
                      Cor anterior: <b class="destaque-em-vermelho">${ultimoRegistroBipado.descCor}</b><br><br>
                      Tamanho bipado: <b class="destaque-em-verde">${item.TAM}</b><br>
                      Cor bipada: <b class="destaque-em-verde">${item.DESC_COR}</b><br><br>
                      Deseja continuar?
                    </span>`,
                  async () => {
                    row.find('.campoSaldo').val(saldo -= 1);

                    if (bSegunda) {
                      row.find('.qtdeSegunda').val(quant += 1);
                    } else {
                      row.find('.campoQuant').val(quant += 1);
                    }

                    ultimoRegistroBipado = {
                      tamanho: item.TAM,
                      cor: item.COR,
                      descCor: item.DESC_COR,
                      saldo: row.find('.campoSaldo').val()
                    };

                    addBarraLida(barra);
                    // adicionaBarraBipadaEPC();
                    if (addBarraLog) {
                      await adicionaBarraBipada(objGravacaoBarraLog, barraLog);
                    }

                    row.find('.campoSaldo').attr('style', 'color: black !important');
                    row.find('.campoQuant').attr('style', 'color: black !important');
                    row.css('background-color', 'rgb(163, 237, 159)');
                    row.css('color', 'black');

                    calcularTotais();
                    $('#txtBarra').focus();

                    qtde = safeParseFloat(row.find('.campoQuant').val()) ?? 0
                    qtdeSegunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0

                    const itemValidar = {
                      codigo,
                      cor,
                      tam,
                      qtdeAtualizada: qtde,
                      qtdeSegundaAtualizada: qtdeSegunda,
                      segundaQualidade: bSegunda,
                      identificador,
                    }

                    if (['1', '2'].includes(bBarraLog)) {
                      validarQtdeBipadaAMais(dadosTabela, itemValidar, barraLog, '7', registrosEncontrados)
                    }
                  },
                  () => {
                    $('#txtBarra').focus()
                    removeBarraLogLida(barraLog);
                  },
                  null,
                  'Sim',
                  'Não'
                );

                SomAlerta(BASE_URI, true);
              } else {
                row.find('.campoSaldo').val(saldo -= 1);

                if (bSegunda) {
                  row.find('.qtdeSegunda').val(quant += 1);
                } else {
                  row.find('.campoQuant').val(quant += 1);
                }

                ultimoRegistroBipado = {
                  tamanho: item.TAM,
                  cor: item.COR,
                  descCor: item.DESC_COR,
                  saldo: row.find('.campoSaldo').val()
                };

                addBarraLida(barra);
                // adicionaBarraBipadaEPC();

                retorno = 0;

                row.find('.campoSaldo').attr('style', 'color: black !important');
                row.find('.campoQuant').attr('style', 'color: black !important');
                row.css('background-color', 'rgb(163, 237, 159)');
                row.css('color', 'black');

                calcularTotais();
                $('#txtBarra').focus();
              }
            } else {
              row.find('.campoSaldo').val(saldo -= 1);

              if (bSegunda) {
                row.find('.qtdeSegunda').val(quant += 1);
              } else {
                row.find('.campoQuant').val(quant += 1);
              }

              addBarraLida(barra);
              // adicionaBarraBipadaEPC();

              retorno = 0;
              calcularTotais();
              $('#txtBarra').focus();
            }
          }
        }

        qtde = safeParseFloat(row.find('.campoQuant').val()) ?? 0
        qtdeSegunda = safeParseFloat(row.find('.qtdeSegunda').val()) ?? 0

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

        return retorno;
      }

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

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

      if (!jsonStr.length) {
        if (jsonStr.codigo != 200) {
          throw msgAlerta(jsonStr.mensagem, () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
        }

        throw msgAlerta('Nenhum item encontrado para a barra lida, verifique!'), () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok';
      }

      const registrosEncontrados = jsonStr.length

      const cor = jsonStr[0].COR;
      const tam = jsonStr[0].TAM;
      const codigo = jsonStr[0].CODIGO;

      if (jsonStr[0].BARRA_LOG == 'S') {
        if (jsonStr[0].NUM_OF && $('#txtNumeroOrdem').val() !== jsonStr[0].NUM_OF) {
          msgErro(`Barra bipada pertence à OF ${jsonStr[0].NUM_OF}, impossível continuar.`)
          return
        }

        if (!biparEstornar) {
          const indiceEncontrado = arrReprovado.findIndex(item =>
            item.codigo === codigo &&
            item.cor === cor &&
            item.tam === tam
          );

          if (indiceEncontrado !== -1) {
            const item = arrReprovado[indiceEncontrado];
            const indexBarra = item.barraLog.findIndex(b => b === barraLog);

            if (indexBarra != -1 && !$('#cbReprovarPagamento').is(':checked')) {
              throw msgAlerta('Barra foi bipada com a opção de reprovar pagamento marcada, por favor, verifique!')
            }
          }

          if (!await estornaBarraBipada(barra)) {
            msgAlerta('Barra não encontrada!', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
            return;
          }
        } else if (!await barraJaEstaBipada(barra, biparEstornar)) {
          addBarraLog = true
        } else {
          return;
        }
      }

      const objGravacaoBarraLog = {
        codigo: codigo,
        cor: cor,
        tam: tam,
        barra: barra,
      }

      const retorno = await bipaBarra(jsonStr, addBarraLog, objGravacaoBarraLog, registrosEncontrados);
      switch (retorno) {
        case 0: {
          SomAlerta();
          if (addBarraLog) {
            await adicionaBarraBipada(objGravacaoBarraLog, barraLog);
          }
          break;
        }
        case 1: {
          voltaFocoBarra = false
          msgAlerta('Impossível bipar quantidade maior do que há de pendente.', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 2: {
          voltaFocoBarra = false
          msgAlerta('Quantidade total do item já conferida', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 3: {
          voltaFocoBarra = false
          msgAlerta('Impossível estornar quantidade maior do que a conferida.', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 4: {
          voltaFocoBarra = false
          msgAlerta('Toda a quantidade já foi estornada.', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 5: {
          voltaFocoBarra = false
          msgAlerta('Estoque insuficiente para o item bipado.', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
        case 6: {
          voltaFocoBarra = false
          msgAlerta('Barra Log já lida neste setor, impossível ler novamente.', () => { retornaFocoBarras(biparEstornar) }, undefined, undefined, undefined, false, true, false, 'Ok');
          SomAlerta(BASE_URI, true);
          break;
        }
      }

      if (voltaFocoBarra) {
        retornaFocoBarras(biparEstornar)
      }

      const itemValidar = {
        codigo,
        cor,
        tam,
        qtdeAtualizada: qtde,
        qtdeSegundaAtualizada: qtdeSegunda,
        segundaQualidade: bSegunda,
        identificador,
      }

      if (biparEstornar && retorno !== 7 && ['1', '2'].includes(bBarraLog)) {
        validarQtdeBipadaAMais(dadosTabela, itemValidar, barraLog, retorno, registrosEncontrados)
      }
    } finally {
      $(`#txtBarraEstorno`).val('');
      $(`#txtBarra`).val('');
      // $(`#txtBarra${biparEstornar ? '' : 'Estorno'}`).focus();
      $('#txtQtde').val('1');
      salvaDadosDigitados()
      calcularTotais()
    }
  };

  function removeBarraLogLida(barraLog, obj = {}) {
    const index = barrasLog.findIndex((it) => it.barra === barraLog)

    if (index > -1) {
      barrasLog.splice(index, 1)
    }

    if (bLancaDefeito) {
      const indiceEncontrado = arrDefeito.findIndex(item => item.barraLog === barraLog);
      if (indiceEncontrado !== -1) {
        arrDefeito.splice(indiceEncontrado, 1)
      }
    }

    if ($('#cbReprovarPagamento').is(':checked')) {
      removePagamento(obj, barraLog)
    }

  };

  async function addBarraLogLida(barraLog, objGravacaoBarraLog, codigo, cor, tam, id) {
    if (!barraLog) {
      return true;
    }
    if (await validaBarraLogFacBarra(barraLog.replace(/#/g, '[HASHTAG]'))) {
      return false
    } else if (await validaBarraLogLiberada(barraLog.replace(/#/g, '[HASHTAG]'))) {
      if (barrasLog.some((it) => it.barra === barraLog)) {
        return false
      }
      if (bLancaDefeito && pegaChave('#txtDefeito')) {
        arrDefeito.push({ defeito: pegaChave('#txtDefeito'), barraLog: barraLog, ...objGravacaoBarraLog })
      }
      barrasLog.push({
        barra: barraLog,
        codigo,
        cor,
        tam,
        idFaccao: id,
      });

      if ($('#cbReprovarPagamento').is(':checked')) {
        preenchePagamento(objGravacaoBarraLog, barraLog, id)
      }

      return true
    } else {
      return false;
    }
  };

  function preenchePagamento(obj, barraLog, identificador) {

    const indiceEncontrado = arrReprovado.findIndex(item =>
      item.codigo === obj.codigo &&
      item.cor === obj.cor &&
      item.tam === obj.tam &&
      item.pago === 'R'
    );

    if (indiceEncontrado !== -1) {
      arrReprovado[indiceEncontrado].quantidade += 1;
      arrReprovado[indiceEncontrado].barraLog.push(barraLog);

    } else {

      arrReprovado.push({
        codigo: obj.codigo,
        cor: obj.cor,
        tam: obj.tam,
        pago: 'R',
        quantidade: 1,
        barraLog: [barraLog],
        identificador
      });
    }
  }

  function removePagamento(obj, barraLog) {
    const indiceEncontrado = arrReprovado.findIndex(item =>
      item.codigo === obj.codigo &&
      item.cor === obj.cor &&
      item.tam === obj.tam
    );

    if (indiceEncontrado !== -1) {

      const item = arrReprovado[indiceEncontrado];

      const indexBarra = item.barraLog.findIndex(b => b === barraLog);

      if (indexBarra !== -1) {

        item.barraLog.splice(indexBarra, 1);

        item.quantidade -= 1;

        if (item.quantidade <= 0 || item.barraLog.length === 0) {
          arrReprovado.splice(indiceEncontrado, 1);
        }
      }
    }
  }

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

  async function adicionaBarraBipada(objItem, barraLog) {
    try {
      if ((bBarraLog == '1') || (bBarraLog == '2')) {
        objItem.barra_log = barraLog
      }
      listaBarrasBipadas.push(objItem);
    } catch (error) {
      console.error(error);
    }
  }

  async function barraJaEstaBipada(sBarra, estornaQuantidade) {
    try {
      const paramBarraLog = bBarraLog == '1' || bBarraLog == '2'
      if (
        listaBarrasBipadas.find(item => item.barra == sBarra && (paramBarraLog && item.barra_log == $('#txtBarra').val()))) {
        if (estornaQuantidade) {
          msgErro(`Barra ${$('#txtBarra').val()} já lida, verifique.`, () => { retornaFocoBarras(estornaQuantidade) });
        }
        return true;
      }
      return false;
    } catch (error) {
      console.error('barra_log', error);
      msgErro('Erro ao processar barra log.');
      return false;
    }
  }

  // async function estornaBarraBipada(sBarra) {
  //   const paramBarraLog = bBarraLog == '1' || bBarraLog == '2'
  //   if (!listaBarrasBipadas.find(item => item.barra == sBarra && (paramBarraLog && item.barra_log == $('#txtBarraEstorno').val()))) {
  //     return false;
  //   }

  //   listaBarrasBipadas = listaBarrasBipadas.filter(item => {
  //     if (paramBarraLog) {
  //       return item.barra_log !== $('#txtBarraEstorno').val();
  //     }

  //     return item.barra !== sBarra;
  //   });
  // }

  async function estornaBarraBipada(sBarra) {
    const paramBarraLog = bBarraLog == '1' || bBarraLog == '2';
    const barraLogEstorno = $('#txtBarraEstorno').val();

    let itemEncontrado;

    if (paramBarraLog) {
      itemEncontrado = listaBarrasBipadas.find(item => item.barra_log === barraLogEstorno);
    } else {
      itemEncontrado = listaBarrasBipadas.find(item => item.barra === sBarra);
    }

    if (!itemEncontrado) {
      return false;
    }

    listaBarrasBipadas = listaBarrasBipadas.filter(item => {
      if (paramBarraLog) {
        return item.barra_log !== barraLogEstorno;
      }
      return 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)
    }
  }

  const epc = new EPC({
    barra: '#txtBarra',
    quantidade: '#txtQtde',
    deposito: '#txtDeposito',
    codigoEPC: '#txtCodigoEPC',
    idItem: '#txtIdItem',
    integracaoEPC: integracaoEPC,
    listaBarrasBipadasEPC: listaBarrasBipadasEPC ?? [],
    callBackSaidaBarra: async () => {
      // console.log('[EPC] Tentando executar saidaBarra...');
      if (bloqueiaSaida) {
        // console.warn('[EPC] Aguardando liberação do lock anterior...');
        // espera até que bloqueiaSaida seja falso
        while (bloqueiaSaida) {
          await sleep(100);
        }
      }

      bloqueiaSaida = true;
      try {
        // console.log('[EPC] Iniciando saidaBarra');
        await saidaBarraEPC();
        // console.log('[EPC] Finalizou saidaBarra');
      } catch (error) {
        // console.error('[EPC] Erro na saidaBarra:', error);
      } finally {
        bloqueiaSaida = false;
      }
    },
    venda: true
  });

  $('#btn-iniciar-epc').on('click', () => {
    if (epc.iniciar()) {
      $('#btn-iniciar-epc').prop('disabled', true);
      $('#btn-parar-epc').prop('disabled', false);
      return
    }
    $('#btn-iniciar-epc').prop('disabled', false);
    $('#btn-parar-epc').prop('disabled', true);
  });

  $('#btn-parar-epc').on('click', () => {
    if (epc.parar()) {
      $('#btn-iniciar-epc').prop('disabled', false);
      $('#btn-parar-epc').prop('disabled', true);
      return
    }
    $('#btn-iniciar-epc').prop('disabled', true);
    $('#btn-parar-epc').prop('disabled', false);
  });

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

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

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

  // async function buscaItensNovaQtde(data) {
  //   if ($.fn.DataTable.isDataTable('#tabelaNovaQtdeOF')) {
  //     $('#tabelaNovaQtdeOF').DataTable().destroy();
  //     $('#tabelaNovaQtdeOF').empty();
  //   };

  //   $.LoadingOverlay('show')
  //   try {

  //     const jsonStr = data.resultado[0];

  //     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: "Quant Nova", data: "QUANT" },
  //     ];

  //     const codigo = jsonStr.codigo;
  //     let jsonObject;
  //     let bloqueiaModal = false

  //     let i = 0;
  //     jsonObject = jsonStr.gradeCores.reduce(function (result, gradeCor) {
  //       let tamanhosRenomeados = extrairRenomearTamanhos(gradeCor.tamanhos);
  //       tamanhosRenomeados.forEach(function (tamanhoRenomeado, index) {
  //         if (tamanhoRenomeado.QUANT !== tamanhoRenomeado.QUANT_ORIG) bloqueiaModal = true
  //         result.push({
  //           CODIGO: codigo,
  //           COR: gradeCor.cor,
  //           DESC_COR: gradeCor.descricao,
  //           TAM: tamanhoRenomeado.TAM,
  //           QUANT_ORIG: tamanhoRenomeado.QUANT_ORIG,
  //           QUANT: `<input type="number" min="0" class="input-default focus form-control campoQuant camposGrade text-right" id="txtQuantNova${i}" value="${tamanhoRenomeado.QUANT}">`,
  //         });
  //         i++;
  //       });
  //       return result;
  //     }, []);

  //     if (bloqueiaModal) return false

  //     $("#tabelaNovaQtdeOF").DataTable({
  //       destroy: true,
  //       filter: false,
  //       paging: false,
  //       autoWidth: false,
  //       columns: titulos,
  //       data: jsonObject,
  //       columnDefs: [
  //         {
  //           "targets": [0],
  //           visible: false
  //         },
  //         {
  //           "targets": [4, 5],
  //           "className": 'pr-4 text-right',
  //           width: '160px',
  //           minWidth: '160px'
  //         },
  //       ]
  //     });

  //     $('#modal-alterar-qtde-of').modal('show')

  //     return true
  //   } catch (error) {
  //     console.error(error)
  //     msgAlerta(error.message)
  //     return false
  //   } finally {
  //     $.LoadingOverlay('hide')
  //   }
  // }

  // $('#modal-alterar-qtde-of').on('show.bs.modal', () => {
  //   ModalAtualizaQuantidade.buscar($('#txtNumeroOrdem').val(), pegaChave('#txtSetor'), pegaChave('#txtParte'), $('#cbMovimento').val(), pegaChave('#txtEmpresa'))
  // })

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

  //     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) {
  //       throw new Error('Erro na função de montar o modal de atualizar quantidades')
  //     }

  //     let jsonStr = await response.json();
  //     if (!jsonStr.resultado) {
  //       throw new Error('Erro na função de montar o modal de atualizar quantidades')
  //     }

  //     if (await buscaItensNovaQtde(jsonStr)) return true
  //   } catch (error) {
  //     console.error(error)
  //     return false
  //   } finally {
  //     $.LoadingOverlay('hide')
  //   }
  // }

  // $('#btnConfirmarQtdeOF').on('click', function () {
  //   $.LoadingOverlay('show')
  //   try {
  //     const dadosOld = $('#tabelaItens').DataTable().data().toArray()
  //     const newDados = []

  //     dadosOld.forEach((item, index) => {
  //       const identificador = item.IDENTIFICADOR;
  //       const novaQuant = bPermiteQtdeFracionada ? isNaN(parseFloat($(`#txtQuantNova${index}`).val())) ? 0 : parseFloat($(`#txtQuantNova${index}`).val()) : isNaN(parseInt($(`#txtQuantNova${index}`).val())) ? 0 : parseInt($(`#txtQuantNova${index}`).val())
  //       const objNovo = {
  //         ...item,
  //         QUANT_ORIG: novaQuant,
  //         SALDO: novaQuant,
  //         QUANT: `<input type="number" min="0" class="input-default focus form-control campoQuant camposGrade text-right" id="QUANT${identificador}" value="${novaQuant}">`,
  //         ALTEROUQTDE: 'S'
  //       }

  //       newDados.push(objNovo)
  //     })

  //     $('#tabelaItens').DataTable().clear().rows.add(newDados).draw(false)

  //     addBlurCamposGrade()

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

  //     $('#modal-alterar-qtde-of').modal('hide')
  //   } catch (error) {
  //     console.error(error)
  //     msgAlerta(error.message)
  //   } finally {
  //     $.LoadingOverlay('hide')
  //   }
  // })

  // $('#btnDesistirQtdeOF').on('click', function () {
  //   $('#modal-alterar-qtde-of').modal('hide')
  //   if ($.fn.DataTable.isDataTable('#tabelaNovaQtdeOF')) {
  //     $('#tabelaNovaQtdeOF').DataTable().destroy();
  //     $('#tabelaNovaQtdeOF').empty();
  //   };
  // })

  function addBlurCamposGrade() {
    $('#tabelaItens').on('draw.dt', function () {
      calcularTotais()
    })

    // $('.camposGrade').on('focusout', function () {
    // calcularTotais()
    // })

    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().filter(item => item.IDENTIFICADOR == numeroId)[0]?.SALDO ?? 0
        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 expurga = isNaN(parseInt($(`#QTDE_EXPURGA${numeroId}`).val())) ? 0 : parseInt($(`#QTDE_EXPURGA${numeroId}`).val());
        const perdida = isNaN(parseInt($(`#QUANT_PERDIDA${numeroId}`).val())) ? 0 : parseInt($(`#QUANT_PERDIDA${numeroId}`).val());
        const qtdeOrig = $('#tabelaItens').DataTable().row($(`#${$(this).attr('id')}`).closest('tr').index()).data().QUANT_ORIG
        const novoSaldo = (saldo - quant - segunda - incompleta - perdida - expurga).toFixed(0);
        const permiteQtdeMaior = $('#cbBaixaMaior').is(':checked')
        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)
            $(`#QTDE_EXPURGA${numeroId}`).val(expurga)
            $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida - expurga + 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)
                $(`#QTDE_EXPURGA${numeroId}`).val(expurga)
                $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida - expurga + 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().filter(item => item.IDENTIFICADOR == numeroId)[0]?.SALDO ?? 0
        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 expurga = isNaN(parseFloat($(`#QTDE_EXPURGA${numeroId}`).val())) ? 0 : parseFloat($(`#QTDE_EXPURGA${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)
            $(`#QTDE_EXPURGA${numeroId}`).val(expurga)
            $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida - expurga + 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)
                $(`#QTDE_EXPURGA${numeroId}`).val(expurga)
                $(`#SALDO${numeroId}`).val(qtdeOrig - quant - segunda - incompleta - perdida - expurga + parseFloat($(this).val()))
                $(this).val(0)
                sair = true
              })
              if (sair) {
                return
              }
            }
          }
        }

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

  async function atualizaQtdeOf() {
    $.LoadingOverlay('show')
    try {
      const movFaccao = retornaObjeto();
      const response = await requisicao('POST', '/sisplan/movimentacaofaccao/v1/atualizaqtdeof?', `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);
      }
    } catch (error) {
      console.error(error)
      msgAlerta(error.message)
    } finally {
      $.LoadingOverlay('hide')
    }
  }

  $('#txtBarra, #txtBarraEstorno').on('input', function () {
    let valor = $(this).val();

    if (valor.startsWith('TQ')) {
      valor = valor.substring(2);
    }

    $(this).val(valor);
  });

  $(document).on('keydown', function (e) {
    if (e.keyCode === 118) {

      e.preventDefault();

      $('#multiCollapseExample1').collapse('toggle');
    }
  });

  $('#modal-warning').on('hide.bs.modal', function () {
    $('#txtBarra').focus()
  })

  $('#multiCollapseExample1').on('show.bs.collapse', function () {
    $('#iconeDropdown')
      .removeClass('fa-angle-right')
      .addClass('fa-angle-down');
  });

  $('#multiCollapseExample1').on('hide.bs.collapse', function () {
    $('#iconeDropdown')
      .removeClass('fa-angle-down')
      .addClass('fa-angle-right');
  });

  async function executarRotinaFacAbreSetor() {
    const dados = await consultarFacAbreSetor();

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

    $("#modalFacAbreSetor").modal("show");
    await preencherFacAbreSetor(dados);

    const promise = new Promise((resolve, reject) => {

      $("#btnConfirmarFacAbreSetor").off("click").on("click", async function () {
        $.LoadingOverlay("show");
        try {
          await gravarFacAbreSetor();
          resolve();
        } catch (error) {
          reject(error);
        } finally {
          $("#modalFacAbreSetor").modal("hide");
        }
      });

      $("#btnFecharFacAbreSetor").off("click").on("click", async function () {
        resolve();
      });
    });

    return promise;
  }

  async function consultarFacAbreSetor() {
    const numeroOF = $("#txtNumeroOrdem").val();
    const codigoProduto = pegaChave("#txtProduto");
    const params = `NUMERO_OF=${numeroOF}` +
      `&CODIGO_PRODUTO=${codigoProduto}`;
    const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/fac_abre_setor?', params, '', 120000);

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

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

    return json;
  }

  async function preencherFacAbreSetor(dados) {
    limparDataTableFacAbreSetor();
    criarDataTableFacAbreSetor();
    $("#tabelaFacAbreSetor").DataTable().rows.add(dados).draw(false);
  }

  function limparDataTableFacAbreSetor() {
    if ($.fn.DataTable.isDataTable('#tabelaFacAbreSetor')) {
      $("#tabelaFacAbreSetor").DataTable().clear().draw(false);
    };
  }

  function criarDataTableFacAbreSetor() {
    const colunas = [
      {
        data: "SEL", title: "Selecionar",
        render: function (data, type, row, meta) {
          return `<div class="icheck-primary d-inline">
                  <input type="checkbox" id="check_col_${meta.row}_row_${meta.col}" class="campoSelFacAbreSetor">
                  <label for="check_col_${meta.row}_row_${meta.col}"></label>
                </div>`;
        },
      },
      { data: "PARTE", title: "Parte" },
      { data: "DESCRICAO", title: "Descrição" },
      { data: "FLUXO", title: "Fluxo" },
    ]

    if (!$.fn.DataTable.isDataTable('#tabelaFacAbreSetor')) {
      criaDataTablePadrao("#tabelaFacAbreSetor"
        , true
        , false
        , true
        , true
        , true
        , false
        , "400px"
        , null
        , colunas);
    };
  }

  async function gravarFacAbreSetor() {
    const listaFacAbreSetor = montaListaFacAbreSetor();
    const response = await requisicao('POST', '/sisplan/movimentacaofaccao/v1/fac_abre_setor?', "", JSON.stringify({ ListaFacAbreSetor: listaFacAbreSetor }), 120000);

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

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

  function montaListaFacAbreSetor() {
    const selecionados = $(".campoSelFacAbreSetor:checked");
    const listaFacAbreSetor = [];

    selecionados.each(function () {
      const dataRow = $("#tabelaFacAbreSetor").DataTable().row($(this).closest("tr")).data();
      const FacAbreSetor = {
        CodigoProduto: pegaChave("#txtProduto"),
        NumeroOF: $("#txtNumeroOrdem").val(),
        Parte: dataRow.PARTE,
        Fluxo: dataRow.FLUXO,
        DataEntrada: $("#txtDtProducao").val(),
        DataRetorno: $("#txtDtRetorno").val(),
        ParteOF: $("#cbPartes").val()
      }

      listaFacAbreSetor.push(FacAbreSetor);
    })

    return listaFacAbreSetor;
  }

  $("#modalFacAbreSetor").on("show.bs.modal", function () {
    $.LoadingOverlay("hide");
  })

  async function carregaDadosArquivo() {
    try {
      if (!($('#cbBaixaPorBarra').is(':checked')) || (contaFs != 2) || carregouDadosNaoSalvos) return

      const response = await carregaDadosDigitados();

      if (!response || response.status != 200) return;

      const dados = await response.json();

      if (dados.Numero == $('#txtNumeroOrdem').val() && pegaChave(dados.Setor) == pegaChave('#txtSetor') && dados.BarrasLog.length > 0) {
        msgAlerta("Carregado dados não salvos, verifique.");

        $('#txtEmpresa').val(dados.CodCli);
        $('#txtParte').val(dados.Parte);
        $('#txtSetor').val(dados.Setor);
        $('#txtProximoSetor').val(dados.SetorDestino);
        $('#txtEmpresaDestino').val(dados.Terceiro);
        $('#txtFuncionario').val(dados.Funcionario);
        $('#txtCelulaDestino').val(dados.CelulaDestino);
        $('#txtDeposito').val(dados.Deposito);
        $('#txtQualidade').val(dados.Qualidade);
        $('#txtTipoBaixa').val(dados.TipoBaixa);
        $('#txtQualidade2').val(dados.Qualidade2);
        $('#txtMotivo').val(dados.Motivo);

        if (dados.GradeCores?.length) {
          populaGradeCores(dados.GradeCores, pegaChave(dados.Codigo));
        }

        objEnfesto = dados.Enfesto || {};
        barrasLog = dados.BarrasLog || [];

        carregouDadosNaoSalvos = true
      }

    } catch (error) {
      console.error('Erro ao carregar dados:', error);
    }
  }

  function populaGradeCores(gradeCores) {
    try {
      if (!$.fn.DataTable.isDataTable('#tabelaItens')) return;

      gradeCores.forEach(cor => {
        cor.Tamanhos.forEach(tam => {
          const id = tam.Identificador;
          const quant = tam.Quant ?? 0
          const quant2 = tam.Quant_2 ?? 0
          const quantI = tam.Quant_I ?? 0
          const quantF = tam.Quant_F ?? 0
          const qtdeExpurga = tam.Qtde_Expurga ?? 0

          $(`#QUANT${id}`).val(quant);
          $(`#QUANT_SEGUNDA${id}`).val(quant2);
          $(`#QUANT_INCOMPLETA${id}`).val(quantI);
          $(`#QUANT_PERDIDA${id}`).val(quantF);
          $(`#QTDE_EXPURGA${id}`).val(qtdeExpurga);

          $(`#SALDO${id}`).val(tam.Saldo - (parseFloat(quant) + parseFloat(quant2) + parseFloat(quantI) + parseFloat(quantF) + parseFloat(qtdeExpurga)))
        });
      });

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

    } catch (error) {
      console.error('Erro ao popular grade:', error);
    }
  }

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

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

  async function salvaDadosDigitados() {
    try {
      const objeto = retornaObjetoArquivo();

      await salvaArquivo('JsonMovimentacao', objeto);


      const response = await fetch(`${BASE_URI}/salvar_arquivo.php?tipo=JsonMovimentacao&id_aba=${sessionStorage.getItem('g_idAba')}`, {
        method: 'POST',
        body: `${JSON.stringify(objeto)}`,
      });

      return response;

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

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

  $('#txtDtProducao').on('blur', function () {
    try {
      const dataAtual = new Date(this.value)
      const dataAtualSemHoras = new Date(dataAtual.getUTCFullYear(), dataAtual.getUTCMonth(), dataAtual.getUTCDate())
      setarDataPraFrente('txtDtRetorno', dataAtualSemHoras, MovimentacaoFaccao.diasProximoSetor);
    } catch (err) {
      console.error(err)
    }
  })
});

MovimentacaoFaccao = window.MovimentacaoFaccao || {}

MovimentacaoFaccao.diasProximoSetor = 0