package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ItemReporteControleEstoqueBoletos;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class RelatorioEstoque extends Relatorio {

	private static final String ARTICULO_ID = "articuloId";
	private static final String AIDF_ID = "aidfId";
	private static final String DATA_INICIO = "dataInicio";
	private List<ItemReporteControleEstoqueBoletos> lsDadosRelatorio;
	
	public RelatorioEstoque(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new ArrayDataSource(this) {

			public void initDados() throws Exception {
				
				Connection conexao = this.relatorio.getConexao();
				Integer empresaId = null;
				String puntoVentaId = null;
				
				Date dtInicio = (Date) parametros.get("DATA_INICIO");
				Date dtFim = (Date) parametros.get("DATA_FIM");
				Integer aidfTipoId = (Integer) parametros.get("AIDFTIPO_ID");
				Integer aidfId = (Integer) parametros.get("AIDF_ID");
				String numInicial = (String) parametros.get("NUM_INICIAL");
				String numFinal = (String) parametros.get("NUM_FINAL");
								
				if (parametros.get("EMPRESA_ID") != null) {
					empresaId = Integer.valueOf(parametros.get("EMPRESA_ID").toString());
				}
				
				if (parametros.get("NUMPUNTOVENTA") != null) {
					puntoVentaId = String.valueOf(parametros.get("NUMPUNTOVENTA"));
				}
				
				String sql = retornarItensConsultaPorPuloFolio(	puntoVentaId,
																empresaId, 
																dtInicio, 
																dtFim, 
																aidfTipoId, 
																aidfId,
																numInicial,
																numFinal);
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
				
				if(dtInicio != null && dtFim != null) {
					stmt.setString(DATA_INICIO, DateUtil.getStringDate(dtInicio, "dd/MM/yyyy") + " 00:00:00");
					stmt.setString("dataFinal", DateUtil.getStringDate(dtFim, "dd/MM/yyyy") + " 23:59:59");
				}else if(dtInicio != null) {
					stmt.setString(DATA_INICIO, DateUtil.getStringDate(dtInicio, "dd/MM/yyyy") + " 00:00:00");
				}
				
				if(aidfTipoId != null) {
					stmt.setInt("aidfTipo",aidfTipoId);
				}
				
				if(aidfId != null) {
					stmt.setInt(AIDF_ID,aidfId);
				}
				
				if( numInicial != null && numFinal != null ) {
					stmt.setString("numInicial", numInicial);				
					stmt.setString("numFinal", numFinal);
				}
				
				lsDadosRelatorio = new ArrayList<ItemReporteControleEstoqueBoletos>();
				ResultSet rset = null;
				rset = stmt.executeQuery();
				List<ItemReporteControleEstoqueBoletos> lsEstoquePorSalto = new ArrayList<>();
				
				while (rset.next()) {

					ItemReporteControleEstoqueBoletos item = new ItemReporteControleEstoqueBoletos();
					item.setAidfId(rset.getInt(AIDF_ID) > 0 ? rset.getInt(AIDF_ID) : null);
					item.setNombEmpresa(rset.getString("nombEmpresa"));
					item.setNomeEstado(rset.getString("nomeEstado"));
					item.setDescPuntoVenta(rset.getString("descPuntoVenta"));
					item.setSerie(rset.getString("serie"));
					item.setTipo(rset.getString("tipoAidf"));
					item.setFolioInicial( rset.getLong("folioInicial"));
					item.setFolioFinal(rset.getLong("folioFinal"));
					item.setFolioCaja(rset.getBigDecimal("folioCaja"));
					item.setArticuloId(rset.getInt(ARTICULO_ID) > 0 ? rset.getInt(ARTICULO_ID) : null);
					item.setFechorAquisicion(rset.getDate("fechorAquisicion"));
					item.setFecVencimento(rset.getDate("fecVencimento"));
					item.setId(rset.getString("ID"));
					item.setPuntoVentaId(rset.getInt("puntoVentaId") > 0 ? rset.getInt("puntoVentaId") : null);
					
					if( numFinal != null && item.getFolioFinal().compareTo(Long.valueOf(numFinal)) > 0 ) {
						item.setFolioFinal(Long.valueOf(numFinal));
					}
					
					lsEstoquePorSalto.add(item);
				}

				this.resultSet = rset;
				
				
				String sqlretornEstoque = sQLretornarEstoque(puntoVentaId, 
																dtInicio, 
																dtFim,
																empresaId, 
																aidfTipoId, 
																aidfId, 
																numInicial,
																numFinal);
				
				NamedParameterStatement stmt2 = new NamedParameterStatement(conexao, sqlretornEstoque);
	
				if(dtInicio != null && dtFim != null) {
					stmt2.setString(DATA_INICIO, DateUtil.getStringDate(dtInicio, "dd/MM/yyyy") + " 00:00:00");
					stmt2.setString("dataFinal", DateUtil.getStringDate(dtFim, "dd/MM/yyyy") + " 23:59:59");
				}else if(dtInicio != null) {
					stmt2.setString(DATA_INICIO, DateUtil.getStringDate(dtInicio, "dd/MM/yyyy") + " 00:00:00");
				}
				
				if(aidfTipoId != null) {
					stmt2.setInt("aidfTipo",aidfTipoId);
				}
				
				if(aidfId != null) {
					stmt2.setInt(AIDF_ID,aidfId);
				}
				
				if( numInicial != null && numFinal != null ) {
					stmt2.setString("numInicial", numInicial);				
					stmt2.setString("numFinal", numFinal);
				}
				
				ResultSet rset2 = null;
				rset2 = stmt2.executeQuery();
				List<ItemReporteControleEstoqueBoletos> lsEstoque = new ArrayList<>() ;
				while (rset2.next()) {

					ItemReporteControleEstoqueBoletos item = new ItemReporteControleEstoqueBoletos();
					item.setAidfId(rset2.getInt(AIDF_ID) > 0 ? rset2.getInt(AIDF_ID) : null);
					item.setNombEmpresa(rset2.getString("nombEmpresa"));
					item.setDescPuntoVenta(rset2.getString("descPuntoVenta"));
					item.setNomeEstado(rset2.getString("nomeEstado"));
					item.setSerie(rset2.getString("serie"));
					item.setTipo( rset2.getString("tipoAidf"));
					item.setFolioInicial(rset2.getLong("folioInicial"));
					item.setFolioFinal(rset2.getLong("folioFinal"));
					item.setFolioCaja(rset2.getBigDecimal("folioCaja"));
					item.setArticuloId(rset2.getInt(ARTICULO_ID) > 0 ? rset2.getInt(ARTICULO_ID) : null);
					item.setFechorAquisicion(rset2.getDate("fechorAquisicion"));
					item.setFecVencimento(rset2.getDate("fecVencimento"));
					item.setId(rset2.getString("ID"));
					item.setCveUsuario(rset2.getString("cveUsuario"));
					item.setDescArticulo(rset2.getObject("descArticulo") != null ? rset2.getBigDecimal("descArticulo").toString(): null);
					item.setDescEstacion(rset2.getString("descEstacion"));
					item.setFolioAtual(rset2.getString("folioAtual"));
					lsEstoque.add(item);
				}
				
				Map<String, String> map = new HashMap<String, String>();
				List<ItemReporteControleEstoqueBoletos> lsTemp = new ArrayList<>();
				List<ItemReporteControleEstoqueBoletos> lsTempRetorno  =  new ArrayList<>();
				List<ItemReporteControleEstoqueBoletos> lsTempRetornoAux = new ArrayList<>();
				lsEstoquePorSalto = removeFoliosDuplicados(lsEstoquePorSalto);
				validarFormularioSeUsado(lsEstoquePorSalto,lsEstoque);
				lsTempRetornoAux = criarRangesBilhetes(puntoVentaId, lsEstoquePorSalto, lsEstoque, map, lsTemp,	lsTempRetorno, lsTempRetornoAux);

				List<ItemReporteControleEstoqueBoletos> lsBlocoJaTodoUtilizado = tratarBlocoJaTodoUtilizado(lsTempRetornoAux);
				
				Collections.sort(lsBlocoJaTodoUtilizado, new Comparator<ItemReporteControleEstoqueBoletos>() {
					@Override
					public int compare(ItemReporteControleEstoqueBoletos rel1, ItemReporteControleEstoqueBoletos rel2) {
						Integer aidf1 = rel1.getAidfId();
						Integer aidf2 = rel2.getAidfId();
						int sComp = aidf1.compareTo(aidf2);

						if (sComp != 0) {
							return sComp;
						}

						return rel1.getFolioInicial().compareTo(rel2.getFolioInicial());
					}
				});
				
				lsDadosRelatorio.addAll(lsBlocoJaTodoUtilizado);
				
				setLsDadosRelatorio(lsDadosRelatorio);
			}

		});
	}

	private List<ItemReporteControleEstoqueBoletos> criarRangesBilhetes(String puntoVentaId,
			List<ItemReporteControleEstoqueBoletos> lsEstoquePorSalto,
			List<ItemReporteControleEstoqueBoletos> lsEstoque, Map<String, String> map,
			List<ItemReporteControleEstoqueBoletos> lsTemp,
			List<ItemReporteControleEstoqueBoletos> lsTempRetorno,
			List<ItemReporteControleEstoqueBoletos> lsTempRetornoAux) {
		for (ItemReporteControleEstoqueBoletos i : lsEstoquePorSalto) {
			if(map.get(i.getId()) == null) {
				for (ItemReporteControleEstoqueBoletos item : lsEstoquePorSalto) {
					if(i.getId().equals(item.getId())) {
						lsTemp.add(item);
					}
				}
				map.put(i.getId(), i.getId());
				lsTempRetorno.addAll(gerarRangesDeFolios(recuperarOsFaltantes(lsTemp), lsTemp));
				lsTempRetorno = validarFolioPreImpressoPuntoventa(lsTempRetorno, puntoVentaId);
				lsTemp = new ArrayList<ItemReporteControleEstoqueBoletos>();
			}					
		}
		lsTempRetornoAux.addAll(lsTempRetorno);
		
		for (ItemReporteControleEstoqueBoletos itemEstoque : lsEstoque) {
			if(!lsTempRetornoAux.contains(itemEstoque)) {
				if(Boolean.FALSE.equals(itemEstoque.isConsumido())) {
					itemEstoque.setQuantidade(calcularQuantidade(itemEstoque.getFolioInicial(), itemEstoque.getFolioFinal()));
					lsTempRetornoAux.add(itemEstoque);
				}

			}
		}
		return lsTempRetornoAux;
	}
	
	@Override
	protected void processaParametros() throws Exception {
	}
	
	public void setLsDadosRelatorio(List<ItemReporteControleEstoqueBoletos> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}
	
	public List<ItemReporteControleEstoqueBoletos> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}	
	
	private String retornarItensConsultaPorPuloFolio( String puntoVentaId, 
													  Integer empresaId, 
													  Date dataInicio, 
													  Date dataFim, 
													  Integer aidfTipo, 
													  Integer aidfId, 
													  String numInicial, 
													  String numFinal) {
		
		StringBuilder sb = new StringBuilder();
	
		sb.append(" select DISTINCT TB.aidfId as aidfId, ");
		sb.append("      TB.serie as serie, ");
		sb.append("      TB.folioCaja as folioCaja, ");
		sb.append("      TB.folioInicial as folioInicial, ");
		sb.append("      TB.folioFinal as folioFinal, ");
		sb.append("      TB.descPuntoVenta as descPuntoVenta, ");
		sb.append("      TB.articuloId as articuloId, ");
		sb.append("      TB.nombEmpresa as nombEmpresa, ");
		sb.append("      TB.empresaId as empresaId, ");
		sb.append("      TB.marcaId as marcaId, ");
		sb.append("      TB.fechorAquisicion as fechorAquisicion,                                                                                    ");
		sb.append("      TB.tipo as tipo,                                                                                                            ");
		sb.append("      TB.fecVencimento as fecVencimento,                                                                                            ");
		sb.append("      TB.ID  as ID , TB.nomeEstado  as nomeEstado,                                                                                  ");
		sb.append("      TB.tipoAidf as tipoAidf,  ");
		sb.append("      TB.puntoVentaId as puntoVentaId  ");
		sb.append("  from (SELECT DAB.AIDF_ID AS aidfId,  est.NOMBESTADO as nomeEstado,                                                          ");
		sb.append("        dab.NUMSERIEPREIMPRESA AS serie,                                                                                           ");
		sb.append("        TO_NUMBER( TRIM(LEADING '0' FROM Cj.NUMFOLIOPREIMPRESO)) AS folioCaja,                                                                             ");
		sb.append("        TO_NUMBER(DAB.NUMFOLIOINICIAL) AS folioInicial,                                                                                       ");
		sb.append("        TO_NUMBER(DAB.NUMFOLIOFINAL) AS folioFinal,                                                                                           ");
		sb.append("        PV.NOMBPUNTOVENTA AS descPuntoVenta,                                                                                       ");
		sb.append("        AB.ARTICULO_ID AS articuloId,                                                                                              ");
		sb.append("        EM.NOMBEMPRESA AS nombEmpresa,                                                                                             ");
		sb.append("        EM.EMPRESA_ID AS empresaId,                                                                                                ");
		sb.append("        M.MARCA_ID AS marcaId,                                                                                                     ");
		sb.append("        DAB.AIDF_ID || DAB.NUMSERIEPREIMPRESA || DAB.NUMFOLIOINICIAL || DAB.NUMFOLIOFINAL || EM.EMPRESA_ID AS ID,                  ");
		sb.append("        CASE                                                                                                                       ");
		sb.append("            WHEN dab.STATUSOPERACION = 4 THEN CONCAT(a.descarticulo, '(Distribuição Estoque)')                                  ");
		sb.append("            ELSE a.descarticulo                                                                                                    ");
		sb.append("        END AS tipo , ");
		sb.append("        AI.fecadquisicion AS fechorAquisicion, ");
		sb.append("        ai.fecvencimiento AS fecVencimento, ");
		sb.append("        AIT.DESCTIPO tipoAidf, ");
		sb.append("        PV.PUNTOVENTA_ID AS puntoVentaId                                                                                                    ");
		sb.append(" FROM CAJA CJ,                                                                                                                     ");
		sb.append("      ARTICULO A,                                                                                                                  ");
		sb.append("      EMPRESA EM,                                                                                                                  ");
		sb.append("      MARCA M,                                                                                                                     ");
		sb.append("      USUARIO U,                                                                                                                   ");
		sb.append("      AIDF AI,                                                                                                                     ");
		sb.append("      AIDF_TIPO AIT,                                                                                                               ");
		sb.append("      ESTADO est,");
		sb.append("      PUNTO_VENTA PV,                                                                                                              ");
		sb.append("      ABASTO_BOLETO AB                                                                                                             ");
		sb.append(" 																																  ");
		sb.append(" LEFT JOIN DET_ABASTO_BOLETO DAB ON (AB.ABASTOBOLETO_ID = DAB.ABASTOBOLETO_ID)                                                     ");
		sb.append(" WHERE  TO_NUMBER(Cj.NUMFOLIOPREIMPRESO) BETWEEN (DAB.NUMFOLIOINICIAL) AND (DAB.NUMFOLIOFINAL)                    ");
		sb.append("    AND (cj.PUNTOVENTA_ID = ab.PUNTOVENTA_ID or  cj.PUNTOVENTA_ID = ai.PUNTOVENTA_ID)                                                                                        ");
		sb.append("   AND DAB.ACTIVO = 1                                                                                                              ");
		sb.append("   AND (cj.NUMSERIEPREIMPRESA = dab.NUMSERIEPREIMPRESA                                                                             ");
		sb.append("        OR (cj.NUMSERIEPREIMPRESA IS NULL                                                                                          ");
		sb.append("            AND dab.NUMSERIEPREIMPRESA IS NULL))                                                                                   ");

		if(empresaId != null) {
			sb.append(" AND Em.empresa_ID = ")
					   .append(empresaId);
		}
		
		if(dataInicio!= null && dataFim != null) {
			sb.append(" AND AI.fecadquisicion BETWEEN TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') AND TO_DATE(:dataFinal,'dd/mm/yyyy hh24:mi:ss') ");
		}else if(dataInicio!= null) {
			sb.append(" AND AI.fecadquisicion >= TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') ");
		}
		
		if( numInicial != null && numFinal != null ) {
			sb.append(" AND TO_NUMBER(Cj.NUMFOLIOPREIMPRESO) >= :numInicial ");
			sb.append(" AND TO_NUMBER(Cj.NUMFOLIOPREIMPRESO) <= :numFinal ");
		}
		
		sb.append("   AND DAB.STATUSOPERACION IN(0,                                                                                                   ");
		sb.append("                              1,                                                                                                   ");
		sb.append("                              4)                                                                                                   ");
		sb.append("   AND A.ARTICULO_ID = AB.ARTICULO_ID                                                                                              ");
		sb.append("   AND EM.EMPRESA_ID = AB.EMPRESA_ID                                                                                               ");
		sb.append("   AND M.EMPRESA_ID = EM.EMPRESA_ID                                                                                                ");
		sb.append("   AND M.ACTIVO = 1                                                                                                               ");
		sb.append("   AND CJ.USUARIO_ID = U.USUARIO_ID  and cj.activo =1                                                                                          ");
		sb.append("   AND (CJ.INDREIMPRESION = 0                                                                                                      ");
		sb.append("        OR (CJ.INDREIMPRESION = 1                                                                                                  ");
		sb.append("            AND CJ.INDSTATUSBOLETO = 'E'))                                                                                         ");
		sb.append("   AND CJ.PUNTOVENTA_ID = PV.PUNTOVENTA_ID                                                                                         ");
		sb.append("   AND DAB.ACTIVO = 1                                                                                                              ");
		sb.append("   AND AB.activo =1  AND AI.activo = 1  and est.estado_id = ai.ESTADO_ID                                                            ");
		sb.append(aidfTipo != null ?  " AND (AI.AIDFTIPO_ID =:aidfTipo  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID) " : "  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID  ");
		sb.append(aidfId != null ?  " AND (AI.AIDF_ID =:aidfId  AND DAB.AIDF_ID = AI.AIDF_ID) " : "  AND DAB.AIDF_ID = AI.AIDF_ID  ");
		sb.append(" GROUP BY DAB.AIDF_ID,                                                                                                             ");
		sb.append("          DAB.NUMSERIEPREIMPRESA,                                                                                                  ");
		sb.append("          CJ.NUMFOLIOPREIMPRESO,                                                                                                   ");
		sb.append("          DAB.NUMFOLIOINICIAL,                                                                                                     ");
		sb.append("          DAB.NUMFOLIOFINAL,                                                                                                       ");
		sb.append("          PV.NOMBPUNTOVENTA,                                                                                                       ");
		sb.append("          AB.ARTICULO_ID,                                                                                                          ");
		sb.append("          EM.NOMBEMPRESA,                                                                                                          ");
		sb.append("          U.USUARIO_ID,                                                                                                            ");
		sb.append("          EM.EMPRESA_ID,                                                                                                           ");
		sb.append("          DAB.AIDF_ID,                                                                                                             ");
		sb.append("          M.MARCA_ID,                                                                                                              ");
		sb.append("          A.descarticulo,                                                                                                          ");
		sb.append("          dab.STATUSOPERACION ,                                                                                                    ");
		sb.append("          AI.fecadquisicion,                                                                                ");
		sb.append("          ai.fecvencimiento, ");
		sb.append("          est.NOMBESTADO, ");
		sb.append("          AIT.DESCTIPO, ");
		sb.append("          PV.PUNTOVENTA_ID ");
		sb.append(" 																																  ");
		sb.append(" UNION ALL                                                                                                                         ");
		sb.append("    SELECT DAB.AIDF_ID AS aidfId,   est.NOMBESTADO as nomeEstado ,                                                            ");
		sb.append("        dab.NUMSERIEPREIMPRESA AS serie,                                                                                          ");
		sb.append("        TO_NUMBER( TRIM(LEADING '0' FROM Cj.NUMFOLIOPREIMPRESO)) AS folioCaja,                                                                             ");
		sb.append("        TO_NUMBER(DAB.NUMFOLIOINICIAL) AS folioInicial,                                                                                       ");
		sb.append("        TO_NUMBER(DAB.NUMFOLIOFINAL) AS folioFinal,                                                                                           ");
		sb.append("        PV.NOMBPUNTOVENTA AS descPuntoVenta,                                                                                       ");
		sb.append("        AB.ARTICULO_ID AS articuloId,                                                                                              ");
		sb.append("        EM.NOMBEMPRESA AS nombEmpresa,                                                                                             ");
		sb.append("        EM.EMPRESA_ID AS empresaId,                                                                                                ");
		sb.append("        M.MARCA_ID AS marcaId,                                                                                                     ");
		sb.append("        DAB.AIDF_ID || DAB.NUMSERIEPREIMPRESA || DAB.NUMFOLIOINICIAL || DAB.NUMFOLIOFINAL || EM.EMPRESA_ID AS ID,                  ");
		sb.append("        CASE                                                                                                                       ");
		sb.append("            WHEN dab.STATUSOPERACION = 4 THEN CONCAT(a.descarticulo, '(Distribuição Estoque)')                                  ");
		sb.append("            ELSE a.descarticulo                                                                                                    ");
		sb.append("        END AS tipo,                                                                                                               ");
		sb.append("        AI.fecadquisicion AS fechorAquisicion, ");
		sb.append("        ai.fecvencimiento AS fecVencimento, ");
		sb.append("        AIT.DESCTIPO tipoAidf , PV.PUNTOVENTA_ID AS puntoVentaId                                                                                                     ");
		sb.append("   FROM caja_diversos               cj ");
		sb.append("        LEFT JOIN aidf              ai ON cj.aidf_id = ai.aidf_id  AND ai.activo = 1 ");
		sb.append("        LEFT JOIN det_abasto_boleto dab ON ai.aidf_id = dab.aidf_id AND dab.activo = 1 ");
		sb.append("        LEFT JOIN abasto_boleto     ab ON ab.abastoboleto_id = dab.abastoboleto_id AND ab.activo = 1 ");
		sb.append("        LEFT JOIN punto_venta       pv ON ( cj.puntoventa_id = ab.puntoventa_id OR cj.puntoventa_id = ai.puntoventa_id ) ");
		sb.append("        LEFT JOIN estado            est ON est.estado_id = ai.estado_id ");
		sb.append("        LEFT JOIN articulo          a ON a.articulo_id = ab.articulo_id ");
		sb.append("        LEFT JOIN empresa           em ON em.empresa_id = ab.empresa_id ");
		sb.append("        LEFT JOIN marca             m ON m.empresa_id = em.empresa_id AND m.activo = 1 ");
		sb.append("        LEFT JOIN aidf_tipo         ait ON ait.aidftipo_id = ai.aidftipo_id ");
		sb.append("        LEFT JOIN usuario           u ON cj.usuario_id = u.usuario_id ");
		
		sb.append(" WHERE TO_NUMBER(cj.NUMFOLIOPREIMPRESO) BETWEEN (DAB.NUMFOLIOINICIAL) AND (DAB.NUMFOLIOFINAL) ");
		sb.append("  AND (cj.PUNTOVENTA_ID = ab.PUNTOVENTA_ID or  cj.PUNTOVENTA_ID = ai.PUNTOVENTA_ID)                                                                                          ");
		sb.append("   AND (cj.NUMSERIEPREIMPRESA = dab.NUMSERIEPREIMPRESA                                                                             ");
		sb.append("        OR (cj.NUMSERIEPREIMPRESA IS NULL                                                                                          ");
		sb.append("            AND dab.NUMSERIEPREIMPRESA IS NULL))                                                                                   ");

		if(empresaId != null) {
			sb.append(" AND Em.empresa_ID = ")
					   .append(empresaId);
		}
		
		if(dataInicio!= null && dataFim != null) {
			sb.append(" AND AI.fecadquisicion BETWEEN TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') AND TO_DATE(:dataFinal,'dd/mm/yyyy hh24:mi:ss') ");
		}else if(dataInicio!= null) {
			sb.append(" AND AI.fecadquisicion >= TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') ");
		}
		
		if( numInicial != null ) {
			sb.append(" AND TO_NUMBER(Cj.NUMFOLIOPREIMPRESO) >= :numInicial ");
		}
		
		if( numFinal != null ) {
			sb.append(" AND TO_NUMBER(Cj.NUMFOLIOPREIMPRESO) <= :numFinal ");
		}
		
		sb.append("   AND DAB.STATUSOPERACION IN(0, 1, 4)                                                                                             ");
		sb.append(aidfTipo != null ?  " AND AI.AIDFTIPO_ID =:aidfTipo " : "");
		sb.append(aidfId != null ?  " AND AI.AIDF_ID =:aidfId " : "  AND cj.AIDF_ID  is null ");
		sb.append("   GROUP BY DAB.AIDF_ID,                                                                                                           ");
		sb.append("          DAB.NUMSERIEPREIMPRESA,                                                                                                  ");
		sb.append("          CJ.NUMFOLIOPREIMPRESO,                                                                                                   ");
		sb.append("          DAB.NUMFOLIOINICIAL,                                                                                                     ");
		sb.append("          DAB.NUMFOLIOFINAL,                                                                                                       ");
		sb.append("          PV.NOMBPUNTOVENTA,                                                                                                       ");
		sb.append("          AB.ARTICULO_ID,                                                                                                          ");
		sb.append("          EM.NOMBEMPRESA,                                                                                                          ");
		sb.append("          U.USUARIO_ID,                                                                                                            ");
		sb.append("          EM.EMPRESA_ID,                                                                                                           ");
		sb.append("          DAB.AIDF_ID,                                                                                                             ");
		sb.append("          M.MARCA_ID,                                                                                                              ");
		sb.append("          A.descarticulo,                                                                                                          ");
		sb.append("          dab.STATUSOPERACION, ");
		sb.append("          AI.fecadquisicion, ");
		sb.append("          ai.fecvencimiento, ");
		sb.append("          est.NOMBESTADO, ");
		sb.append("          AIT.DESCTIPO, ");
		sb.append("          PV.PUNTOVENTA_ID  ) TB ");                 
		sb.append("       ORDER BY  TB.aidfId,                                                                                                        ");
		sb.append("          TB.serie,                                                                                                                ");
		sb.append("          TB.folioCaja                                                                                                             ");
		
		return sb.toString();
		
	}
	
