package br.com.centralit.citcorpore.integracao;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import br.com.centralit.citcorpore.bean.BaseConhecimentoDTO;
import br.com.centralit.citcorpore.bean.PesquisaRequisicaoMudancaDTO;
import br.com.centralit.citcorpore.bean.RequisicaoMudancaDTO;
import br.com.centralit.citcorpore.util.CITCorporeUtil;
import br.com.centralit.citcorpore.util.Enumerados.ChangeRequestStatus;
import br.com.citframework.dto.IDto;
import br.com.citframework.excecao.PersistenceException;
import br.com.citframework.integracao.Condition;
import br.com.citframework.integracao.CrudDaoDefaultImpl;
import br.com.citframework.integracao.Field;
import br.com.citframework.integracao.Order;
import br.com.citframework.util.Constantes;
import br.com.citframework.util.SQLConfig;
import br.com.citframework.util.UtilDatas;
import br.com.citframework.util.UtilNumbersAndDecimals;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class RequisicaoMudancaDao extends CrudDaoDefaultImpl {

	public RequisicaoMudancaDao() {
		super(Constantes.getValue("DATABASE_ALIAS"), null);
	}

	/**
	 * Desenvolvedor: ibimon.morais - Data: 17/08/2015 - Horário: 10:52 - ID
	 * Citsmart: 176362 - Motivo/Comentário: Possibilitara geração dos
	 * relatórios do Citsmart através do dataSsource passado por parâmetro para
	 * o DAO, citsmart_reports, por exemplo.
	 */
	public RequisicaoMudancaDao(final String aliasDataBase) {
		super(aliasDataBase, null);
	}

	@Override
	public Collection<Field> getFields() {
		Collection<Field> listFields = new ArrayList<>();
		listFields.add(new Field("idrequisicaomudanca", "idRequisicaoMudanca", true, true, false, false));
		listFields.add(new Field("idproprietario", "idProprietario", false, false, false, false));
		listFields.add(new Field("idsolicitante", "idSolicitante", false, false, false, false));
		// /listFields.add(new Field("tipo", "tipo", false, false, false, false));
		// listFields.add(new Field("idcategoriamudanca", "idCategoriaMudanca", false, false, false, false));
		listFields.add(new Field("idtipomudanca", "idTipoMudanca", false, false, false, false));
		listFields.add(new Field("motivo", "motivo", false, false, false, false));
		listFields.add(new Field("nivelimportancianegocio", "nivelImportanciaNegocio", false, false, false, false));
		listFields.add(new Field("classificacao", "classificacao", false, false, false, false));
		listFields.add(new Field("nivelimpacto", "nivelImpacto", false, false, false, false));
		listFields.add(new Field("analiseimpacto", "analiseImpacto", false, false, false, false));
		listFields.add(new Field("razaoMudanca", "razaoMudanca", false, false, false, false));
		listFields.add(new Field("datahoraconclusao", "dataHoraConclusao", false, false, false, false));
		listFields.add(new Field("dataaceitacao", "dataAceitacao", false, false, false, false));
		listFields.add(new Field("datavotacao", "dataVotacao", false, false, false, false));
		listFields.add(new Field("datahorainicio", "dataHoraInicio", false, false, false, false));
		listFields.add(new Field("datahoratermino", "dataHoraTermino", false, false, false, false));
		listFields.add(new Field("titulo", "titulo", false, false, false, false));
		listFields.add(new Field("descricao", "descricao", false, false, false, false));
		listFields.add(new Field("risco", "risco", false, false, false, false));
		listFields.add(new Field("estimativacusto", "estimativaCusto", false, false, false, false));
		listFields.add(new Field("planoreversao", "planoReversao", false, false, false, false));
		listFields.add(new Field("idStatus", "idStatus", false, false, false, false));
		listFields.add(new Field("prioridade", "prioridade", false, false, false, false));
		listFields.add(new Field("nomecategoriamudanca", "nomeCategoriaMudanca", false, false, false, false));
		listFields.add(new Field("enviaemailcriacao", "enviaEmailCriacao", false, false, false, false));
		listFields.add(new Field("enviaemailfinalizacao", "enviaEmailFinalizacao", false, false, false, false));
		listFields.add(new Field("enviaemailacoes", "enviaEmailAcoes", false, false, false, false));
		listFields.add(new Field("exibirquadromudancas", "exibirQuadroMudancas", false, false, false, false));
		listFields.add(new Field("seqreabertura", "seqReabertura", false, false, false, false));
		listFields.add(new Field("tempodecorridohh", "tempoDecorridoHH", false, false, false, false));
		listFields.add(new Field("tempodecorridomm", "tempoDecorridoMM", false, false, false, false));
		listFields.add(new Field("datahorasuspensao", "dataHoraSuspensao", false, false, false, false));
		listFields.add(new Field("datahorareativacao", "dataHoraReativacao", false, false, false, false));
		listFields.add(new Field("prazohh", "prazoHH", false, false, false, false));
		listFields.add(new Field("prazomm", "prazoMM", false, false, false, false));
		listFields.add(new Field("idgrupoatual", "idGrupoAtual", false, false, false, false));
		listFields.add(new Field("idgruponivel1", "idGrupoNivel1", false, false, false, false));
		listFields.add(new Field("idcalendario", "idCalendario", false, false, false, false));
		listFields.add(new Field("datahoracaptura", "dataHoraCaptura", false, false, false, false));
		listFields.add(new Field("tempocapturahh", "tempoCapturaHH", false, false, false, false));
		listFields.add(new Field("tempocapturamm", "tempoCapturaMM", false, false, false, false));
		listFields.add(new Field("tempoatrasohh", "tempoAtrasoHH", false, false, false, false));
		listFields.add(new Field("tempoatrasomm", "tempoAtrasoMM", false, false, false, false));
		listFields.add(new Field("tempoatendimentohh", "tempoAtendimentoHH", false, false, false, false));
		listFields.add(new Field("tempoatendimentomm", "tempoAtendimentoMM", false, false, false, false));
		listFields.add(new Field("idPhase", "idPhase", false, false, false, false));
		listFields.add(new Field("nivelurgencia", "nivelUrgencia", false, false, false, false));
		listFields.add(new Field("idbaseconhecimento", "idBaseConhecimento", false, false, false, false));
		listFields.add(new Field("idcontrato", "idContrato", false, false, false, false));
		listFields.add(new Field("idGrupoComite", "idGrupoComite", false, false, false, false));
		listFields.add(new Field("idunidade", "idUnidade", false, false, false, false));
		listFields.add(new Field("idcontatorequisicaomudanca", "idContatoRequisicaoMudanca", false, false, false, false));
		listFields.add(new Field("enviaEmailGrupoComite", "enviaEmailGrupoComite", false, false, false, false));
		listFields.add(new Field("datahorainicioagendada", "dataHoraInicioAgendada", false, false, false, false));
		listFields.add(new Field("datahoraterminoagendada", "dataHoraTerminoAgendada", false, false, false, false));
		listFields.add(new Field("idlocalidade", "IdLocalidade", false, false, false, false));
		listFields.add(new Field("fechamento", "fechamento", false, false, false, false));
		listFields.add(new Field("ehPropostaAux", "ehPropostaAux", false, false, false, false));
		listFields.add(new Field("votacaoPropostaAprovadaAux", "votacaoPropostaAprovadaAux", false, false, false, false));
		listFields.add(new Field("idGrupoAtvPeriodica", "idGrupoAtvPeriodica", false, false, false, false));
		listFields.add(new Field("idcategoriasolucao", "idCategoriaSolucao", false, false, false, false));
		listFields.add(new Field("fecharItensRelacionados", "fecharItensRelacionados", false, false, false, false));
		listFields.add(new Field("vencendo", "vencendo", false, false, false, false));
		listFields.add(new Field("votacaoRequisicaoAprovadaAux", "votacaoRequisicaoAprovadaAux", false, false, false, false));

		return listFields;
	}

	@Override
	public String getTableName() {
		return this.getOwner() + "requisicaomudanca";
	}

	@Override
	public Class getBean() {
		return RequisicaoMudancaDTO.class;
	}

	@Override
	public Collection find(IDto solicitacaoServicoDTO) throws PersistenceException {
		List ordenacao = new ArrayList();
		ordenacao.add(new Order("idRequisicaoMudanca"));
		return super.find(solicitacaoServicoDTO, ordenacao);
	}

	@Override
	public void updateNotNull(IDto obj) throws PersistenceException {
		super.updateNotNull(obj);
	}

	@Override
	public Collection list() throws PersistenceException {
		return super.list("idRequisicaoMudanca");
	}

	public void updateFase(Integer idRequisicao, Integer idPhase) {
		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE " + getTableName() + " SET idPhase = ? WHERE (idrequisicaomudanca = ?)");
		Object[] params = { idPhase, idRequisicao };
		try {
			this.execUpdate(sql.toString(), params);
		} catch (PersistenceException e) {
			System.out.println("Problemas com atualização da requisição de mudança.");
			e.printStackTrace();
		}
	}

	public List<RequisicaoMudancaDTO> listMudancaByIdSolicitacao(RequisicaoMudancaDTO bean) throws Exception {
		List parametro = new ArrayList();
		List fields = new ArrayList();
		List list = new ArrayList();
		StringBuilder sql = new StringBuilder();
		sql.append(" select distinct  sol.idSolicitacaoServico, ser.nomeServico  from requisicaomudanca  mud ");
		sql.append(" inner join solicitacaoservicomudanca solmud on solmud.idrequisicaoMudanca = mud.idrequisicaoMudanca ");
		sql.append(" inner join solicitacaoservico sol on sol.idsolicitacaoservico = solmud.idsolicitacaoservico ");
		sql.append(" inner join servicocontrato sercont on  sol.idservicocontrato =  sercont.idservicocontrato ");
		sql.append(" inner join servico ser on ser.idservico = sercont.idservico ");

		if (bean != null) {
			if (bean.getIdSolicitacaoServico() != null) {
				sql.append("and sol.idSolicitacaoServico = ? ");
				parametro.add(bean.getIdSolicitacaoServico());
			}
		}

		if (bean != null) {
			if (bean.getIdRequisicaoMudanca() != null) {
				sql.append("and mud.idrequisicaomudanca = ? ");
				parametro.add(bean.getIdRequisicaoMudanca());
			}
		}

		list = this.execSQL(sql.toString(), parametro.toArray());
		fields.add("idSolicitacaoServico");
		fields.add("nomeServico");

		if (list != null && !list.isEmpty()) {
			return this.listConvertion(getBean(), list, fields);
		} else {
			return null;
		}
	}

	public Collection findByIdRequisicaoMudancaEDataFim(Integer idRequisicaoMudanca) throws Exception {
		List parametro = new ArrayList();
		List fields = new ArrayList();
		List list = new ArrayList();
		StringBuilder sql =  new StringBuilder();
		sql.append("select mud.idrequisicaomudanca,  sol.idSolicitacaoServico, ser.nomeServico ");
		sql.append("from requisicaomudanca  mud ");
		sql.append("inner join solicitacaoservicomudanca solmud on solmud.idrequisicaoMudanca = mud.idrequisicaoMudanca ");
		sql.append("inner join solicitacaoservico sol on sol.idsolicitacaoservico = solmud.idsolicitacaoservico ");
		sql.append("inner join servicocontrato sercont on  sol.idservicocontrato =  sercont.idservicocontrato ");
		sql.append("inner join servico ser on ser.idservico = sercont.idservico and mud.idrequisicaomudanca = ? and idhistoricomudanca is null ");

		parametro.add(idRequisicaoMudanca);
		list = this.execSQL(sql.toString(), parametro.toArray());
		fields.add("idRequisicaoMudanca");
		fields.add("idSolicitacaoServico");
		fields.add("nomeServico");
		if (list != null && !list.isEmpty()) {
			return this.listConvertion(getBean(), list, fields);
		} else {
			return null;
		}
	}

	public List<RequisicaoMudancaDTO> listProblemaByIdSolicitacao(RequisicaoMudancaDTO bean) throws Exception {
		List parametro = new ArrayList();
		List fields = new ArrayList();
		List list = new ArrayList();
		String sql = " select  mud.idrequisicaomudanca , mud.titulo, empcriadopor.nome, empmudpri.nome, mud.idStatus, sol.idSolicitacaoServico, ser.nomeServico  from requisicaomudanca  mud  "
				+ "	inner join  empregados empcriadopor on mud.idsolicitante = empcriadopor.idempregado  " + "	inner join  empregados empmudpri on mud.idproprietario = empmudpri.idempregado  "
				+ "	inner join solicitacaoservicomudanca solmud on solmud.idrequisicaoMudanca = mud.idrequisicaoMudanca  "
				+ "	inner join solicitacaoservico sol on sol.idsolicitacaoservico = solmud.idsolicitacaoservico  "
				+ "	inner join servicocontrato sercont on  sol.idservicocontrato =  sercont.idservicocontrato  " + "	inner join servico ser on ser.idservico = sercont.idservico  ";

		if (bean != null) {
			if (bean.getIdSolicitacaoServico() != null) {
				sql += "and sol.idSolicitacaoServico = ? ";
				parametro.add(bean.getIdSolicitacaoServico());
			}
		}

		if (bean != null) {
			if (bean.getIdRequisicaoMudanca() != null) {
				sql += "and mud.idrequisicaomudanca = ? ";
				parametro.add(bean.getIdRequisicaoMudanca());
			}
		}

		list = this.execSQL(sql, parametro.toArray());
		fields.add("idRequisicaoMudanca");
		fields.add("titulo");
		fields.add("nomeSolicitante");
		fields.add("nomeProprietario");
		fields.add("idStatus");
		fields.add("idSolicitacaoServico");
		fields.add("nomeServico");

		if (list != null && !list.isEmpty()) {
			return this.listConvertion(getBean(), list, fields);
		} else {
			return null;
		}
	}

	public List<RequisicaoMudancaDTO> listMudancaByIdItemConfiguracao(Integer idItemConfiguracao) throws Exception {

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT mud.idrequisicaomudanca, mud.titulo, mud.descricao , mud.idproprietario, mud.idsolicitante, ");
		sql.append(" mud.nivelimpacto, mud.idtipomudanca, mud.motivo, mud.prioridade, mud.idStatus, tm.nometipomudanca, emp.nome, us.nome, mud.dataHoraInicio ");
		sql.append(" FROM requisicaomudancaitemconfiguracao reqconf ");
		sql.append(" INNER JOIN  requisicaomudanca mud ON reqconf.idrequisicaomudanca = mud.idrequisicaomudanca ");
		sql.append(" INNER JOIN itemconfiguracao item ON item.iditemconfiguracao = reqconf.iditemconfiguracao ");
		sql.append(" INNER JOIN empregados emp ON emp.idempregado = mud.idsolicitante ");
		sql.append(" INNER JOIN usuario us ON us.idusuario = mud.idproprietario ");
		sql.append(" INNER JOIN tipomudanca tm ON tm.idtipomudanca = mud.idtipomudanca ");
		sql.append(" WHERE item.iditemconfiguracao = ? ");
		sql.append(" AND reqconf.datafim is null ");

		/**
		 * A regra relacionada ao idStatus estava comentada
		 *
		 * @author flavio.santana
		 * 25/10/2013 14:00
		 */
		List parametro = new ArrayList();
		List retorno = new ArrayList();
		List<String> listRetorno = new ArrayList<String>();
		parametro.add(idItemConfiguracao);

		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("descricao");
		listRetorno.add("idProprietario");
		listRetorno.add("idSolicitante");
		listRetorno.add("nivelImpacto");
		listRetorno.add("idTipoMudanca");
		listRetorno.add("motivo");
		listRetorno.add("prioridade");
		listRetorno.add("idStatus");
		// listRetorno.add("tipo");
		listRetorno.add("nomeTipoMudanca");
		listRetorno.add("nomeSolicitante");
		listRetorno.add("nomeProprietario");
		listRetorno.add("dataHoraInicio");

		List lista = this.execSQL(sql.toString(), parametro.toArray());
		retorno = this.engine.listConvertion(getBean(), lista, listRetorno);

		return retorno;
	}

	public Integer listQuantidadeMudancaByIdItemConfiguracao(Integer idItemConfiguracao) throws Exception {
		String sql = " select count(*) quantidade " + " from requisicaomudancaitemconfiguracao reqconf "
				+ " inner join  requisicaomudanca mud on reqconf.idrequisicaomudanca = mud.idrequisicaomudanca "
				+ " inner join itemconfiguracao item on item.iditemconfiguracao = reqconf.iditemconfiguracao " + " inner join empregados emp on emp.idempregado = mud.idsolicitante "
				+ " inner join usuario us on us.idusuario = mud.idproprietario " + " where item.iditemconfiguracao = ?  and reqconf.datafim is null";

		List parametro = new ArrayList();
		parametro.add(idItemConfiguracao);

		List<String> listRetorno = new ArrayList<String>();
		listRetorno.add("quantidade");

		List lista = this.execSQL(sql, parametro.toArray());

		List<RequisicaoMudancaDTO> retorno = this.engine.listConvertion(getBean(), lista, listRetorno);

		if (retorno != null && !retorno.isEmpty()) {
			RequisicaoMudancaDTO requisicaoMudancaDTO = retorno.get(0);
			return requisicaoMudancaDTO.getQuantidade();
		}
		return 0;
	}

	public Collection<RequisicaoMudancaDTO> listaMudancasPorBaseConhecimento(RequisicaoMudancaDTO mudanca) throws Exception {

		StringBuilder sql = new StringBuilder();
		List parametro = new ArrayList();
		List listRetorno = new ArrayList();

		sql.append("SELECT rm.idrequisicaomudanca, rm.tipo, rm.motivo, rm.descricao, rm.risco, rm.idStatus, ");
		sql.append("rm.planoreversao, rm.datahorainicio, rm.datahoraconclusao, e.nome FROM requisicaomudanca rm, empregados e ");
		sql.append("WHERE rm.idproprietario = e.idempregado AND rm.idbaseconhecimento = ? ");

		parametro.add(mudanca.getIdBaseConhecimento());

		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("tipo");
		listRetorno.add("motivo");
		listRetorno.add("descricao");
		listRetorno.add("risco");
		listRetorno.add("idStatus");
		listRetorno.add("planoReversao");
		listRetorno.add("dataHoraInicio");
		listRetorno.add("dataHoraConclusao");
		listRetorno.add("nomeProprietario");

		List list = execSQL(sql.toString(), parametro.toArray());

		if (list != null && !list.isEmpty()) {
			Collection<RequisicaoMudancaDTO> listaMudancaPorBaseConhecimento = this.listConvertion(RequisicaoMudancaDTO.class, list, listRetorno);
			return listaMudancaPorBaseConhecimento;
		}

		return null;
	}

	public Collection<RequisicaoMudancaDTO> quantidadeMudancaPorBaseConhecimento(RequisicaoMudancaDTO mudanca) throws Exception {

		StringBuilder sql = new StringBuilder();
		List parametro = new ArrayList();
		List listRetorno = new ArrayList();

		sql.append("select idbaseconhecimento,count(idbaseconhecimento) from requisicaomudanca where idbaseconhecimento = ? group by idbaseconhecimento");

		parametro.add(mudanca.getIdBaseConhecimento());
		listRetorno.add("idBaseConhecimento");
		listRetorno.add("quantidade");

		List list = execSQL(sql.toString(), parametro.toArray());
		if (list != null && !list.isEmpty()) {
			Collection<RequisicaoMudancaDTO> listaQuantidadeMudancaPorBaseConhecimento = this.listConvertion(RequisicaoMudancaDTO.class, list, listRetorno);
			return listaQuantidadeMudancaPorBaseConhecimento;
		}
		return null;
	}

	/**
	 * Retorna Requisições de Mudança associadas a Base de Conhecimento.
	 *
	 * @param baseConhecimentoDto
	 * @return List<RequisicaoMudancaDTO>
	 * @throws Exception
	 * @author Vadoilo Damasceno
	 */
	public List<RequisicaoMudancaDTO> findByConhecimento(BaseConhecimentoDTO baseConhecimentoDto) throws Exception {
		List parametro = new ArrayList();
		List listRetorno = new ArrayList();
		List list = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append(
				"select requisicaomudanca.idRequisicaoMudanca, requisicaomudanca.titulo, requisicaomudanca.tipo, requisicaomudanca.motivo, requisicaomudanca.descricao, requisicaomudanca.risco, requisicaomudanca.idStatus from requisicaomudanca requisicaomudanca ");
		sql.append("inner join mudancabaseconhecimento mudancabaseconhecimento on requisicaomudanca.idRequisicaoMudanca = mudancabaseconhecimento.idrequisicaomudanca ");
		sql.append("where mudancabaseconhecimento.idbaseconhecimento = ? ");

		parametro.add(baseConhecimentoDto.getIdBaseConhecimento());

		list = this.execSQL(sql.toString(), parametro.toArray());

		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("tipo");
		listRetorno.add("motivo");
		listRetorno.add("descricao");
		listRetorno.add("risco");
		listRetorno.add("idStatus");

		if (list != null && !list.isEmpty()) {

			return this.listConvertion(getBean(), list, listRetorno);

		} else {

			return null;
		}
	}

	public List<RequisicaoMudancaDTO> findByPeriodoAndSituacao(Date dataInicial, Date dataFinal, Integer idStatus) throws Exception {
        List parametro = new ArrayList();
        List listRetorno = new ArrayList();
        List list = new ArrayList();
        StringBuilder sql = new StringBuilder();

		sql.append("SELECT idRequisicaoMudanca, titulo, dataHoraInicio, dataHoraConclusao, descricao, risco, idStatus FROM requisicaomudanca ");
        sql.append("WHERE dataHoraInicio BETWEEN ? AND ? ");
        parametro.add(Timestamp.valueOf(UtilDatas.dateToSTRWithFormat(dataInicial, "yyyy-MM-dd") + " 00:00:00"));
        parametro.add(Timestamp.valueOf(UtilDatas.dateToSTRWithFormat(dataFinal, "yyyy-MM-dd") + " 23:59:59"));

		if (!UtilNumbersAndDecimals.isNullOrZeroOrEmpty(idStatus)) {
			sql.append("AND idStatus = ? ");
			parametro.add(idStatus);
		}

        sql.append("ORDER BY idRequisicaoMudanca");

        list = this.execSQL(sql.toString(), parametro.toArray());

        listRetorno.add("idRequisicaoMudanca");
        listRetorno.add("titulo");
        listRetorno.add("dataHoraInicio");
        listRetorno.add("dataHoraConclusao");
        listRetorno.add("descricao");
        listRetorno.add("risco");
		listRetorno.add("idStatus");

        if (list != null && !list.isEmpty()) {
            return this.listConvertion(getBean(), list, listRetorno);
        } else {
            return null;
        }
    }

	/**
	 * Retorna uma lista de requisicao mudanca de acordo com os criterios passados.
	 *
	 * @param requisicaoMudancaDto
	 * @return Collection<RequisicaoMudancaDTO>
	 * @throws Exception
	 * @author thays.araujo
	 * @author bruno.franco
	 */
	public Collection<PesquisaRequisicaoMudancaDTO> listRequisicaoMudancaByCriterios(PesquisaRequisicaoMudancaDTO pesquisaRequisicaoMudancaDto) throws Exception {

		List parametro = new ArrayList();
		List listRetorno = new ArrayList();
		List list = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("SELECT requisicaomudanca.idrequisicaomudanca,tipomudanca.nometipomudanca,requisicaomudanca.idStatus,requisicaomudanca.titulo,")
				.append("requisicaomudanca.motivo, requisicaomudanca.datahoraconclusao,")
				.append("requisicaomudanca.datahorainicio,requisicaomudanca.datahoratermino, requisicaomudanca.descricao,")
				.append("proprietario.nome, solicitante.nome, requisicaomudanca.nomecategoriamudanca, grupo.nome,")
				.append("requisicaomudanca.idcontrato, requisicaomudanca.fechamento,")
				.append("itf.iditemtrabalho as idtarefa,ef.nome AS nometarefa ")
			.append("FROM ").append(getTableName()).append(" ")
			.append("inner join empregados as proprietario on proprietario.idempregado = requisicaomudanca.idproprietario ")
			.append("inner join empregados as solicitante on solicitante.idempregado = requisicaomudanca.idsolicitante ")
			.append("inner join grupo on grupo.idgrupo = requisicaomudanca.idgrupoatual ")
			.append("inner join tipomudanca on tipomudanca.idtipomudanca = requisicaomudanca.idtipomudanca ");

		/*
		 * euler.ramos f_execucao_mudanca - Função no banco de dados
		 * responsável por retornar uma lista de requisições de mudança e seus
		 * respectivos itens de trabalho correspondentes: todos os itens em
		 * execução ou o último item de trabalho executado, que é o responsável
		 * pela definição do status atual da requisição. 
		 * Teremos duplicidade na listagem apenas quando existirem mais de um 
		 * item de trabalho ainda em execução.
		 */
		sql.append("JOIN ");
		if (CITCorporeUtil.SGBD_PRINCIPAL.trim().toUpperCase().equalsIgnoreCase(SQLConfig.ORACLE)) {
			sql.append("table(");
		}

		sql.append("f_execucao_mudanca(?,?,?,?)");

		if (CITCorporeUtil.SGBD_PRINCIPAL.trim().toUpperCase().equalsIgnoreCase(SQLConfig.ORACLE)) {
			sql.append(")");
		}
		sql.append(" f ON f.idrequisicaomudanca=requisicaomudanca.idrequisicaomudanca ");
		if (pesquisaRequisicaoMudancaDto.getDataInicio() != null && pesquisaRequisicaoMudancaDto.getDataFim() != null) {
			parametro.add("A");
			parametro.add(UtilDatas.getSqlDate(pesquisaRequisicaoMudancaDto.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(pesquisaRequisicaoMudancaDto.getDataFim()));
		} else {
			if (pesquisaRequisicaoMudancaDto.getDataHoraConclusao() != null
					&& pesquisaRequisicaoMudancaDto.getDataHoraConclusao() != null) {
				parametro.add("F");
				parametro.add(UtilDatas.getSqlDate(pesquisaRequisicaoMudancaDto.getDataHoraConclusao()));
				parametro.add(
						UtilDatas.getTimeStampComUltimaHoraDoDia(pesquisaRequisicaoMudancaDto.getDataHoraConclusao()));
			} else {
				parametro.add(null);
				parametro.add(null);
				parametro.add(null);
			}
		}
		if (pesquisaRequisicaoMudancaDto.getIdRequisicaoMudanca() != null) {
			parametro.add(pesquisaRequisicaoMudancaDto.getIdRequisicaoMudanca());
		} else {
			parametro.add(null);
		}

		sql.append("inner join bpm_itemtrabalhofluxo itf on f.iditemtrabalho = itf.iditemtrabalho ")
			.append("inner join bpm_elementofluxo ef ON itf.idelemento = ef.idelemento ");

		if (pesquisaRequisicaoMudancaDto.getIdItemConfiguracao() != null) {
			sql.append("join (select distinct idrequisicaomudanca from requisicaomudancaitemconfiguracao where requisicaomudancaitemconfiguracao.iditemconfiguracao = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdItemConfiguracao());
			sql.append("AND requisicaomudancaitemconfiguracao.datafim IS NULL) ");
			sql.append("ritcfg on requisicaomudanca.idrequisicaomudanca = ritcfg.idrequisicaomudanca ");
		}

		StringBuilder sqlWhere = new StringBuilder();
		
		if(pesquisaRequisicaoMudancaDto.getDataInicio() != null && pesquisaRequisicaoMudancaDto.getDataFim() != null){
			sqlWhere.append(" requisicaomudanca.datahorainicio BETWEEN ? and ? ");
		parametro.add(UtilDatas.getSqlDate(pesquisaRequisicaoMudancaDto.getDataInicio()));
		parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(pesquisaRequisicaoMudancaDto.getDataFim()));
		}

		if (pesquisaRequisicaoMudancaDto.getIdRequisicaoMudanca() != null) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.idrequisicaomudanca = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdRequisicaoMudanca());
		}
		
		if (!UtilNumbersAndDecimals.isNullOrZeroOrEmpty(pesquisaRequisicaoMudancaDto.getIdStatus())) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.idStatus = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdStatus());
		}

		if (pesquisaRequisicaoMudancaDto.getIdSolicitante() != null) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.idsolicitante = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdSolicitante());
		}
		if (pesquisaRequisicaoMudancaDto.getIdProprietario() != null) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.idproprietario = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdProprietario());
		}
		if (pesquisaRequisicaoMudancaDto.getIdGrupoAtual() != null) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.idgrupoatual = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdGrupoAtual());
		}
		if (pesquisaRequisicaoMudancaDto.getIdTipoMudanca() != null) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" tipomudanca.idtipomudanca = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getIdTipoMudanca());
		}

		if (pesquisaRequisicaoMudancaDto.getNomeCategoriaMudanca() != null && !pesquisaRequisicaoMudancaDto.getNomeCategoriaMudanca().equalsIgnoreCase("")) {
			sqlWhere.append(verificaSeExisteFiltroInformado(sqlWhere));
			sqlWhere.append(" requisicaomudanca.nomecategoriamudanca = ? ");
			parametro.add(pesquisaRequisicaoMudancaDto.getNomeCategoriaMudanca());
		}

		sql.append(" where ").append(sqlWhere);
		
		if (pesquisaRequisicaoMudancaDto.getOrdenacao() != null) {
			sql.append("ORDER BY " + pesquisaRequisicaoMudancaDto.getOrdenacao());
		}

		list = this.execSQL(sql.toString(), parametro.toArray());

		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("tipo");
		listRetorno.add("idStatus");
		listRetorno.add("titulo");
		listRetorno.add("motivo");
		listRetorno.add("dataHoraConclusao");
		listRetorno.add("dataHoraInicio");
		listRetorno.add("dataHoraTermino");
		listRetorno.add("descricao");
		listRetorno.add("nomeProprietario");
		listRetorno.add("nomeSolicitante");
		listRetorno.add("nomeCategoriaMudanca");
		listRetorno.add("nomeGrupoAtual");
		listRetorno.add("idContrato");
		listRetorno.add("fechamento");
		listRetorno.add("idTarefa");
		listRetorno.add("nomeTarefa");

		if (list != null && !list.isEmpty()) {
			Collection<PesquisaRequisicaoMudancaDTO> listRequisicaoMudancaByCriterios = this.listConvertion(PesquisaRequisicaoMudancaDTO.class, list, listRetorno);
			return listRequisicaoMudancaByCriterios;
		}
		return null;
	}

	/**
	 * Retorna uma lista de requisicao mudança associados a um tipo mudança
	 *
	 * @param idCargo
	 * @return
	 * @throws Exception
	 * @author thays.araujo
	 */
	public boolean verificarSeRequisicaoMudancaPossuiTipoMudanca(Integer idTipoMudanca) throws Exception {
		List parametro = new ArrayList();
		String sql = "select idrequisicaomudanca from " + getTableName() + " where idtipomudanca = ? ";
		parametro.add(idTipoMudanca);
		List lista = this.execSQL(sql.toString(), parametro.toArray());
		if (lista != null && !lista.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	public RequisicaoMudancaDTO findByIdInstanciaFluxo(Integer idInstanciaFluxo) throws Exception {
		List condicao = new ArrayList();
		condicao.add(new Condition("idInstanciaFluxo", "=", idInstanciaFluxo));

		Collection col = super.findByCondition(condicao, null);
		if (col == null || col.size() == 0) {
			return null;
		}
		return (RequisicaoMudancaDTO) ((List) col).get(0);
	}

	public Collection listaIdETituloMudancasPorPeriodo(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("       requisicaomudanca.titulo ");
		sql.append("from requisicaomudanca ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by requisicaomudanca.idrequisicaomudanca,requisicaomudanca.titulo ");
		sql.append("order by requisicaomudanca.idrequisicaomudanca,requisicaomudanca.titulo ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaMudancaIncidente(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("       requisicaomudanca.titulo mudanca, ");
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.POSTGRESQL) || CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.SQLSERVER)) {
			sql.append("   cast(solicitacaoservico.idsolicitacaoservico as varchar) incidente ");
		} else {
			sql.append("   solicitacaoservico.idsolicitacaoservico incidente ");
		}
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join solicitacaoservicomudanca solicitacaoservicomudanca ");
		sql.append("	  on solicitacaoservicomudanca.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
		sql.append("inner join solicitacaoservico solicitacaoservico  ");
		sql.append("      on solicitacaoservico.idsolicitacaoservico = solicitacaoservicomudanca.idsolicitacaoservico ");
		sql.append("inner join tipodemandaservico tipodemandaservico  ");
		sql.append("      on tipodemandaservico.idtipodemandaservico = solicitacaoservico.idtipodemandaservico ");
		sql.append("         and tipodemandaservico.classificacao = 'I' ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("order by requisicaomudanca.idrequisicaomudanca ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("incidente");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaMudancaServico(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("       requisicaomudanca.titulo mudanca, ");
		sql.append("       servico.nomeservico servico ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join requisicaomudancaservico requisicaomudancaservico ");
		sql.append("       on requisicaomudancaservico.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
		sql.append("inner join servico servico ");
		sql.append("       on servico.idservico = requisicaomudancaservico.idservico ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("order by requisicaomudanca.idrequisicaomudanca ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("servico");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaMudancaProblema(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("       requisicaomudanca.titulo mudanca, ");
		sql.append("	   problema.titulo problema ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join problemamudanca problemamudanca ");
		sql.append("       on problemamudanca.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
		sql.append("inner join problema problema ");
		sql.append("      on problema.idproblema = problemamudanca.idproblema ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("problema");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaMudancaConhecimento(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("      requisicaomudanca.titulo mudanca, ");
		sql.append("      baseconhecimento.titulo conhecimento ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join baseconhecimento baseconhecimento ");
		sql.append("       on baseconhecimento.idbaseconhecimento = requisicaomudanca.idbaseconhecimento ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("conhecimento");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaMudancaItemConfiguracao(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idrequisicaomudanca, ");
		sql.append("       requisicaomudanca.titulo mudanca, ");
		sql.append("       itemconfiguracao.identificacao itemconfigucacao ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join requisicaomudancaitemconfiguracao requisicaomudancaitemconfiguracao ");
		sql.append("       on requisicaomudancaitemconfiguracao.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
		sql.append("inner join itemconfiguracao itemconfiguracao ");
		sql.append("       on itemconfiguracao.iditemconfiguracao = requisicaomudancaitemconfiguracao.iditemconfiguracao ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("titulo");
		listRetorno.add("itemConfiguracao");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	public Collection listaQuantidadeMudancaPorPeriodo(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {

		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorPeriodo = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("quantidadeMudancaPorPeriodo");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorPeriodo = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorPeriodo;
	}

	public Collection listaQuantidadeMudancaPorSolicitante(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorSolicitante = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select empregados.nome, count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join empregados empregados on empregados.idempregado = requisicaomudanca.idsolicitante ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by empregados.nome");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("nomeSolicitante");
		listRetorno.add("quantidadeSolicitante");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorSolicitante = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorSolicitante;
	}

	public Collection listaQuantidadeMudancaPorImpacto(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorImpacto = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.nivelimpacto, count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by requisicaomudanca.nivelimpacto");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("nivelImpacto");
		listRetorno.add("quantidadeImpacto");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorImpacto = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorImpacto;
	}

	public Collection listaQuantidadeMudancaPorUrgencia(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorImpacto = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.nivelurgencia, count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by requisicaomudanca.nivelurgencia");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("nivelUrgencia");
		listRetorno.add("quantidadeUrgencia");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorImpacto = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorImpacto;
	}

	public Collection listaQuantidadeSemAprovacaoPorPeriodo(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorImpacto = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("SELECT COUNT(DISTINCT idrequisicaomudanca) ");
		sql.append("FROM requisicaomudanca ");
		sql.append("WHERE datahorainicio BETWEEN ? AND ? ");
		sql.append("AND idrequisicaomudanca NOT IN(");
		sql.append("SELECT DISTINCT idrequisicaomudanca ");
		sql.append("FROM   aprovacaomudanca )");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("quantidadeMudancaSemAprovacaoPorPeriodo");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorImpacto = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorImpacto;
	}

	public Collection listaQuantidadeMudancaPorProprietario(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorProprietario = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select empregados.nome, count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("inner join empregados empregados on empregados.idempregado = requisicaomudanca.idproprietario ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by empregados.nome");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("nomeProprietario");
		listRetorno.add("quantidadeProprietario");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorProprietario = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorProprietario;
	}

	public Collection listaQuantidadeMudancaPorStatus(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listaQuantidadeMudancaPorStatus = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select requisicaomudanca.idStatus, count(*) ");
		sql.append("from requisicaomudanca requisicaomudanca ");
		sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");
		sql.append("group by requisicaomudanca.idStatus");

		parametro.add(requisicaoMudancaDTO.getDataInicio());
		if (CITCorporeUtil.SGBD_PRINCIPAL.toUpperCase().equals(SQLConfig.ORACLE)) {
			parametro.add(requisicaoMudancaDTO.getDataFim());
		} else {
			parametro.add(transformaHoraFinal(requisicaoMudancaDTO.getDataFim()));
		}

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("idStatus");
		listRetorno.add("quantidadeStatus");
		if (lista != null && !lista.isEmpty()) {
			listaQuantidadeMudancaPorStatus = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listaQuantidadeMudancaPorStatus;
	}

	public Collection listaMudancaGrupo(RequisicaoMudancaDTO requisicaoMudancaDTO) throws Exception {
		List listRetorno = new ArrayList();
		List parametro = new ArrayList();
		List listResultado = new ArrayList();
		StringBuilder sql = new StringBuilder();

		sql.append("select grupo.idgrupo, ");
		sql.append(" grupo.nome grupo ");
		sql.append(" from requisicaomudanca requisicaomudanca ");
		sql.append(" inner join gruporequisicaomudanca grupomudanca ");
	    sql.append(" on grupomudanca.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
	    sql.append(" inner join grupo grupo ");
	    sql.append(" on grupo.idgrupo = grupomudanca.idgrupo ");
	    sql.append(" where grupomudanca.idrequisicaomudanca=? ");

		parametro.add(requisicaoMudancaDTO.getIdRequisicaoMudanca());

		List lista = new ArrayList();
		lista = this.execSQL(sql.toString(), parametro.toArray());
		listRetorno.add("grupo");
		if (lista != null && !lista.isEmpty()) {
			listResultado = this.engine.listConvertion(RequisicaoMudancaDTO.class, lista, listRetorno);
		}
		return listResultado;
	}

	private Timestamp transformaHoraFinal(Date data) throws ParseException {
		String dataHora = data + " 23:59:59";
		String pattern = "yyyy-MM-dd hh:mm:ss";
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		java.util.Date d = sdf.parse(dataHora);
		java.sql.Timestamp sqlDate = new java.sql.Timestamp(d.getTime());
		return sqlDate;
	}

	public Collection listSolicitacoesByRegra() throws Exception {
		List listRetorno = new ArrayList();
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT distinct (s.idrequisicaomudanca), "
		 + " s.prioridade, s.datahoratermino,  regra1.idcontrato as idcontrato, regra3.idsolicitante as idsolicitante,  "
		 + " regra4.idgrupo as idgrupo, s.vencendo, s.datahorainicio, s.prazohh, s.prazomm, s.nivelimpacto, s.nivelurgencia  "
		 + " FROM requisicaomudanca s   "
		 + " INNER JOIN contratos contratos on contratos.idcontrato = s.idcontrato "
		 + " INNER JOIN empregados solicitante on solicitante.idempregado = s.idsolicitante "
		 + " LEFT JOIN grupo grupo on grupo.idgrupo = s.idgrupoatual "
		 + " LEFT JOIN regraescalonamento regra1 on regra1.idcontrato = contratos.idcontrato "
		 + " LEFT JOIN regraescalonamento regra3 on regra3.idsolicitante = solicitante.idempregado "
		 + " LEFT JOIN regraescalonamento regra4 on regra4.idgrupo = grupo.idgrupo  "
				+ " WHERE s.idStatus not in (?, ?, ?, ?) ");

		List parametro = new ArrayList<>();
		parametro.add(ChangeRequestStatus.CANCELED.getId());
		parametro.add(ChangeRequestStatus.SOLVED.getId());
		parametro.add(ChangeRequestStatus.SUSPENDED.getId());
		parametro.add(ChangeRequestStatus.CONCLUDED.getId());

		listRetorno.add("idRequisicaoMudanca");
		listRetorno.add("prioridade");
		listRetorno.add("dataHoraTermino");
		listRetorno.add("idContrato");
		listRetorno.add("idSolicitante");
		listRetorno.add("idGrupo");
		listRetorno.add("vencendo");
		listRetorno.add("dataHoraInicio");
		listRetorno.add("prazoHH");
		listRetorno.add("prazoMM");
		listRetorno.add("nivelImpacto");
		listRetorno.add("nivelUrgencia");

		List list = this.execSQL(sql.toString(), parametro.toArray());
		if (list != null && !list.isEmpty()) {
			return this.listConvertion(getBean(), list, listRetorno);
		} else {
			return null;
		}
	}

	public ArrayList<RequisicaoMudancaDTO> listaQuantidadeERelacionamentos(RequisicaoMudancaDTO requisicaoMudancaDTO) {
		List result;
		try {
			List resp = new ArrayList();
            final List parametro = new ArrayList();
            final List listRetorno = new ArrayList();

			listRetorno.add("idRequisicaoMudanca");
			listRetorno.add("titulo");
			listRetorno.add("incidente");
			listRetorno.add("servico");
			listRetorno.add("problema");
			listRetorno.add("conhecimento");
			listRetorno.add("itemConfiguracao");

            final StringBuilder sql = new StringBuilder();
			sql.append("select requisicaomudanca.idrequisicaomudanca, requisicaomudanca.titulo, incidente, servico, problema, conhecimento, itemconfiguracao ");

			sql.append("from requisicaomudanca left join ");

			sql.append("(SELECT solicitacaoservicomudanca.idrequisicaomudanca,");
			sql.append("count(solicitacaoservicomudanca.idsolicitacaoservico) as incidente ");
			sql.append("FROM requisicaomudanca requisicaomudanca ");
			sql.append("INNER JOIN solicitacaoservicomudanca ON solicitacaoservicomudanca.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
			sql.append("INNER JOIN solicitacaoservico ON solicitacaoservico.idsolicitacaoservico = solicitacaoservicomudanca.idsolicitacaoservico ");
			sql.append("INNER JOIN tipodemandaservico ON tipodemandaservico.idtipodemandaservico = solicitacaoservico.idtipodemandaservico AND tipodemandaservico.classificacao = 'I' ");
			sql.append("WHERE  requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("group by solicitacaoservicomudanca.idrequisicaomudanca) as incidentes on requisicaomudanca.idrequisicaomudanca = incidentes.idrequisicaomudanca ");

			sql.append("left join ");
			sql.append("(select requisicaomudancaservico.idrequisicaomudanca,count(requisicaomudancaservico.idservico) servico ");
			sql.append("from requisicaomudanca join requisicaomudancaservico on requisicaomudancaservico.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
			sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("group by requisicaomudancaservico.idrequisicaomudanca) servicos on requisicaomudanca.idrequisicaomudanca = servicos.idrequisicaomudanca ");

			sql.append("left join ");
			sql.append("(select problemamudanca.idrequisicaomudanca, count(problemamudanca.idproblema) problema ");
			sql.append("from requisicaomudanca join problemamudanca on problemamudanca.idrequisicaomudanca = requisicaomudanca.idrequisicaomudanca ");
			sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("group by problemamudanca.idrequisicaomudanca) problemas on requisicaomudanca.idrequisicaomudanca = problemas.idrequisicaomudanca ");

			sql.append("left join ");
			sql.append("(select requisicaomudanca.idrequisicaomudanca, count(mudancabaseconhecimento.idbaseconhecimento) conhecimento ");
			sql.append("from requisicaomudanca join mudancabaseconhecimento  on requisicaomudanca.idrequisicaomudanca = mudancabaseconhecimento.idrequisicaomudanca  ");
			sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("group by requisicaomudanca.idrequisicaomudanca) basesconhecimento on requisicaomudanca.idrequisicaomudanca = basesconhecimento.idrequisicaomudanca  ");

			sql.append("left join ");
			sql.append("(select requisicaomudancaitemconfiguracao.idrequisicaomudanca, count(requisicaomudancaitemconfiguracao.iditemconfiguracao) itemconfiguracao ");
			sql.append("from requisicaomudanca join requisicaomudancaitemconfiguracao on requisicaomudanca.idrequisicaomudanca = requisicaomudancaitemconfiguracao.idrequisicaomudanca ");
			sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("group by requisicaomudancaitemconfiguracao.idrequisicaomudanca) itensconfig on requisicaomudanca.idrequisicaomudanca = itensconfig.idrequisicaomudanca ");

			sql.append("where requisicaomudanca.datahorainicio BETWEEN ? AND ? ");

			parametro.add(UtilDatas.getSqlDate(requisicaoMudancaDTO.getDataInicio()));
			parametro.add(UtilDatas.getTimeStampComUltimaHoraDoDia(requisicaoMudancaDTO.getDataFim()));

			sql.append("order by requisicaomudanca.idrequisicaomudanca,requisicaomudanca.titulo");

			resp = this.execSQL(sql.toString(), parametro.toArray());
            result = engine.listConvertion(this.getBean(), resp, listRetorno);
        } catch (final PersistenceException e) {
			e.printStackTrace();
			result = null;
        } catch (final Exception e) {
			e.printStackTrace();
			result = null;
		}
        return (ArrayList<RequisicaoMudancaDTO>) (result == null || result.size() <= 0 ? new ArrayList<RequisicaoMudancaDTO>() : result);
	}

	private StringBuilder verificaSeExisteFiltroInformado(StringBuilder sql){
		StringBuilder and = new StringBuilder();
		if(sql != null && sql.length() > 0){
			and.append(" and ");
		}
		return and; 
	}

}