/**
 * 
 */
package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioAcompanhamentoEquivalenteBean;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

/**
 * @author Bruno H. G. Gouvêa <bruno@rjconsultores.com.br>
 * 
 */
public class RelatorioAcompanhamentoEquivalentes extends Relatorio {

	private static final Integer CEM = Integer.valueOf(100);
	private static final Integer DECIMAL = Integer.valueOf(4);
	private static String CONSTANTE_GRATUIDADE_CRIANCA;

	enum IndicadorRelatorio {

		MPE(1), RECEITA_KM(2), RECEITA_VIAGEM(3), IAP(4), PAXKM(5), ABSOLUTO(6), EQ(7);

		public final int valor;

		IndicadorRelatorio(int valorOpcao) {
			valor = valorOpcao;
		}

		public static IndicadorRelatorio fromInt(Integer value) {
			if (value != null) {
				for (IndicadorRelatorio b : IndicadorRelatorio.values()) {
					if (value.equals(b.valor)) {
						return b;
					}
				}
			}
			return null;
		}
	}

	/**
	 * @param parametros
	 * @param conexao
	 * @throws Exception
	 */
	public RelatorioAcompanhamentoEquivalentes(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new ArrayDataSource(this) {

			protected void prepareQuery() throws SQLException {

				CONSTANTE_GRATUIDADE_CRIANCA = buscarConstante("GRATUIDADE_CRIANCA");

				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				String sql = getSql();
				
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				if (parametros.get("EMPRESA_ID") != null)
					stmt.setInt("EMPRESA_ID", (Integer) parametros.get("EMPRESA_ID"));
				else
					stmt.setNull("EMPRESA_ID", java.sql.Types.INTEGER);

				if (parametros.get("TIPOSERVICIO_ID") != null)
					stmt.setInt("TIPOSERVICIO_ID", (Integer) parametros.get("TIPOSERVICIO_ID"));
				else
					stmt.setNull("TIPOSERVICIO_ID", java.sql.Types.INTEGER);

				stmt.setDate("DATA_MES", new java.sql.Date(((Date) parametros.get("DATA_MES")).getTime()));

				this.resultSet = stmt.executeQuery();
			}

			private boolean verificaTipoServicoExtra(String tipoServico) {
				if (StringUtils.equalsIgnoreCase(tipoServico, "Extra")) {
					return true;
				}
				return false;
			}

			@Override
			public void initDados() throws Exception {

				this.prepareQuery();

				Date dataInicial = (Date) this.relatorio.getParametros().get("DATA_MES");

				while (this.resultSet.next()) {

					Integer indicador = (Integer) this.relatorio.getParametros().get("INDICADOR");
					Integer rolOperativoId = this.resultSet.getInt("ROLOPERATIVO_ID");
					Integer corridaId = this.resultSet.getInt("CORRIDA_ID");
					Integer assentos = this.resultSet.getInt("ASSENTOS");
					Integer rutaId = this.resultSet.getInt("RUTA_ID");

					String horario = this.resultSet.getString("HORARIO");
					boolean isServicoExtra = verificaTipoServicoExtra(this.resultSet.getString("TIPO_SERVICO"));

					Map<String, Object> row = new HashMap<String, Object>();
					BigDecimal totalMes = BigDecimal.ZERO;
					Integer totalDias = 0;

					Calendar cal = Calendar.getInstance();
					cal.setTime(dataInicial);
					cal.set(Calendar.DATE, 1);

					List<RelatorioAcompanhamentoEquivalenteBean> ls = getValorByIndicador(corridaId, rolOperativoId, indicador, assentos, dataInicial, rutaId, horario, isServicoExtra);

					// Roda todos os dias do mes
					for (int dia = 1; dia <= cal.getActualMaximum(Calendar.DATE); dia++) {

						BigDecimal valor = null;
						RelatorioAcompanhamentoEquivalenteBean equivalenteBean = buscarAcompanhamentoEquivalente(ls, cal.getTime());

						if (equivalenteBean != null) {
							valor = equivalenteBean.getValor();
						}

						if (valor != null) {
							totalMes = totalMes.add(valor);
							totalDias++;
						}

						if (valor != null) {
							row.put("LINHA", this.resultSet.getString("SIGLA"));
							row.put("LOTACAO", this.resultSet.getInt("ASSENTOS"));
							row.put("SERVICO", this.resultSet.getString("TIPO_SERVICO"));
							row.put("CODIGO", this.resultSet.getInt("CORRIDA_ID"));
							row.put("HORARIO", this.resultSet.getString("HORARIO"));
							row.put("INTERESTADUAL", this.resultSet.getString("INTERESTADUAL"));
							row.put("GRUPO_LINHA", this.resultSet.getString("GRUPO_LINHA"));

							row.put(String.valueOf(cal.get(Calendar.DATE)), valor);
						}

						if (cal.get(Calendar.DATE) < cal.getActualMaximum(Calendar.DATE))
							cal.add(Calendar.DATE, 1);
					}

					if (totalMes != null && !totalMes.equals(BigDecimal.ZERO) && totalDias > 0) {
						row.put("MEDIA", totalMes.divide(BigDecimal.valueOf(totalDias), 4, RoundingMode.HALF_UP));
						this.dados.add(row);
					}
				}

			}

			protected List<RelatorioAcompanhamentoEquivalenteBean> getValorByIndicador(Integer corridaId,
					Integer rolOperativoId, Integer indicador, Integer assentos, Date dataInicial,
					Integer rutaId, String horario, boolean isServicoExtra) throws SQLException {

				String sql = null;

				switch (IndicadorRelatorio.fromInt(indicador)) {
				case MPE:
					sql = getSqlIndicadorEquivalentes(isServicoExtra);
					break;
				case ABSOLUTO:
					sql = getSqlIndicadorAbsoluto(isServicoExtra);
					break;
				case EQ:
					sql = getSqlIndicadorEq(isServicoExtra);
					break;
				case IAP:
					sql = getSqlIndicadorIap(isServicoExtra);
					System.out.println(sql);
					break;
				case PAXKM:
					sql = getSqlIndicadorPax(isServicoExtra);
					break;
				case RECEITA_KM:
					sql = getSqlIndicadorReceitaKm(isServicoExtra);
					break;
				case RECEITA_VIAGEM:
					sql = getSqlIndicadorReceitaViagem(isServicoExtra);
					break;
				}

				return getListaValoresIndicadores(corridaId, rolOperativoId, indicador, assentos, sql, dataInicial, rutaId, horario);
			}

		});
	}

	protected List<RelatorioAcompanhamentoEquivalenteBean> getListaValoresIndicadores(Integer corridaId, Integer rolOperativoId,
			Integer indicador, Integer assentos, String sql, Date dataInicial, Integer rutaId, String horario) throws SQLException {

		List<RelatorioAcompanhamentoEquivalenteBean> lsEquivalente = new ArrayList<RelatorioAcompanhamentoEquivalenteBean>();
		try {

			Connection conexao = this.getConexao();

			NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

			stmt.setInt("CORRIDA_ID", corridaId);
			stmt.setDate("DATA_MES", new java.sql.Date(dataInicial.getTime()));
			stmt.setInt("ROLOPERATIVO_ID", rolOperativoId);
			stmt.setInt("RUTA_ID", rutaId);
			stmt.setString("HORARIO", horario);

			if (IndicadorRelatorio.fromInt(indicador).equals(IndicadorRelatorio.IAP)) {
				stmt.setInt("CAPACIDADE", assentos);
				stmt.setInt("CEM", CEM);
				stmt.setInt("DECIMAL", DECIMAL);
			}

			ResultSet resultSet = stmt.executeQuery();
			while (resultSet.next()) {
				RelatorioAcompanhamentoEquivalenteBean equivalenteBean = new RelatorioAcompanhamentoEquivalenteBean();
				equivalenteBean.setValor(resultSet.getBigDecimal("VALOR"));
				equivalenteBean.setCorridaId(resultSet.getInt("CORRIDA_ID"));
				equivalenteBean.setFeccorrida(resultSet.getDate("FECCORRIDA"));
				lsEquivalente.add(equivalenteBean);
			}

			resultSet.close();
			stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return lsEquivalente;
	}

	protected RelatorioAcompanhamentoEquivalenteBean buscarAcompanhamentoEquivalente(List<RelatorioAcompanhamentoEquivalenteBean> ls, Date data) {

		for (RelatorioAcompanhamentoEquivalenteBean equivalente : ls) {
			if (equivalente.getFeccorrida().equals(data))
				return equivalente;
		}
		return null;
	}

	protected String getSqlIndicadorEq(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("ROUND((EQ.VALOR / TARIFA), 0) AS VALOR, ");
		sql.append("EQ.CORRIDA_ID AS CORRIDA_ID, ");
		sql.append("EQ.FECCORRIDA AS FECCORRIDA ");
		sql.append("FROM ");
		sql.append("       (SELECT ");
		sql.append("            SUM(BO.PRECIOPAGADO + BO.IMPORTEPEDAGIO + BO.IMPORTESEGURO + BO.IMPORTETAXAEMBARQUE) AS VALOR, ");
		sql.append("            BO.CORRIDA_ID, ");
		sql.append("            BO.FECCORRIDA, ");
		sql.append("            (SELECT ");
		sql.append("                    TF.PRECIO ");
		sql.append("                FROM ");
		sql.append("                    CORRIDA CR, ");
		sql.append("                    TRAMO TR, ");
		sql.append("                    TARIFA TF, ");
		sql.append("                    VIGENCIA_TARIFA VT ");
		sql.append("                WHERE ");
		sql.append("                    CR.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("                AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("                AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? " AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("                AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("                AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("                AND TF.CLASESERVICIO_ID = CR.CLASESERVICIO_ID ");
		sql.append("                AND TF.MARCA_ID = CR.MARCA_ID ");
		sql.append("                AND TF.RUTA_ID = CR.RUTA_ID ");
		sql.append("                AND TF.TRAMO_ID = TR.TRAMO_ID ");
		sql.append("                AND TF.STATUSTARIFA = 'A' ");
		sql.append("                AND CR.ACTIVO <> 0 ");
		sql.append("                AND TF.ACTIVO = 1 ");
		sql.append("                AND TR.ORIGEN_ID = CR.ORIGEN_ID ");
		sql.append("                AND TR.DESTINO_ID = CR.DESTINO_ID ");
		sql.append("                AND TF.VIGENCIATARIFA_ID = VT.VIGENCIATARIFA_ID ");
		sql.append("                AND VT.ACTIVO = 1 ");
		sql.append("                AND CR.FECCORRIDA BETWEEN VT.FECINICIOVIGENCIA AND VT.FECFINVIGENCIA ");
		sql.append("                GROUP BY TF.PRECIO) TARIFA ");
		sql.append("        FROM ");
		sql.append("            BOLETO BO ");
		sql.append("            INNER JOIN CORRIDA CR ON ");
		sql.append("                    CR.CORRIDA_ID = BO.CORRIDA_ID AND CR.FECCORRIDA = BO.FECCORRIDA ");
		sql.append("        WHERE ");
		sql.append("            BO.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("        AND TO_CHAR(BO.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("        AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("        AND CR.ACTIVO <> 0 ");
		sql.append("        AND BO.ACTIVO = 1 ");
		sql.append("        AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("        AND BO.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("        OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("        GROUP BY ");
		sql.append("            BO.CORRIDA_ID, ");
		sql.append("            BO.FECCORRIDA) EQ ");
		sql.append("ORDER BY EQ.FECCORRIDA");

		return sql.toString();
	}

	protected String getSqlIndicadorPax(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("    SUM(BO.NUMKMVIAJE) AS VALOR, ");
		sql.append("    CR.CORRIDA_ID AS CORRIDA_ID, ");
		sql.append("    CR.FECCORRIDA AS FECCORRIDA ");
		sql.append("FROM ");
		sql.append("    CORRIDA CR ");
		sql.append("    INNER JOIN BOLETO BO ON  BO.CORRIDA_ID = CR.CORRIDA_ID AND BO.FECCORRIDA = CR.FECCORRIDA ");
		sql.append("WHERE ");
		sql.append("    CR.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("AND BO.ACTIVO = 1 ");
		sql.append("AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("AND BO.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("GROUP BY CR.CORRIDA_ID, CR.FECCORRIDA ");
		sql.append("ORDER BY CR.FECCORRIDA");

		return sql.toString();

	}
	
	protected String getSqlIndicadorIap(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("        COALESCE(ROUND(SUM(:CEM * (( EQUIVALENTE * EXTENSAO_LINHA ) / ");
		sql.append("        ( :CAPACIDADE * EXTENSAO_LINHA ))), :DECIMAL ), 0) AS VALOR, ");
		sql.append("        FINAL_TAV.CORRIDA_ID, FINAL_TAV.FECCORRIDA ");
		sql.append("FROM ");
		sql.append("    (SELECT ");
		sql.append("        ROUND(SUM(TAV.EQ), :DECIMAL) EQUIVALENTE, TAV.EL EXTENSAO_LINHA, TAV.CORRIDA_ID, TAV.FECCORRIDA ");
		sql.append("        FROM ");
		sql.append("            (SELECT ");
		sql.append("                ROUND(( BO.NUMKMVIAJE / ( EXTENSAO_LINHA.EL ) * COUNT(BO.BOLETO_ID) ), :DECIMAL) EQ, ");
		sql.append("                        EXTENSAO_LINHA.EL EL, C.CORRIDA_ID, C.FECCORRIDA ");
		
		sql.append("                FROM CORRIDA C ");
		sql.append("                LEFT JOIN BOLETO BO ON ((BO.MOTIVOCANCELACION_ID IS NULL OR  BO.MOTIVOCANCELACION_ID = 0 ) ");
		sql.append("                              AND C.CORRIDA_ID = BO.CORRIDA_ID AND C.FECCORRIDA = BO.FECCORRIDA ");
		sql.append("                AND BO.CATEGORIA_ID <> ").append(CONSTANTE_GRATUIDADE_CRIANCA).append(" ), ") ;
		sql.append("            (SELECT SUM(TR1.CANTKMREAL) EL, ");
		sql.append("                    CR.CORRIDA_ID, ");
		sql.append("                    CR.FECCORRIDA, ");
		sql.append("                    CR.ROLOPERATIVO_ID ");
		sql.append("             FROM CORRIDA CR ");
		sql.append("            		  INNER JOIN RUTA_COMBINACION RS ON RS.RUTA_ID = CR.RUTA_ID ");
		sql.append("            		  INNER JOIN TRAMO TR1 ON TR1.TRAMO_ID = RS.TRAMO_ID ");
		sql.append("            		                       AND (TR1.ORIGEN_ID = CR.ORIGEN_ID AND TR1.DESTINO_ID = CR.DESTINO_ID) ");
		sql.append("            		  WHERE CR.ACTIVO = 1 AND RS.ACTIVO = 1 AND TR1.ACTIVO = 1 ");
		sql.append("             GROUP BY CR.CORRIDA_ID, CR.FECCORRIDA, CR.ROLOPERATIVO_ID) EXTENSAO_LINHA ");
		sql.append("                WHERE C.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("                AND TO_CHAR(C.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("                AND EXTENSAO_LINHA.CORRIDA_ID = C.CORRIDA_ID ");
		sql.append("                AND EXTENSAO_LINHA.FECCORRIDA = C.FECCORRIDA ");
		sql.append("                AND EXTENSAO_LINHA.ROLOPERATIVO_ID = C.ROLOPERATIVO_ID ");
		sql.append("                AND C.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("                AND TO_CHAR(C.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? " AND C.TIPOSERVICIO_ID = 2 " : " AND C.TIPOSERVICIO_ID <> 2 ");
		sql.append("                AND C.RUTA_ID = :RUTA_ID ");
		sql.append("                AND C.ACTIVO = 1 ");
		sql.append("                GROUP BY BO.NUMKMVIAJE, EXTENSAO_LINHA.EL, C.CORRIDA_ID, C.FECCORRIDA) TAV ");
		sql.append("        GROUP BY EQ, TAV.EL, TAV.CORRIDA_ID, TAV.FECCORRIDA ) FINAL_TAV ");
		sql.append("GROUP BY FINAL_TAV.CORRIDA_ID, FINAL_TAV.FECCORRIDA ");
		sql.append("ORDER BY FINAL_TAV.FECCORRIDA");

		return sql.toString();

	}
	
	protected String getSqlIndicadorReceitaKm(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("COALESCE((SUB_REC.RECEITA/SUB_REC.KM), 0) AS VALOR, ");
		sql.append("SUB_REC.CORRIDA_ID AS CORRIDA_ID, ");
		sql.append("SUB_REC.FECCORRIDA AS FECCORRIDA ");
		sql.append("FROM ");
		sql.append("        (SELECT ");
		sql.append("        SUM(BO.PRECIOPAGADO) AS RECEITA, ");
		sql.append("        SUB_KM.KM, ");
		sql.append("        CR.CORRIDA_ID, ");
		sql.append("        CR.FECCORRIDA ");
		sql.append("        FROM CORRIDA CR ");
		sql.append("        LEFT JOIN BOLETO BO ON (CR.CORRIDA_ID = BO.CORRIDA_ID AND CR.FECCORRIDA = BO.FECCORRIDA ");
		sql.append("                    AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("                    AND BO.MOTIVOCANCELACION_ID IS NULL OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("                    AND BO.CATEGORIA_ID <> ").append(CONSTANTE_GRATUIDADE_CRIANCA).append(") ");
		sql.append("        INNER JOIN (SELECT SUM(TR1.CANTKMREAL) KM, CR.CORRIDA_ID, CR.FECCORRIDA ");
		sql.append("                    FROM CORRIDA CR ");
		sql.append("                    INNER JOIN RUTA_COMBINACION RS ON RS.RUTA_ID = CR.RUTA_ID ");
		sql.append("                    INNER JOIN TRAMO TR1 ON TR1.TRAMO_ID = RS.TRAMO_ID  ");
		sql.append("                                     AND (TR1.ORIGEN_ID = CR.ORIGEN_ID AND TR1.DESTINO_ID = CR.DESTINO_ID)");
		sql.append("                    WHERE CR.ACTIVO = 1 AND RS.ACTIVO = 1 AND TR1.ACTIVO = 1 ");
		sql.append("                    AND CR.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("                    AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("                    AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "   AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("                    AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("                    AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("                    GROUP BY CR.CORRIDA_ID, CR.FECCORRIDA ");
		sql.append("        )SUB_KM ON SUB_KM.CORRIDA_ID = CR.CORRIDA_ID AND SUB_KM.FECCORRIDA = CR.FECCORRIDA ");
		sql.append("        WHERE CR.ACTIVO = 1 ");
		sql.append("        AND CR.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("        AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("        AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? " AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("        AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("        AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("        GROUP BY CR.CORRIDA_ID, CR.FECCORRIDA, SUB_KM.KM ");
		sql.append("        ) SUB_REC  ");
		sql.append("ORDER BY SUB_REC.FECCORRIDA ");

		return sql.toString();
	}

	protected String getSqlIndicadorReceitaViagem(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("    SUM(BO.PRECIOPAGADO + BO.IMPORTEPEDAGIO + BO.IMPORTESEGURO + BO.IMPORTETAXAEMBARQUE) AS VALOR, ");
		sql.append("    BO.CORRIDA_ID AS CORRIDA_ID, ");
		sql.append("    BO.FECCORRIDA AS FECCORRIDA ");
		sql.append("FROM BOLETO BO ");
		sql.append("INNER JOIN CORRIDA CR ON CR.CORRIDA_ID = BO.CORRIDA_ID AND CR.FECCORRIDA = BO.FECCORRIDA ");
		sql.append("WHERE ");
		sql.append("    BO.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("AND TO_CHAR(BO.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("AND BO.ACTIVO = 1 ");
		sql.append("AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("AND BO.MOTIVOCANCELACION_ID IS NULL OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("GROUP BY BO.CORRIDA_ID, BO.FECCORRIDA ");
		sql.append("ORDER BY BO.FECCORRIDA");

		return sql.toString();
	}

	protected String getSqlIndicadorEquivalentes(boolean isServicoExtra) {

		/* O calculo do MPE não leva em consideração a quantidade de viagens conforme formula, uma vez que o detalhemtno do relatório já é por viagem */
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("    SUM(BO.NUMKMVIAJE/EL.EXTENSAO_LINHA) AS VALOR, ");
		sql.append("    EL.CORRIDA_ID AS CORRIDA_ID, ");
		sql.append("    EL.FECCORRIDA AS FECCORRIDA ");
		sql.append("FROM ");
		sql.append("    CORRIDA CR ");
		sql.append("INNER JOIN ");
		sql.append("    BOLETO BO ");
		sql.append("ON ");
		sql.append("    BO.CORRIDA_ID = CR.CORRIDA_ID ");
		sql.append("AND BO.FECCORRIDA = CR.FECCORRIDA ");
		sql.append("INNER JOIN ");
		sql.append("    ( ");
		sql.append("        SELECT ");
		sql.append("            SUM(TR1.CANTKMREAL) EXTENSAO_LINHA, ");
		sql.append("            CT1.CORRIDA_ID, ");
		sql.append("            CT1.FECCORRIDA ");
		sql.append("        FROM ");
		sql.append("            CORRIDA_TRAMO CT1 ");
		sql.append("        INNER JOIN ");
		sql.append("            TRAMO TR1 ");
		sql.append("        ON ");
		sql.append("            TR1.TRAMO_ID = CT1.TRAMO_ID ");
		sql.append("        INNER JOIN ");
		sql.append("            CORRIDA CR ");
		sql.append("        ON ");
		sql.append("            CR.FECCORRIDA = CT1.FECCORRIDA ");
		sql.append("        AND CR.CORRIDA_ID = CT1.CORRIDA_ID ");
		sql.append("  WHERE CT1.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("    AND TO_CHAR(CT1.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("    AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID   ");
		sql.append("    AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("    AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("        GROUP BY ");
		sql.append("            CT1.CORRIDA_ID, ");
		sql.append("            CT1.FECCORRIDA, CR.ROLOPERATIVO_ID) EL ");
		sql.append("ON (EL.CORRIDA_ID = CR.CORRIDA_ID AND EL.FECCORRIDA = CR.FECCORRIDA) ");
		sql.append("  WHERE CR.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("    AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("    AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID   ");
		sql.append("    AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("    AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("AND BO.ACTIVO = 1 ");
		sql.append("AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("AND BO.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("GROUP BY ");
		sql.append("    EL.EXTENSAO_LINHA, ");
		sql.append("    EL.CORRIDA_ID, ");
		sql.append("    EL.FECCORRIDA ");
		sql.append("ORDER BY ");
		sql.append("    EL.FECCORRIDA");

		return sql.toString();

	}

	protected String getSqlIndicadorAbsoluto(boolean isServicoExtra) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("    COUNT(1) AS VALOR, ");
		sql.append("    CR.CORRIDA_ID, ");
		sql.append("    CR.FECCORRIDA ");
		sql.append("FROM BOLETO BO ");
		sql.append("INNER JOIN CORRIDA CR ON CR.CORRIDA_ID = BO.CORRIDA_ID AND CR.FECCORRIDA = BO.FECCORRIDA ");
		sql.append("WHERE ");
		sql.append("    BO.CORRIDA_ID = :CORRIDA_ID ");
		sql.append("AND TO_CHAR(BO.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("AND TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') = TO_CHAR(TO_DATE(:HORARIO, 'HH24:MI'), 'HH24:MI') ");
		sql.append(isServicoExtra ? "AND CR.TIPOSERVICIO_ID = 2 " : " AND CR.TIPOSERVICIO_ID <> 2 ");
		sql.append("AND CR.RUTA_ID = :RUTA_ID ");
		sql.append("AND CR.ROLOPERATIVO_ID = :ROLOPERATIVO_ID ");
		sql.append("AND BO.ACTIVO = 1 ");
		sql.append("AND BO.INDSTATUSOPERACION = 'F' ");
		sql.append("AND BO.MOTIVOCANCELACION_ID IS NULL OR  BO.MOTIVOCANCELACION_ID = 0 ");
		sql.append("GROUP BY CR.CORRIDA_ID, CR.FECCORRIDA ");
		sql.append("ORDER BY CR.FECCORRIDA");

		return sql.toString();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio#processaParametros()
	 */
	@Override
	public void processaParametros() throws Exception {
	}

	private String getSql() {

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT DISTINCT RT.RUTA_ID, ");
		sql.append("                 CR.CORRIDA_ID, ");
		sql.append("                 RT.DESCRUTA, ");
		sql.append("                 DA.CANTASIENTOS ASSENTOS, ");
		sql.append("                 PO.CVEPARADA||' - '||PD.CVEPARADA SIGLA, ");
		sql.append("                 TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') HORARIO,  ");
		sql.append("                 CR.ROLOPERATIVO_ID, ");
		sql.append("                 CASE ");
		sql.append("                   WHEN CO.ESTADO_ID <> CD.ESTADO_ID THEN ");
		sql.append("                    'S' ");
		sql.append("                   ELSE ");
		sql.append("                    'N' ");
		sql.append("                 END INTERESTADUAL, ");
		sql.append("                 NVL(GR.DESCGRUPO, 'Não Definido') GRUPO_LINHA, ");
		sql.append("                 (CASE ");
		sql.append("                   WHEN CR.TIPOSERVICIO_ID = 2 THEN ");
		sql.append("                    'Extra' ");
		sql.append("                   ELSE ");
		sql.append("                    NULL ");
		sql.append("                 END) TIPO_SERVICO ");
		sql.append("  ");
		sql.append("   FROM RUTA             RT, ");
		sql.append("        CORRIDA          CR, ");
		sql.append("        TRAMO            TR, ");
		sql.append("        ROL_OPERATIVO    RO, ");
		sql.append("        DIAGRAMA_AUTOBUS DA, ");
		sql.append("        GRUPO_RUTA       GR, ");
		sql.append("        PARADA           PO, ");
		sql.append("        PARADA           PD, ");
		sql.append("        CIUDAD           CO, ");
		sql.append("        CIUDAD           CD ");
		sql.append("  WHERE RT.RUTA_ID = CR.RUTA_ID ");
		sql.append("    AND CR.ACTIVO = 1 ");
		sql.append("    AND RT.ACTIVO = 1 ");
		sql.append("    AND RO.ACTIVO = 1 ");
		sql.append("    AND DA.ACTIVO = 1 ");
		sql.append("    AND TR.ACTIVO = 1 ");
		sql.append("    AND CR.EMPRESACORRIDA_ID = NVL(:EMPRESA_ID, CR.EMPRESACORRIDA_ID) ");
		sql.append("    AND CR.ORIGEN_ID = PO.PARADA_ID ");
		sql.append("    AND CR.DESTINO_ID = PD.PARADA_ID ");
		sql.append("    AND PO.CIUDAD_ID = CO.CIUDAD_ID ");
		sql.append("    AND PD.CIUDAD_ID = CD.CIUDAD_ID ");
		sql.append("    AND RT.GRUPORUTA_ID = GR.GRUPORUTA_ID(+) ");
		sql.append("    AND RO.ROLOPERATIVO_ID = CR.ROLOPERATIVO_ID ");
		sql.append("    AND RO.DIAGRAMAAUTOBUS_ID = DA.DIAGRAMAAUTOBUS_ID ");
		sql.append("    AND TR.ORIGEN_ID = CR.ORIGEN_ID ");
		sql.append("    AND TR.DESTINO_ID = CR.DESTINO_ID ");
		sql.append("    AND CR.TIPOSERVICIO_ID = NVL(:TIPOSERVICIO_ID, CR.TIPOSERVICIO_ID)  ");
		sql.append("    AND TO_CHAR(CR.FECCORRIDA, 'MMYYYY') = TO_CHAR(:DATA_MES, 'MMYYYY') ");
		sql.append("    ORDER BY INTERESTADUAL, GRUPO_LINHA, SIGLA, CR.CORRIDA_ID, TO_CHAR(CR.FECHORSALIDAORIGINAL, 'HH24:MI') ");

		return sql.toString();
	}

	private String buscarConstante(String nomeConstante) {
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
		return constanteService.buscarPorNomeConstante(nomeConstante).getValorconstante();
	}

}
