$("#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 () {
  let idTabela;
  const permissaoUsuarioLogado = await permissaoAcessos("MOVIMENTACAOFACCAO");
  MontaPesquisa();

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

  $('#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;
      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;
        }
      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 url = '/sisplan/movimentacaofaccao/v1/movimentacaofaccao?';
      const filtros = await retornaFiltros();
      const response = await requisicao('GET', url, filtros, 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;
      }
      const colunasItens = [
        { title: "Número", data: "NUMERO" },
        { title: "Código", data: "CODIGO" },
        { title: "Descrição", data: "DESCRICAO" },
        { title: "Data Cad.", data: "DATA_CAD" },
        { title: "Data Iníc.", data: "DT_INICIO" },
        { title: "Data Final", data: "DT_FINAL" },
        { title: "Programação", data: "PROGRAMACAO" },
        { title: "Pedido", data: "PEDIDO" },
        { title: "Cód. Cli.", data: "CODCLI" },
        { title: "Nome", data: "NOME" },
        { title: "Setor Pend.", data: "SETOR_PEND" },
        { title: "Observação", data: "OBSERVACAO" }
      ];

      $('#tabelaOrdemProducao').DataTable({
        searching: true,
        paging: true,
        filter: false,
        order: [],
        sort: true,
        destroy: true,
        scrollY: '33vh',
        scrollX: true,
        autoWidth: true,
        data: jsonStr,
        columns: colunasItens,
        colReorder: true,
        columnDefs: [{
          targets: [0], render: function (data, type, row) {
            return retornaBotaoOpcoes(data);
          }
        },
        {
          targets: [10],
          render: function (data, type, row) {
            return `<span style="text-wrap: nowrap;color: #75BE25">${data}</span>`
          }
        },
        {
          "type": 'date-br',
          "targets": [3, 4, 5],
          "render": function (data) {
            if (data != undefined) {
              x = data.slice(0, 10).split('-');
              return `${x[2]}/${x[1]}/${x[0]}`;
            } else {
              return ''
            }
          }
        }]
      });

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

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


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

  $('#tabelaOrdemProducao').on('click', 'td', async function () {
    await buscaPartes();
  });

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

  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 Saldo", data: "saldo" },
          { title: "Reprocesso", data: "reprocesso" },
          { title: "Reprocessado", data: "reprocessado" },
          { title: "Tempo Gasto", data: "tempoGasto" },
        ];

        $('#tabelaResumo').DataTable({
          searching: false,
          paging: true,
          filter: false,
          order: [],
          sort: true,
          destroy: true,
          colReorder: true,
          scrollY: '31vh',
          scrollX: true,
          createdRow: function (row, data, dataIndex) {
            if (data.cor === 'verde') {
              $('td', row).css('color', '#75BE25')
            } else if (data.cor === 'vermelho') {
              $('td', row).css('color', 'red')
            } else if (data.cor === 'azul') {
              $('td', row).css('color', '#2195f0')
            }
          },
          autoWidth: true,
          data: jsonStr,
          columns: colunasItens,
          columnDefs: [{
            targets: 0,
          },
          {
            "targets": [2, 3, 4, 5, 6, 7],
            "className": 'pr-4 text-right'
          }]
        });
      }

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

      if (!response) {
        return;
      }

      const jsonStr = await response.json();

      if (jsonStr.length == 0) {
        if (estorno) {
          msgAlerta('Nenhum registro encontrado!');
        }
        $("#labelSelecionarTodos").addClass("d-none");
        return;
      } else {
        $("#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: '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!");
      }

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

  function retornaBotaoOpcoes(data) {
    var 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" 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" disabled title="Impr. Etq. Composição" id="btnImprimirEtiqueta">Impr. Etq. Composição</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>';
    return retorno;
  };

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

  function abreRelatorioEtqComposicao(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}/reletiquetacomposicao/`, btoa(jsonTag))

    } catch (error) {

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

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

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

  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: function (row, data, index) {
        $(`td:eq(0)`, row).css("display", "flex");

        if (data._rowId === rowIdSelecionado) {
          $(row).addClass('selected');
        }
      },
      initComplete: function () {
        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();
      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"));
  })

  $("#txtOFEstorno").on("focusout", async function () {
    if ($(this).val() != "") {
      const ordemProd = {};
      ordemProd.NUMERO = pegaChave(this);
      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 () {
    if ($(this).prop("checked")) {
      $('.campoSelEstorno:not(:checked)').trigger("click");
      $("#checkSelecionarTodosSetor").prop('checked', false);
      $("#checkSelecionarTodosCor").prop('checked', false);
    } else {
      $('.campoSelEstorno:checked').trigger("click");
    }
  })

  $("#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 tabela = $("#tabelaEstornar").DataTable().data().toArray();

      tabela.forEach((item, index) => {
        if (item.SETOR == registro[0].SETOR) {
          $(`#checkEstorno${index}`).prop('checked', true);
          $(`#checkEstorno${index}`).closest("tr").addClass("selected");
        }
      });

      $("#checkSelecionarTodos").prop('checked', false);
      $("#checkSelecionarTodosCor").prop('checked', false);
    } else {
      const registro = $("#tabelaEstornar").DataTable().data().toArray();
      registro.forEach((item, index) => {
        $(`#checkEstorno${index}`).prop('checked', false);
        $(`#checkEstorno${index}`).closest("tr").removeClass("selected");
      });
    }
  })

  $("#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 tabela = $("#tabelaEstornar").DataTable().data().toArray();

      tabela.forEach((item, index) => {
        if (item.COR == registro[0].COR) {
          $(`#checkEstorno${index}`).prop('checked', true);
          $(`#checkEstorno${index}`).closest("tr").addClass("selected");
        }
      });
      $("#checkSelecionarTodosSetor").prop('checked', false);
      $("#checkSelecionarTodos").prop('checked', false);
    } else {
      const registro = $("#tabelaEstornar").DataTable().data().toArray();
      registro.forEach((item, index) => {
        $(`#checkEstorno${index}`).prop('checked', false);
        $(`#checkEstorno${index}`).closest("tr").removeClass("selected");
      });
    }
  })

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

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

  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"]}`, '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"]}`, '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');
  }

  $("#btnLimpaOFEstorno").on('click', function () {
    $('#txtOFEstorno').val('');
  });

  $("#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 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());
    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') {
      let data = $('#tabelaOrdemProducao').DataTable().row($(registro).parents('tr')).data();
      let registroLiberado = await verificarRegistro('NUMERO', data.NUMERO);
      if (registroLiberado) {
        window.location.href = `movimentacaofaccao/${data.NUMERO}`;
      }
    } else {
      msgAlertaSemConfirmacao("Sem permissão para movimentar!");
    }
  }

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

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