package com.dacrt.SBIABackend.controler;

import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.dacrt.SBIABackend.dto.CoverageDto;
import com.dacrt.SBIABackend.dto.CoverageEvalProcessHistoryDto;
import com.dacrt.SBIABackend.dto.CoverageEvalProcessRecordsDto;
import com.dacrt.SBIABackend.dto.CoverageEvaluationDto;
import com.dacrt.SBIABackend.dto.CoverageHistoryActualizarDto;
import com.dacrt.SBIABackend.dto.CoverageRecordDet;
import com.dacrt.SBIABackend.dto.EntryCoverageProcessesDto;
import com.dacrt.SBIABackend.dto.EntryCoverageProcessesDto2;
import com.dacrt.SBIABackend.dto.EvalProcessRequestDto;
import com.dacrt.SBIABackend.dto.EvalProcessResponseDto;
import com.dacrt.SBIABackend.dto.EvalUnitsRecordDto;
import com.dacrt.SBIABackend.dto.LevelDto;
import com.dacrt.SBIABackend.dto.OperationlineDto;
import com.dacrt.SBIABackend.dto.OperationlineDtoStatus2;
import com.dacrt.SBIABackend.dto.OperationlineUniProcessesDto;
import com.dacrt.SBIABackend.dto.PeriodsResponseDto;
import com.dacrt.SBIABackend.dto.ProcessResponDto;
import com.dacrt.SBIABackend.dto.ScaleResponseDto;
import com.dacrt.SBIABackend.dto.StateDetailDto;
import com.dacrt.SBIABackend.dto.StateDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.StatusEvalUnitsResponseDto;
import com.dacrt.SBIABackend.dto.StrategiesDetDto;
import com.dacrt.SBIABackend.dto.TotalPosiResUnitsDto;
import com.dacrt.SBIABackend.dto.UnitsResponseDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto2;
import com.dacrt.SBIABackend.dto.UnitsUsersDto3;
import com.dacrt.SBIABackend.dto.responseDto.CoverageProcessUnitResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.EvalUnitsListResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.EvalUnitsResponseDto;
import com.dacrt.SBIABackend.entity.Coverageapps;
import com.dacrt.SBIABackend.entity.Coverageprocesses;
import com.dacrt.SBIABackend.entity.Coverageprocesseshistory;
import com.dacrt.SBIABackend.entity.Strategiesdet;
import com.dacrt.SBIABackend.repository.ApplicationsRepository;
import com.dacrt.SBIABackend.repository.CampaignsRepository;
import com.dacrt.SBIABackend.repository.CoverageprocessesRepository;
import com.dacrt.SBIABackend.repository.CoverageprocesseshistoryRepository;
import com.dacrt.SBIABackend.repository.EvalprocappsRepository;
import com.dacrt.SBIABackend.repository.EvalprocessesRepository;
import com.dacrt.SBIABackend.repository.EvalprosuppliersRepository;
import com.dacrt.SBIABackend.repository.StrategiesdetRepository;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesAllDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.entity.Params;
import com.dacrt.SBIABackend.security.entity.Users;
import com.dacrt.SBIABackend.security.repository.AuditRepository;
import com.dacrt.SBIABackend.security.repository.ParamsRepository;
import com.dacrt.SBIABackend.security.repository.RolesPrivilegesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.ParamsService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

@RestController
@CrossOrigin(origins = "*")
public class CoverageprocessesController {
	
	@Autowired
	private ParamsRepository paramsRepository;
	
	@Autowired
	private UsersRepository usersRepository;
	
	@Autowired
	private AuditRepository auditRepository;
	
	@Autowired
	private EvalprosuppliersRepository evalprosuppliersRepository;
	
	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;
	
	@Autowired
	UsersService usersService;
	
	@Autowired
	ParamsService paramsService;
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	MenuService menuService;
	
	@Autowired
	CampaignsRepository campaignsRepository;
	
	@Autowired
	ApplicationsRepository applicationsRepository;
	
	@Autowired
	EvalprocappsRepository evalprocappsRepository;
	
	@Autowired
	StrategiesdetRepository strategiesdetRepository;
	
	@Autowired
    private JdbcTemplate jdbcTemplate;
	
	@Value("${var.ambiente}")
	private String urlAmbiente;
	
	@Value("${spring.datasource.url}")
	private String conexion;
	
	@Value("${spring.datasource.username}")
	private String userbd;
	
	@Value("${spring.datasource.password}")
	private String passbd;
	
	
	@PersistenceContext
    private EntityManager entityManager;
	
	@Autowired
	CoverageprocesseshistoryRepository coverageprocesseshistoryRepository;
	
	@Autowired
	CoverageprocessesRepository coverageprocessesRepository;
	
	Logger logger = LoggerFactory.getLogger(CoverageprocessesController.class);