/*	TODO avaliar a mudanca da logica pra usar a query abaixo
	private String retornarItensConsultaPorPuloFolio(
			String puntoVentaId, 
			Integer empresaId, 
			Date dataInicio, 
			Date dataFim, 
			Integer aidfTipo, 
			Integer aidfId, 
			String numInicial, 
			String numFinal) {
		
		
		
		WITH Sequencia AS (
			    SELECT 
			        b.numfoliopreimpreso,
			        dab.numfolioinicial,
			        dab.numfoliofinal,
			        dab.aidf_id,
			        dab.detabastoboleto_id,
			        LAG(b.numfoliopreimpreso) OVER (PARTITION BY dab.aidf_id ORDER BY b.numfoliopreimpreso) AS numfoliopreimpreso_anterior
			    FROM 
			        boleto b
			    LEFT JOIN 
			        det_abasto_boleto dab 
			        ON  b.aidf_id = dab.aidf_id
			        AND b.NUMSERIEPREIMPRESA = dab.NUMSERIEPREIMPRESA 
			        AND TO_NUMBER(b.numfoliopreimpreso) BETWEEN dab.numfolioinicial AND dab.numfoliofinal
			    WHERE 
			        b.activo = 1
			        AND (b.aidf_id = :aidfid or b.aidf_id is null)
			        AND TO_NUMBER(b.numfoliopreimpreso) >= :numinicial 
			        AND TO_NUMBER(b.numfoliopreimpreso) <= :numfinal 
			)
			SELECT 
			    numfolioinicial,
			    numfoliofinal,
			    aidf_id,
			    numfoliopreimpreso,
			    numfoliopreimpreso_anterior,
			    detabastoboleto_id,
			    (TO_NUMBER(numfoliopreimpreso) - TO_NUMBER(numfoliopreimpreso_anterior)) AS diferenca
			FROM 
			    Sequencia
			WHERE 
			    numfoliopreimpreso_anterior IS NOT NULL
			    AND (TO_NUMBER(numfoliopreimpreso) - TO_NUMBER(numfoliopreimpreso_anterior)) > 1
			    
			ORDER BY 
			    numfoliopreimpreso;

	}
*/
	
	private String sQLretornarEstoque( String puntoVentaId, 
									   Date dataInicio, 
									   Date dataFim, 
									   Integer empresaId, 
									   Integer aidfTipo, 
									   Integer aidfId,
									   String numInicial, 
									   String numFinal) {
		
		StringBuilder queryString = new StringBuilder("SELECT DISTINCT ai.fecvencimiento as fecVencimento, ")
				.append(" ai.fecadquisicion as fechorAquisicion, ")
				.append(" dab.NUMSERIEPREIMPRESA as serie, ")
				.append(" TO_NUMBER(dab.NUMFOLIOINICIAL) as folioInicial, ")
				.append(" TO_NUMBER(dab.NUMFOLIOFINAL) as folioFinal, ")
				.append(" pv.NOMBPUNTOVENTA as descPuntoVenta, ")
				.append(" to_number(dab.NUMFOLIOINICIAl) as ultimoFolioCaja, ")
			    .append("   CASE                                                                                                        ")
		        .append("  WHEN dab.STATUSOPERACION = 1 THEN fp.FOLIOPREIMPRESO                                                      ")
		        .append("   ELSE COALESCE(                                                                                           ")
		        .append("                                                                                                            ")
		        .append("                (SELECT TO_CHAR(MAX(c.numfoliopreimpreso)+1)                                                ")
		        .append("                 FROM caja c                                                                                ")
		        .append("                 WHERE (c.numseriepreimpresa = dab.numseriepreimpresa                                       ")
		        .append("                        OR (c.numseriepreimpresa IS NULL                                                    ")
		        .append("                            AND dab.numseriepreimpresa IS NULL))                                            ")
		        .append("                   AND to_number(c.numfoliopreimpreso) BETWEEN dab.numfolioinicial AND dab.numfoliofinal    ")
		        .append("                   AND (c.indreimpresion = 0                                                                ")
		        .append("                        OR (c.indreimpresion = 1                                                            ")
		        .append("                            AND c.indstatusboleto = 'E'))                                                   ")
		        .append("                   AND c.marca_id = m.marca_id), (SELECT to_char(MAX(cd.numfoliopreimpreso)+1)              ")
		        .append("                 FROM caja_diversos cd                                                                      ")
		        .append("                 WHERE cd.numseriepreimpresa = dab.numseriepreimpresa  AND to_number(cd.numfoliopreimpreso) BETWEEN dab.numfolioinicial AND dab.numfoliofinal ), dab.NUMFOLIOINICIAL)              ")
				.append("END as folioAtual, ")
				.append("ab.ARTICULO_ID as articuloId, ")
				.append("a.ARTICULO_ID as descArticulo, ")
				.append("CASE WHEN dab.STATUSOPERACION = 4 THEN CONCAT(a.descarticulo,' (DistribuiÃ§Ã£o Estoque)') ELSE a.descarticulo END as tipo, ")
				.append("em.nombEmpresa as \"nombEmpresa\", ")
				.append("em.EMPRESA_ID as \"empresaId\", ")
				.append("CASE WHEN dab.STATUSOPERACION = 1 THEN to_number(fp.FOLIOPREIMPRESO) ELSE NULL END as folioCaja, ")
				.append("dab.AIDF_ID as aidfId, ")
				.append("m.MARCA_ID as marcaId, ")
				.append("ai.SUBSERIE as subSerie, ")
				.append("us.CVEUSUARIO as cveUsuario, ") 
				.append(" DAB.AIDF_ID || DAB.NUMSERIEPREIMPRESA ||  EM.EMPRESA_ID AS ID,  " )
				.append("est.NOMBESTADO as nomeEstado, ")
				.append("coalesce(es.descestacion, 'Todas') AS descEstacion, ")
				.append("ait.DESCTIPO as tipoAidf ")
				.append("FROM DET_ABASTO_BOLETO dab ")
				.append("INNER JOIN ABASTO_BOLETO ab ON dab.ABASTOBOLETO_ID = ab.ABASTOBOLETO_ID ")
				.append("LEFT JOIN USUARIO us ON ab.USUARIOESTOQUE_ID = us.USUARIO_ID ")
				.append("INNER JOIN PUNTO_VENTA pv ON  ab.PUNTOVENTA_ID = pv.PUNTOVENTA_ID ")
				.append("LEFT JOIN FOLIO_PREIMPRESO fp ON fp.EMPRESA_ID = ab.EMPRESA_ID  ")
				.append("	AND (fp.NUMESERIE = dab.NUMSERIEPREIMPRESA OR (fp.NUMESERIE IS NULL AND dab.NUMSERIEPREIMPRESA IS NULL)) ")
				.append("	AND to_number(fp.FOLIOPREIMPRESO)   BETWEEN to_number(dab.NUMFOLIOINICIAL) AND to_number(dab.NUMFOLIOFINAL)  ")
				.append("	AND (fp.ACTIVO = 1) ")
				.append("LEFT  JOIN ARTICULO a ON a.ARTICULO_ID = ab.ARTICULO_ID ")
				.append("LEFT  JOIN EMPRESA em ON em.EMPRESA_ID = ab.EMPRESA_ID ")
				.append("LEFT  JOIN MARCA m ON m.EMPRESA_ID = em.EMPRESA_ID AND m.ACTIVO = 1 ")
				.append("LEFT  JOIN AIDF ai ON dab.AIDF_ID = ai.AIDF_ID ")
				.append("LEFT  JOIN aidf_tipo ait ON ait.AIDFTIPO_ID= ai.AIDFTIPO_ID ")
				.append("LEFT  JOIN ESTADO est ON est.ESTADO_ID = ai.ESTADO_ID ")
				.append("LEFT JOIN ESTACION ES ON es.ESTACION_ID = ab.ESTACION_ID  ")
				.append("WHERE dab.STATUSOPERACION IN(0,1,4) ")
				.append("AND dab.ACTIVO = 1 ");
				
				if( numInicial != null && numFinal != null ) {
					queryString.append(" AND ( TO_NUMBER(dab.numfolioinicial) BETWEEN :numInicial AND :numFinal ");
					queryString.append("       OR TO_NUMBER(dab.numfoliofinal) BETWEEN :numInicial AND :numFinal ) ");
				}else {
					queryString.append(" and dab.NUMFOLIOFINAL < 2147483647 ");
				}
				
				queryString.append("  AND DAB.AIDF_ID = AI.AIDF_ID and ai.activo = 1   ")
				.append(aidfTipo != null ?  " AND AI.AIDFTIPO_ID = :aidfTipo " : " ")
				.append(aidfId != null ?  " AND AI.AIDF_ID = :aidfId " : " ");
		
		if (puntoVentaId != null) {
			queryString.append(" AND pv.PUNTOVENTA_ID in("+puntoVentaId+ ")");
		}
		
		if (empresaId != null) {
			queryString.append(" AND em.EMPRESA_ID = ")
					   .append(empresaId);
		}
		if(dataInicio!= null && dataFim != null) {
			queryString.append(" AND fecadquisicion BETWEEN TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') AND TO_DATE(:dataFinal,'dd/mm/yyyy hh24:mi:ss') ");
		}else if(dataInicio!= null) {
			queryString.append(" AND fecadquisicion >= TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') ");
		}
		queryString.append(" ORDER BY 5,11,1,7");

		return queryString.toString();
		
	}
		
	 private List<ItemReporteControleEstoqueBoletos> gerarRangesDeFolios(int[] a, List<ItemReporteControleEstoqueBoletos> lsTemp){
		 
	        int length = 1;
	        List<ItemReporteControleEstoqueBoletos> list   = new ArrayList<ItemReporteControleEstoqueBoletos>();
	        ItemReporteControleEstoqueBoletos itemReporteStockBoletos=  null;
	        
	        if (a.length == 0) {
	            return list;
	        }

	        for (int i = 1; i <= a.length; i++) {
	           
	        	if (i == a.length || a[i] - a[i - 1] != 1) {
	            	
	            	itemReporteStockBoletos = new ItemReporteControleEstoqueBoletos();
	        		itemReporteStockBoletos.setEstacionId(lsTemp.get(0).getEstacionId());
	        		itemReporteStockBoletos.setDescEstacion((lsTemp.get(0).getDescEstacion()));
	        		itemReporteStockBoletos.setDescPuntoVenta((lsTemp.get(0).getDescPuntoVenta()));
	        		itemReporteStockBoletos.setAidfId(lsTemp.get(0).getAidfId());
	        		itemReporteStockBoletos.setNombEmpresa(lsTemp.get(0).getNombEmpresa());
	        		itemReporteStockBoletos.setNombreUsuario(lsTemp.get(0).getNombreUsuario());
	        		itemReporteStockBoletos.setCveUsuario(lsTemp.get(0).getCveUsuario());
	        		itemReporteStockBoletos.setTipo(lsTemp.get(0).getTipo());
	        		itemReporteStockBoletos.setId(lsTemp.get(0).getId());
	        		itemReporteStockBoletos.setFechorAquisicion(lsTemp.get(0).getFechorAquisicion());
	        		itemReporteStockBoletos.setFecVencimento(lsTemp.get(0).getFecVencimento());
	        		itemReporteStockBoletos.setSerie(lsTemp.get(0).getSerie());
	        		itemReporteStockBoletos.setNomeEstado(lsTemp.get(0).getNomeEstado());
	        		itemReporteStockBoletos.setDescEstacion("Todas");
	        		itemReporteStockBoletos.setPuntoVentaId(lsTemp.get(0).getPuntoVentaId());
	            	
	                if (length == 1) {
	                	if(a[i - length] != 0) {	                			                		
	                		itemReporteStockBoletos.setFolioInicial(Long.valueOf(a[i - length]));
	                		itemReporteStockBoletos.setFolioAtual(String.valueOf(a[i - length]));
	                		itemReporteStockBoletos.setFolioFinal(Long.valueOf(a[i - length]));  
	                		itemReporteStockBoletos.setQuantidade(calcularQuantidade(itemReporteStockBoletos.getFolioInicial(), itemReporteStockBoletos.getFolioFinal()));
	                		list.add(itemReporteStockBoletos);
	                	}                  
	                }
	                else {

	            		itemReporteStockBoletos.setFolioInicial(Long.valueOf(a[i - length]));
	            		itemReporteStockBoletos.setFolioAtual(String.valueOf(a[i - length]));
	            		itemReporteStockBoletos.setFolioFinal(Long.valueOf(a[i - 1]));   
                		itemReporteStockBoletos.setQuantidade(calcularQuantidade(itemReporteStockBoletos.getFolioInicial(), itemReporteStockBoletos.getFolioFinal()));
	            		list.add(itemReporteStockBoletos);	            		
	                }
	                length = 1;
	            }
	            else {
	                length++;
	            }
	        }
	 
	        return list;
	    }
	 
	 private Long calcularQuantidade(Long folioInicial, Long folioFinal) {
		 return folioInicial.equals(folioFinal) ? 1 : (folioFinal - folioInicial)+1;
		 
	 }
	 
    private int[] recuperarOsFaltantes(List<ItemReporteControleEstoqueBoletos> listEstoque) {

    	int arrayTemp[] = new int[listEstoque.size()];
    	int array[] = new int[listEstoque.size()];
    	int i = 0;

    	for (ItemReporteControleEstoqueBoletos item : listEstoque) {
    		arrayTemp[i] = item.getFolioCaja().intValue();
    		i++;
		}

    	array = recuperarFaltantes(arrayTemp,  Integer.parseInt(listEstoque.get(0).getFolioCaja().toString()),  listEstoque.get(listEstoque.size()-1).getFolioFinal().intValue());
		return array;
	}
    
	private int[] recuperarFaltantes(int arr[], int menor, int maior) {

		int[] array = new int[maior];
		int j = 0;
		if (maior - menor + 1 > 0) {
			// System.out.println();
			boolean[] range = new boolean[maior - menor + 1];

			for (int i = 0; i < arr.length; i++) {
				if (menor <= arr[i] && arr[i] <= maior)
					range[arr[i] - menor] = true;
			}
			for (int x = 0; x <= maior - menor; x++) {
				if (range[x] == false) {
					// System.out.println((menor + x) + " ");
					array[j] = (menor + x);
					j++;
				}
			}
		}
		return array;
	}

	private List<ItemReporteControleEstoqueBoletos> tratarBlocoJaTodoUtilizado(List<ItemReporteControleEstoqueBoletos> lsTempRetornoAux) {
		List<ItemReporteControleEstoqueBoletos> lsBlocoJaTodoUtilizado = new ArrayList<ItemReporteControleEstoqueBoletos>();
		for (ItemReporteControleEstoqueBoletos itemReporteStockBoletos : lsTempRetornoAux) {
			if(itemReporteStockBoletos.getFolioAtual() != null) {
				if(Long.valueOf(itemReporteStockBoletos.getFolioAtual()) <= itemReporteStockBoletos.getFolioFinal()) {
					lsBlocoJaTodoUtilizado.add(itemReporteStockBoletos);
				}	
			}
		}
		return lsBlocoJaTodoUtilizado;
	}

	private List<ItemReporteControleEstoqueBoletos> removeFoliosDuplicados(List<ItemReporteControleEstoqueBoletos> lsTemp) {
		return lsTemp;
	}
	
	private List<ItemReporteControleEstoqueBoletos>  validarFolioPreImpressoPuntoventa(List<ItemReporteControleEstoqueBoletos> lsEstoquePorSalto, String puntoVentaId) {
		
		List<ItemReporteControleEstoqueBoletos> lsEstoquePorSaltoaux = new ArrayList<>();
		String[] puntoVentaIds = null;
		if (puntoVentaId == null) {
			return lsEstoquePorSalto;
		}
		if (puntoVentaId != null) {
			 puntoVentaIds = puntoVentaId.split(",");
			for (ItemReporteControleEstoqueBoletos itemReporteControleEstoqueBoletos : lsEstoquePorSalto) {
				for (String id : puntoVentaIds) {				
					if(itemReporteControleEstoqueBoletos.getPuntoVentaId().equals(Integer.valueOf(id))) {
						lsEstoquePorSaltoaux.add(itemReporteControleEstoqueBoletos);
					}
				}
			}
		}
		return lsEstoquePorSaltoaux;
	}
	
	private void validarFormularioSeUsado(List<ItemReporteControleEstoqueBoletos> lsEstoquePorSalto, List<ItemReporteControleEstoqueBoletos> lsEstoque) {
		
		for (ItemReporteControleEstoqueBoletos item : lsEstoque) {
			for (ItemReporteControleEstoqueBoletos item2 : lsEstoquePorSalto) {
				if(item.getFolioInicial().equals(item2.getFolioInicial()) 
						&& item.getFolioFinal().equals(item2.getFolioFinal()) 
						&& item.getSerie().equals(item2.getSerie()) 
						    || item.getAidfId().equals(item2.getAidfId())) {
					item.setConsumido(Boolean.TRUE);
				}
			}
		}
	}
}
