$("#tutorial").on("click", function () {
  $(document).ready(async function () {
    const driver = new Driver({
      doneBtnText: "Sair",
      closeBtnText: "Fechar",
      nextBtnText: "Próximo",
      prevBtnText: "Anterior",
      allowClose: false,
    });
    driver.defineSteps([
      {
        element: "#btnFiltros",
        popover: {
          title: "Botão Filtros",
          description: "Clique aqui para filtrar a consulta.",
          position: "right"
        },
      },
      {
        element: "#btnImprimir",
        popover: {
          title: "Botão Imprimir",
          description: "Clique aqui para imprimir os dados consultados.",
          position: "right"
        },
      },
      {
        element: "#tabelaOrdemProducao",
        popover: {
          title: "Tabela Ordens de Produção",
          description: "Aqui estão os dados das ordens de produção consultadas.",
          position: "top"
        },
      },
      {
        element: '#tabelaResumo',
        popover: {
          title: "Tabela Setores",
          description: "Aqui estão os dados dos setores.",
          position: "top"
        }
      }
    ]);
    driver.start();
  });
});

$(document).ready(async function () {
  const parametrosOP = await BuscaParametrosOrdemProducao();
  const bEstornaMovimentacao = parametrosOP[8].VALOR;
  let idTabela;
  const permissaoUsuarioLogado = await permissaoAcessos("MOVIMENTACAOFACCAO");
  MontaPesquisa();
  barrasReimpressas = [];

  let colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));

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

  if (colunas == null || colunas.acessoMovimentacaoFaccaoSetor == undefined) {
    localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunas, acessoMovimentacaoFaccaoSetor: ['EMPRESA'] }));
    colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
  }

  if (colunas == null || colunas.acessoMovimentacaoFaccaoEstorno == undefined) {
    localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunas, acessoMovimentacaoFaccaoEstorno: ['EMPRESA'] }));
    colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
  }

  if (colunas == null || colunas.acessoMovimentacaoFaccaoGrade == undefined) {
    localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunas, acessoMovimentacaoFaccaoGrade: ['EMPRESA'] }));
    colunas = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
  }

  $('#btnLimparFiltros').on('click', function () {
    $('#txtDataSaidaIni').val('1200-01-01');
    $('#txtDataSaidaFim').val('2500-12-31');
    $('#txtDataRetornoIni').val('1200-01-01');
    $('#txtDataRetornoFim').val('2500-12-31');
    $('#txtDataCadastroIni').val('1200-01-01');
    $('#txtDataCadastroFim').val('2500-12-31');
    $('#btnLimpaOrdemProducao').trigger('click');
    $('#btnLimpaProduto').trigger('click');
    $('#btnLimpaCliente').trigger('click');
    $('#btnLimpaPedido').trigger('click');
    $('#btnLimpaSetor').trigger('click');
    $('#txtStatus').val('1');
    $('#txtDataInicioIni').val('1200-01-01');
    $('#txtDataInicioFim').val('1200-01-01');
    $('#txtDataFimIni').val('2500-12-31');
    $('#txtDataFimFim').val('2500-12-31');
  });

  const columnsSetoresAltera = [
    { "data": "ordem_orig", "title": "Ordem Original" },
    { "data": "setor", "title": "Setor" },
    { "data": "desc_setor", "title": "Desc. Setor" },
    { "data": "ordem", "title": "Ordem" },
  ];

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

  $('#modal-ColunasVisiveis').on('show.bs.modal', function () {
    let colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
    let colunasVisiveis = pegaColunasVisiveis();
    switch (idTabela) {
      case '#tabelaResumo':
        adicionaColunas(colunasVisiveis, colunasInvisiveis.acessoMovimentacaoFaccaoSetor ?? ['EMPRESA']);
        break;
      case '#tabelaEstornar':
        adicionaColunas(colunasVisiveis, colunasInvisiveis.acessoMovimentacaoFaccaoEstorno ?? ['EMPRESA']);
        break;
      case '#tabelaGradeOF':
        adicionaColunas(colunasVisiveis, colunasInvisiveis.acessoMovimentacaoFaccaoGrade ?? ['EMPRESA']);
        break;
      default:
        adicionaColunas(colunasVisiveis, colunasInvisiveis.movimentacaoFaccao ?? ['EMPRESA']);
        break;
    }
  });

  function pegaColunasVisiveis() {
    const cols = [];
    $(`${idTabela}`).DataTable().columns().every(function () {
      cols.push({
        'title': $(this.header()).text(),
        'data': this.dataSrc()
      });
    });
    return cols;
  }

  criaDataTablePadrao('#tabelaSetoresAltera', false, false, false, false, true, true, '250px', null, columnsSetoresAltera, [], [], [], []);

  $('#btnConfirmarColunas').on('click', async function () {
    try {
      $.LoadingOverlay('show');
      setarColunas();
    } finally {
      $.LoadingOverlay('hide');
      $('#modal-ColunasVisiveis').modal('hide');
    }
  });

  function setarColunas() {
    const novasColunas = retornaNovasColunasInvisiveis();
    let colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
    switch (idTabela) {
      case '#tabelaResumo':
        localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunasInvisiveis, acessoMovimentacaoFaccaoSetor: novasColunas }));
        break;
      case '#tabelaEstornar':
        {
          removeColunasFixas(novasColunas, ["SEL"]);
          localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunasInvisiveis, acessoMovimentacaoFaccaoEstorno: novasColunas }));
          break;
        }
      case '#tabelaGradeOF':
        localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunasInvisiveis, acessoMovimentacaoFaccaoGrade: novasColunas }));
        break;
      default:
        {
          removeColunasFixas(novasColunas, ["NUMERO"]);
          localStorage.setItem('colunasInvisiveisRelatorios', JSON.stringify({ ...colunasInvisiveis, movimentacaoFaccao: novasColunas }));
          break;
        }
    }
    $(`${idTabela}`).DataTable().columns().visible(true);

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

  async function consultaOrdemProducao() {
    $.LoadingOverlay("show");
    try {
      if ($.fn.DataTable.isDataTable('#tabelaOrdemProducao')) {
        $('#tabelaOrdemProducao').DataTable().destroy();
        $('#tabelaOrdemProducao').empty();
      }
      const filtros = await retornaFiltrosPesquisa();

      const columns = [
        {
          title: "Número",
          data: "numero",
          render(data, type, row) {
            return retornaBotaoOpcoes(data);
          }
        },
        { title: "Código", data: "codigo" },
        { title: "Código2", data: "codigo2" },
        { title: "Descrição", data: "descricao" },
        {
          title: "Data Cad.",
          data: "dataCad",
          render(data) {
            if (data != undefined) {
              x = data.slice(0, 10).split('-');
              return `${x[2]}/${x[1]}/${x[0]}`;
            }
            return '';

          }
        },
        {
          title: "Data Iníc.",
          data: "dataIni",
          render(data) {
            if (data != undefined) {
              x = data.slice(0, 10).split('-');
              return `${x[2]}/${x[1]}/${x[0]}`;
            }
            return '';

          }
        },
        {
          title: "Data Final",
          data: "dataFin",
          render(data) {
            if (data != undefined) {
              x = data.slice(0, 10).split('-');
              return `${x[2]}/${x[1]}/${x[0]}`;
            }
            return '';

          }
        },
        { title: "Programação", data: "programacao" },
        { title: "Pedido", data: "pedido" },
        { title: "Cód. Cli.", data: "codcli" },
        { title: "Nome", data: "nome" },
        {
          title: "Setor Pend.",
          data: "setorPend",
          render(data, type, row) {
            return `<span style="text-wrap: nowrap;color: #75BE25">${data}</span>`;
          }
        },
        { title: "Observação", data: "observacao" }
      ];

      $('#tabelaOrdemProducao').DataTable({
        sort: false,
        paging: true,
        destroy: true,
        lengthChange: true,
        filter: true,
        info: true,
        ordering: false,
        sorting: false,
        order: false,
        colReorder: true,
        serverSide: false,
        searching: true,
        processing: true,
        ajax: {
          url: `${getCookie('protocolo')}://${getCookie('ip_api')}/sisplan/movimentacaofaccao/v1/movimentacaofaccao?`,
          type: "POST",
          headers: {
            'Authorization': getCookie('accessToken') ? `Bearer ${getCookie('accessToken')}` : '',
          },
          data(data) {
            const { start, length, draw, search } = data;
            return JSON.stringify({
              paginacao: {
                quantidadeMaximaRegistros: length,
                quantidadeRegistrosPular: start,
                contadorRequisicoes: draw,
              },
              empresa: getCookie('empresa'),
              idUsuario: getCookie('id_usuario'),
              filtros,
              search: search?.value ?? ''
            });
          },
          dataSrc(json) {
            if (!json || !json.data) {
              return [];
            }
            return json.data;
          },
          cache: true,
          beforeSend() {
            $.LoadingOverlay('show');
          },
          complete() {
            $.LoadingOverlay('hide');

            selecionarPrimeiroRegistro();
          },
        },
        autoWidth: true,
        columns,
        scrollY: '33vh',
        scrollX: true,
      });

      const colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));
      $('#tabelaOrdemProducao_length').prepend('<button class="buttonColVis" id="buttonColVis"><i class="fas fa-cogs"></i></button>');
      $('#tabelaOrdemProducao_length').prepend('<button class="buttonExcel" id="buttonExcel"><i class="fas fa-file-excel"></i></button>');

      $('#buttonColVis').prop('title', 'Configurar colunas visíveis');
      $('#buttonExcel').prop('title', 'Exportar');

      $('#buttonColVis').on('click', async function () {
        idTabela = '#tabelaOrdemProducao';
        $.LoadingOverlay('show');
        $('#modal-ColunasVisiveis').modal('show');
        $.LoadingOverlay('hide');
      });

      $('#buttonExcel').on('click', async function () {
        const filtros = await retornaFiltros();
        const url = `/sisplan/movimentacaofaccao/v1/movimentacaofaccao?`;

        await exportaCSV(url, filtros, false, null, 'Relatório da aba acesso da movimentação de facção', '');
      });

      $('#tabelaOrdemProducao').DataTable().columns().every(function () {
        if ((colunasInvisiveis.movimentacaoFaccao).indexOf(this.dataSrc()) != -1) {
          this.visible(false);
        }
      });

      const tabela = $('#tabelaOrdemProducao').DataTable();

      $('#tabelaOrdemProducao tbody').off('click');
      $('#tabelaOrdemProducao tbody').on('click', 'tr', function () {
        const $row = $(this);

        // if (!$row.hasClass('selected')) {
        tabela.rows().nodes().to$().removeClass('selected');
        // }

        $row.toggleClass('selected');
      });

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

  $('#tabelaOrdemProducao').on('click', 'td', async function () {
    await buscaPartes();
    const table = $('#tabelaOrdemProducao').DataTable();
    const dados = table.rows('.selected').data();
    const numeroOF = dados.toArray()[0]?.numero;
    const etiquetaImpressa = !!(await buscaValor('BARRA_LOG', ['BARRA'], [`(TELA <> 'RelTag_WEB' AND TELA <> '') AND NUM_OF`], [numeroOF])).BARRA;

    if (etiquetaImpressa) {
      $('#etiquetaImpressa').html('Etiqueta de Composição: Impressa').css('color', 'green')
    } else {
      $('#etiquetaImpressa').html('Etiqueta de Composição: Não Impressa').css('color', 'red')
    }
    await buscaGradeOrdemProducao()
  });

  async function buscaPartes() {
    $.LoadingOverlay('show');
    try {
      limpaSetores();
      const table = $('#tabelaOrdemProducao').DataTable();
      const dados = table.rows('.selected').data();
      const numeroOF = dados.toArray()[0]?.numero;
      Graficos.limpaGrafico(['graficoAcessoMovimentacaoSetores']);

      if (!numeroOF) return;

      const params = `NUMERO=${numeroOF}`;
      const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/retornapartes?', params);

      if (!response) {
        return;
      }

      let jsonStr = await response.json();
      if (jsonStr.resultado) {
        const componente = $('#cbPartes');
        jsonStr.resultado.forEach(parte => {
          componente.append($('<option>', {
            value: parte.codigo,
            text: `${parte.codigo} - ${parte.descricao}`
          }));
        });
      }

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

  $('#cbPartes').on('change', async function () {
    await buscaSetores();
    await buscaGradeOrdemProducao()
  });

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

    $('#cbPartes').empty();
  }

  function retornaObjComTempoGasto(jsonStr) {
    const dataPadrao = "1899-12-30T00:00:00.000Z";

    function formatarDiferenca(ms) {
      const segundos = Math.floor(ms / 1000);
      const dias = Math.floor(segundos / 86400);
      const horas = Math.floor((segundos % 86400) / 3600);
      const minutos = Math.floor((segundos % 3600) / 60);
      const segs = segundos % 60;

      return `${dias} dia(s), ${horas} hora(s), ${minutos} minuto(s), ${segs} segundo(s)`;
    }

    const agora = new Date();

    const novoJson = jsonStr.map((item, index) => {
      const proximoItem = jsonStr[index + 1];
      const dt_Saida_Hora = new Date(new Date(item.dt_Saida_Hora).getTime() + 3 * 60 * 60 * 1000);
      const horaBase = proximoItem ? proximoItem.hora : item.hora;
      const hora = new Date(new Date(horaBase).getTime() + 3 * 60 * 60 * 1000);
      let tempoGasto = "";
      let diff = 0;

      if (item.dt_Saida_Hora === dataPadrao) {
        tempoGasto = "0 dia(s)";
      } else if (horaBase === dataPadrao) {
        diff = Math.abs(dt_Saida_Hora.getTime() - agora.getTime());
        tempoGasto = formatarDiferenca(diff);
      } else {
        diff = Math.abs(dt_Saida_Hora.getTime() - hora.getTime());
        tempoGasto = formatarDiferenca(diff);
      }

      const duracao = moment.duration(diff);
      const tempo = duracao.asDays();

      return {
        ...item,
        tempoGasto,
        tempo
      };
    });

    return novoJson;
  }

  async function buscaSetores() {
    $.LoadingOverlay('show');
    try {
      Graficos.limpaGrafico(['graficoAcessoMovimentacaoSetores']);
      const table = $('#tabelaOrdemProducao').DataTable();
      const dados = table.rows('.selected').data();
      const numeroOF = dados.toArray()[0]?.numero;

      if (!numeroOF) return;

      const params = `NUMERO=${numeroOF}&PARTE=${$('#cbPartes').val()}`;
      const response = await requisicao('GET', '/buscaresumoprod?', params, undefined, 120000);

      if (!response) {
        return;
      }

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

        jsonStr = retornaObjComTempoGasto(jsonStr);

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

        const colunasItens = [
          { title: "Setor", data: "cod_Setor" },
          { title: "Desc. Setor", data: "setor" },
          { title: "Qtde Orig.", data: "orig" },
          { title: "Qtde", data: "qtde" },
          { title: "Qtde Segunda", data: "segunda" },
          { title: "Qtde Incomp.", data: "incompleta" },
          { title: "Qtde Perdida", data: "perdida" },
          { title: "Qtde Expurga", data: "expurga" },
          { title: "Qtde Saldo", data: "saldo" },
          { title: "Reprocesso", data: "reprocesso" },
          { title: "Reprocessado", data: "reprocessado" },
          { title: "Tempo Gasto", data: "tempoGasto" },
          { title: "Data Saída", data: "dt_Saida" },
        ];

        $('#tabelaResumo').DataTable({
          searching: false,
          paging: true,
          filter: false,
          order: [],
          sort: true,
          destroy: true,
          colReorder: true,
          scrollY: '31vh',
          scrollX: true,
          createdRow(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,
          columnDefs: [{
            targets: [0], render(data, type, row) {
              return retornaBotaoOpcoesSetores(data, row);
            }
          },
          {
            targets: [1], render(data, type, row) {
              return retornaExclamacao(data, row);
            }
          },
          {
            "targets": [2, 3, 4, 5, 6, 7, 8],
            "className": 'pr-4 text-right'
          },
          {
            type: 'date-br',
            targets: [12],
            render(data) {
              if (data != undefined && data != '' && data != '1899-12-30T00:00:00.000Z') {
                const x = data.slice(0, 10).split('-');
                const hora = data.split(' ')[1];
                if (x[2]) {
                  return `${x[2]}/${x[1]}/${x[0]}`;
                }
                return `${x} ${hora}`;

              }
              return '';

            }
          }]
        });
      }

      $($('#tabelaResumo').find('th')[8]).prop('title', 'O Tempo Gasto é calculado através da data de inicio do setor até a saída para o próximo setor (FACCAO.DT_SAIDA_HORA - FACCAO3.HORA)');

      const colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));

      $('#tabelaResumo_length').prepend('<button class="buttonColVis" id="buttonColVisSetor"><i class="fas fa-cogs"></i></button>');
      $('#tabelaResumo_length').prepend('<button class="buttonExcel" id="buttonExcelSetor"><i class="fas fa-file-excel"></i></button>');

      $('#buttonColVisSetor').prop('title', 'Configurar colunas visíveis');
      $('#buttonExcelSetor').prop('title', 'Exportar');

      $('#buttonColVisSetor').on('click', async function () {
        idTabela = '#tabelaResumo';
        $.LoadingOverlay('show');
        $('#modal-ColunasVisiveis').modal('show');
        $.LoadingOverlay('hide');
      });

      $('#buttonExcelSetor').on('click', async function () {
        const url = `/buscaresumoprod?`;
        const dados = $("#tabelaResumo").DataTable().data().toArray();
        await exportaCSV(url, params, false, null, 'Relatório da aba acesso da movimentação de facção - Setores', '#tabelaResumo', '', 999, false, false, dados);
      });

      $('#tabelaResumo').DataTable().columns().every(
        function () {
          if ((colunasInvisiveis.acessoMovimentacaoFaccaoSetor).indexOf(this.dataSrc()) != -1) {
            this.visible(false);
          }
        }
      );

      const dadosGrafico = $('#tabelaResumo').DataTable().data().toArray();

      Graficos.criarGrafico({
        container: 'graficoAcessoMovimentacaoSetores',
        tipo: 'column',
        dados: dadosGrafico,
        nomeSerie: 'Setores',
        colunasAgrupamento: ['setor'],
        colunasValor: ['tempo'],
        title: 'Tempo gasto (em dias) por setor'
      });
    } catch (error) {
      console.error(error);
      msgErro(`Não foi possível buscar os dados ${error.message}`);
    } finally {
      $.LoadingOverlay('hide');
    };
  }

  function selecionarPrimeiroRegistro() {
    const $primeiraLinha = $('#tabelaOrdemProducao tbody tr:first');

    if ($primeiraLinha.length) {
      const $primeiroTd = $primeiraLinha.find('td:first');
      $primeiroTd.trigger('click');
    }
  }

  async function consultaOrdemProducaoParaEstornar(estorno = true) {
    try {
      if ($.fn.DataTable.isDataTable('#tabelaEstornar')) {
        $('#tabelaEstornar').DataTable().destroy();
        $('#tabelaEstornar').empty();
      }
      $('#panelDeposito').addClass('d-none');
      const url = '/sisplan/movimentacaofaccao/v1/estornomovimentofaccao?';
      const filtros = await retornaFiltrosEstorno();
      const response = await requisicao('GET', url, filtros, '', 3600000);

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

      if (jsonStr.length == 0) {
        if (estorno) {
          msgAlerta('Nenhum registro encontrado!');
        }
        $("#labelSelecionarTodos").addClass("d-none");
        return;
      }
      $("#checkSelecionarTodos").prop("checked", false);
      $("#labelSelecionarTodos").removeClass("d-none");


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

      const dataSetCols = [
        { title: 'Sel.', data: 'SEL', width: '15px' },
        { title: 'Mov.', data: 'MOV' },
        { title: 'Mov. Ant.', data: 'MOV_ANT' },
        { title: 'Identificador', data: 'IDENTIFICADOR' },
        { title: 'Cód. Cli.', data: 'CODCLI' },
        { title: 'Nome', data: 'NOME' },
        { title: 'Lançamento', data: 'DT_LAN' },
        { title: 'Número', data: 'NUMERO' },
        { title: 'Código', data: 'CODIGO' },
        { title: 'Cor', data: 'COR' },
        { title: 'Desc. Cor', data: 'DESC_COR' },
        { title: 'Tam.', data: 'TAM' },
        { title: 'Parte', data: 'PARTE' },
        { title: 'Setor', data: 'SETOR' },
        { title: 'Desc. Setor', data: 'DESC_SETOR' },
        { title: 'Setor Dest.', data: 'SETOR_DEST' },
        { title: 'Qtde Orig.', data: 'QT_ORIG' },
        { title: 'Qtde', data: 'QUANT' },
        { title: 'Qtde 2', data: 'QUANT_2' },
        { title: 'Qtde I.', data: 'QUANT_I' },
        { title: 'Qtde F.', data: 'QUANT_F' },
        { title: 'Qtde Expurga', data: 'QTDE_EXPURGA' },
        { title: 'Qual.', data: 'QUAL' },
        { title: 'Qual. 2', data: 'QUAL2' },
        { title: 'Depósito', data: 'DEPOSITO' },
        { title: 'Estoque', data: 'ESTOQUE' },
        { title: 'Pago', data: 'PAGO' },
        { title: 'Pagamento', data: 'DT_PAGTO' },
        { title: 'Lanç.', data: 'LANCTO' },
        { title: 'Cód. Trocado', data: 'CODIGO_TROCADO' },
        { title: 'Lanç. Kit', data: 'LANCTO_KIT' },
        { title: 'Estoque Parte', data: 'ESTOQUE_PARTE' },
        { title: 'Obrig. Motivo', data: 'OBRIGA_MOTIVO' },
        { title: 'Existe Fac3', data: 'EXISTE_FAC3' },
        { title: 'Repro. Pend.', data: 'REPRO_PEND' },
        { title: 'Cód. 2 Produto', data: 'CODIGO2_PRODUTO' },
        { title: 'Nota', data: 'NOTA' },
        { title: 'ID Ant. Facção', data: 'ID_ANT_FACCAO' },
        { title: 'ID Ant.', data: 'ID_ANT' },
        { title: 'Cód. Cli. Ant.', data: 'CODCLI_ANT' },
        { title: 'Acréscimo', data: 'ACRESCIMO' },
        { title: 'Ordem', data: 'ORDEM' },
        { title: 'Caixa', data: 'CAIXA' },
        { title: 'Mov. Kit', data: 'MOV_KIT' }
      ];

      jsonStr.forEach((item, i) => {
        item.SEL = `<div class="icheck-primary d-inline">
        <input type="checkbox" id="checkEstorno${i}" class="campoSelEstorno">
        <label for="checkEstorno${i}"></label>
        </div>`;
      });

      $('#tabelaEstornar').DataTable({
        searching: true,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        paging: true,
        scrollX: true,
        scrollY: '330px',
        info: true,
        autoWidth: true,
        data: jsonStr,
        columns: dataSetCols,
        colReorder: true,
      });

      $("#tabelaEstornar").off("click", ".campoSelEstorno");
      $('#tabelaEstornar').on('click', '.campoSelEstorno', function () {
        const registro = $('#tabelaEstornar').DataTable().row($(this).closest('tr')).data();
        if ($(this).prop('checked') == true) {
          $(this).closest("tr").addClass("selected");
          $(this).addClass("selected");
          if (registro.ESTOQUE == "S") {
            $("#panelDeposito").removeClass("d-none");
          }
        } else {
          $(this).closest("tr").removeClass("selected");
          validaOFMovimentaEstoque() ? "" : $("#panelDeposito").addClass("d-none");
        }
      });

      const colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));

      $('#tabelaEstornar_length').prepend('<button class="buttonColVis" id="buttonColVisEstorno"><i class="fas fa-cogs"></i></button>');
      $('#tabelaEstornar_length').prepend('<button class="buttonExcel" id="buttonExcelEstorno"><i class="fas fa-file-excel"></i></button>');

      $('#buttonColVisEstorno').prop('title', 'Configurar colunas visíveis');
      $('#buttonExcelEstorno').prop('title', 'Exportar');

      $('#buttonColVisEstorno').on('click', async function () {
        idTabela = '#tabelaEstornar';
        $.LoadingOverlay('show');
        $('#modal-ColunasVisiveis').modal('show');
        $.LoadingOverlay('hide');
      });

      $('#buttonExcelEstorno').on('click', async function () {
        const dados = $("#tabelaEstornar").DataTable().data().toArray();
        await exportaCSV("", "", undefined, null, 'Relatório da aba acesso da movimentação de facção - Estorno', '', '', 999, false, false, dados);
      });

      $('#tabelaEstornar').DataTable().columns().every(
        function () {
          if ((colunasInvisiveis.acessoMovimentacaoFaccaoEstorno).indexOf(this.dataSrc()) != -1) {
            this.visible(false);
          }
        }
      );

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

  function retornaSetores() {
    return $('#tabelaSetoresAltera').DataTable().data().toArray();
  }

  $('#btnGravarSetor').on('click', async function () {
    if ($('#tabelaSetoresAltera').DataTable().data().length == 0) {
      throw new Error('Nenhum setor informado, impossível gravar. Por favor, verifique!');
    }
    try {
      $.LoadingOverlay('show');
      const body = {
        numero: $('#txtNumeroAltera').val(),
        parte: pegaChave('#txtParteAltera'),
        Setores: retornaSetores(),
      };
      const response = await requisicao('POST', '/sisplan/movimentacaofaccao/v1/setores?', `&TODAS_PARTES=${0}`, JSON.stringify(body), 50000);

      if (!response) {
        return;
      }
      if (response.status != 200) {
        throw new Error('Não foi possível gravar os setores. Por favor, verifique!');
      }

      criaMensagemSucesso('Setores gravados com sucesso!');
    } catch (error) {
      msgAlerta(error.message);
    } finally {
      $.LoadingOverlay('hide');
      $('#modal-alterar-setor').modal('hide');
    }
  });

  async function verificaSetor(data) {
    let where = '';

    const { setor, numero, parte, codigo } = data;

    where += '1 = 1';
    where += ` AND NUMERO = '${numero}'`;
    where += ` AND CODIGO = '${codigo}'`;
    where += ` AND PARTE = '${parte}'`;
    where += ` AND SETOR = '${setor}'`;
    where += ` AND DATA_PREV <> '1899-12-30'`;

    const pesquisaParam = {
      tabela: 'FAC_PREV_SETOR',
      camposSelect: ['COUNT(*) COUNT'],
      where: [where],
    };

    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
    return jsonStr[0].COUNT;

  }

  $('#btnExcluirSetor').on('click', async function () {
    $.LoadingOverlay('show');
    try {
      const dataSelecionada = $('#tabelaSetoresAltera').DataTable().row('.selected').data();

      if (await verificaSetor({
        setor: dataSelecionada.setor,
        numero: $('#txtNumeroAltera').val(),
        parte: pegaChave('#txtParteAltera'),
        codigo: pegaChave('#txtCodigoAltera')
      })) {
        return msgAlerta("Setor já possui datas previstas preenchidas. \n" +
          "Verificar Cadastro de Agendamento na Ordem de Produção. \n" +
          "Impossível excluir o Fluxo!");// (Alterar parâmetro 780 da Facção para S).
      }

      if (!dataSelecionada) {
        throw new Error('Nenhum setor selecionado, por favor, selecione um setor para realizar a exclusão.');
      }

      const params =
        `&SETOR=${dataSelecionada.setor}` +
        `&NUMERO=${$('#txtNumeroAltera').val()}` +
        `&PARTE=${pegaChave('#txtParteAltera')}` +
        `&TODAS_PARTES=${0}`;

      const response = await requisicao('DELETE', '/sisplan/movimentacaofaccao/v1/setores?', params, null, 50000);

      if (!response) {
        return;
      }
      if (response.status != 200) {
        throw new Error('Não foi possível excluir os setores. Por favor, verifique!');
      }

      criaMensagemSucesso('Setores excluídos com sucesso!');
    } catch (error) {
      msgAlerta(error.message);
    } finally {
      $.LoadingOverlay('hide');
      $('#modal-alterar-setor').modal('hide');
    }
  });

  $('#btnEstornarMovto').on('click', async function () {
    msgAlerta("Tem certeza que deseja estornar os movimentos selecionados!", async () => {
      $.LoadingOverlay("show");
      try {
        await estornarMovimento();
      } finally {
        $.LoadingOverlay("hide");
      }
    });
  });

  $('#selectParte').on('change', async function () {
    $.LoadingOverlay('show');
    try {
      await consultaOrdemProducaoParaEstornar(false);
    } finally {
      $.LoadingOverlay('hide');
    }
  });

  async function estornarMovimento() {
    const registros = $.extend(true, [], $("#tabelaEstornar").DataTable().rows().data().toArray());
    try {

      ajustaPropsRegistros(registros);

      if (!validaRegistrosSelecionados(registros)) {
        throw msgAlerta("Nenhum registro selecionado!");
      }

      if ((bEstornaMovimentacao == '3') && (registros.filter(item => item.SEL == 'S' && item.ESTOQUE == 'S' && item.QUANT > 0).length > 0)) {
        throw msgAlerta("Não é permitido estornar setores que já movimentaram estoque. Impossível continuar!");
      }

      let deposito;

      try {
        const data = $('#tabelaEstornar').DataTable().rows($('tr.selected')).data().toArray();
        deposito = data[data.length - 1].DEPOSITO;
      } catch (_) {
        deposito = '';
      }

      const obj = {
        NUMERO: $("#txtNumeroTitle").text(),
        PARTE: $("#txtEstornarParte").val(),
        TIPO: pegaChave("#txtEstornarTipoMov"),
        DEPOSITO: deposito,
        MOTIVO: $("#selectMotivo option:selected").text(),
        ITENS: registros
      };

      const url = '/estornofaccao?';
      const response = await requisicao('POST', url, '', JSON.stringify(obj), 900000);

      if (!response) {
        msgAlerta("Não foi possível estornar o movimento.");
        return;
      }

      if (response.status != 200) {
        const jsonStr = await response.json();
        msgAlerta(jsonStr.mensagem);
        return;
      }
      criaMensagemSucesso("Estorno concluído com sucesso.", async () => { await consultaOrdemProducaoParaEstornar(false); });

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

  async function buscaFoto(codigo) {
    try {
      if (!codigo) {
        $("#infoimagem").attr('src', `${BASE_URI}/dist/img/prod-1.png`)
        return
      }

      let urlRequisicao = '/Sisplan/Funcoes/v1/FotoItem?';
      let response = await requisicao('GET', urlRequisicao, `codigo=${codigo}`, null);

      if (!response) {
        return;
      }
      let jsonStr = await response.json();
      if (response.status !== 200) {
        $("#infoimagem").attr('src', `${BASE_URI}/dist/img/prod-1.png`);
        return;
      }

      let sBase64 = jsonStr.mensagem;

      let extension = "png";
      let contentType = response.headers.get('content-type');
      if (contentType && contentType.indexOf('image/') === 0) {
        extension = contentType.replace('image/', '');
      }

      if (extension === "png") {
        $("#infoimagem").attr('src', `data:image/png;base64,${sBase64}`);
      } else {
        let jpegBase64 = await convertToJPEG(sBase64);
        $("#infoimagem").attr('src', `data:image/jpg;base64,${jpegBase64}`);
      }

    } catch (error) {
      console.error(error);
      $("#infoimagem").attr('src', `${BASE_URI}/dist/img/prod-1.png`);
    } finally {
      $('#imagemodal').modal('show')
    }
  }

  function retornaBotaoOpcoes(data) {
    let retorno = `<div style="text-align:start;"> ` +
      `    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" id="tutorialTabela" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ` +
      `      ${data} ` +
      `    </button> ` +
      `    <div class="dropdown-menu"> ` +
      `    <button class="dropdown-item" type="button" title="Movimentar" id="btnMovimentar">Movimentar</button>  ` +
      `    <button class="dropdown-item" type="button" title="Estornar" ${bEstornaMovimentacao == '1' ? 'disabled' : ''} id="btnEstornar">Estornar</button>  ` +
      `    <button class="dropdown-item" type="button" title="Manutenção de Setor" id="btnManutencaoSetor">Manutenção de Setor</button>  ` +
      `    <div class="dropdown-divider"></div>  ` +
      `    <button class="dropdown-item" type="button" title="Imprimir FT" id="btnImprimirFT">Imprimir FT</button>  ` +
      `    <button class="dropdown-item" type="button" title="Impr. Seq.Operacional" id="btnImprimirSequencia">Impr. Seq.Operacional </button>  ` +
      `    <button class="dropdown-item" type="button" title="Imprimir TAG" id="btnImprimirTAG">Imprimir TAG </button>  ` +
      `    <div class="dropdown-divider"></div>  ` +
      `    <button class="dropdown-item" type="button" title="Foto Produto" id="btnFotoProduto">Foto Produto </button>  ` +
      `    <button class="dropdown-item" type="button" title="Gestão Documentos" id="btnAnexos">Gestão Documentos </button>  ` +
      `</div>`;
    return retorno;
  };

  function retornaBotaoOpcoesSetores(data, row) {
    if (row.imp_etq_composi == 'S') {
      let retorno = `<div style="text-align:start;"> ` +
        `    <button class="btn btn-info btn-sm dropdown-toggle btnVerificaOpcoes" id="tutorialTabela" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ` +
        `      ${data} ` +
        `    </button> ` +
        `    <div class="dropdown-menu"> ` +
        `    <button class="dropdown-item" type="button" title="Impr. Etq. Composição" id="btnAbreModalEtiqueta">Impr. Etq. Composição</button>  ` +
        `</div>`;
      return retorno;
    } return data;
  };

  function retornaExclamacao(data, row) {
    return `<div style="text-align:start;"> ` +
      `      ${data} ` +
      ` <label><i class="fas fa-exclamation-circle pt-1 ml-2 btnExclamacao" title="Consumos do setor" style="color: var(--font-color)"></i></label> ` +
      `</div>`;
  };

  $('#tabelaOrdemProducao').on('click', "#btnFotoProduto", async function () {
    try {
      $.LoadingOverlay("show");
      const data = $('#tabelaOrdemProducao').DataTable().row($(this).parents('tr')).data();
      buscaFoto(data.codigo)

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

  $("#tabelaOrdemProducao").on('click', "#btnAnexos", async function () {
    const data = $('#tabelaOrdemProducao').DataTable().row($(this).parents('tr')).data();

    await abreModalAnexos(data.codigo, data.descricao, 'PRODUTO');
  });

  $('#tabelaResumo').on('click', '.btnExclamacao', async function () {
    const tabelaResumo = $('#tabelaResumo').DataTable().rows($(this).closest('tr')).data()[0];
    const tabelaOF = $('#tabelaOrdemProducao').DataTable().row('.selected').data();
    const { numero } = tabelaOF;
    const setor = tabelaResumo.cod_Setor;

    const response = await requisicao(
      'GET',
      '/sisplan/movimentacaofaccao/v1/componentes_of?',
      `NUMERO=${numero}&SETOR=${setor}&`,
      null,
      50000
    );

    if (!response) return;

    const retorno = await response.json();

    const container = $('#container-consumos');
    container.empty();

    if (retorno.length > 0) {
      retorno.forEach(item => {
        const bloco = $(`
          <div class="mb-3 border-bottom pb-2">
            <div><span class="font-weight-bold">Material:</span> ${item.CODIGO} - ${item.DESCRICAO}</div>
            <div><span class="font-weight-bold">Cor:</span> ${item.COR} - ${item.DESC_COR}</div>
            <div class="col-12 p-0 d-flex">
              
              ${item.TAMANHOS ? `
                <div class="col-6 p-0">
                  <span class="font-weight-bold">Tam</span>: ${item.TAMANHOS}
                </div>
              ` : ''}

              <div class="${item.TAMANHOS ? 'col-6 text-center' : 'col-12'} p-0">
                <span class="font-weight-bold">Consumo:</span> ${Number(item.CONSUMO).toFixed(4)}
              </div>

            </div>
          </div>
        `);

        container.append(bloco);
      });
    } else {
      const bloco = $(`
            <div class="mb-3 border-bottom pb-2 text-center">
              <div><span class="font-weight-bold">Não conseguiu encontrar os componentes.</span></div>
            </div>
      `);

      container.append(bloco);
    }

    $('#modal-consumos-setor').modal('show');
  });

  async function consultaCor(codigoProduto) {
    const pesquisaParam = {
      tabela: 'PA_ITEN',
      camposSelect: ['DISTINCT PA_ITEN.COR'],
      where: [`PA_ITEN.CODIGO = '${codigoProduto}'`],
      innerJoin: [{ tabela: "CADCOR", condicao: "PA_ITEN.COR = CADCOR.COR" }]
    };
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

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

    const listaCores = [];

    for (i in jsonStr) {
      listaCores.push(jsonStr[i].COR);
    };

    const listaFormatada = await formataListas(listaCores.toString());

    return listaFormatada;
  };

  $('#tabelaOrdemProducao').on('click', "#btnImprimirFT", async function () {
    try {
      $.LoadingOverlay("show");
      const data = $('#tabelaOrdemProducao').DataTable().row($(this).parents('tr')).data();
      const coresProd = await consultaCor(data.codigo);
      const arrayObsMontagem = await buscarObsMontagem(data.codigo);
      const arrayObsMontEmRtf = arrayObsMontagem?.map((it) => (
        {
          ID: it.id,
          CODIGO: it.CODIGO,
          COR: it.cor,
          DESC_COR: it.descCor,
          ORDEM: it.ordem,
          OBS: htmlToRtf(it.obs),
          DATA: it.data,
          SETOR: it.setor,
          DESC_SETOR: it.descSetor,
          PRIORIDADE: it.prioridade,
          USUARIO: it.usuario,
          DATA_ALT: it.data_alt,
          CODCLI: it.codcli,
          NOME_CLI: it.nomecli,
        }
      )) ?? [];
      const url = `/sisplan/impressao/v1/imprimirft?CODIGO_PROD=${data.codigo}&CORES_PROD=${coresProd}&OBS_MONTAGEM=${JSON.stringify(arrayObsMontEmRtf)}`;
      const bImprimeAutomatico = await verificaImprimirAutomatico('FichaTecnica');
      let arquivo = await GeraRelatorio(`${url}&`, "POST", 15000, false, 'FichaTecnica');
      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
        }
        await limparRelatorios();
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });

  const RetornaEtiqueta = async (numero, setor, parte, layout, barras_reimpressas = []) => {
    // barras = barras_reimpressas.replaceAll('#', '[HASHTAG]')
    const response = await requisicao(
      'GET',
      '/sisplan/movimentacaofaccao/v1/etiqueta_composicao?',
      `NUMERO=${numero}&SETOR=${setor}&PARTE=${parte}&BARRAS_REIMPRESSAS=${encodeURIComponent(barras_reimpressas)}&LAYOUT=${layout}&`,
      null,
      50000
    );

    if (!response) return;

    const jsonStr = await response.json();

    if (!jsonStr || jsonStr.length === 0) {
      return msgAlerta('Nenhum registro encontrado!');
    }

    return jsonStr;
  };

  $('#tabelaResumo').on('click', '#btnAbreModalEtiqueta', async function () {
    const setores = $('#tabelaResumo').DataTable().rows($(this).closest('tr')).data()[0];
    const data = $('#tabelaOrdemProducao').DataTable().row($('.selected')).data();
    const parte = $('#cbPartes').val();

    $('#txtNumeroOpEtiqueta').val(data.numero);
    $('#txtProdutoOpEtiqueta').val(data.codigo);
    $('#txtSetorEtiqueta').val(setores.cod_Setor);
    $('#txtParteEtiqueta').val(parte);
    $('#modal-imprimir-composicao').modal('show');
    // $('#selectImpressao option[value="0"]').remove();
    const etiquetaImpressa = !!(await buscaValor('BARRA_LOG', ['BARRA'], [`(TELA <> 'RelTag_WEB' AND TELA <> '') AND NUM_OF`], [data.numero])).BARRA;
    if (etiquetaImpressa) {
      $('#selectImpressao').prepend('<option value="0">Reimprimir</option>');
      $('#selectImpressao').val('0');
    }
    await explodeGradeProduto(data.codigo, data.numero, !!document.querySelector('#selectImpressao option[value="0"]'));
    await adicionaChangeImpressao();
  });

  async function adicionaChangeImpressao() {
    $('#selectImpressao').on('change', async function () {
      const data = $('#tabelaOrdemProducao').DataTable().row($('.selected')).data();
      if ($(this).val() == '0') {
        await explodeGradeProduto(data.codigo, data.numero, true);
      } else if ($(this).val() == '1') {
        await explodeGradeProduto(data.codigo, data.numero, false);
      }
    });
  }

  $('#modal-imprimir-composicao').on('hidden.bs.modal', function (e) {
    $('#selectImpressao option[value="0"]').remove();
  });

  // $('#modal-imprimir-composicao').on('click', '.dropdown-item', function (e) {
  //   e.preventDefault();
  //   e.stopPropagation();

  //   imprimirEtiqueta($(this).data('tipo'));
  // });

  async function imprimirEtiqueta(layout) {
    try {
      const response = await RetornaEtiqueta($('#txtNumeroOpEtiqueta').val(), $('#txtSetorEtiqueta').val(), $('#txtParteEtiqueta').val(), layout, barrasReimpressas);

      if (!response) return;

      if (response.codigo == '400') {
        throw new Error(response.mensagem || 'Não foi possível criar a etiqueta. Por favor, verifique!');
      }

      const result = await requisicao_impressora(
        'POST',
        '/etiqueta_composicao/imprimir?',
        `LAYOUT=${layout}&REIMPRESSAO=${$('#selectImpressao').val()}`,
        JSON.stringify(response.resultado),
        50000
      );

      if (!result) {
        return msgAlerta('Não conseguiu imprimir');
      }
    } catch (error) {
      msgAlerta(error.message);
    } finally {
      $.LoadingOverlay("hide");
      $('#modal-imprimir-composicao').modal('hide');
      barrasReimpressas = [];
    }
  }

  async function todosSetoresMovimentados() {
    const table = $('#tabelaOrdemProducao').DataTable();
    const dados = table.rows('.selected').data();
    const numeroOF = dados.toArray()[0]?.NUMERO;

    if (!numeroOF) return;

    const params = `NUMERO=${numeroOF}&PARTE=${$('#cbPartes').val()}`;
    const response = await requisicao('GET', '/buscaresumoprod?', params, undefined, 120000);

    if (!response) {
      return;
    }

    let jsonStr = await response.json();

    let iQtde = 0;
    let totalQuantidade = 0;
    let totalRecords = jsonStr.resultado.length;

    jsonStr.resultado.map(function (row) {
      let qtdeOrig = parseFloat(row.orig) || 0;
      totalQuantidade += qtdeOrig;
      if (qtdeOrig > 0) {
        iQtde++;
      }
    });

    return iQtde === totalRecords;
  }

  $('#tabelaOrdemProducao').on('click', '#btnManutencaoSetor', async function () {
    if (await todosSetoresMovimentados()) {
      return msgAlerta('Atenção: Todos os setores já possuem quantidades movimentadas. Nesta condição, não é possível alterar ou excluir setores movimentados, nem incluir novos setores, pois há peças registradas no último movimento!');
    }
    if ($.fn.DataTable.isDataTable('#tabelaSetoresAltera')) {
      $('#tabelaSetoresAltera').DataTable().destroy();
      $('#tabelaSetoresAltera').empty();
    }

    const data = $('#tabelaOrdemProducao').DataTable().row($(this).closest('tr')).data();
    const parte = (await buscaValor('OF1', 'PARTE', 'NUMERO', data.numero)).PARTE;
    const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/setores?', `NUMERO=${data.numero}&PARTE=${parte}&`, null, 50000);

    if (!response) {
      return;
    }

    const jsonStr = await response.json();

    if (jsonStr.length == 0) {
      msgAlerta('Nenhum registro encontrado!');
      return;
    }

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

    $('#txtNumeroAltera').val(data.numero);
    $('#txtFluxoAltera').val('');
    insereValor('#txtCodigoAltera', data.codigo, data.descricao);
    insereValor('#txtParteAltera', parte, { tabela: 'TIPO_APL', campoBusca: 'DESCRICAO', campoWhere: 'CODIGO', valorWhere: parte });

    const resultado = jsonStr.resultado.filter(item => item.ordem_banco === 0);

    let rowIdSelecionado = null;

    resultado.forEach((item, index) => {
      item._rowId = `row_${index}_${item.setor}`;
    });

    const tabela = $('#tabelaSetoresAltera').DataTable({
      rowReorder: {
        dataSrc: 'setor',
        selector: 'td.reorder-handle'
      },
      responsive: true,
      searching: false,
      paging: false,
      filter: false,
      scrollX: true,
      scrollY: '300px',
      autoWidth: true,
      info: false,
      data: resultado,
      columns: [
        {
          data: null,
          orderable: false,
          className: 'reorder-handle',
          render: () => '<i title="Use o ícone para arrastar as linhas movendo os setores para onde desejar" class="fas fa-grip-vertical pt-1"></i>'
        },
        ...columnsSetoresAltera
      ],
      columnDefs: [
        { targets: 0, width: '30px' }
      ],
      rowCallback(row, data, index) {
        $(`td:eq(0)`, row).css("display", "flex");

        if (data._rowId === rowIdSelecionado) {
          $(row).addClass('selected');
        }
      },
      initComplete() {
        const $table = $('#tabelaSetoresAltera');

        $table.off('click.rowSelect').on('click.rowSelect', 'tbody tr', function (e) {
          if ($(e.target).closest('.reorder-handle').length || $(e.target).is('input, button, a, select')) {
            return;
          }

          const $row = $(this);
          const isSelected = $row.hasClass('selected');

          $table.find('tbody tr').removeClass('selected');

          if (!isSelected) {
            $row.addClass('selected');
            const data = tabela.row(this).data();
            rowIdSelecionado = data ? data._rowId : null;
            $('#txtOrdemAltera').val(data.ordem);
            insereValor('#txtSetorAltera', data.setor, data.desc_setor);
          } else {
            rowIdSelecionado = null;
            $('#txtOrdemAltera').val('');
            $('#txtSetorAltera').val('');
          }
        });
      }
    });

    $('#tabelaSetoresAltera').off('row-reorder.dt').on('row-reorder.dt', function (e, diff, edit) {
      let dados = tabela.rows().data().toArray();
      const dadosAntigos = dados.map(row => ({ ...row }));
      let novaOrdem = dados.map(row => ({ ...row }));

      diff.forEach(function (d) {
        const fromIndex = d.oldPosition;
        const toIndex = d.newPosition;
        novaOrdem[toIndex].setor = dadosAntigos[fromIndex].setor;
        novaOrdem[toIndex].desc_setor = dadosAntigos[fromIndex].desc_setor;
        novaOrdem[toIndex]._rowId = dadosAntigos[fromIndex]._rowId;
      });

      dados = [...novaOrdem];
      tabela.clear().rows.add(dados).draw(false);

      if (rowIdSelecionado) {
        tabela.rows().every(function () {
          const data = this.data();
          if (data._rowId === rowIdSelecionado) {
            $(this.node()).addClass('selected');
          }
        });
      }
    });

    $('#modal-alterar-setor').modal('show');
  });

  $('#btnIncluirSetor').on('click', function () {
    $('.manipulaCampo').attr('disabled', false);
    $('#btnAlterarSetor').addClass('d-none');
    $('#btnIncluirSetor').addClass('d-none');
    $('#btnConfirmarSetor').removeClass('d-none');
    $('#btnDesistirSetor').removeClass('d-none');

    const tabela = $('#tabelaSetoresAltera').DataTable();
    const dados = tabela.rows().data().toArray();

    const ultimaOrdem = dados.length > 0 ? Math.max(...dados.map(item => parseInt(item.ordem) || 0)) : 0;
    const novaOrdem = ultimaOrdem + 10;

    $('#txtOrdemAltera').val(novaOrdem).attr('disabled', true);
    $('#txtSetorAltera').val('');
  });

  $('#btnConfirmarSetor').on('click', function () {
    const tabela = $('#tabelaSetoresAltera').DataTable();
    const dados = tabela.rows().data().toArray();
    const novaOrdem = $('#txtOrdemAltera').val();
    const novoSetor = pegaChave('#txtSetorAltera');
    const novaDescricao = pegaDescricao('#txtSetorAltera');

    if (!novaOrdem || !novoSetor) {
      msgAlerta('Por favor, preencha os campos de ordem e setor!');
      return;
    }

    const linhaSelecionadaIndex = tabela.rows('.selected').indexes()[0];
    const setorExistente = dados.some((item, index) =>
      item.setor === novoSetor && (linhaSelecionadaIndex == undefined || index != linhaSelecionadaIndex)
    );
    if (setorExistente) {
      msgAlerta('Este setor já existe na tabela!');
      return;
    }

    const ordemExistenteIndex = dados.findIndex(item => item.ordem == novaOrdem);

    if (ordemExistenteIndex !== -1) {
      const linhaExistente = dados[ordemExistenteIndex];
      linhaExistente.setor = novoSetor;
      linhaExistente.desc_setor = novaDescricao;
      linhaExistente.ordem_orig = novaOrdem / 10;

      tabela.row(ordemExistenteIndex).data(linhaExistente).draw(false);
      tabela.row(ordemExistenteIndex).node().classList.add('selected');
    } else {
      const novaLinha = {
        ordem: novaOrdem,
        setor: novoSetor,
        desc_setor: novaDescricao,
        _rowId: `row_${dados.length}_${novoSetor}`,
        ordem_orig: novaOrdem / 10
      };

      tabela.row.add(novaLinha).draw(false);
    }

    $('#txtOrdemAltera').val('').attr('disabled', false);
    $('#txtSetorAltera').val('');
    $('.manipulaCampo').attr('disabled', true);
    $('#btnAlterarSetor').removeClass('d-none');
    $('#btnIncluirSetor').removeClass('d-none');
    $('#btnConfirmarSetor').addClass('d-none');
    $('#btnDesistirSetor').addClass('d-none');
  });

  $('#btnDesistirSetor').on('click', function () {
    $('.manipulaCampo').attr('disabled', true);
    $('#btnAlterarSetor').removeClass('d-none');
    $('#btnIncluirSetor').removeClass('d-none');
    $('#btnConfirmarSetor').addClass('d-none');
    $('#btnDesistirSetor').addClass('d-none');
  });

  $('#btnAlterarSetor').on('click', function () {
    const tabela = $('#tabelaSetoresAltera').DataTable();
    const linhasSelecionadas = tabela.rows('.selected').data().toArray();

    if (linhasSelecionadas.length === 0) {
      msgAlerta('Nenhuma linha selecionada na tabela!');
      return;
    }
    $('.manipulaCampo').attr('disabled', false);
    $('#btnAlterarSetor').addClass('d-none');
    $('#btnIncluirSetor').addClass('d-none');
    $('#btnConfirmarSetor').removeClass('d-none');
    $('#btnDesistirSetor').removeClass('d-none');

    const data = tabela.row('.selected').data();
    $('#txtOrdemAltera').val(data.ordem);
    insereValor('#txtSetorAltera', data.setor, data.desc_setor);
  });

  const imprimirSequencia = async ({ produto }) => {
    $.LoadingOverlay('show');
    try {
      const url = `/sisplan/movimentacaofaccao/v1/imprimir_sequencia_operacional?`;
      const ordem = `&TELA_ORDENACAO=RelSequenciaOperacional&ORDEM_ORDENACAO=${$('#txtOrdem').val()}`;
      const bImprimeAutomatico = await verificaImprimirAutomatico('RelOrcamentoIndividual');
      let arquivo = await GeraRelatorio(`${url}${ordem}&PRODUTO=${produto}`, 'GET', 1000000, false, 'RelSequenciaOperacional');
      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, '_blank');
        }
        await limparRelatorios();
      }

    } catch (error) {
      console.error(error);
      msgErro('Não foi possível encontrar a sequência operacional do produto.');
    } finally {
      $.LoadingOverlay('hide');
    }
  };

  $('#tabelaOrdemProducao').on('click', '#btnImprimirSequencia', async function () {
    try {
      const data = $('#tabelaOrdemProducao').DataTable().row($(this).closest('tr')).data();
      imprimirSequencia({ produto: data.codigo });

    } catch (error) {
      console.error(error);
      msgErro('Ocorreu um erro ao validar os dados.');
    }
  });

  function abreRelatorioTAG(objeto) {
    $.LoadingOverlay('show');
    try {
      const { numero, codigo, descricao } = objeto;
      let tag = {};
      tag.NUMERO = numero;
      tag.CODIGO = codigo;
      tag.DESCRICAO = descricao;

      let jsonTag = JSON.stringify(tag);

      parent.abrirEmNovaAbaIFrame('Relatório de Tag', `${BASE_URI}/reltag/`, btoa(jsonTag));

    } catch (error) {

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

  $('#tabelaOrdemProducao').on('click', '#btnImprimirTAG', async function () {
    try {
      const data = $('#tabelaOrdemProducao').DataTable().row($(this).closest('tr')).data();
      abreRelatorioTAG({ numero: data.numero, codigo: data.codigo, descricao: data.descricao });

    } catch (error) {
      console.error(error);
      msgErro('Ocorreu um erro ao validar os dados.');
    }
  });

  $('#tabelaOrdemProducao').on('click', '#btnMovimentar', async function () {
    await movimentarSetor(this);
  });

  $('#tabelaOrdemProducao').on('click', '#btnEstornar', async function () {
    $.LoadingOverlay('show');
    try {
      const ordemProd = $('#tabelaOrdemProducao').DataTable().row($(this).parents('tr')).data();
      validarRegistroExpiracao(
        'MOVIMENTOFACCAO',
        ordemProd.numero,
        async () => {
          adicionarRegistroParaLiberarSessionStorage('movimentacaofaccao', 'MOVIMENTOFACCAO', ordemProd.numero)
          if (bEstornaMovimentacao == '2') {
            await senhaSupervisor('Necessário senha de supervisor para estornar o movimento',
              async () => {
                await iniciaModalEstornar(ordemProd);
                $('#modalEstornar').modal('show');
              }
            );
          } else {
            await iniciaModalEstornar(ordemProd);
            $('#modalEstornar').modal('show');
          }
        }
      )
    } finally {
      $.LoadingOverlay('hide');
    }
  });

  $('#btnConsultarEstorno').on('click', async function () {
    $.LoadingOverlay('show');
    try {
      await consultaOrdemProducaoParaEstornar();
    } finally {
      $.LoadingOverlay('hide');
    }
  });

  $('#tabelaOrdemProducao').on('dblclick', 'tr', async function () {
    await movimentarSetor(this);
  });

  $('#btnConsultar').on('click', async function () {
    $('#modal-filtros').modal('hide');
    await consultaOrdemProducao();
  });

  await setorUsuario();
  $('#btnConsultar').trigger('click');

  preencheOrdenacaoTela('RelAcessoMovimentacaoFaccao');
  retornaHintRelatorio('btnImprimir', 'AcessoMovimentacaoFaccao');

  $("#btnImprimir").on("click", async function () {
    try {
      $.LoadingOverlay("show");
      const filtros = await retornaFiltros();
      const url = `/sisplan/impressao/v1/relacessomovimentacaofaccao?`;
      const ordem = `&TELA_ORDENACAO=RelAcessoMovimentacaoFaccao&ORDEM_ORDENACAO=${$('#txtOrdem').val()}`;
      const bImprimeAutomatico = await verificaImprimirAutomatico('RelAMovimentacaoFaccao');
      let arquivo = await GeraRelatorio(`${url}${filtros}${ordem}&`, "GET", 15000, false, 'RelAMovimentacaoFaccao');
      if (arquivo != undefined) {
        if (!bImprimeAutomatico) {
          window.open(`${BASE_URI}/relatorios_api/pdf/${arquivo}`, "_blank");
        }
        await limparRelatorios();
      }
    } finally {
      $.LoadingOverlay("hide");
    }
  });

  $("#modalEstornar").on("shown.bs.modal", function () {
    $(".scrollOrdemFaccao").scrollTop($(".scrollOrdemFaccao").prop("scrollHeight"));
    $('#tabelaEstornar').DataTable().columns.adjust().draw(false);
  });

  $('#modalEstornar').on('hide.bs.modal', function () {
    excluirRegistroExpiracao('MOVIMENTOFACCAO', $('#txtNumeroAnterior').val(), false)
  })

  $("#txtOFEstorno").on("focusout", async function () {
    const ordemProd = {};
    ordemProd.numero = pegaChave(this);
    const numeroOfAnterior = $('#txtNumeroAnterior').val()

    if (ordemProd.numero === numeroOfAnterior) {
      return
    }

    if (numeroOfAnterior) {
      await excluirRegistroExpiracao('MOVIMENTOFACCAO', numeroOfAnterior, false)
    }

    $('#txtOFEstorno').val('')
    $('#selectParte').val('')
    $('#txtEstornarProduto').val('')
    $('#txtNumeroAnterior').val('')

    if (!ordemProd.numero) {
      return
    }

    validarRegistroExpiracao(
      'MOVIMENTOFACCAO',
      ordemProd.numero,
      async () => {
        const codigoProduto = await buscaValor('OF1', 'CODIGO', 'NUMERO', ordemProd.numero);
        ordemProd.codigo = codigoProduto.CODIGO;
        const descricaoProduto = await buscaValor('PRODUTO', 'DESCRICAO', 'CODIGO', codigoProduto.CODIGO);
        ordemProd.descricao = descricaoProduto.DESCRICAO;
        limpaFiltrosOrdemFaccaoEstornar();
        await iniciaModalEstornar(ordemProd);
      }
    )
  });

  $("#checkSelecionarTodos").on("click", function () {
    const table = $('#tabelaEstornar').DataTable()
    const isChecked = $(this).prop('checked')
    if (isChecked) {
      table.rows().every(function () {
        const row = $(this.node())
        row.addClass("selected");
        const inputCheckbox = $(this.node()).find('.campoSelEstorno')
        $(inputCheckbox).prop('checked', true)
      })

      const mostrarPanelDeposito = table.data().toArray().some((it) => it.ESTOQUE === 'S')
      mostrarPanelDeposito ? $("#panelDeposito").removeClass("d-none") : $("#panelDeposito").addClass("d-none");
      return
    }

    table.rows().every(function () {
      const row = $(this.node())
      row.removeClass("selected");
      const inputCheckbox = $(this.node()).find('.campoSelEstorno')
      $(inputCheckbox).prop('checked', false)
    })
    $("#panelDeposito").addClass("d-none");
  });

  $("#checkSelecionarTodosSetor").on("click", function () {
    if ($(this).prop("checked")) {
      const qtde = $('#tabelaEstornar').DataTable().rows('.selected').count();

      if (qtde != 1) {
        msgAlerta('Necessário conter apenas um registro selecionado para usar essa opção.');
        $(this).prop('checked', false);
        return;
      }

      const registro = $("#tabelaEstornar").DataTable().rows(".selected").data().toArray();

      const table = $('#tabelaEstornar').DataTable()
      table.rows().every(function () {
        const data = this.data()
        if (data.SETOR === registro[0].SETOR) {
          const row = $(this.node())
          row.addClass("selected");
          const inputCheckbox = $(this.node()).find('.campoSelEstorno')
          $(inputCheckbox).prop('checked', true)
        }
      })

      $("#checkSelecionarTodos").prop('checked', false);
      $("#checkSelecionarTodosCor").prop('checked', false);
      const mostrarPanelDeposito = table.rows(".selected").data().toArray().some((it) => it.ESTOQUE === 'S')
      mostrarPanelDeposito ? $("#panelDeposito").removeClass("d-none") : $("#panelDeposito").addClass("d-none");
    } else {
      const table = $('#tabelaEstornar').DataTable()
      table.rows().every(function () {
        const row = $(this.node())
        row.removeClass("selected");
        const inputCheckbox = $(this.node()).find('.campoSelEstorno')
        $(inputCheckbox).prop('checked', false)
      })
      $("#panelDeposito").addClass("d-none");
    }
  });

  $("#checkSelecionarTodosCor").on("click", function () {
    if ($(this).prop("checked")) {
      const qtde = $('#tabelaEstornar').DataTable().rows('.selected').count();

      if (qtde != 1) {
        msgAlerta('Necessário conter apenas um registro selecionado para usar essa opção.');
        $(this).prop('checked', false);
        return;
      }

      const registro = $("#tabelaEstornar").DataTable().rows(".selected").data().toArray();
      const table = $('#tabelaEstornar').DataTable()
      table.rows().every(function () {
        const data = this.data()
        if (data.COR === registro[0].COR) {
          const row = $(this.node())
          row.addClass("selected");
          const inputCheckbox = $(this.node()).find('.campoSelEstorno')
          $(inputCheckbox).prop('checked', true)
        }
      })

      $("#checkSelecionarTodos").prop('checked', false);
      $("#checkSelecionarTodosSetor").prop('checked', false);
      const mostrarPanelDeposito = table.rows(".selected").data().toArray().some((it) => it.ESTOQUE === 'S')
      mostrarPanelDeposito ? $("#panelDeposito").removeClass("d-none") : $("#panelDeposito").addClass("d-none");
    } else {
      const table = $('#tabelaEstornar').DataTable()
      table.rows().every(function () {
        const row = $(this.node())
        row.removeClass("selected");
        const inputCheckbox = $(this.node()).find('.campoSelEstorno')
        $(inputCheckbox).prop('checked', false)
      })
      $("#panelDeposito").addClass("d-none");
    }
  });

  function MontaPesquisa() {
    // componenteFiltro('ordemProducao', true)
    componenteFiltro('produto', true);
    componenteFiltro('pedido', true);
    componenteFiltro('setor', true);

    componenteFiltro('setor', false, false, 'SetorAltera');

    $('#txtOrdemProducao').pesquisa_variosServerside(1, '{ "tabela":"OF1", "camposSelect":[ "OF1.NUMERO", "OF1.CODIGO","PRODUTO.CODIGO2", "OF1.CODCLI", "PRODUTO.DESCRICAO", "ENTIDADE.NOME", "ENTIDADE.CNPJ", "ENTIDADE.FANTASIA" ], "leftjoin":[{"tabela":"PRODUTO","condicao":"PRODUTO.CODIGO = OF1.CODIGO"},{"tabela":"ENTIDADE","condicao":"ENTIDADE.CODCLI = OF1.CODCLI"}], "where": null }', 'NUMERO', 'CODIGO', 'CODCLI', 'CODIGO2', 'DESCRICAO', 'NOME', 'CNPJ', 'FANTASIA');
    $('#btnOrdemProducao').pesquisa_serversideSel('#txtOrdemProducao', '{ "tabela":"OF1", "camposSelect":[ "OF1.NUMERO", "OF1.CODIGO", "PRODUTO.CODIGO2", "OF1.CODCLI", "PRODUTO.DESCRICAO", "ENTIDADE.NOME", "ENTIDADE.CNPJ", "ENTIDADE.FANTASIA" ], "leftjoin":[{"tabela":"PRODUTO","condicao":"PRODUTO.CODIGO = OF1.CODIGO"},{"tabela":"ENTIDADE","condicao":"ENTIDADE.CODCLI = OF1.CODCLI"}], "where": null }', 'Pesquisa de ordem de produção:');
    $('#btnLimpaOrdemProducao').on('click', function () { $('#txtOrdemProducao').empty().trigger('change'); });

    $('#txtCliente').pesquisa_variosServerside(1, '{ "tabela":"ENTIDADE", "camposSelect":[ "CODCLI", "NOME", "CNPJ" ], "where": null}', 'CODCLI', 'NOME', 'CNPJ');
    $('#btnCliente').pesquisa_serversideSel('#txtCliente', `{ "tabela":"ENTIDADE", "camposSelect":[ "CODCLI", "NOME", "CNPJ"], "where": null}`, 'Pesquisa de cliente');
    $('#btnLimpaCliente').on('click', function () { $('#txtCliente').empty().trigger('change'); });
  }

  async function preencheParte(numero) {
    $('#selectParte').empty();
    const pesquisaParam = {
      tabela: 'FACCAO',
      camposSelect: ['DISTINCT FACCAO.PARTE', 'TIPO_APL.DESCRICAO'],
      where: [`FACCAO.NUMERO = '${numero}'`],
      innerJoin: [{ tabela: "TIPO_APL", condicao: "TIPO_APL.CODIGO = FACCAO.PARTE" }],
      orderby: ["FACCAO.PARTE"]
    };
    const jsonStr = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));

    if (jsonStr.length > 0) {
      jsonStr.forEach(parte => {
        let objeto = {
          id: parte.PARTE,
          text: `[${parte.PARTE}] - ${parte.DESCRICAO}`
        };
        const newOption = new Option(objeto.text, objeto.id, true, false);
        $('#selectParte').append(newOption);
      });
    }

  }

  function montaPesquisaEstornar(numero) {
    $('#txtOFEstorno').autocompleta(1, `JSON={ "tabela":"OF1", "camposSelect":["NUMERO CHAVE, CODIGO DESCRICAO"], "where": []}`);
    $('#txtEstornarCor').autocompleta(1, `JSON={ "tabela":"CADCOR", "camposSelect":["COR CHAVE, DESCRICAO DESCRICAO"], "where": []}`);
    $('#txtEstornarTam').autocompleta(1, `JSON={ "tabela":"TABTAM", "camposSelect":["TAM CHAVE, FAIXA DESCRICAO"], "where": []}`);
    $('#txtEstornarFaccao').autocompleta(1, `JSON={ "tabela":"ENTIDADE", "camposSelect":["CODCLI CHAVE, NOME DESCRICAO"], "where": []}`);
    $('#txtEstornarSetor').autocompleta(1, `JSON={ "tabela":"CADFLUXO", "camposSelect":["CODIGO CHAVE, DESCRICAO DESCRICAO"], "where": []}`);
    $('#txtEstornarMov').pesquisa_variosServerside(1, `{ "tabela":"FACCAO", "camposSelect":[ "MOV", "NUMERO"], "where": ["NUMERO = '${numero}'"], "groupby": ["MOV", "NUMERO"], "orderBy": ["MOV"]}`, 'MOV', 'NUMERO');
    $('#txtEstornarTipoMov').autocompleta(1, `JSON={ "tabela":"TABBAI", "camposSelect":["CODIGO CHAVE, DESCRICAO DESCRICAO"], "where": []}`);

    $('#btnOFEstorno').pesquisa_serverside(['#txtOFEstorno'], ['NUMERO'], ['CODIGO'], '{"tabela":"OF1", "camposSelect":[ "NUMERO", "CODIGO"], "where": null}', 'Pesquisa de Ordem de Facção');
    $('#btnEstornarCor').pesquisa('#txtEstornarCor', 'COR', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"CADCOR", "camposSelect":[ "COR", "DESCRICAO"], "where": null}`, 'Pesquisa de Cor', 'CADCOR');
    $('#btnEstornarTam').pesquisa('#txtEstornarTam', 'TAM', 'FAIXA', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"TABTAM", "camposSelect":[ "TAM", "FAIXA"], "where": null}`, 'Pesquisa de Tamanho', 'TABTAM');
    $('#btnEstornarFaccao').pesquisa('#txtEstornarFaccao', 'CODCLI', 'NOME', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"ENTIDADE", "camposSelect":[ "CODCLI", "NOME"], "where": null}`, 'Pesquisa de Facção', 'ENTIDADE');
    $('#btnEstornarSetor').pesquisa('#txtEstornarSetor', 'CODIGO', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"CADFLUXO", "camposSelect":[ "CODIGO", "DESCRICAO"], "where": null}`, 'Pesquisa de Setor', 'CADFLUXO');
    $('#btnEstornarMov').pesquisa_serversideSel('#txtEstornarMov', `{ "tabela":"FACCAO", "camposSelect":[ "MOV", "NUMERO"], "where": ["NUMERO = '${numero}'"], "groupby": ["MOV", "NUMERO"], "orderBy": ["MOV"]}`, 'Pesquisa de Movimento');
    $('#btnEstornarTipoMov').pesquisa('#txtEstornarTipoMov', 'CODIGO', 'DESCRICAO', `/sisplan/funcoes/v1/pesquisa?JSON={ "tabela":"TABBAI", "camposSelect":[ "CODIGO", "DESCRICAO"], "where": null}`, 'Pesquisa de Tipo de Baixa', 'TABBAI');
  }

  $("#btnLimpaEstornarMov").on('click', function () {
    $('#txtEstornarMov').empty().trigger('change');
  });

  $("#btnLimpaEstornarCor").on('click', function () {
    $('#txtEstornarCor').val('');
  });

  $("#btnLimpaEstornarTam").on('click', function () {
    $('#txtEstornarTam').val('');
  });

  $("#btnLimpaEstornarFaccao").on('click', function () {
    $('#txtEstornarFaccao').val('');
  });

  $("#btnLimpaEstornarSetor").on('click', function () {
    $('#txtEstornarSetor').val('');
  });

  $("#btnLimpaEstornarTipoMov").on('click', function () {
    $('#txtEstornarTipoMov').val('');
  });

  async function retornaFiltros() {
    const dtSaidaDe = $('#txtDataSaidaIni').val();
    const dtSaidaAte = $('#txtDataSaidaFim').val();
    const dtRetornoDe = $('#txtDataSaidaFim').val();
    const dtRetornoAte = $('#txtDataSaidaFim').val();
    const dtCadastroDe = $('#txtDataCadastroIni').val();
    const dtCadastroAte = $('#txtDataCadastroFim').val();
    const numero = await formataListas($('#txtOrdemProducao').val().toString());
    const produto = await formataListas($('#txtProduto').val().toString());
    const cliente = await formataListas($('#txtCliente').val().toString());
    const pedido = await formataListas($('#txtPedido').val().toString());
    const setor = await formataListas($('#txtSetor').val().toString());
    const status = $('#txtStatus').val() == 1 ? 'S' : 'N';
    const dtInicioDe = $('#txtDataInicioIni').val();
    const dtInicioAte = $('#txtDataInicioFim').val();
    const dtFimDe = $('#txtDataFimIni').val();
    const dtFimAte = $('#txtDataFimFim').val();

    const retorno = `DT_SAIDA_DE=${dtSaidaDe}` +
      `&DT_SAIDA_ATE=${dtSaidaAte}` +
      `&DT_RETORNO_DE=${dtRetornoDe}` +
      `&DT_RETORNO_ATE=${dtRetornoAte}` +
      `&DT_CADASTRO_DE=${dtCadastroDe}` +
      `&DT_CADASTRO_ATE=${dtCadastroAte}` +
      `&NUMERO=${numero}` +
      `&PRODUTO=${produto}` +
      `&CLIENTE=${cliente}` +
      `&PEDIDO=${pedido}` +
      `&SETOR=${setor}` +
      `&PENDENTE=${status}` +
      `&DT_INICIO_DE=${dtInicioDe}` +
      `&DT_INICIO_ATE=${dtInicioAte}` +
      `&DT_FIM_DE=${dtFimDe}` +
      `&DT_FIM_ATE=${dtFimAte}`;

    return retorno;
  }

  async function retornaFiltrosPesquisa() {
    const dtSaidaDe = $('#txtDataSaidaIni').val();
    const dtSaidaAte = $('#txtDataSaidaFim').val();
    const dtRetornoDe = $('#txtDataSaidaFim').val();
    const dtRetornoAte = $('#txtDataSaidaFim').val();
    const dtCadastroDe = $('#txtDataCadastroIni').val();
    const dtCadastroAte = $('#txtDataCadastroFim').val();
    const numero = await formataListas($('#txtOrdemProducao').val().toString());
    const produto = await formataListas($('#txtProduto').val().toString());
    const cliente = await formataListas($('#txtCliente').val().toString());
    const pedido = await formataListas($('#txtPedido').val().toString());
    const setor = await formataListas($('#txtSetor').val().toString());
    const status = $('#txtStatus').val() == 1 ? 'S' : 'N';
    const dtInicioDe = $('#txtDataInicioIni').val();
    const dtInicioAte = $('#txtDataInicioFim').val();
    const dtFimDe = $('#txtDataFimIni').val();
    const dtFimAte = $('#txtDataFimFim').val();

    return {
      dtSaidaDe,
      dtSaidaAte,
      dtRetornoDe,
      dtRetornoAte,
      dtCadastroDe,
      dtCadastroAte,
      numero,
      produto,
      cliente,
      pedido,
      setor,
      status,
      dtInicioDe,
      dtInicioAte,
      dtFimDe,
      dtFimAte
    };
  }

  async function retornaFiltrosEstorno() {
    const numero = $('#txtNumeroTitle').text();
    const produto = pegaChave('#txtEstornarProduto');
    const cor = pegaChave('#txtEstornarCor');
    const tam = pegaChave('#txtEstornarTam');
    const faccao = pegaChave('#txtEstornarFaccao');
    const setor = pegaChave('#txtEstornarSetor');
    const movimento = await formataListas($('#txtEstornarMov').val().toString(), true);
    const parte = $('#selectParte').val();

    const retorno = `&NUMERO=${numero}` +
      `&PRODUTO=${produto}` +
      `&COR=${cor}` +
      `&TAM=${tam}` +
      `&FACCAO=${faccao}` +
      `&SETOR=${setor}` +
      `&MOVIMENTO=${movimento}` +
      `&PARTE=${parte}`;

    return retorno;
  }

  async function movimentarSetor(registro) {
    if (permissaoUsuarioLogado.ALTERA !== 'S') {
      msgAlertaSemConfirmacao("Sem permissão para movimentar!")
      return
    }
    const data = $('#tabelaOrdemProducao').DataTable().row($(registro).parents('tr')).data();
    validarRegistroExpiracao(
      'MOVIMENTOFACCAO',
      data.numero,
      () => {
        adicionarRegistroParaLiberarSessionStorage('movimentacaofaccao', 'MOVIMENTOFACCAO', data.numero)
        window.location.href = `movimentacaofaccao/NUMERO=${data.numero}&RECARREGAR=N`
      }
    )
  }

  function ajustaPropsRegistros(registros) {
    const selecionados = $("#tabelaEstornar").DataTable().rows('.selected').data().toArray();
    registros.forEach((objeto, i) => {
      objeto.SEL = selecionados.some(sel => sel.IDENTIFICADOR == objeto.IDENTIFICADOR) ? 'S' : 'N';
      objeto.MOVANT = objeto.MOV_ANT;
      objeto.MOVKIT = objeto.MOV_KIT;
      objeto.IDANT = objeto.ID_ANT;
      objeto.CODCLIANT = objeto.CODCLI_ANT;
      objeto.DTLAN = objeto.DT_LAN;
      objeto.DESCCOR = objeto.DESC_COR;
      objeto.DESCSETOR = objeto.DESC_SETOR;
      objeto.SETORDEST = objeto.SETOR_DEST;
      objeto.QTORIG = objeto.QT_ORIG;
      objeto.QUANT2 = objeto.QUANT_2;
      objeto.QUANTI = objeto.QUANT_I;
      objeto.QUANTF = objeto.QUANT_F;
      objeto.DTPAGTO = objeto.DT_PAGTO;
      objeto.CODIGOTROCADO = objeto.CODIGO_TROCADO;
      objeto.LANCTOKIT = objeto.LANCTO_KIT;
      objeto.ESTOQUEPARTE = objeto.ESTOQUE_PARTE;
      objeto.OBRIGAMOTIVO = objeto.OBRIGA_MOTIVO;
      objeto.EXISTEFACCAO3 = objeto.EXISTE_FAC3;
      objeto.REPROPEND = objeto.REPRO_PEND;
      objeto.CODIGO2PRODUTO = objeto.CODIGO2_PRODUTO;
      objeto.IDANTFACCAO = objeto.ID_ANT_FACCAO;

      delete objeto.MOV_ANT;
      delete objeto.MOV_KIT;
      delete objeto.ID_ANT;
      delete objeto.CODCLI_ANT;
      delete objeto.DT_LAN;
      delete objeto.DESC_COR;
      delete objeto.DESC_SETOR;
      delete objeto.SETOR_DEST;
      delete objeto.QT_ORIG;
      delete objeto.QUANT_2;
      delete objeto.QUANT_I;
      delete objeto.QUANT_F;
      delete objeto.DT_PAGTO;
      delete objeto.CODIGO_TROCADO;
      delete objeto.LANCTO_KIT;
      delete objeto.ESTOQUE_PARTE;
      delete objeto.OBRIGA_MOTIVO;
      delete objeto.EXISTE_FAC3;
      delete objeto.REPRO_PEND;
      delete objeto.CODIGO2_PRODUTO;
      delete objeto.ID_ANT_FACCAO;
    });
  }

  async function preencheMotivos() {
    try {

      const pesquisa = {
        tabela: 'MENSAGEM',
        camposSelect: ['CODMEN', 'DESCRICAO'],
        where: ['((TIPO = 0) OR (TIPO = 1))']
      };

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

      if (jsonStr.length > 0) {
        $('#selectMotivo').empty();
        jsonStr.forEach(mensagem => {
          const objeto = {
            id: mensagem.CODMEN,
            text: `${mensagem.DESCRICAO}`
          };
          const newOption = new Option(objeto.text, objeto.id, true, false);
          $('#selectMotivo').append(newOption);
        });
      }

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

  async function iniciaModalEstornar(ordemProd) {
    if (ordemProd.numero) {
      liberarRegistro('MOVIMENTOFACCAO', ordemProd.numero)
    }
    $('#txtNumeroTitle').text(ordemProd.numero);
    insereValor("#txtOFEstorno", ordemProd.numero, ordemProd.codigo);
    limpaFiltrosOrdemFaccaoEstornar();
    insereValor('#txtEstornarProduto', ordemProd.codigo, ordemProd.descricao);
    montaPesquisaEstornar(ordemProd.numero);
    await preencheParte(ordemProd.numero);
    await preencheMotivos();
    await consultaOrdemProducaoParaEstornar(false);
    $('#txtNumeroAnterior').val(ordemProd.numero)
  }

  function validaOFMovimentaEstoque() {
    const registros = $("#tabelaEstornar").DataTable().data().toArray();
    for (let i = 0; i < registros.length; i++) {
      if ($(`#checkEstorno${i}`).prop("checked") && registros[i].ESTOQUE == "S") {
        return true;
      }
    }
    return false;
  }

  function limpaFiltrosOrdemFaccaoEstornar() {
    $("#txtEstornarCor").val("");
    $("#txtEstornarTam").val("");
    $("#txtEstornarFaccao").val("");
    $("#txtEstornarSetor").val("");
    $("#txtEstornarMov").empty().trigger("change");
    $("#txtEstornarTipoMov").val("");
  }

  function validaRegistrosSelecionados(registros) {
    for (let i = 0; i < registros.length; i++) {
      if (registros[i].SEL == "S") {
        return true;
      }
    }
    return false;
  }

  async function setorUsuario() {
    try {
      const responseUsuario = await requisicao(
        "GET",
        "/sisplan/funcoes/v1/pesquisa?",
        `JSON={
          "tabela": "ACESSO_USUARIOS", 
          "camposSelect": ["SETORES"], 
          "where": ["CODIGO = '${getCookie('cod_usuario')}'"]
        }`
      );

      if (!responseUsuario) {
        return;
      }

      const jsonUsuario = await responseUsuario.json();
      if (responseUsuario.status != 200) {
        msgAlerta(jsonUsuario.RESULT[0].mensagem);
        return;
      }

      if (jsonUsuario.RESULT[0][0].SETORES != '') {
        const responseSetores = await requisicao(
          "GET",
          "/sisplan/funcoes/v1/pesquisa?",
          `JSON={
            "tabela": "CADFLUXO", 
            "camposSelect": ["CODIGO", "DESCRICAO"], 
            "where": ["CODIGO IN (${jsonUsuario.RESULT[0][0].SETORES})"]
          }`
        );

        if (!responseSetores) {
          return;
        }

        const jsonSetores = await responseSetores.json();
        if (responseSetores.status != 200) {
          msgAlerta(jsonSetores.RESULT[0].mensagem);
          return;
        }

        await insereValorPesquisaVarios('txtSetor', 'CODIGO', 'DESCRICAO', jsonSetores.RESULT[0]);
      }
    } catch (error) {
      console.log(error);
    }
  }

  async function buscarObsMontagem(codigo) {
    try {
      const response = await requisicao("GET", `/Sisplan/produto/v1/obsmontagem?`, `&CODIGO=${encodeURIComponent(codigo)}`, '', 3600000);

      const json = await response.json();

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

      return resultado;
    } catch (e) {
      console.error(e);
    }
  }

  async function explodeGradeProduto(codigo, numOf = null, quantidadesZeradas = false) {
    $.LoadingOverlay('show');
    try {
      let tam;
      let qtde;
      if ($.fn.DataTable.isDataTable('#tabelaGradeProduto')) {
        $('#tabelaGradeProduto').DataTable().destroy();
        $('#tabelaGradeProduto').empty();
      };

      const response = await requisicao('GET', '/sisplan/funcoes/v1/gradeproduto?', `CODIGO=${codigo}&NUMERO=${numOf}`, null);
      const jsonStr = await response.json();
      if (response.status != 200) {
        msgAlerta(jsonStr.RESULT[0].mensagem);
      }

      let jsonStrQtdeCorTam = [];
      if (numOf != null) {
        let pesquisaParam;
        if (await Existe('CADFLUXO', ['IMP_ETQ_COMPOSI'], ['S'])) {
          pesquisaParam = {
            tabela: 'FACCAO',
            camposSelect: [
              'FACCAO.CODIGO',
              'FACCAO.COR',
              'FACCAO.TAM',
              'SUM(FACCAO.QT_ORIG - FACCAO.QUANT - FACCAO.QUANT_2 - FACCAO.QUANT_F - FACCAO.QUANT_I) QTDE'
            ],
            leftjoin: [
              {
                tabela: 'PRO_FLUXO',
                condicao: `PRO_FLUXO.CODIGO = FACCAO.CODIGO AND PRO_FLUXO.PARTE = '00'`
              },
              {
                tabela: 'FLUXO',
                condicao: 'FLUXO.CODIGO = PRO_FLUXO.FLUXO AND FLUXO.SETOR = FACCAO.OP'
              }
            ],
            where: [
              `FACCAO.NUMERO = '${numOf}'`,
              `FACCAO.PARTE = '${$('#txtParteEtiqueta').val()}'`,
              `FLUXO.ORDEM = (SELECT MAX(FX.ORDEM)
                                FROM [FLUXO] FX
                                LEFT JOIN [FACCAO] FACCAOSUB ON FACCAOSUB.OP = FX.SETOR
                                WHERE FX.CODIGO = PRO_FLUXO.FLUXO
                                AND FACCAOSUB.NUMERO = FACCAO.NUMERO
                             )`
            ],
            groupby: [
              'FACCAO.CODIGO',
              'FACCAO.COR',
              'FACCAO.TAM'
            ]
          };

          jsonStrQtdeCorTam = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
        }


        if (jsonStrQtdeCorTam.length <= 0) {
          pesquisaParam = {
            tabela: 'OF_ITEN',
            camposSelect: ['COR', 'TAM', 'QTDE'],
            where: [`NUMERO = '${numOf}'`],
          };
          jsonStrQtdeCorTam = await retornaJsonPesquisaPadrao(JSON.stringify(pesquisaParam));
        }
      }

      for (let i = 0; i < parseInt(jsonStr.length); i++) {
        const colunas = Object.keys(jsonStr[i]);
        const tamanhos = [];
        colunas.forEach((coluna) => {
          if (!['CODIGO', 'COR', 'DESC_COR', 'POSICAO'].includes(coluna)) {
            tamanhos.push(coluna);
          }
        });

        tamanhos.sort();

        const jsonObject = jsonStr.map(obj => {
          const newObject = { ...obj };
          delete newObject.CODIGO;
          delete newObject.POSICAO;
          Object.keys(obj).forEach(key => {
            tam = RetornaIdTamFormatado(key);
            if (!['CODIGO', 'COR', 'POSICAO', 'DESC_COR'].includes(tam)) {
              qtde = jsonStrQtdeCorTam.filter(f => f.COR == newObject.COR && f.TAM == tam.split('HIFEN')[1]).length > 0 ? jsonStrQtdeCorTam.filter(f => f.COR == newObject.COR && f.TAM == tam.split('HIFEN')[1])[0].QTDE : 0;
              newObject[tam] = `<input type="text" class="input-default focus form-control camposGrade" id="${newObject.COR.replace('.', '_PONTO_') + tam}" value="${jsonStr[i][tam]}">`;
              newObject[tam.split('HIFEN')[1]] = `<input type="text" class="input-default focus form-control camposGrade" ${quantidadesZeradas ? '' : 'disabled'} id="${newObject.COR.replace('.', '_PONTO_') + tam}" value="${quantidadesZeradas ? 0 : qtde}">`;
              delete newObject[tam];
            }
          });
          return { ...newObject };
        });

        if (i == 0) {
          const titulosFixos = ['COR', 'DESC_COR'];
          const titulosGeral = [...titulosFixos, ...tamanhos];
          const titulos = titulosGeral.map(titulo => {
            const coluna = ['COR', 'DESC_COR'].includes(titulo) ? titulo : titulo.split('HIFEN')[1];
            const objeto = { title: coluna, data: RetornaIdTamFormatado(coluna) };
            return objeto;
          });

          criaDataTablePadrao('#tabelaGradeProduto', false, false, false, false, true, true, '250px', jsonObject, titulos);
        }
      }

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

      $('.camposGrade').on('blur', function () {
        preencheComZero();
      });

      $('.camposGrade').maskMoney({
        decimal: ".",
        thousands: "",
        precision: 0,
      });
      preencheComZero();
    }
  };

  function preencheComZero() {
    setTimeout(() => {
      $('.camposGrade').map((index) => {
        if ($($('.camposGrade')[index]).val() == '') {
          $($('.camposGrade')[index]).val('0');
        }
      });
    }, 100);
  };

  function retornaGrade(impressao = false, tag = '', qtdeColunas = '0') {
    let grade = [];

    const listaDados = $('#tabelaGradeProduto').DataTable().data().toArray();
    listaDados.forEach(dado => {
      const objeto = Object.entries(dado);
      let coluna;
      const colunas = objeto.map(prop => prop[0]);

      for (let i = 0; i < colunas.length; i++) {
        if ((!['COR', 'DESC_COR'].includes(colunas[i])) && (colunas[i].indexOf('/') == -1)) {
          coluna = RetornaIdTamFormatado(colunas[i], true);
          const idSemFormatacao = dado[colunas[i]].split('id="')[1].replace('"', '');
          const idFormatado = idSemFormatacao.split("value=")[0];
          const retorno = {
            NUM_OF: $('#txtNumeroOpEtiqueta').val(),
            CODIGO: $('#txtProdutoOpEtiqueta').val(),
            COR: dado.COR,
            DESC_COR: dado.DESC_COR,
            TAM: coluna,
            QTDE: $(`#${idFormatado}`).val(),
            TABPRECO: '',
            COLUNAS: qtdeColunas,
            TAG: tag,
            COLINI: '',
          };

          if (impressao || retorno.QTDE > 0) {
            grade.push(retorno);
          }
        }
      }
    });

    return grade;
  }

  async function gerarTag() {
    const tag = (await buscaValor('CADTAG', 'CODIGO', 'PADRAO', 'S')).CODIGO;
    const gravaBarraLog = (await buscaValor('CADTAG', 'GRAVAR_BARRALOG', 'CODIGO', tag)).GRAVAR_BARRALOG == 'S';
    const colunas = (await buscaValor('CADTAG', 'COLUNAS', 'PADRAO', 'S')).COLUNAS;

    if (!tag) {
      throw new Error('Nenhuma TAG padrão cadastrada, por favor verificar no cadastro de TAG!');
    };

    if (!gravaBarraLog) {
      throw new Error('A TAG padrão não está habilitada para gerar barra_log, por favor verifique no cadastro de TAG!');
    }

    if (!colunas > '0') {
      throw new Error('Quantidade de colunas não informada no cadastro de tag, impossível continuar!');
    };

    let grade = [];

    grade = retornaGrade(false, tag, colunas);

    if (!grade.length > 0) {
      throw new Error('Nenhuma quantidade informada na grade do produto, impossível continuar!');
    }

    try {
      const url = `/sisplan/impressao/v1/consulta_tag?`;
      const params = `TAG=${tag}&JSON=${JSON.stringify(grade)}&JSONTAG=${JSON.stringify([])}&TIPO_IMPRESSAO=${'DE'}&TELA=${'MovFaccao_WEB'}`;
      const response = await requisicao("POST", url, "", params, 770000);
      const jsonStr = await response.json();

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

      let barras = [];

      $.each(jsonStr, function (i, item) {
        if (item.BARRA2801) {
          barras.push(item.BARRA2801);
        }

        if (item.BARRA2802) {
          barras.push(item.BARRA2802);
        }
      });

      console.log(barras);
      barrasReimpressas = await formataListas(barras.toString());
    } catch (error) {
      console.log(error);
      msgAlerta(error.message);
    }
  }

  $('#btnImprimirEtiqueta').on('click', async function () {
    $.LoadingOverlay('show');

    const layout = $('#txtLayout option:selected').text()
    const tipoImpressao = $('#selectImpressao').val();
    const etiquetaImpressa = !!(await buscaValor('BARRA_LOG', ['BARRA'], [`(TELA <> 'RelTag_WEB' AND TELA <> '') AND NUM_OF`], [$('#txtNumeroOpEtiqueta').val()])).BARRA;
    try {
      if (tipoImpressao === '0') {
        await gerarTag();
        await imprimirEtiqueta(layout);
      } else if ((tipoImpressao === '1')) {
        if (etiquetaImpressa) {
          await imprimirEtiqueta(layout);
        } else {
          await gerarTag();
          await imprimirEtiqueta(layout);
        }
      }
    } catch (error) {
      console.log(error);
      msgAlerta(error.message);
    } finally {
      $.LoadingOverlay('hide');
    }
  });

  async function buscaGradeOrdemProducao() {
    try {
      $.LoadingOverlay('show')
      const numero = $('#tabelaOrdemProducao').DataTable().row('.selected').data().numero

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

      const response = await requisicao('GET', '/sisplan/movimentacaofaccao/v1/grade_ordem_producao?', `NUMERO=${numero}&PARTE=${$('#cbPartes').val()}`, null);
      const jsonStr = await response.json();
      if (response.status != 200) {
        msgAlerta(jsonStr.RESULT[0].mensagem);
      }

      const dataSetCols = [
        { title: 'Número', data: 'NUMERO' },
        { title: 'Mov.', data: 'MOV' },
        { title: 'Código', data: 'CODIGO' },
        { title: 'Codcli', data: 'CODCLI' },
        { title: 'Nome', data: 'NOME' },
        { title: 'Cor', data: 'COR' },
        { title: 'Desc. Cor', data: 'DESC_COR' },
        { title: 'Tam.', data: 'TAM' },
        { title: 'OP', data: 'OP' },
        { title: 'Desc. Setor', data: 'DESC_SETOR' },
        { title: 'Qt. Orig.', data: 'QT_ORIG' },
        { title: 'Quant.', data: 'QUANT' },
        { title: 'Quant. 2', data: 'QUANT_2' },
        { title: 'Quant. I', data: 'QUANT_I' },
        { title: 'Quant. F', data: 'QUANT_F' },
        { title: 'Saldo.', data: 'SALDO' },
        { title: 'Qtde. Restante', data: 'QTDE_RESTANTE' },
        { title: 'Data Sai.', data: 'DATA_SAI' },
        { title: 'Data Ret.', data: 'DATA_RET' },
        { title: 'Parte', data: 'PARTE' },
        { title: 'Desc. Parte', data: 'DESC_PARTE' },
        { title: 'Tipo', data: 'TIPO' },
        { title: 'Data Cad.', data: 'DATA_CAD' },
        { title: 'Periodo', data: 'PERIODO' },
        { title: 'Desc. Periodo', data: 'DESC_PERIODO' },
        { title: 'Ordem', data: 'ORDEM' },
        { title: 'Quant. B', data: 'QUANT_B' },
        { title: 'Cor Parte', data: 'CORPARTE' },
        { title: 'Código 2', data: 'CODIGO2' },
        { title: 'Desc. Prod.', data: 'DESC_PROD' },
        { title: 'Pedido', data: 'PEDIDO' },
        { title: 'Mov. Ant.', data: 'MOV_ANT' },
        { title: 'Lancto.', data: 'LANCTO' },
        { title: 'Identificador', data: 'IDENTIFICADOR' },
        { title: 'Id', data: 'ID' },
        { title: 'Usuário', data: 'USUARIO' },
        { title: 'Data R.', data: 'DT_R' },
        { title: 'Data R. Orig.', data: 'DT_R_ORIG' },
        { title: 'Data Prev. Pag.', data: 'DT_PREVPG' },
        { title: 'Hora Fac3', data: 'HORA_FAC3' },
      ];

      $('#tabelaGradeOF').DataTable({
        searching: false,
        paging: true,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        colReorder: true,
        scrollY: true,
        scrollX: true,
        lengthMenu: [[1000, -1], [1000, "Todos"]],
        pageLength: 1000,
        createdRow(row, data) {
          if (data.SALDO === 0) {
            $('td', row).css('color', '#75BE25');
          } else if (data.SALDO > 0) {
            $('td', row).css('color', 'red');
          }
        },
        autoWidth: true,
        data: jsonStr,
        columns: dataSetCols,
        columnDefs: [
          {
            "targets": [10, 11, 12, 13, 14, 15, 16, 26],
            "className": 'pr-4 text-right'
          },
          {
            type: 'date-br',
            targets: [17, 18, 22, 36, 37, 38, 39],
            render(data) {
              if (data != undefined && data != '' && data != '1899-12-30T00:00:00.000Z') {
                const x = data.slice(0, 10).split('-');
                const hora = data.split(' ')[1];
                if (hora) {
                  return `${x[2]}/${x[1]}/${x[0]} ${hora}`;
                }
                return `${x[2]}/${x[1]}/${x[0]}`;

              }
              return '';
            }
          }
        ]
      });

      const colunasInvisiveis = JSON.parse(localStorage.getItem('colunasInvisiveisRelatorios'));

      $('#tabelaGradeOF_length').prepend('<button class="buttonColVis" id="buttonColVisGrade"><i class="fas fa-cogs"></i></button>');
      $('#tabelaGradeOF_length').prepend('<button class="buttonExcel" id="buttonExcelGrade"><i class="fas fa-file-excel"></i></button>');

      $('#tabelaGradeOF_length').css('margin-top', '0 !important')
      $('#buttonColVisGrade').prop('title', 'Configurar colunas visíveis');
      $('#buttonExcelGrade').prop('title', 'Exportar');

      $('#buttonColVisGrade').on('click', async function () {
        idTabela = '#tabelaGradeOF';
        $.LoadingOverlay('show');
        $('#modal-ColunasVisiveis').modal('show');
        $.LoadingOverlay('hide');
      });

      $('#buttonExcelGrade').on('click', async function () {
        const dados = $("#tabelaGradeOF").DataTable().data().toArray();
        await exportaCSV("", "", undefined, null, `Relatório da Grade da OF: ${numero}`, '', '', 999, false, false, dados);
      });

      $('#tabelaGradeOF').DataTable().columns().every(
        function () {
          if ((colunasInvisiveis.acessoMovimentacaoFaccaoGrade).indexOf(this.dataSrc()) != -1) {
            this.visible(false);
          }
        }
      );

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

  $("#divSetores").addClass('d-none')

  $('#tabGrade').on('click', async function () {
    $('#divSetores').addClass('d-none')
    $('#divGrade').removeClass('d-none')
  })

  $('#tabSetores').on('click', async function () {
    $('#divGrade').addClass('d-none')
    $('#divSetores').removeClass('d-none')
  })

  $('#tabGrade').trigger('click')
  $('#tabSetores').trigger('click')
});