	@Transactional
	@PostMapping("/coverageprocesses")
	public ResponseEntity<EvalUnitsResponseDto> coverProcessUnit(HttpServletRequest request,@RequestBody EvalProcessRequestDto evalProcessRequestDto) throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);

		String searchIn = "";
		int statusIn = 0;
		int campaingIn=0;

		String searchModule = "";
		String searchUsr = "";
		String contentIn = "";
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		int rolisvalid = 0;

		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);
		
		Long resource= 0L;
		Long positions= 0L;
		
		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}
				
				// Obtengo el rol de usuario y verifico si corresponde al privilegio del usuario
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 340);
				//rolisvalid = 3;
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}
				
				// Obtengo los datos del Body
				searchIn = evalProcessRequestDto.getFilters().getSearch();// dato de busqueda por nombre
				
			    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
				  
				  if (Salida=="NOOK") {
					  String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				  }
				   
				statusIn = evalProcessRequestDto.getFilters().getStatus();// dato de busqueda por status
				campaingIn = evalProcessRequestDto.getFilters().getCampaignid();
				
				orderIn = evalProcessRequestDto.getOrder(); // Orden Ascedente o Descendente
				offsetIn = evalProcessRequestDto.getOffset();// Primer registro a mostrar
				numofrecordsIn = evalProcessRequestDto.getNumofrecords();// Número de registros a mostrar
				contentIn = evalProcessRequestDto.getContent();
				// Verifico los Shorcouts
				if (contentIn != null && contentIn != "")
					menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());

				try {
					Query query,query2,query3;
					Integer idUsuario2=encontreSessionUsuario.get().getId();
					//Cantidad de procesos a evaluar																										
				
					cuantosregistro=0;
					
					//SE INSERTA EN LA coverageprocesses los registros que no tengan entrada en dicha tabla, se valida por la clave compuesta :strategiesdetunitid,strategiesdetprocessid
					
				
					
					String SentenciaInsertUnits = " INSERT  INTO   main.coverageprocesses (strategiesdetunitid, strategiesdetprocessid,createdat,modifiedat) "
							+ " select su.id strategiesdetunitid,null strategiesdetprocessid,current_timestamp, current_timestamp from main.strategiesdetunits su "
							+ " INNER JOIN main.units u ON su.unitid = u.id and u.status=1     "
							+ " INNER JOIN   main.strategiesdet ed ON  su.strategydetid=ed.id AND ed.status=1     "
							+ " INNER JOIN    main.strategies e ON  ed.strategyid=e.id  "
							//+ "    where  su.strategydetid not in (  "
							+ "    where  cast(CONCAT(su.strategydetid,su.unitid) as integer) not in (  "
							+ "  select cast(CONCAT(sp.strategyid,su1.unitid) as integer) from main.strategiesdetprocesses sp    "
							+ "  inner join main.strategiesdetunits su1 ON su1.strategydetid = sp.strategyid "
							+ " inner join main.unitprocesses up on sp.unitprocessid = up.id  and su1.unitid = up.unitid )  "
							+ "    and su.unitid IN    (SELECT     UU.unitid   "
							+ "    FROM        main.userunits UU   "
							+ " WHERE        UU.userid=   " + idUsuario2 + " ) "  
							+ " AND    e.strategytypepar = 1  "
							+ " AND    e.strategydependencypar IN (1, 2, 3, 4, 5) "
							+ " and su.id not in (select strategiesdetunitid from main.coverageprocesses) ";
					
					System.out.println(SentenciaInsertUnits);
					query2 = entityManager.createNativeQuery(SentenciaInsertUnits);
					//query2.setParameter("idUsuario", idUsuario2);
					int cuantosregistro2 = query2.executeUpdate();
					
					String SentenciaInsertProcesses = " INSERT  INTO   main.coverageprocesses (strategiesdetunitid, strategiesdetprocessid,createdat,modifiedat) "
							+ " select  su.id,sp.id strategiesdetprocessid,current_timestamp, current_timestamp from main.strategiesdetprocesses sp	 "
							+ " INNER JOIN main.unitprocesses up  ON sp.unitprocessid = up.id and up.deleted is null  	 "
							+ " INNER JOIN main.units u ON up.unitid = u.id and u.status=1	 "
							+ " INNER JOIN  main.strategiesdet ed ON  sp.strategyid=ed.id AND ed.status=1 "
							+ " INNER JOIN main.strategiesdetunits su on su.unitid = up.unitid and su.strategydetid =ed.id "
							+ " INNER JOIN  main.strategies e ON  ed.strategyid=e.id  "
							+ "	where  up.unitid IN    (SELECT     UU.unitid   "
							+ "	FROM        main.userunits UU   "
							+ " WHERE        UU.userid=   " + idUsuario2 + " ) " 
							+ " AND    e.strategytypepar = 1  "
							+ " AND    e.strategydependencypar IN (1, 2, 3, 4, 5) "
							+ " AND sp.id not in (select strategiesdetprocessid from main.coverageprocesses where strategiesdetprocessid is not null)";
					// agregar a este query que la unidad este activa y en la relacion unitprocesses tenga el delete null
					
					System.out.println(SentenciaInsertProcesses);
					query3 = entityManager.createNativeQuery(SentenciaInsertProcesses);
					//query2.setParameter("idUsuario", idUsuario2);
					int cuantosregistro3 = query3.executeUpdate();
					
					//Luego query de consulta
					
					
					String QueryTotal="";
					String LowerSearch = searchIn.toLowerCase(); // se convierte en minúscula
					
					
		String SentenciaBase  = " SELECT   "
				+ "				     e.id AS idstrategiesdetunits,   "
				+ "				     ep.id AS idstrategiesdetprocesses,   "
				+ "				     e.strategydetid,   "
				+ "				     uu.unitid,   "
				+ "				     u.name AS nameunidad,   "
				+ "				     p.name AS proceso,   "
				+ "				     p.id AS idproceso,   "
				+ "				     ed.name AS namestra,   "
				+ "				     cov.estatus,   "
				+ "				     CAST(coalesce(cov.eval,0) AS integer) AS eval,   "
				+ "				     cov.id AS idcover,   "
				+ "				     ed.id AS idstra,   "
				+ "				     ed.status AS estatusestr,   "
				+ "				     coalesce(u.status,1) AS statusunit,   "
				+ "				     coalesce(p.status,1) AS statusprocess,   "
				+ "				     CAST(UP.deleted AS text)   "
				+ "				 FROM   "
				+ "				     (   "
				+ "				         SELECT   "
				+ "				             CASE WHEN tot.eval = tot.totalestatus THEN TRUE ELSE FALSE END AS estatus,   "
				+ "				             tot.eval,   "
				+ "				             tot.coverageprocessid,   "
				+ "				             cover.strategiesdetprocessid,   "
				+ "				             cover.strategiesdetunitid,   "
				+ "				             cover.id   "
				+ "				         FROM (   "
				+ "				             SELECT   "
				+ "				                 COUNT(1) AS eval,   "
				+ "				                 (SELECT COUNT(ch2.status)   "
				+ "				                  FROM main.coverageprocesseshistory ch2   "
				+ "				                  WHERE ch2.status = 1 AND ch2.coverageprocessid = ch.coverageprocessid) AS totalestatus,   "
				+ "				                 ch.coverageprocessid   "
				+ "				             FROM main.coverageprocesseshistory ch   "
				+ "				             GROUP BY ch.coverageprocessid   "
				+ "				         ) AS tot   "
				+ "				         RIGHT JOIN (    "
				+ "				             SELECT   "
				+ "				                 cp.strategiesdetprocessid,   "
				+ "				                 cp.strategiesdetunitid,   "
				+ "				                 cp.id   "
				+ "				             FROM main.coverageprocesses cp   "
				+ "				             LEFT JOIN main.coverageprocesseshistory ch ON ch.coverageprocessid = cp.id   "
				+ "				             GROUP BY cp.strategiesdetprocessid, cp.strategiesdetunitid, cp.id   "
				+ "				         ) AS cover ON tot.coverageprocessid = cover.id   "
				+ "				     ) AS cov   "
				+ "				 LEFT JOIN main.strategiesdetunits e ON cov.strategiesdetunitid = e.id   "
				+ "				 LEFT JOIN main.strategiesdetprocesses ep ON cov.strategiesdetprocessid = ep.id   "
				+ "				 LEFT JOIN main.strategiesdet ed ON ed.id = e.strategydetid   "
				+ "				 LEFT JOIN main.userunits uu ON e.unitid = uu.unitid   "
				+ "				 LEFT JOIN main.unitprocesses UP ON e.unitid = UP.unitid AND  ep.unitprocessid = UP.id "
				+ "	             LEFT JOIN main.processes p ON p.id = UP.processid AND ep.unitprocessid = UP.id  "
				+ "				 LEFT JOIN main.units u ON u.id = uu.unitid "
				+ "WHERE uu.userid =  " + idUsuario2;
					 	//	+ "	group by e.id,ep.id ,e.strategydetid,uu.unitid,u.name,p.name ,p.id,eg.name,cov.estatus,cov.eval,cov.id" ;
		//idUsuario2
					if (searchIn!=null) {
						switch (searchIn) {
							case "":
								QueryTotal = SentenciaBase + " AND 1=1 ";
								break;
							default: // viene con el parametro para buscar por el like
								QueryTotal = SentenciaBase + " AND ( lower(u.name) LIKE  " + "'%" + LowerSearch + "%'" +  " OR lower(p.name) LIKE  " + "'%" + LowerSearch + "%'" +  " OR lower(ed.name) LIKE  " + "'%" + LowerSearch + "%'" + " ) "  ;
								break;
						}
					}else {
						 respuesta.setMsg("Llamada al servicio malformado");
						 estatus = HttpStatus.BAD_REQUEST;
						 return new ResponseEntity(respuesta, estatus);
				 	 }

					
						switch (statusIn) {
							case 0:
								QueryTotal = QueryTotal + " AND 1=1 ";
								break;
							case 1:
								QueryTotal = QueryTotal + " AND estatus =  true";
								break;
							case 2:
								QueryTotal = QueryTotal + " AND estatus =  false ";
								break;
							default:
								respuesta.setMsg("Llamada al servicio malformado");
								estatus = HttpStatus.BAD_REQUEST;
								return new ResponseEntity(respuesta, estatus);
						 }
					
					
					switch (orderIn) {
						case 1: // ordena por nombre de unidad
							QueryTotal = QueryTotal + " ORDER BY u.name ASC ";
							break;
	
						case 2:// ordena por nombre de proceso
							QueryTotal = QueryTotal + " ORDER BY p.name ASC ";
							break;
	
						case 3: // ordena por estatus impactst
							QueryTotal = QueryTotal + " ORDER BY ed.name ASC";
							break;															
	
						case -1: // ordena por nombre de unidad
							QueryTotal = QueryTotal + " ORDER BY u.name DESC  ";
							break;
	
						case -2:// ordena por nombre de proceso
							QueryTotal = QueryTotal + " ORDER BY p.name DESC ";
							break;
	
						case -3: // ordena por estatus impactst
							QueryTotal = QueryTotal + " ORDER BY ed.name DESC ";
							break;
	
						default:
							respuesta.setMsg("Llamada al servicio mal formado");
							estatus = HttpStatus.BAD_REQUEST;
							return new ResponseEntity(respuesta, estatus);
					}
					
					query = entityManager.createNativeQuery(QueryTotal);
					//query.setParameter("idUsuario", idUsuario2);
					cuantosregistro = (long) query.getResultList().size();
					query.setFirstResult(offsetIn);
					query.setMaxResults(numofrecordsIn);
					List<Object[]> resultados = query.getResultList();
					
				
					
					CoverageRecordDet coverageRecordDto = new CoverageRecordDet();
					CoverageProcessUnitResponseDto coverageProcessUnitResponseDto = new CoverageProcessUnitResponseDto();
					CoverageEvaluationDto  coverageEvaluationDto = new CoverageEvaluationDto();
					List<CoverageRecordDet> listRecord = new ArrayList<>();
					
					
					UnitsResponseDto unitsResponseDto = new UnitsResponseDto();
					TotalPosiResUnitsDto statusPosiResour = new TotalPosiResUnitsDto();
					OperationlineDto operationDto = new OperationlineDto();
					OperationlineDto operationDtoPro = new OperationlineDto();
					OperationlineDto operationDtoStr = new OperationlineDto();
					OperationlineDtoStatus2 operationDtoStr2 = new OperationlineDtoStatus2();
					OperationlineUniProcessesDto operationDtoUni = new OperationlineUniProcessesDto();
					OperationlineUniProcessesDto operationDtoProcesses = new OperationlineUniProcessesDto();
					
					ProcessResponDto processResponDto = new ProcessResponDto();
					StatusEvalUnitsResponseDto statusResponseDto= new StatusEvalUnitsResponseDto();
					PrivilegesAllDto detallePrivilege = new PrivilegesAllDto();
					TotalPosiResUnitsDto totalsResponseDto = new TotalPosiResUnitsDto();
					//comentario
					Integer contador=0;
					Integer contadorPosition=0;
					Integer contadorResource=0;
					boolean Deleteboolean; 
					
					if (cuantosregistro > 0) {
						for (Object[] fila : resultados) {
							
							coverageRecordDto.setId((int) fila[10]);
							//seteando la unidad
							
							String deleteValue = (String) fila[15];
							//if (deleteValue=="") {
							if (deleteValue != null) {	
								Deleteboolean = true ;
							} else {
								Deleteboolean = false;
							}
							
							operationDtoUni.setId((int) fila[3]);
							operationDtoUni.setName((String) fila[4]);
							operationDtoUni.setStatus((int) fila[13]);	
							operationDtoUni.setDeleted(Deleteboolean);
							
							coverageRecordDto.setUnit(operationDtoUni);
							// seteando el proceso
							
							try {
								operationDtoProcesses.setId((int) fila[6]);
								operationDtoProcesses.setName((String) fila[5]);
								operationDtoProcesses.setStatus((int) fila[14]);
								operationDtoProcesses.setDeleted(Deleteboolean);
								
							}  catch(Exception e) { 
								Deleteboolean = false;
								operationDtoProcesses.setId(0);
								operationDtoProcesses.setName("");
								operationDtoProcesses.setStatus(0);
								operationDtoProcesses.setDeleted(Deleteboolean);
							}
							
							
							
							coverageRecordDto.setProcess(operationDtoProcesses);
							
							// setenado la estrategia
							
							operationDtoStr2.setId((int) fila[11]);
							operationDtoStr2.setName((String) fila[7]);
							operationDtoStr2.setStatus((int) fila[12]);
							
							coverageRecordDto.setStrategydet(operationDtoStr2);
							
							//seteando los datos de la evaluacion
							
							coverageEvaluationDto.setCnt((int) fila[9]);
							coverageEvaluationDto.setCompleted((boolean) fila[8]);
							coverageRecordDto.setEvaluations(coverageEvaluationDto);																			
							
							listRecord.add(coverageRecordDto);
							
							unitsResponseDto = new UnitsResponseDto();
							processResponDto = new ProcessResponDto();
							statusResponseDto= new StatusEvalUnitsResponseDto();
							
							coverageRecordDto = new CoverageRecordDet();
							//coverageProcessUnitResponseDto = new CoverageProcessUnitResponseDto();
							coverageEvaluationDto = new CoverageEvaluationDto();
							 operationDto = new OperationlineDto();
							 operationDtoPro = new OperationlineDto();
							 operationDtoStr = new OperationlineDto();
							 operationDtoStr2 = new OperationlineDtoStatus2();
							 operationDtoUni= new OperationlineUniProcessesDto();
							 operationDtoProcesses= new OperationlineUniProcessesDto();
							 
							 
						}
					
				
						
						
						rolisvalid=0;
						detallePrivilege = new PrivilegesAllDto();
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 341);
						if (rolisvalid>0)
							detallePrivilege.setUpdate(true);
						else
							detallePrivilege.setUpdate(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 340);
						if (rolisvalid>0)
							detallePrivilege.setView(true);
						else
							detallePrivilege.setView(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 342);
						if (rolisvalid>0)
							detallePrivilege.setAdd(true);
						else
							detallePrivilege.setAdd(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 343);
						if (rolisvalid>0)
							detallePrivilege.setDelete(true);
						else
							detallePrivilege.setDelete(false);
						
						coverageProcessUnitResponseDto.setNumofrecords(cuantosregistro);
						coverageProcessUnitResponseDto.setRecords(listRecord);
						coverageProcessUnitResponseDto.setSessionvalidthru(fechaComoCadena);
						//evalUnitsResponseDto.setTotals(totalsResponseDto);
						coverageProcessUnitResponseDto.setPrivileges(detallePrivilege);
						
						
					}else {
						rolisvalid=0;
						detallePrivilege = new PrivilegesAllDto();
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 341);
						if (rolisvalid>0)
							detallePrivilege.setUpdate(true);
						else
							detallePrivilege.setUpdate(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 340);
						if (rolisvalid>0)
							detallePrivilege.setView(true);
						else
							detallePrivilege.setView(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 342);
						if (rolisvalid>0)
							detallePrivilege.setAdd(true);
						else
							detallePrivilege.setAdd(false);

						rolisvalid=0;
						rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 343);
						if (rolisvalid>0)
							detallePrivilege.setDelete(true);
						else
							detallePrivilege.setDelete(false);
						
						coverageProcessUnitResponseDto.setNumofrecords(cuantosregistro);
						coverageProcessUnitResponseDto.setRecords(listRecord);
						coverageProcessUnitResponseDto.setSessionvalidthru(fechaComoCadena);
						//evalUnitsResponseDto.setTotals(totalsResponseDto);
						coverageProcessUnitResponseDto.setPrivileges(detallePrivilege);
					
					}
						
						return new ResponseEntity(coverageProcessUnitResponseDto, HttpStatus.OK);
				}catch(Exception e) {
					respuesta.setMsg("Error interno del servidor " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				}
				finally {
			        if (entityManager != null && entityManager.isOpen()) {
			            entityManager.close();
			        }
			    }
			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}
			return new ResponseEntity(respuesta, estatus);
		}
	}
	
	@GetMapping("/coverageprocesses/{coverageprocessid}/history")
	public ResponseEntity<?> coverEvaluacionProcessUnit(HttpServletRequest request,
			@PathVariable("coverageprocessid") final Integer coverageprocessid) 
			throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		
		int offsetIn = 0;
		int numofrecordsIn = 0;
		int rolisvalid = 0;

		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);
		
		Long resource= 0L;
		Long positions= 0L;
		
		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}
				
				// Obtengo el rol de usuario y verifico si corresponde al privilegio del usuario
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 340);
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}
				
				// Verifico si existe el id de la Evaluación de Cobertura de Procesos
				Optional<Coverageprocesses> obtCoverageProcesos = coverageprocessesRepository.findById(coverageprocessid);
				
				// Verifico si encontre la evaluaciòn de la cobertura de procesos
				if (!obtCoverageProcesos.isPresent()) {
					respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				}

				try {
					Query query,query2;
					Integer idUsuario2=encontreSessionUsuario.get().getId();
					//Cantidad de procesos a evaluar																										
				
					cuantosregistro=0;
					
					String SentenciaBase = " SELECT c.date, "
							+ "                     c.coveragestatepar, "
							+ "	                    ce.statec, "
							+ "	                    c.status, "
							+ "	                    (CASE WHEN c.status = 0 THEN 'En Proceso' ELSE 'Completada' END) AS desStatus, "
							+ "	                    c.coveragelevelpar AS idCoverage, "
							+ "	                    pr.coverage AS coverage, "
							+ "	                    c.dsc, "
							+ "	                    c.id "
							+ "              FROM main.coverageprocesseshistory c "
							+ "              LEFT JOIN (SELECT elemento ->> 'dsc' AS coverage,elemento ->> 'value' AS valor FROM  "
							+ "                         main.params p,jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento  "
							+ "                         WHERE p.paramname = 'COVERAGE_LEVEL' ) pr ON c.coveragelevelpar = CAST(pr.valor AS integer) "
							+ "              LEFT JOIN (SELECT elemento ->> 'dsc' AS statec,elemento ->> 'value' AS valor FROM  "
							+ "                         main.params p,jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento  "
							+ "                         WHERE p.paramname = 'COVERAGE_STATE' ) ce ON c.coveragestatepar = CAST(ce.valor AS integer) "
							+ "              WHERE c.coverageprocessid=:coverageprocessid "
							+ "              order by 1 DESC";
					
					String SentenciaUniProStrate = " SELECT          p.id as idprocess, "
							+ "		                                 p.name AS nombre_proceso, "
							+ "		                                 stu.unitid, "
							+ "		                                 u.name AS nombre_unidad, "
							+ "		                                 s.id as idstrategia, "
							+ "		                                 s.name AS nombre_estrate, "
							+ "		                                 s.status AS estatusestrate, "
							+ "	 u.status as estatusunit,COALESCE(p.status ,0)  as estatusproc,up.deleted AS TEXT, "
							+ "	  COALESCE(CAST(up.deleted AS TEXT), 'v')  "
							+ "                       FROM main.coverageprocesses c "
							+ "                       JOIN main.strategiesdetunits stu ON c.strategiesdetunitid=stu.id and c.id=:coverageprocessid "
							+ "	                      JOIN main.units u ON stu.unitid=u.id "
							+ "	                      JOIN main.strategiesdet s ON s.id=stu.strategydetid "
							+ "	                      LEFT JOIN main.strategiesdetprocesses stp ON c.strategiesdetprocessid=stp.id "
							+ "                      LEFT JOIN main.unitprocesses up on up.id =  stp.unitprocessid "
							+ "	                      LEFT JOIN main.processes p ON up.processid=p.id";
					
					query = entityManager.createNativeQuery(SentenciaBase);
					query.setParameter("coverageprocessid", coverageprocessid);
					cuantosregistro = (long) query.getResultList().size();
					query.setFirstResult(offsetIn);
					query.setMaxResults(numofrecordsIn);
					List<Object[]> resultados = query.getResultList();
					
					
					CoverageEvalProcessHistoryDto coverageEvalProcessHistoryDto= new CoverageEvalProcessHistoryDto();
					CoverageEvalProcessRecordsDto coverageEvalProcessRecordsDto = new CoverageEvalProcessRecordsDto();
					StrategiesDetDto strategiesDetDto=new StrategiesDetDto();
					OperationlineDtoStatus2 strategiesDetDto2 = new OperationlineDtoStatus2();
					
					//UnitsResponseDto unitsResponseDto = new UnitsResponseDto();
					UnitsUsersDto2 unitsResponseDto = new UnitsUsersDto2();
					//ProcessResponDto processResponDto = new ProcessResponDto();		
					UnitsUsersDto3 processResponDto = new UnitsUsersDto3();
					List<CoverageEvalProcessRecordsDto> records= new ArrayList();
					StateDto state = new StateDto();
					StatusDto2 status = new StatusDto2();
					CoverageDto covergae = new CoverageDto();		
					query2 = entityManager.createNativeQuery(SentenciaUniProStrate);
					query2.setParameter("coverageprocessid", coverageprocessid);
					List<Object[]> resultados2 = query2.getResultList();
					
					for (Object[] fila : resultados2) {
						unitsResponseDto.setId((int) fila[2]);
						unitsResponseDto.setName((String) fila[3]);
						unitsResponseDto.setStatus((int) fila[7]);
						
						processResponDto.setId(fila[0]==null ? 0:(int) fila[0]);
						processResponDto.setName(fila[1]==null? "":(String) fila[1]);
						processResponDto.setStatus((int) fila[8]);
						
						String deletestring = (String) fila[10];
						
							if (deletestring.length()==1) {
								processResponDto.setDeleted(false);
				        	} else if (deletestring.length()>1) {
				        		processResponDto.setDeleted(true);
				        	} else {
				        		processResponDto.setDeleted(false);
				        	}
						
						
						strategiesDetDto2.setId((int) fila[4]);
						strategiesDetDto2.setName((String) fila[5]);
						strategiesDetDto2.setStatus((int) fila[6]);
					}
					
					if (cuantosregistro > 0) {
						for (Object[] fila : resultados) {
							coverageEvalProcessRecordsDto.setId((Integer) fila[8]);
							coverageEvalProcessRecordsDto.setDate((Date) fila[0]);
							coverageEvalProcessRecordsDto.setDsc((String) fila[7]);
							state.setId((int) fila[1]);
							state.setName((String) fila[2]);
							
							status.setId((int) fila[3]);
							status.setName((String) fila[4]);
							
							covergae.setId((int) fila[5]);
							covergae.setName((String) fila[6]);
							coverageEvalProcessRecordsDto.setState(state);
							coverageEvalProcessRecordsDto.setStatus(status);
							coverageEvalProcessRecordsDto.setCoverage(covergae);
							records.add(coverageEvalProcessRecordsDto);
							
							coverageEvalProcessRecordsDto = new CoverageEvalProcessRecordsDto();
							state = new StateDto();
							status = new StatusDto2();
							covergae = new CoverageDto();	
						}
					
							
						
						coverageEvalProcessHistoryDto.setNumofrecords(cuantosregistro);
						coverageEvalProcessHistoryDto.setSessionvalidthru(fechaComoCadena);
						coverageEvalProcessHistoryDto.setProcess(processResponDto);
						coverageEvalProcessHistoryDto.setUnit(unitsResponseDto);
						coverageEvalProcessHistoryDto.setStrategydet(strategiesDetDto2);
						coverageEvalProcessHistoryDto.setRecords(records);
						
					}else {
						coverageEvalProcessHistoryDto.setNumofrecords(cuantosregistro);
						coverageEvalProcessHistoryDto.setSessionvalidthru(fechaComoCadena);
						coverageEvalProcessHistoryDto.setProcess(processResponDto);
						coverageEvalProcessHistoryDto.setUnit(unitsResponseDto);
						coverageEvalProcessHistoryDto.setStrategydet(strategiesDetDto2);
						coverageEvalProcessHistoryDto.setRecords(records);
					}
						
						return new ResponseEntity(coverageEvalProcessHistoryDto, HttpStatus.OK);
				}catch(Exception e) {
					respuesta.setMsg("Error interno del servidor " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				}
				finally {
			        if (entityManager != null && entityManager.isOpen()) {
			            entityManager.close();
			        }
			    }
			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}
			return new ResponseEntity(respuesta, estatus);
		}
	}
	
	@GetMapping("/coverageprocesses/{coverageprocessid}/history/{coverageprocesseshistoryid}")
	public ResponseEntity<?> coverEvaluacionObtenerUnoHistoria(HttpServletRequest request,
			@PathVariable("coverageprocessid") final Integer coverageprocessid,
	        @PathVariable("coverageprocesseshistoryid") final Integer coverageprocesseshistoryid)
			throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		
		int offsetIn = 0;
		int numofrecordsIn = 0;
		int rolisvalid = 0;

		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);
		
		Long resource= 0L;
		Long positions= 0L;
		
		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}
				
				// Obtengo el rol de usuario y verifico si corresponde al privilegio del usuario
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 340);
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}
				

				try {
					Query query,query2,query3;
					Integer idUsuario2=encontreSessionUsuario.get().getId();
					//Cantidad de procesos a evaluar																										
				
					cuantosregistro=0;
					
					String SentenciaBase = " SELECT c.id, "
							+ "                     c.date, "
							+ "                     c.coveragestatepar, "
							+ "	                    ce.statec, "
							+ "	                    c.status, "
							+ "	                    (CASE WHEN c.status = 1 THEN 'En Proceso' ELSE 'Completada' END) AS desStatus, "
							+ "	                    c.coveragelevelpar AS idCoverage, "
							+ "	                    pr.coverage AS coverage, "
							+ "	                    c.dsc "
							+ "              FROM main.coverageprocesseshistory c "
							+ "              LEFT JOIN (SELECT elemento ->> 'dsc' AS coverage,elemento ->> 'value' AS valor FROM  "
							+ "                         main.params p,jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento  "
							+ "                         WHERE p.paramname = 'COVERAGE_LEVEL' ) pr ON c.coveragelevelpar = CAST(pr.valor AS integer) "
							+ "              LEFT JOIN (SELECT elemento ->> 'dsc' AS statec,elemento ->> 'value' AS valor FROM  "
							+ "                         main.params p,jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento  "
							+ "                         WHERE p.paramname = 'COVERAGE_STATE' ) ce ON c.coveragestatepar = CAST(ce.valor AS integer) "
							+ "              WHERE c.coverageprocessid=:coverageprocessid "
							+ "                AND c.id=:coverageprocesseshistoryid"
							+ "              order by 1 ASC";
					
					query = entityManager.createNativeQuery(SentenciaBase);
					query.setParameter("coverageprocessid", coverageprocessid);
					query.setParameter("coverageprocesseshistoryid", coverageprocesseshistoryid);
					cuantosregistro = (long) query.getResultList().size();
					query.setFirstResult(offsetIn);
					query.setMaxResults(numofrecordsIn);
					List<Object[]> resultados = query.getResultList();
					
					EntryCoverageProcessesDto entryCoverageProcessesDto = new EntryCoverageProcessesDto();
					EntryCoverageProcessesDto2 entryCoverageProcessesDto2 = new EntryCoverageProcessesDto2();
					StateDto state = new StateDto();
					StatusDto2 status = new StatusDto2();
					CoverageDto covergae = new CoverageDto();	
					LevelDto levelDto = new LevelDto();
					List<LevelDto> levelDtoList = new ArrayList();
					StateDetailDto stateDetailDto = new StateDetailDto();
					List<StateDetailDto> stateDetailDtoList = new ArrayList();
					String QueryLevels = "SELECT CAST(elem AS TEXT) " + "	FROM main.params pa, "
							+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
							+ "	WHERE pa.paramname = 'COVERAGE_LEVEL' ";

					String QueryStates = "SELECT CAST(elem AS TEXT) " + "	FROM main.params pa, "
							+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
							+ "	WHERE pa.paramname = 'COVERAGE_STATE' ";
					
					query2 = entityManager.createNativeQuery(QueryLevels);
					List<Object[]> resultadosLevels = query2.getResultList();
					
					JSONObject jsonObject;
					String jsonStringPeriod = "";
					if (resultadosLevels.size() > 0) {
						for (Object levels : resultadosLevels) {
							jsonStringPeriod = (String) levels; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringPeriod); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							levelDto.setDsc(dsc);
							levelDto.setValue(value);
							levelDtoList.add(levelDto);
							levelDto = new LevelDto();
						}
					}
					
					query3 = entityManager.createNativeQuery(QueryStates);
					List<Object[]> resultadosStates = query3.getResultList();
					
					String jsonStringScale = "";
					if (resultadosStates.size() > 0) {
						for (Object states : resultadosStates) {
							jsonStringScale = (String) states; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringScale); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							stateDetailDto.setDsc(dsc);
							stateDetailDto.setValue(value);
							stateDetailDtoList.add(stateDetailDto);
							stateDetailDto = new StateDetailDto();
						}
					}
					
					if (cuantosregistro > 0) {
						for (Object[] fila : resultados) {
							entryCoverageProcessesDto2.setId((int) fila[0]);
							entryCoverageProcessesDto2.setDate((Date) fila[1]);
							entryCoverageProcessesDto2.setDsc((String) fila[8]);
							state.setId((int) fila[2]);
							state.setName((String) fila[3]);
							
							status.setId((int) fila[4]);
							status.setName((String) fila[5]);
							
							covergae.setId((int) fila[6]);
							covergae.setName((String) fila[7]);
							entryCoverageProcessesDto2.setState(state);
							entryCoverageProcessesDto2.setStatus(status);
							entryCoverageProcessesDto2.setCoverage(covergae);
							
						}
						
					}else {
						entryCoverageProcessesDto2.setId(0);
						entryCoverageProcessesDto2.setDate(null);
						entryCoverageProcessesDto2.setDsc(null);
						entryCoverageProcessesDto2.setState(null);
						entryCoverageProcessesDto2.setStatus(null);
						entryCoverageProcessesDto2.setCoverage(null);
					}
						entryCoverageProcessesDto.setEntry(entryCoverageProcessesDto2);
						entryCoverageProcessesDto.setLevels(levelDtoList);
						entryCoverageProcessesDto.setStates(stateDetailDtoList);
						return new ResponseEntity(entryCoverageProcessesDto, HttpStatus.OK);
				}catch(Exception e) {
					respuesta.setMsg("Error interno del servidor " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				}
				finally {
			        if (entityManager != null && entityManager.isOpen()) {
			            entityManager.close();
			        }
			    }
			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}
			return new ResponseEntity(respuesta, estatus);
		}
	}
	
	
	@PostMapping({ "/coverageprocesses/{coverageprocessid}/history/{coverageprocesseshistoryid}" })
	public ResponseEntity<?> actualizarCoverageProcessHistory(HttpServletRequest request,
			@RequestBody CoverageHistoryActualizarDto coverageHistoryActualizarDto,
			@PathVariable("coverageprocessid") final Integer coverageprocessid,
			@PathVariable("coverageprocesseshistoryid") final Integer coverageprocesseshistoryid)
			throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		AuditRequestDto auditDto = new AuditRequestDto();

		String contentIn = "";
		int orderIn = 0;
		int offsetIn = 0;
		int numofrecordsIn = 0;
		int rolisvalid = 0;

		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);

		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
        // calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
        // lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);

        // Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {

		
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}

			
				
				// Verifico si existe el id de la Evaluación de Cobertura de Procesos
				Optional<Coverageprocesses> obtCoverageProcesos = coverageprocessesRepository.findById(coverageprocessid);
				
				// Verifico si encontre la evaluaciòn de la cobertura de procesos
				if (!obtCoverageProcesos.isPresent()) {
					respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				}
				String module, Descmodule = "";
				Query query;

				try {

					if (coverageprocesseshistoryid != 0) {// actualizar cobertura de procesos de historia
						try {
							// verifico si tiene el privilegio
							rolisvalid = auditRepository
									.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 341);
							if (rolisvalid == 0) {
								respuesta.setMsg("No tiene los Privilegios");
								estatus = HttpStatus.FORBIDDEN;
								return new ResponseEntity(respuesta, estatus);
							}
																											
					    	       // Verifico si existe el id de la Evaluación de Cobertura de App
								   /*Optional<Coverageprocesses> obtCoverageProcesos2 = coverageprocessesRepository.findById(coverageprocessid);
					    	       Optional<Strategiesdet> estrategia=strategiesdetRepository.findById(obtCoverageProcesos2.get().getStrategiesdetprocessid().getStrategyid());
					    	      // Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(obtCoverageProcesos2.get().getStrategiesdetunitid().getStrategydetid());
								if (estrategia.isPresent()){
									if (estrategia.get().getStatus()==0) {
										respuesta.setMsg("Estrategia Inactiva");
										estatus = HttpStatus.CONFLICT;
										return new ResponseEntity(respuesta, estatus);
									}
								}*/
					       

							
							// Verifico si existe la cobertura de procesos de historia
							Optional<Coverageprocesseshistory> obtCoverageProcess = coverageprocesseshistoryRepository.findByCoverageprocesseshistory(coverageprocessid, coverageprocesseshistoryid);
							Coverageprocesseshistory coverageprocesseshistory =new Coverageprocesseshistory();
							Coverageprocesseshistory coverageprocesseshistory2 =new Coverageprocesseshistory();
							// Verifico si encontre el proceso
							if (!obtCoverageProcess.isPresent()) {
								respuesta.setMsg("Registro no encontrado");
								return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
							}
							
									
							if (coverageprocesseshistoryRepository.existByCoverageprocesseshistory(coverageprocessid, coverageHistoryActualizarDto.getDate())>0 
									&& obtCoverageProcess.get().getCoverageprocessid().getId()!=coverageprocessid) {
								respuesta.setMsg("Registro Duplicado");
								return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
							}
							
							
							coverageprocesseshistory=obtCoverageProcess.get();
							//asi lo tenia originalmente Neldy
							//Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(coverageprocesseshistory.getCoverageprocessid().getStrategiesdetprocessid().getStrategyid());
							//Lo cambie a esta linea
							Optional<Coverageprocesses> obtCoveragePro = coverageprocessesRepository.findById(coverageprocessid);
							Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(obtCoveragePro.get().getStrategiesdetunitid().getStrategydetid());
							 // final de la modificacion - jackson
							
							if (estrategia2.isPresent()){
								if (estrategia2.get().getStatus()==0) {
									respuesta.setMsg("Estrategia Inactiva");
									estatus = HttpStatus.CONFLICT;
									return new ResponseEntity(respuesta, estatus);
								}
							}
							
							Optional<Coverageprocesses> obtCoverageProcess2=coverageprocessesRepository.findById(coverageprocessid);
							coverageprocesseshistory.setCoveragelevelpar(coverageHistoryActualizarDto.getCoveragelevelpar());
							coverageprocesseshistory.setCoveragestatepar(coverageHistoryActualizarDto.getCoveragestatepar());
							coverageprocesseshistory.setCoverageprocessid(obtCoverageProcess2.get());
							coverageprocesseshistory.setModifiedat(fechaDate2);
							coverageprocesseshistory.setDate(coverageHistoryActualizarDto.getDate());
							coverageprocesseshistory.setStatus(coverageHistoryActualizarDto.getStatus());
							coverageprocesseshistory.setDsc(coverageHistoryActualizarDto.getDsc());
							coverageprocesseshistory2=coverageprocesseshistoryRepository.save(coverageprocesseshistory);
							// Auditoría
							module = "Cobertura de Procesos";
							Descmodule = "Se actualizó la Evaluación de Coberturas de Procesos de Historia: "
									+ coverageprocesseshistory2.getId();
							auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
							String singo1 = "(";
							String singo2 = ")";
							String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
									.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
							auditDto.setUserref(usryemail);
							auditDto.setModule(module);
							auditDto.setDesc(Descmodule);
							auditDto.setCreatedat(fechaDate2);
							usersService.registrarAuditSesion(auditDto);

							RespuestaValueDto respuestaValueDto = new RespuestaValueDto(coverageprocesseshistory2.getId());
							URI location = URI.create("/coverageprocesses/" + coverageprocessid + "/history/" + coverageprocesseshistory2.getId()); 
							return ResponseEntity.created(location).body(respuestaValueDto);

						} catch (Exception e) {
							respuesta.setMsg("Error interno del servidor " + e.getMessage());
							estatus = HttpStatus.INTERNAL_SERVER_ERROR;
						} finally {
							if (entityManager != null && entityManager.isOpen()) {
								entityManager.close();
							}
						}

					} else {
						try {
							// verifico si tiene el privilegio
							rolisvalid = auditRepository
									.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 342);
							if (rolisvalid == 0) {
								respuesta.setMsg("No tiene los Privilegios");
								estatus = HttpStatus.FORBIDDEN;
								return new ResponseEntity(respuesta, estatus);
							}

							
							Coverageprocesseshistory coverageprocesseshistory =new Coverageprocesseshistory();
							Coverageprocesseshistory coverageprocesseshistory2 =new Coverageprocesseshistory();
							
							Optional<Coverageprocesses> obtCoverageProcess=coverageprocessesRepository.findById(coverageprocessid);
							if (coverageprocesseshistoryRepository.existByCoverageprocesseshistory(coverageprocessid, coverageHistoryActualizarDto.getDate())>0) {
								respuesta.setMsg("Registro Duplicado");
								return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
							}
							
							//coverageprocesseshistory=obtCoverageProcess.get();
							//asi lo tenia originalmente Neldy
							//Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(coverageprocesseshistory.getCoverageprocessid().getStrategiesdetprocessid().getStrategyid());
							//Lo cambie a esta linea
							Optional<Coverageprocesses> obtCoveragePro = coverageprocessesRepository.findById(coverageprocessid);
							Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(obtCoveragePro.get().getStrategiesdetunitid().getStrategydetid());
							
							 // final de la modificacion - jackson
							
							//Optional<Strategiesdet> estrategia2=strategiesdetRepository.findById(obtCoverageProcess.get().getStrategiesdetprocessid().getStrategyid());
							if (estrategia2.isPresent()){
								if (estrategia2.get().getStatus()==0) {
									respuesta.setMsg("Estrategia Inactiva");
									estatus = HttpStatus.CONFLICT;
									return new ResponseEntity(respuesta, estatus);
								}
							}
							
							coverageprocesseshistory.setCoverageprocessid(obtCoverageProcess.get());
							coverageprocesseshistory.setCoveragelevelpar(coverageHistoryActualizarDto.getCoveragelevelpar());
							coverageprocesseshistory.setCoveragestatepar(coverageHistoryActualizarDto.getCoveragestatepar());
							coverageprocesseshistory.setDate(coverageHistoryActualizarDto.getDate());
							coverageprocesseshistory.setStatus(coverageHistoryActualizarDto.getStatus());
							coverageprocesseshistory.setDsc(coverageHistoryActualizarDto.getDsc());
							coverageprocesseshistory.setModifiedat(fechaDate2);
							coverageprocesseshistory.setCreatedat(fechaDate2);
							
							coverageprocesseshistory2=coverageprocesseshistoryRepository.save(coverageprocesseshistory);
							// Auditoría
							module = "Cobertura de Procesos";
							Descmodule = "Se agregó la Evaluación de Coberturas de Procesos de Historia: "
									+ coverageprocesseshistory2.getId();
							auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
							String singo1 = "(";
							String singo2 = ")";
							String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
									.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
							auditDto.setUserref(usryemail);
							auditDto.setModule(module);
							auditDto.setDesc(Descmodule);
							auditDto.setCreatedat(fechaDate2);
							usersService.registrarAuditSesion(auditDto);

							RespuestaValueDto respuestaValueDto = new RespuestaValueDto(coverageprocesseshistory2.getId());
							URI location = URI.create("/coverageprocesses/" + coverageprocessid + "/history/" + coverageprocesseshistory2.getId()); 
							return ResponseEntity.created(location).body(respuestaValueDto);

						} catch (Exception e) {
							respuesta.setMsg("Error interno del servidor " + e.getMessage());
							estatus = HttpStatus.INTERNAL_SERVER_ERROR;
						} finally {
							if (entityManager != null && entityManager.isOpen()) {
								entityManager.close();
							}
						}
					}

				} catch (Exception e) {
					respuesta.setMsg("Error interno del servidor " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				} finally {
					if (entityManager != null && entityManager.isOpen()) {
						entityManager.close();
					}
				}

			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}
			return new ResponseEntity(respuesta, estatus);
		}
	}
	
	@DeleteMapping({ "/coverageprocesses/{coverageprocessid}/history/{coverageprocesseshistoryid}" })
	public ResponseEntity<?> deleteCoverageHistoryProcesses(HttpServletRequest request,
			@PathVariable("coverageprocessid") final Integer coverageprocessid,
			@PathVariable("coverageprocesseshistoryid") final Integer coverageprocesseshistoryid) throws ParseException {
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);

		AuditRequestDto auditDto = new AuditRequestDto();
		String module = "";
		String Descmodule = "";

		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);

		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);

		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {

			sessionid = sessionid.substring(7); // verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				if (fechaComoCadena == "") {
					RespuestaMsgDto respuestaDto2;
					String var2 = "";
					boolean bloked2 = false;
					respuestaDto2 = new RespuestaMsgDto(var2);
					respuestaDto2.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
				}

				int rolisvalid = 0;
				try {

					// verifico si tiene el privilegio
					rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(),
							343);
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}
					
					Optional<Coverageprocesses> obtCoverageProcesos = coverageprocessesRepository.findById(coverageprocessid);
					
					// Verifico si encontre la evaluaciòn de la cobertura de procesos
					if (!obtCoverageProcesos.isPresent()) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}
					
				    // Verifico si existe el id de la Evaluación de Cobertura de Procesos
					   Optional<Coverageprocesses> obtCoverageProcesos2 = coverageprocessesRepository.findById(coverageprocessid);
		    	      // Optional<Strategiesdet> estrategia=strategiesdetRepository.findById(obtCoverageProcesos2.get().getStrategiesdetprocessid().getStrategyid());
		    	       Optional<Strategiesdet> estrategia=strategiesdetRepository.findById(obtCoverageProcesos2.get().getStrategiesdetunitid().getStrategydetid());
					if (estrategia.isPresent()){
						if (estrategia.get().getStatus()==0) {
							respuesta.setMsg("Estrategia Inactiva");
							estatus = HttpStatus.CONFLICT;
							return new ResponseEntity(respuesta, estatus);
						}
					}
					
			

					Optional<Coverageprocesseshistory> obtCoverage = coverageprocesseshistoryRepository.findByCoverageprocesseshistory(coverageprocessid, coverageprocesseshistoryid);
					
					// Verifico si encontre la evaluaciòn de la cobertura de procesos en la tabla de historia
					if (!obtCoverage.isPresent()) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}

					try {
						coverageprocesseshistoryRepository.delete(obtCoverage.get());
						
						module = "Cobertura de Procesos";
						Descmodule = "Se Eliminó la Evaluación de Cobertura de Procesos de História con Id:" + coverageprocesseshistoryid;
						auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
						String singo1 = "(";
						String singo2 = ")";
						String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
								.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
						auditDto.setUserref(usryemail);
						auditDto.setModule(module);
						auditDto.setDesc(Descmodule);
						auditDto.setCreatedat(fechaDate2);
						usersService.registrarAuditSesion(auditDto);

						RespuestaValueDto respuestaValueDto = new RespuestaValueDto(coverageprocesseshistoryid);
						
						URI location = URI.create("/coverageprocesses/" + coverageprocessid + "/history/" + coverageprocesseshistoryid); 
						
						return ResponseEntity.created(location).body(respuestaValueDto);
					} catch (Exception e) {
						respuesta.setMsg("No se pudo borrar por alguna razón");
						estatus = HttpStatus.CONFLICT;
						return new ResponseEntity(respuesta, estatus);
					} finally {
						if (entityManager != null && entityManager.isOpen()) {
							entityManager.close();
						}
					}
				} catch (Exception e) {
					respuesta.setMsg("Error interno. Descripción del error " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					return new ResponseEntity(respuesta, estatus);
				} finally {
					if (entityManager != null && entityManager.isOpen()) {
						entityManager.close();
					}
				}
			}
			return new ResponseEntity(respuesta, HttpStatus.OK);
		}
	}
}