package com.dacrt.SBIABackend.controler;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

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

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
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.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
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.AppTypeDto;
import com.dacrt.SBIABackend.dto.CampaignFormat2Dto;
import com.dacrt.SBIABackend.dto.ChannelsRecordDto;
import com.dacrt.SBIABackend.dto.EnddateDto;
import com.dacrt.SBIABackend.dto.EntryRiskEvaluationsDto;
import com.dacrt.SBIABackend.dto.EntryRiskEvaluationsDto2;
import com.dacrt.SBIABackend.dto.FailDto;
import com.dacrt.SBIABackend.dto.InitialdateDto;
import com.dacrt.SBIABackend.dto.PrivilegesRiskDto;
import com.dacrt.SBIABackend.dto.RecordCatalogoResponseDto;
import com.dacrt.SBIABackend.dto.RiskFactorsElementDto;
import com.dacrt.SBIABackend.dto.RiskFactorsEntryRecordDto2;
import com.dacrt.SBIABackend.dto.RiskFactorsRecordDto;
import com.dacrt.SBIABackend.dto.RiskRecordDto;
import com.dacrt.SBIABackend.dto.ScalesDto;
import com.dacrt.SBIABackend.dto.SceneryDto2;
import com.dacrt.SBIABackend.dto.ServiceOffersDescDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.TypesUnitDto;
import com.dacrt.SBIABackend.dto.scalesDtoAll;
import com.dacrt.SBIABackend.dto.requestDto.ElementDto;
import com.dacrt.SBIABackend.dto.requestDto.EvalProcessesAppRequestDto;
import com.dacrt.SBIABackend.dto.requestDto.FactorDto;
import com.dacrt.SBIABackend.dto.requestDto.RiskRequestDto;
import com.dacrt.SBIABackend.dto.requestDto.SupplierRequestDto;
import com.dacrt.SBIABackend.dto.responseDto.EvalRiskResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.RiskFactorsResponseDto;
import com.dacrt.SBIABackend.entity.Applications;
import com.dacrt.SBIABackend.entity.Evalprocapps;
import com.dacrt.SBIABackend.entity.Evalprocesses;
import com.dacrt.SBIABackend.entity.Instrumentriskfactors;
import com.dacrt.SBIABackend.entity.Instruments;
import com.dacrt.SBIABackend.entity.Riskevalfactorelements;
import com.dacrt.SBIABackend.entity.Riskevalfactors;
import com.dacrt.SBIABackend.entity.Riskevaluations;
import com.dacrt.SBIABackend.entity.Riskfactorelements;
import com.dacrt.SBIABackend.entity.Riskfactors;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Unitprocesses;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.repository.ApplicationsRepository;
import com.dacrt.SBIABackend.repository.CampaignsRepository;
import com.dacrt.SBIABackend.repository.EvalprocappsRepository;
import com.dacrt.SBIABackend.repository.EvalprocessesRepository;
import com.dacrt.SBIABackend.repository.EvalprosuppliersRepository;
import com.dacrt.SBIABackend.repository.InstrumentriskfactorsRepository;
import com.dacrt.SBIABackend.repository.InstrumentsRepository;
import com.dacrt.SBIABackend.repository.RiskevalfactorelementsRepository;
import com.dacrt.SBIABackend.repository.RiskevalfactorsRepository;
import com.dacrt.SBIABackend.repository.RiskevaluationsRepository;
import com.dacrt.SBIABackend.repository.RiskfactorelementsRepository;
import com.dacrt.SBIABackend.repository.RiskfactorsRepository;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.ParamsDto;
import com.dacrt.SBIABackend.security.dto.ParamsResponseDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesAllDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesDto;
import com.dacrt.SBIABackend.security.dto.RespuestaDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.dto.UsersListDto;
import com.dacrt.SBIABackend.security.entity.Params;
import com.dacrt.SBIABackend.security.entity.Roles;
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 EvalRiskController {
	
	@Autowired
	private ParamsRepository paramsRepository;
	
	@Autowired
	private UsersRepository usersRepository;
	
	@Autowired
	private AuditRepository auditRepository;
	
	@Autowired
	private EvalprosuppliersRepository evalprosuppliersRepository;
	
	@Autowired
	private RiskevaluationsRepository riskevaluationsRepository2;
	
	@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
	InstrumentsRepository instrumentsRepository;
	
	@Autowired
	InstrumentriskfactorsRepository instrumentriskfactorsRepository;
	
	@Autowired
	RiskfactorsRepository riskfactorsRepository;
	
	@Autowired
	RiskevaluationsRepository riskevaluationsRepository;
	
	@Autowired
	RiskevalfactorsRepository riskevalfactorsRepository;
	
	@Autowired
	RiskevalfactorelementsRepository riskevalfactorelementsRepository;
	
	@Autowired
	InstrumentriskfactorsRepository instrumentRiskFactorsRepository;
	
	@Autowired
	RiskfactorelementsRepository riskFactorElementsRepository;
	
	

	@Autowired
    private JdbcTemplate jdbcTemplate;
	
	@Value("${var.ambiente}")
	private String urlAmbiente;
	
	
	
	
	@PersistenceContext
    private EntityManager entityManager;
	
	@Autowired
	EvalprocessesRepository evalprocessesRepository;
	
	Logger logger = LoggerFactory.getLogger(EvalRiskController.class);
	
	@Transactional(rollbackOn = Exception.class) // <--- CRITICO: Habilita el rollback
	@PostMapping("/riskevaluations/{riskevaluationid}")
	public ResponseEntity<ParamsResponseDto> evalRiskUpsert(HttpServletRequest request,
			@Valid @RequestBody RiskRequestDto datosvp, @PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, SQLException {
		// @GetMapping("/vicepresidencies/{vicepresidencyid}")

		RespuestaValueDto respuestaValueDto;
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ParamsResponseDto paramsResponseDto = new ParamsResponseDto();
		ParamsDto detalleParams;
		PrivilegesDto detallePrivilege;
		List<ParamsDto> listasParams = new ArrayList<>();
		List<PrivilegesDto> listasPrivelege = new ArrayList<>();

		int idparametro = riskevaluationid;

		int valor = idparametro;
		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		Date fechaDate = formatter.parse(dataFormattata);
		AuditRequestDto auditDto = new AuditRequestDto();
		Optional<Users> encontreSessionUsuario;
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		Statement sentenciaPreparada2 = null;
		// Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
			// respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Llamada al servicio malformado");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			String fechaComoCadena;

			if (encontreSessionUsuario.isPresent()) {

				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);
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				if (fechaComoCadena == "") {

					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);

				}
				
	                 String SalidaDsc = usersService.verificarCaracteresValidosConRegex(datosvp.getRelatedItemDsc());
					  
					  if (SalidaDsc=="NOOK") {
						  String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("Caracteres no permitidos en la busqueda Desc"); 
							return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
					  }
					  String mensajeestatus;
					  switch (datosvp.getStatus()) { 
					    case 1:  // Busca por cualquier estatus
					    	 mensajeestatus = "ok";
					     break;
					    case 0:  // Busca por estatus activo
					    	
					    	 mensajeestatus = "ok";
					     break;
					    
					  
					    default:	// viene con el parametro para buscar por el like		   			    				    	
					    	String var2 = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
							respuestaDto= new RespuestaMsgDto("Llamada al servicio mal Formado");
							estatus=HttpStatus.BAD_REQUEST;   
							return new ResponseEntity(respuestaDto, estatus);
					    	
			         }
					  
                
			if (idparametro == 0) {
				
				Optional<Riskevaluations> existingEval = riskevaluationsRepository2.findDuplicate(
				        datosvp.getInstrument(),
				        datosvp.getRelatedItemId(),
				        datosvp.getRelatedItemDsc(),
				        datosvp.getInitialDate()
				    );
				
				if (existingEval.isPresent()) {
			        RespuestaMsgDto respuestaDto = new RespuestaMsgDto("");
			        respuestaDto.setMsg("Ya existe una evaluación para este instrumento y elemento en la fecha seleccionada.");
			        return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // Error 409 es ideal para duplicados
			    }
					// el permiso es el 632
					Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 822);
					// rolisvalid = 3;
					if (rolisvalid == 0) {

						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("No tiene los Privilegios");
						return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

					}

				} else {

					Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 821);
					// rolisvalid = 3;
					if (rolisvalid == 0) {

						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("No tiene los Privilegios");
						return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

					}

					boolean existeSup = riskevaluationsRepository.existsById(idparametro);
					
					if (!existeSup) {

						String var = "";
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Registro No encontrado");
						// Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);

					}
					
				}

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				respuestaDto.setMsg("Sesión expirada o inválida");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Suppliers tiposupl2 = null;
			Riskevaluations tipoRiskEval = null;
			Riskevalfactors tipoRiskEvalFac = null;
			Riskevalfactorelements tipoEvalFactorEle = null;
			 Integer vScenery =0;
			Suppliers tiposupl = null;
			String mensajeAudit="";
			String vDescEscenario = "";
			String vDescInstrumento = "";
			  String vDescValor="";
			Suppliers tiposuplNew2 = null;
			Optional<Suppliers> nuevoinsertado = null;
			Instruments vInstrument=null;
			if (idparametro==0) {
			    if (!instrumentsRepository.existsById(datosvp.getInstrument())) {
          	       String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado - el Id del Instrumento no existe");
					estatus=HttpStatus.BAD_REQUEST;   
					return new ResponseEntity(respuestaDto, estatus);
                 } 
			    else 
				 {
	            	 
					  vInstrument = instrumentsRepository.getById(datosvp.getInstrument());				 
					  vScenery = vInstrument.getScenery();
					  vDescInstrumento = vInstrument.getName();
					  String descScenery = " SELECT  "
								+ "    elemento ->> 'dsc' AS descr,  "
								+ "    elemento ->> 'value' AS valor 	  "
								+ "FROM  "
								+ "    main.params p,  "
								+ "    jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
								+ "WHERE  "
								+ "    p.paramname = 'RISK_SCENERIES'  "
								+ "    AND " + vScenery +  "= CAST(elemento ->> 'value' AS integer);";
						
						
						Query query;
					      query = entityManager.createNativeQuery(descScenery);
						   List<Object[]> listacompleta = query.getResultList();
						  
						   for (Object[] reg : listacompleta) {	
							   vDescEscenario = ((String) reg[0]);
							   vDescValor = ((String) reg[1]);
							   
						   }
						   mensajeAudit= " Escenario con id: " + vDescValor + " con nombre: "+vDescEscenario + " , Instrumento con Id: " + vInstrument.getId() + " con nombre: "+ vDescInstrumento +  
								     ", Elemento con Id: " + datosvp.getRelatedItemId()  + " con nombre: " + datosvp.getRelatedItemDsc();
								
						   
	             }	 
			} 
				
				
				     
				    //mensajeAudit= " con id de Escenario: " + vScenery + " + Desc de Escenario: " +  vDescEscenario + " -> Instrumento: " + vDescInstrumento + " -> Elemento Evaluado: " + datosvp.getRelatedItemDsc();

			if (datosvp.getAttenuator()==null)
				datosvp.setAttenuator(new BigDecimal(0));
             
			if (datosvp.getImpact()==null)
				datosvp.setImpact(new BigDecimal(0));
			
			if (datosvp.getProbability()==null)
				datosvp.setProbability(new BigDecimal(0));

			if (idparametro == 0) {

				Suppliers tipoSuplNew = new Suppliers();
				Riskevaluations tipoRiskEvalNew = new Riskevaluations();
				 if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
				 
				 if (datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
				 
				 if (datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
					 String var2 = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
						respuestaDto= new RespuestaMsgDto("Llamada al servicio malformado");
						estatus=HttpStatus.BAD_REQUEST;   
						return new ResponseEntity(respuestaDto, estatus);
				 } 
                                         							
			 
				 tipoRiskEvalNew.setInstrumentid(datosvp.getInstrument());
				 tipoRiskEvalNew.setInstrumentname(vDescInstrumento);
				 tipoRiskEvalNew.setInitialdate(datosvp.getInitialDate());
				 tipoRiskEvalNew.setRelateditem(datosvp.getRelatedItemId());
				 tipoRiskEvalNew.setRelateditemdsc(datosvp.getRelatedItemDsc());
				 tipoRiskEvalNew.setStatus(datosvp.getStatus()); 
				 tipoRiskEvalNew.setProbability(datosvp.getProbability());
				 tipoRiskEvalNew.setImpact(datosvp.getImpact());
				 tipoRiskEvalNew.setAttenuator(datosvp.getAttenuator());
				 tipoRiskEvalNew.setDsc(datosvp.getDsc());
				 tipoRiskEvalNew.setScenery(vScenery);
				 tipoRiskEvalNew.setScenerydsc(vDescEscenario);
				 tipoRiskEvalNew.setCreatedat(fechaDate); 
				 tipoRiskEvalNew.setModifiedat(fechaDate);
				 if (datosvp.getEndDate()==null && datosvp.getStatus()==0) 
					 tipoRiskEvalNew.setEnddate(fechaDate);
				 else
					 tipoRiskEvalNew.setEnddate(datosvp.getEndDate());
								 								 						
				 Riskevaluations savedEval = riskevaluationsRepository2.save(tipoRiskEvalNew);
				 
				// --- INICIO LÓGICA AUTOMÁTICA ---
				 List<FactorDto> factoresAProcesar = datosvp.getFactors();

				 // Si el JSON no trae factores, los buscamos en las tablas maestras por el Instrumento
				 if (factoresAProcesar == null || factoresAProcesar.isEmpty()) {
				     factoresAProcesar = obtenerFactoresDesdeMaestras(datosvp.getInstrument());
				 }
				 // --- FIN LÓGICA AUTOMÁTICA ---

				 // Ahora procesamos la lista (ya sea la del JSON o la que cargamos de la BD)
				 if (factoresAProcesar != null) {
				     for (FactorDto fDto : factoresAProcesar) {
				         Riskevalfactors factor = new Riskevalfactors();
				         factor.setRiskevaluationid(savedEval.getId());
				         factor.setRiskfactorid(fDto.getId()); 
				         factor.setRiskcategory(fDto.getCategory());
				       //  factor.setWeight(fDto.getWeight().intValue());
				         factor.setWeight(fDto.getWeight());
				         factor.setRiskfactornam(fDto.getName());
				         factor.setRiskfactordsc(fDto.getDsc());
				         Riskevalfactors savedFactor = riskevalfactorsRepository.save(factor);

				         if (fDto.getElements() != null) {
				             for (ElementDto eDto : fDto.getElements()) {
				                 Riskevalfactorelements element = new Riskevalfactorelements();
				                 element.setRiskevalfactorid(savedFactor.getId());
				                 element.setRiskfactorelementid(eDto.getId());
				                 element.setRiskfactorelementdsc(eDto.getDsc());
				     			
				     			if (eDto.getImpact()==null)
				     				eDto.setImpact(new BigDecimal(0));

				     			if (eDto.getProbability()==null)
				     				eDto.setProbability(new BigDecimal(0));
				     			
				                 element.setProbability(eDto.getProbability());
				                 element.setImpact(eDto.getImpact());
				                 element.setWeight(eDto.getWeight());
				                 element.setActive(0); // Por defecto activo al ser carga automática
				                 
				                 riskevalfactorelementsRepository.save(element);
				             }
				         }
				     }
				 }

			
				 
			
				//int idInsertado = nuevoinsertado.get().getId();
				int idInsertado= savedEval.getId();
				int idmensaje = idInsertado;

				////////////////////////// INSERCION BLOQUE DE AUDITORIA///////////////////
				String module = "Evaluación de Riesgo";
				// String Descmodule = "Actualización de parametro del Sistema con id: " +
				// parmid ;
				String Descmodule = "Se agregó la Evaluación de Riesgo " +  " con Id: " + idInsertado  + " " + mensajeAudit;

				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(fechaDate);
				usersService.registrarAuditSesion(auditDto);

				respuestaValueDto = new RespuestaValueDto(idmensaje);
				estatus = HttpStatus.OK;
				return new ResponseEntity(respuestaValueDto, estatus);
			 } else {
				// --- LÓGICA PARA MODIFICAR (UPDATE) ---
				    
				    // 1. Verificar que la evaluación de riesgo exista
				    Optional<Riskevaluations> opRiskEval = riskevaluationsRepository2.findById(idparametro);
				    int idEvalFactorInsertado;
				    if (!opRiskEval.isPresent()) {
				        return new ResponseEntity(new RespuestaMsgDto("La evaluación de riesgo no existe"), HttpStatus.NOT_FOUND);
				    }

				    Riskevaluations evalToUpdate = opRiskEval.get();

				    mensajeAudit= " Escenario con id: " + evalToUpdate.getScenery() + " con nombre: "+ evalToUpdate.getScenerydsc() + " , Instrumento con Id: " + evalToUpdate.getInstrumentid() + " con nombre: "+ evalToUpdate.getInstrumentname() +  
						     ", Elemento con Id: " + evalToUpdate.getRelateditem()  + " con nombre: " + evalToUpdate.getRelateditemdsc();
				    
				    // 2. Validaciones de negocio (ej. valores negativos)
				    if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
				        return new ResponseEntity(new RespuestaMsgDto("Llamada al servicio malformado: valores negativos"), HttpStatus.BAD_REQUEST);
				    }


				    // 3. Actualizar campos de la entidad principal
				    evalToUpdate.setInstrumentid(evalToUpdate.getInstrumentid());
				    evalToUpdate.setInstrumentname(evalToUpdate.getInstrumentname());
				    evalToUpdate.setInitialdate(datosvp.getInitialDate());
				    evalToUpdate.setRelateditem(datosvp.getRelatedItemId());
				    evalToUpdate.setRelateditemdsc(datosvp.getRelatedItemDsc());
				    evalToUpdate.setStatus(datosvp.getStatus());
				    evalToUpdate.setProbability(datosvp.getProbability());
				    evalToUpdate.setImpact(datosvp.getImpact());
				    evalToUpdate.setAttenuator(datosvp.getAttenuator());
				    evalToUpdate.setScenery(evalToUpdate.getScenery());
				    evalToUpdate.setScenerydsc(evalToUpdate.getScenerydsc());
				    evalToUpdate.setDsc(datosvp.getDsc());
				    evalToUpdate.setModifiedat(fechaDate); // Fecha de modificación actual
				    if (datosvp.getEndDate()==null && datosvp.getStatus()==0) 
				    	evalToUpdate.setEnddate(fechaDate);
					 else
						 evalToUpdate.setEnddate(datosvp.getEndDate());
				    
				    riskevaluationsRepository2.save(evalToUpdate);

				    // 4. Gestionar Factores y Elementos
				    // Recomendación: Eliminar los existentes para evitar duplicados o huérfanos
				    // (Asegúrate de tener este método en tus repositorios o manejar la lógica de borrado)
				    
				    // Suponiendo que borramos los factores previos asociados a esta evaluación:
				    // riskevalfactorsRepository.deleteByRiskevaluationid(idparametro);

				    if (datosvp.getFactors() != null) {
				        for (FactorDto fDto : datosvp.getFactors()) {
				            // 1. Obtener o actualizar el Factor
				         //   Riskevalfactors factor = riskevalfactorsRepository.getByRiskevaluationid(idparametro);
				            //Riskevalfactors factor = riskevalfactorsRepository.getByRiskevaluationidAndRiskfactorid(idparametro,fDto.getId());
				           //Optional<Riskevalfactors> factor = riskevalfactorsRepository.findByRiskevaluationidAndRiskfactorid(riskevaluationid, fDto.getId());
				            Optional<Riskevalfactors> factor = riskevalfactorsRepository.findById(fDto.getId());
				            Riskevalfactors factor2 = new Riskevalfactors();
				            factor2  = factor.get();
				            // Si por alguna razón el factor no existe para esa evaluación, lo creamos
				            if (factor2 == null) {
				                factor2 = new Riskevalfactors();
				                factor2.setRiskevaluationid(idparametro);
				            }
				            
				            factor2.setWeight(fDto.getWeight());
				            factor2.setRiskcategory(fDto.getCategory());
				            //factor.setWeight(fDto.getWeight().intValue());
				            Riskevalfactors savedFactor = riskevalfactorsRepository.save(factor2);

				            // --- AQUÍ EL CAMBIO CRÍTICO PARA ELEMENTOS ---
				            
				            // 2. BORRADO PREVIO: Eliminamos todos los elementos actuales de este factor
				            // Asegúrate de tener este método en tu RiskevalfactorelementsRepository
				            riskevalfactorelementsRepository.deleteByRiskevalfactorid(savedFactor.getId());

				            // 3. INSERCIÓN NUEVA: Si el JSON trae elementos, los insertamos todos de cero
				            if (fDto.getElements() != null) {
				                for (ElementDto eDto : fDto.getElements()) {
				                    // Solo insertamos si vienen como activos (o según tu lógica de negocio)
				                  //  if (eDto.getActive() != 0) { 
				                        Riskevalfactorelements element = new Riskevalfactorelements();
				                        element.setRiskevalfactorid(savedFactor.getId());
				                        element.setRiskfactorelementid(eDto.getId());
				                        element.setRiskfactorelementdsc(eDto.getDsc());
				                        if (eDto.getImpact()==null)
						     				eDto.setImpact(new BigDecimal(0));

						     			if (eDto.getProbability()==null)
						     				eDto.setProbability(new BigDecimal(0));
						     			
				                        element.setProbability(eDto.getProbability());
				                        element.setImpact(eDto.getImpact());
				                        element.setWeight(eDto.getWeight());
				                        element.setActive(eDto.getActive());

				                        riskevalfactorelementsRepository.save(element);
				                    //}
				                }
				            }
				        }
				    }

				    Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 824);

					if (rolisvalid == 0) { //No tiene el privilegio 824
						if (datosvp.getEndDate()!=null) {
							String maxRISKEVALOPENLIMIT = "SELECT p.value FROM main.params p WHERE p.paramname = 'RISK_EVALOPENLIMIT'";
							    
							  try {
								    Query query2 = entityManager.createNativeQuery(maxRISKEVALOPENLIMIT);
								    List<Object> resultados = query2.getResultList();
		
								    if (!resultados.isEmpty()) {
								        // 1. Extraemos el valor (ej: "10")
								        String maximoDiasStr = resultados.get(0).toString();
								        int dias = Integer.parseInt(maximoDiasStr);
		
								        LocalDate base = datosvp.getEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
								        LocalDate fechaAbir = base.plusDays(dias);
		
								        if (fechaAbir.isBefore(LocalDate.now())) {
								        	evalToUpdate.setStatus(0); //estatus completado
								        }
								    }
								} catch (NumberFormatException e) {
								    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("El valor de RISK_EVALOPENLIMIT no es un número: " + e.getMessage());
						            return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
								} catch (Exception e) {
									RespuestaMsgDto respuestaDto = new RespuestaMsgDto(e.getMessage());
						            return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
								}
						
						}

					}
				    
				    // 5. Auditoría de Modificación
				    String module = "Evaluación de Riesgo";
				    String Descmodule = "Se modificó la Evaluación de Riesgo con Id: " + idparametro + ", " + mensajeAudit ;

				    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); // Usar la descripción de modificación
				    auditDto.setCreatedat(fechaDate);
				    usersService.registrarAuditSesion(auditDto);

				    return new ResponseEntity(new RespuestaValueDto(idparametro), HttpStatus.OK);
			 }
			

		} catch (DataIntegrityViolationException e) {
		    // ESTO SE DISPARA POR: Duplicados, llaves foráneas inexistentes, etc.
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error de integridad: El registro ya existe o datos relacionados son inválidos.");
		    return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // HTTP 409

		} catch (Exception e) {
		    // ERROR GENÉRICO (500)
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error interno: " + e.getMessage());
		    return new ResponseEntity(respuestaDto, HttpStatus.INTERNAL_SERVER_ERROR);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		//return new ResponseEntity(respuesta, estatus);

	}
	
	@Transactional(rollbackOn = Exception.class) // <--- CRITICO: Habilita el rollback
	@PostMapping("/riskevaluations/attupdate/{riskevaluationid}")
	public ResponseEntity<ParamsResponseDto> evalRiskUpsertAtt(HttpServletRequest request,
			@Valid @RequestBody RiskRequestDto datosvp, @PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, SQLException {
		// @GetMapping("/vicepresidencies/{vicepresidencyid}")

		RespuestaValueDto respuestaValueDto;
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ParamsResponseDto paramsResponseDto = new ParamsResponseDto();
		ParamsDto detalleParams;
		PrivilegesDto detallePrivilege;
		List<ParamsDto> listasParams = new ArrayList<>();
		List<PrivilegesDto> listasPrivelege = new ArrayList<>();

		int idparametro = riskevaluationid;

		int valor = idparametro;
		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		Date fechaDate = formatter.parse(dataFormattata);
		AuditRequestDto auditDto = new AuditRequestDto();
		Optional<Users> encontreSessionUsuario;
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		Statement sentenciaPreparada2 = null;
		// Connection conexion2 = DriverManager.getConnection(conexion,userbd, passbd);
		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
			// respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Llamada al servicio malformado");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			String fechaComoCadena;

			if (encontreSessionUsuario.isPresent()) {

				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);
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());
				if (fechaComoCadena == "") {

					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Sesión expirada o inválida");
					return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);

				}
				       

					Roles roles = encontreSessionUsuario.get().getRolid();
					int idrol = roles.getId();
					int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 821);
					int rolisvalid2 = auditRepository.getCantbyRolAndPrivi(idrol, 825);
					int rolisvalid3 = auditRepository.getCantbyRolAndPrivi(idrol, 826);
					if (rolisvalid == 0) {

						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("No tiene los Privilegios");
						return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

					}
					if (rolisvalid2 == 0) {

						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("No tiene los Privilegios");
						return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

					}
					if (rolisvalid3 == 0) {

						String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("No tiene los Privilegios");
						return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);

					}

					boolean existeSup = riskevaluationsRepository.existsById(idparametro);
					

					if (!existeSup) {

						String var = "";
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						// respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Registro No encontrado-No existe la evaluación");
						// Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);

					}
				

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				respuestaDto.setMsg("Sesión expirada o inválida");
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

		
			Riskevaluations tipoRiskEval = null;
			Riskevalfactors tipoRiskEvalFac = null;
			Riskevalfactorelements tipoEvalFactorEle = null;
			Integer vScenery; 
			 
			Suppliers tiposuplNew2 = null;
			Optional<Suppliers> nuevoinsertado = null;
			
 {
				// --- LÓGICA PARA MODIFICAR (UPDATE) ---
				    
				    // 1. Verificar que la evaluación de riesgo exista
				    Optional<Riskevaluations> opRiskEval = riskevaluationsRepository2.findById(idparametro);
				    int idEvalFactorInsertado;
				   
				    Riskevaluations evalToUpdate = opRiskEval.get();

				    // 2. Validaciones de negocio (ej. valores negativos)
				  /*  if (datosvp.getAttenuator().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getImpact().compareTo(BigDecimal.ZERO) < 0 || 
				        datosvp.getProbability().compareTo(BigDecimal.ZERO) < 0) {
				        return new ResponseEntity(new RespuestaMsgDto("Llamada al servicio malformado: valores negativos"), HttpStatus.BAD_REQUEST);
				    }*/

				  
				    evalToUpdate.setAttenuator(datosvp.getAttenuator());
				  
				    
				    riskevaluationsRepository2.save(evalToUpdate);

				    // 4. Gestionar Factores y Elementos
				    // Recomendación: Eliminar los existentes para evitar duplicados o huérfanos
				    // (Asegúrate de tener este método en tus repositorios o manejar la lógica de borrado)
				    
				    // Suponiendo que borramos los factores previos asociados a esta evaluación:
				    // riskevalfactorsRepository.deleteByRiskevaluationid(idparametro);


				    // 5. Auditoría de Modificación
				    String module = "Actualización de Atenuación";
				    String Descmodule = "Se modificó la Atenuación a "  + datosvp.getAttenuator() +  " de la Evaluación de Riesgo con Id: " + idparametro;

				    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); // Usar la descripción de modificación
				    auditDto.setCreatedat(fechaDate);
				    usersService.registrarAuditSesion(auditDto);

				    return new ResponseEntity(new RespuestaValueDto(idparametro), HttpStatus.OK);
			 }
			

		} catch (DataIntegrityViolationException e) {
		    // ESTO SE DISPARA POR: Duplicados, llaves foráneas inexistentes, etc.
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error de integridad: El registro ya existe o datos relacionados son inválidos.");
		    return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT); // HTTP 409

		} catch (Exception e) {
		    // ERROR GENÉRICO (500)
		    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		    
		    RespuestaMsgDto respuestaDto = new RespuestaMsgDto("Error interno: " + e.getMessage());
		    return new ResponseEntity(respuestaDto, HttpStatus.INTERNAL_SERVER_ERROR);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}


	}

	private List<FactorDto> obtenerFactoresDesdeMaestras(Integer instrumentId) {
	    List<FactorDto> listaFactores = new ArrayList<>();
	    
	    // 1. Buscamos los factores vinculados al instrumento
	    List<Instrumentriskfactors> relaciones = instrumentRiskFactorsRepository.findByInstrumentid(instrumentId);

	    for (Instrumentriskfactors rel : relaciones) {
	        FactorDto fDto = new FactorDto();
	        
	        // --- CAMBIO: Buscamos la entidad maestra del factor para obtener nombre y descripción ---
	        Optional<Riskfactors> opRf = riskfactorsRepository.findById(rel.getRiskfactorid());
	        
	        if (opRf.isPresent()) {
	            Riskfactors rf = opRf.get();
	            
	            fDto.setId(rf.getId());
	            fDto.setName(rf.getName()); // <-- ASIGNAMOS EL NOMBRE
	            fDto.setDsc(rf.getDsc());   // <-- ASIGNAMOS LA DESCRIPCIÓN
	            fDto.setWeight(rel.getWeight()); // El peso se mantiene de la tabla relacional (específico del instrumento)
	            
	            // 2. Buscamos los elementos de ese factor
	            List<ElementDto> listaElementos = new ArrayList<>();
	            List<Riskfactorelements> elementosBase = riskFactorElementsRepository.findByRiskfactorid(rf);
	            
	            for (Riskfactorelements eb : elementosBase) {
	                ElementDto eDto = new ElementDto();
	                eDto.setId(eb.getId());
	                eDto.setDsc(eb.getName()); 
	                eDto.setWeight(eb.getWeight());
	                eDto.setProbability(BigDecimal.ZERO); 
	                eDto.setImpact(BigDecimal.ZERO);
	                eDto.setActive(1);
	                listaElementos.add(eDto);
	            }
	            
	            fDto.setElements(listaElementos);
	            listaFactores.add(fDto);
	        }
	    }
	    
	    return listaFactores;
	}
	
	
	@PostMapping("/riskevaluations")
	public ResponseEntity<?> lisriskevaluations(HttpServletRequest request,HttpServletResponse response,@RequestBody UsersListDto tiposfiltros) throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
	//	ParamsDto detalleParams;
		RiskRecordDto detalleRiskRecordDto;
		List<RiskRecordDto> listasRiskRecordDto= new ArrayList<>();
		
		
		RiskFactorsElementDto detalleRiskFactorsElementDto;
		List<RiskFactorsElementDto> listasRiskFactorsElementDto= new ArrayList<>();
		
		PrivilegesRiskDto detallePrivilege;
		RiskFactorsRecordDto detalleRiskFactorsRecordDto;
		List<RiskFactorsRecordDto> listasRiskFactorsRecordDto= new ArrayList<>();
		EvalRiskResponseDto riskFactorsResponseDto = new EvalRiskResponseDto();
		 
		StatusDto2 detalleStatus;
		StatusDto2 detalleType;
		StatusDto2 detalleScenery;
		StatusDto detalleStatus2;
		StatusDto2 detalleElement;
		StatusDto2 detalleInstrument;
		
		StatusDto2 detallecapacityperiod;
		ServiceOffersDescDto detalleserviceoffers;
		RiskFactorsElementDto detalleElements;
		List<TypesUnitDto> listasTypes = new ArrayList<>();
			     
	     Long cuantosregistro = (long) 0;
	     
	     List<PrivilegesRiskDto> listasPrivelege = new ArrayList<>();
	     List<RiskFactorsRecordDto> listasRecordRisk= new ArrayList<>();
	     
	     TypesUnitDto detalleTypes;
	     TypesUnitDto detallePeriodos;
	     List<TypesUnitDto> listasPeriodos = new ArrayList<>();
		 
		 String sessionid = request.getHeader("Authorization");
		  Date fecha = new Date();
		    SimpleDateFormat  formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        String dataFormattata = formatter.format(fecha);
	        Date fechaDate = formatter.parse(dataFormattata);
	        AuditRequestDto  auditDto=new AuditRequestDto();
	       	     
	      int idrol;
	   	  String searchIn = "";
	   	  String contentIn = "";
	     // String searchModule = "";
		  int searchStatus = 0;
		  int typeIn=0;
		  String fechaComoCadena; 
		 int orderIn = 0;
		 int offsetIn = 0;
		 int numofrecordsIn = 0;
		 Date fecha2 = new Date();
		
			if (sessionid==null) {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				//Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
			} else   {
				 
				   sessionid = sessionid.substring(7);
				   Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
				
				   
				   if (encontreSessionUsuario.isPresent()) {
					   
					   Date FechaReg = encontreSessionUsuario.get().getValidthru(); 

					   fechaComoCadena  = securityService.consultarSessionActiva(FechaReg,fecha2,encontreSessionUsuario.get().getId());
           
					    if (fechaComoCadena=="") {
						   
						   
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("Sesión expirada o inválida"); 
							return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
						   
					    }
					    
					    
					  // Este proceso permite obtener un listado de los proveedores. (Priv 440)
					   Roles roles = encontreSessionUsuario.get().getRolid();
					   idrol = roles.getId();
					   int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);
					
					  // if (!mostraTodo) {
					        if (rolisvalid==0) {
						   
						   String var = "";
							boolean bloked = false;
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							//respuestaDto.setBlocked(bloked);
							respuestaDto.setMsg("No tiene los Privilegios"); 
							return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
					        }	
					   
						  searchIn = tiposfiltros.getFilters().getSearch();
						  
						  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);
						  }
						 
						       
						   searchIn = usersService.eliminarAcentosService(tiposfiltros.getFilters().getSearch());
						   searchStatus = tiposfiltros.getFilters().getStatus();
					
						  orderIn = tiposfiltros.getOrder();
						  offsetIn = tiposfiltros.getOffset();
						  numofrecordsIn = tiposfiltros.getNumofrecords();
						  contentIn = tiposfiltros.getContent();
						  
						  
						  try {
							  typeIn= tiposfiltros.getFilters().getSceneryid();
								 if (typeIn==0) {
									  typeIn = 0;
								  }
								  
							  }  catch (Exception e) { 
								  
								  typeIn = 0;
								  
							  }
							
						  
						  if (contentIn !=null) {
						     menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());
						  }
						 
					
					
				 } else {
						String var = "";
						boolean bloked = false;
						RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
						respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Sesión expirada o inválida");
						//Error 400
						return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
				 }
			}
			
			
		
		try {
			
			String SentenciaBase;
		
		
			
			/*SentenciaBase = " SELECT  re.id, it.id as idisntrumento, it.name,re.scenery, re.scenerydsc AS scenery_name, "
					+ "							 re.status,  CASE WHEN re.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, "
					+ "							 re.probability,re.impact,re.attenuator ,re.dsc,re.relateditem,re.relateditemdsc, "
					+ "	(re.probability * re.impact * re.attenuator) AS severidad "
					+ "							 FROM main.riskevaluations re "
					+ "							 LEFT JOIN main.instruments it  on it.id = re.instrumentid ";*/
			
			SentenciaBase = " SELECT  re.id, re.instrumentid, re.instrumentname,re.scenery, re.scenerydsc AS scenery_name, 	"						
			                 + " re.status,  CASE WHEN re.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, 	"					
			                 + "  re.probability,re.impact,re.attenuator ,re.dsc,re.relateditem,re.relateditemdsc, "
			                 + "  (re.probability * re.impact * re.attenuator) AS severidad "							 
			                  + "   FROM main.riskevaluations re ";
			
				Query query;
				 String QueryTotal;
			
			String name = " re.instrumentname ";
			String status = "re.status ";				
			String lowernameInst = "main.sinacentos(LOWER(re.instrumentname)) ";
			String lowerelemento = "main.sinacentos(LOWER(re.relateditemdsc)) ";
			String lowerdscParams = "main.sinacentos(LOWER(re.scenerydsc)) ";
			String LowerSearch = searchIn.toLowerCase();
			
			 switch (searchIn) { 
			    case "":  
			    	
			    	QueryTotal = SentenciaBase  + " WHERE TRUE = TRUE";
			     break;
			  
			    default:	  
			         	    QueryTotal = SentenciaBase + " WHERE (" + lowernameInst + " LIKE  " + "'%" + LowerSearch + "%'"  + " OR " +  lowerelemento + " LIKE " + "'%" + LowerSearch + "%' " + " OR " + lowerdscParams + " LIKE " + "'%" + LowerSearch + "%')";
			    	
			    	
	         }
			 
			 switch (searchStatus) { 
			    case 0:  // Busca por cualquier estatus
			    	QueryTotal = QueryTotal;
			     break;
			    case 1:  // Busca por estatus activo
			    	
			    	QueryTotal = QueryTotal  + " AND " + status + " = " + searchStatus;
			     break;
			    case 2:  // Busca por estatus Inactivo
			    	
			    	QueryTotal = QueryTotal  + " AND " + status + " <> " + 1;
			     break;
			  
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			    	
	         }
			 
				 
			    switch (typeIn) { 
			    case 0: 
			      	QueryTotal = QueryTotal;
			     break;
			    case 1: 
			    	
			    	QueryTotal = QueryTotal  + " AND " + " re.scenery " + " = " + typeIn;
			     break;
			    case 2: 
			    	
			    	QueryTotal = QueryTotal  + " AND " + " re.scenery " + " = " + typeIn;
			     break;
			     
                 case 3:  
			    	
			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
			     break;
                 case 4:  
 			    	
 			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
 			     break;
                 case 5:  
 			    	
 			    	QueryTotal = QueryTotal  + " AND " +  " re.scenery " + " = " + typeIn;
 			     break;
			    default:	// viene con el parametro para buscar por el like		   			    				    	
			    	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			    	
	         }
		     
		
		    //  QueryTotal = QueryTotal + groupby;
		      query = entityManager.createNativeQuery(QueryTotal);	  			            	        
			    	     			 			 			
			 
			 String ordena="";
			  if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 5 || orderIn == 6 || orderIn == 7 || orderIn == 8 || orderIn == 99) {
				  ordena = " ASC";
			 }  else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || orderIn == -5 || orderIn == -6 || orderIn == -7 || orderIn == -8 || orderIn == -99) {
				  ordena = " DESC";
			 } else {
				 	String var2 = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var2);
					respuestaDto= new RespuestaMsgDto("Error interno del servidor");
					estatus=HttpStatus.INTERNAL_SERVER_ERROR;   
					return new ResponseEntity(respuestaDto, estatus);
			 }		
			 int absolutoOrden = Math.abs(orderIn);			 			 			 			 
			 switch (absolutoOrden) { 
			    case 1:  //ordena por name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + " re.scenerydsc " + ordena + ", " + name + ordena  ;
			     break;
			    case 2://ordena por status ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + name + ordena;
			     break;	
                case 3:  //ordena por name ascendente
			    	
			    	QueryTotal = QueryTotal + " ORDER BY " + " re.relateditemdsc " + ordena;
			     break;
                case 4:  //ordena por name ascendente
 	
 	             QueryTotal = QueryTotal + " ORDER BY " + " re.probability " + ordena;
                 break;
                case 5:  //ordena por name ascendente
                 	
    	             QueryTotal = QueryTotal + " ORDER BY "   + " re.impact " + ordena;
                    break;
                case 6:  //ordena por name ascendente
                 	
   	             QueryTotal = QueryTotal + " ORDER BY "   + " severidad" + ordena;
                   break;
                case 7:  //ordena por name ascendente
                 	
   	             QueryTotal = QueryTotal + " ORDER BY "   + " re.attenuator " + ordena;
                   break;
                case 8:  //ordena por name ascendente
                 	
      	             QueryTotal = QueryTotal + " ORDER BY "   + " re.status " + ordena;
                      break;    
                case 99:   //ordena por status ascendente
                	
                    QueryTotal = QueryTotal + " ORDER BY " + " re.id " + ordena;
                break; 
			 
			    
			   }
	  
	
	   
				       query = entityManager.createNativeQuery(QueryTotal);
				       cuantosregistro = (long) query.getResultList().size();	
				       query.setFirstResult(offsetIn);
					   query.setMaxResults(numofrecordsIn);
					   List<Object[]> listacompleta = query.getResultList();
				
			   
		    	   listasRiskRecordDto= new ArrayList<>();
		    		 for (Object[] reg : listacompleta) {	  
		    				//RiskRecordDto detalleRiskRecordDto;
		    				
		    		  detalleRiskRecordDto = new RiskRecordDto(); 			 
		    		   detalleStatus = new StatusDto2();
		    		   detalleScenery = new StatusDto2();
		    		   detalleInstrument= new StatusDto2();
		    		   detalleElement= new StatusDto2();
		    		   
		    		
		    		   ///////////////////////llenando el scenery//////////////////
		    		 //  detalleScenery.setId((int) reg[3]);
		    		   detalleRiskRecordDto.setId((int) reg[0]);
		    		   ///seteando el instrumento/////
		    		   detalleInstrument.setId((int) reg[1]);
		    		   detalleInstrument.setName((String) reg[2]);
		    		   
		    		   detalleRiskRecordDto.setInstrument(detalleInstrument);
		    		   ///seteando el scenery/////
		    		   detalleScenery.setId((int) reg[3]);
		    		   detalleScenery.setName((String) reg[4]);
		    		   detalleRiskRecordDto.setScenery(detalleScenery);
		    		   ///////////////////////////////////////////////////////
		    		   /////seteando el elemento//////////////
		    		   detalleElement.setId((int) reg[11]);
		    		   detalleElement.setName((String) reg[12]);
		    		   detalleRiskRecordDto.setElement(detalleElement);
		    		   ////////////////////////////
		    		   
		    		   /////////////////////llenando el estatus//////////////////////
		    		   detalleStatus.setId((int) reg[5]);
			    	   detalleStatus.setName((String) reg[6]);			    	   			    	   				 
			    	   detalleRiskRecordDto.setStatus(detalleStatus);
		    		 
		    		  ////////////seteando los valores restantes//////////
			    	   
			    	   detalleRiskRecordDto.setProbability((BigDecimal) reg[7]);
			    	   detalleRiskRecordDto.setImpact((BigDecimal) reg[8]);
			    	   detalleRiskRecordDto.setAttenuator((BigDecimal) reg[9]);
			    	   detalleRiskRecordDto.setDsc((String) reg[10]);
			    	   ////////////////////////////////////////////
			    	   
			    	   listasRiskRecordDto.add(detalleRiskRecordDto);
			    		
		    	   }
		    	
		    	   
      	    	 	detallePrivilege = new PrivilegesRiskDto();
      	    	       boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,820);
					   boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,821);
					   boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,822);
					   boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,823);
					   boolean tieneUpdatt = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,825);
					   //existsByRolidAndPrivilegeid
					   
	      	    	 	detallePrivilege.setView(tieneView);
			    	  	detallePrivilege.setUpdate(tieneUpdate);		    	  
			    	  	detallePrivilege.setAdd(tieneAdd);
			    	  	detallePrivilege.setDelete(tieneDelete);
			    	  	detallePrivilege.setUpdatt(tieneUpdatt);
			    	  	
			    	  	 String SetenciaSceneries="";
							
			    	  	SetenciaSceneries= "SELECT  elemento ->> 'dsc' AS descr,elemento ->> 'value' AS valor "
					 		+ " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento WHERE paramname = 'RISK_SCENERIES' ORDER BY valor ASC";
					      
					      Query queryTypes = entityManager.createNativeQuery(SetenciaSceneries);
					       List<Object[]> listasceneries= queryTypes.getResultList();
					       for (Object[] types : listasceneries) {
					    	   detalleTypes = new TypesUnitDto();
					    	  
					    	   detalleTypes.setDsc((String) types[0]);
					    	   detalleTypes.setValue((String) types[1]);
					    	   listasTypes.add(detalleTypes);
					       }
		    	          
					       riskFactorsResponseDto.setNumofrecords(cuantosregistro); 
					       riskFactorsResponseDto.setSessionvalidthru(fechaComoCadena);
					       riskFactorsResponseDto.setRecords(listasRiskRecordDto);
					       riskFactorsResponseDto.setPrivileges(detallePrivilege);
					       riskFactorsResponseDto.setSceneries(listasTypes);
		    	   	    	   			
		  						           
                return ResponseEntity.ok(riskFactorsResponseDto);
		     						
			 
	
	
		} catch (Exception e) {
            // Manejo de excepciones
			respuesta= new RespuestaDto("Error interno del servidor", false);
			estatus=HttpStatus.INTERNAL_SERVER_ERROR;            
        } finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
	    }
		
		return new ResponseEntity(respuesta, estatus);
	
	}

	
	@GetMapping("/riskevaluations/{riskevaluationid}")
	public ResponseEntity<?> obtenerunoriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;

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

		int idrol;
		String fechaComoCadena;
		Date fecha2 = new Date();

		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
			respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Sesión expirada o inválida");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);

				if (rolisvalid == 0) {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
				}

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				// Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Optional<Riskevaluations> riskevaluations = riskevaluationsRepository.findById(riskevaluationid);

			// Verifico si encontre la aplicación
			if (!riskevaluations.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			String SentenciaBase;
		
			SentenciaBase = "SELECT  re.id,         "
					+ "					 		re.instrumentid,       "
					+ "					 		re.instrumentname,       "
					+ "					 		re.scenery,     "
					+ "					 		re.scenerydsc,      "
					+ "					 		re.relateditem,       "
					+ "					 		re.dsc,       "
					+ "					 		re.initialdate,       "
					+ "					 		re.enddate,         "
					+ "					 		re.status,         "
					+ "					 		CASE WHEN re.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus,         "
					+ "					 		cast(re.probability as decimal(19,3)) as prob,         "
					+ "					 		cast(re.impact as decimal(19,3)),      "
					+ "					 		cast(re.attenuator as decimal(19,3)),       "
					+ "					 		re.relateditemdsc,       "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.id AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_id,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.riskfactornam AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_nombres,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.riskfactordsc AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_dsc,      "
					+ "					 		STRING_AGG(COALESCE(CAST(rf.weight AS TEXT), '0'), ',' ORDER BY rf.id) AS factores_weight,    "
					+ "					 		STRING_AGG(  "
					+ "					         (  "
					+ "					             SELECT STRING_AGG(  "
					+ "					                 rfe.riskfactorelementid || ':' ||   "
					+ "					                 rfe.riskfactorelementdsc || ':' ||   "
					+ "					                 TRIM(TO_CHAR(rfe.probability, '999990.000')) || ':' ||   "
					+ "					                 TRIM(TO_CHAR(rfe.impact, '999990.000')) || ':' ||   "
					+ "					                 rfe.active || ':' ||   "
					+ "					                 rfe.weight,   "
					+ "					                 '|' ORDER BY rfe.riskfactorelementid   "
					+ "					             )  "
					+ "					             FROM main.riskevalfactorelements rfe   "
					+ "					             WHERE rfe.riskevalfactorid = rf.id  "
					+ "					         ),  "
					+ "					         ';' ORDER BY rf.id   "
					+ "					     ) AS elementos_por_factor   "
					+ "					 					 			FROM main.riskevaluations re    	       "
					+ "					 					 			INNER JOIN main.riskevalfactors rf ON rf.riskevaluationid = re.id     "
					//+ "					 					 			INNER JOIN main.instruments it  on it.id = re.instrumentid        "
					+ "					 					 			     "
					+ "					 					 					   			       "
					+ "					 					 			WHERE re.id = :riskevaluationid  "
					+ "					 					 			GROUP BY     "
					+ "					 					 		    re.id, re.instrumentid, re.instrumentname, re.scenery, re.relateditem, re.dsc,     "
					+ "					 					 		    re.scenerydsc, re.initialdate, re.enddate, re.status,     "
					+ "					 					 		    re.probability, re.impact, re.attenuator, re.relateditemdsc " ; 
			
			Query query;
			String QueryTotal;
			EntryRiskEvaluationsDto2 entry = new EntryRiskEvaluationsDto2();
			
			SceneryDto2 sceneri = new SceneryDto2();
			ScalesDto scale = new ScalesDto();
			List<SceneryDto2> sceneries = new ArrayList<>();
			List<ScalesDto> scales = new ArrayList<>();
			List<ScalesDto> scalespro = new ArrayList<>();
			StatusDto2 instrument = new StatusDto2();
			StatusDto2 scenery= new StatusDto2();
			StatusDto2 scenery2= new StatusDto2();
			StatusDto2 element= new StatusDto2();
			InitialdateDto initialdate= new InitialdateDto();
			EnddateDto enddate= new EnddateDto();
			StatusDto2 status = new StatusDto2();
			Integer probability;
			Integer impact;
			Integer attenuator;
			String dsc ="";
			RiskFactorsEntryRecordDto2 riskFactorsEntryRecordDto2 = new RiskFactorsEntryRecordDto2();
			List<RiskFactorsEntryRecordDto2>  riskfactors = new ArrayList<>();
			EntryRiskEvaluationsDto entryRiskEvaluationsDto = new EntryRiskEvaluationsDto();
			
			query = entityManager.createNativeQuery(SentenciaBase);
			query.setParameter("riskevaluationid", riskevaluationid);
			List<Object[]> listacompleta = query.getResultList();

			for (Object[] reg : listacompleta) {
			    EntryRiskEvaluationsDto2 entryLocal = new EntryRiskEvaluationsDto2();
			    StatusDto2 instDto = new StatusDto2();
			    StatusDto2 scenDto = new StatusDto2();
			    StatusDto2 elemDto = new StatusDto2();
			    StatusDto2 statDto = new StatusDto2();

			 
			    entryLocal.setId(((Number) reg[0]).intValue());

			    
			    instDto.setId(((Number) reg[1]).intValue());
			    instDto.setName(String.valueOf(reg[2]));
			    entryLocal.setInstrument(instDto);

		
			    scenDto.setId(((Number) reg[3]).intValue());
			    scenDto.setName(String.valueOf(reg[4]));
			    entryLocal.setScenery(scenDto);

			
			    elemDto.setId(((Number) reg[5]).intValue());
			    elemDto.setName(String.valueOf(reg[6]));
			    entryLocal.setElement(elemDto);

			 // --- PROCESAMIENTO DE FECHAS ---
			    SimpleDateFormat sdfIso = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
			    SimpleDateFormat sdfFormatted = new SimpleDateFormat("dd/MM/yyyy hh:mma", Locale.US);
			    
			   
			    if (reg[7] != null) {
			        Date d1 = (Date) reg[7];
			        InitialdateDto initDto = new InitialdateDto();
			        initDto.setDate(sdfIso.format(d1)); 
			        String formattedDate = sdfFormatted.format(d1)
	                        .toLowerCase()
	                        .replace(".", "")
	                        .replace(" ", "");
			        String finalString = formattedDate.substring(0, 10) + " " + formattedDate.substring(10);
			        initDto.setFormatted(finalString); // 
			        entryLocal.setInitialdate(initDto);
			    }

			
			    if (reg[8] != null) {
			        Date d2 = (Date) reg[8];
			        EnddateDto endDto = new EnddateDto();
			        
			        endDto.setDate(sdfIso.format(d2)); 
			        String formattedDate = sdfFormatted.format(d2)
	                        .toLowerCase()
	                        .replace(".", "")
	                        .replace(" ", "");
			        String finalString = formattedDate.substring(0, 10) + " " + formattedDate.substring(10);
			        endDto.setFormatted(finalString);
			        entryLocal.setEnddate(endDto);
			    }
			    boolean allowopen=true;
			    Integer allowopenInt=0;
			    statDto.setId((Integer)reg[9]);
			    statDto.setName((String)reg[10]);
			    entryLocal.setStatus(statDto);
			    entryLocal.setProbability(reg[11] != null ? new BigDecimal(reg[11].toString()) : BigDecimal.ZERO);
			    entryLocal.setImpact(reg[12] != null ? new BigDecimal(reg[12].toString()) : BigDecimal.ZERO);
			    entryLocal.setAttenuator(reg[13] != null ? new BigDecimal(reg[13].toString()) : BigDecimal.ZERO);
			   
			    ///////trabajando la fecha para el permiso especial de editar la evaluacion luego de cerrada///////
			    if (reg[8] != null) {
			        // 1. Convertimos el Date antiguo a LocalDate de Java 8
			        java.util.Date d1Old = (java.util.Date) reg[8];
			        java.time.LocalDate d1 = d1Old.toInstant()
			                                      .atZone(java.time.ZoneId.systemDefault())
			                                      .toLocalDate();

			        // 2. Obtenemos el límite del repositorio
			        String valorparams = "RISK_EVALOPENLIMIT";
			        Optional<Params> paramDate = paramsRepository.findByParamname(valorparams);
			        
			        if (paramDate.isPresent()) {
			            int limite = Integer.parseInt(paramDate.get().getValue());

			            // 3. Sumamos los días
			            java.time.LocalDate fechaFinal = d1.plusDays(limite);

			            // 4. Obtenemos la fecha de hoy
			            java.time.LocalDate hoy = java.time.LocalDate.now();

			            // Aquí es donde comparamos...
			            //allowopen
			           
			           
			            if (fechaFinal.isAfter(hoy) || fechaFinal.isEqual(hoy)) {
			            	  allowopen  = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,824);
			            	    if (!allowopen) {
		            			     allowopenInt = 1;
		            		        } else {
		            			     allowopenInt = 2;
		            		     }
			                     	//allowopenInt = 1;
			            	  } else {
			            		  allowopen  = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,824);
			            		  if (!allowopen) {
			            			  allowopenInt = 0;
			            		  } else {
			            			  allowopenInt = 2;
			            		  }
			            	     // allowopen = false;
			             }
			            
			        }
			    } else {
			       	allowopenInt =0;
			    }
			 
			 
			     
			    boolean allowtotalupdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol,826);
			    entryLocal.setAllowopen(allowopenInt);
			    entryLocal.setAllowtotalupdate(allowtotalupdate);
		
			    entryLocal.setDsc(reg[6] != null ? reg[6].toString() : "");

			 // --- PROCESAMIENTO DE FACTORES (SEGURIDAD AÑADIDA) ---
			    List<RiskFactorsEntryRecordDto2> listaF = new ArrayList<>();

			    try {
			   // if (reg[15] != null && !reg[15].toString().equals("0") && !reg[15].toString().isEmpty()) {
			        
			    	String[] idsF = reg[15].toString().split(",");
			    	String[] nomF = (reg[16] != null) ? reg[16].toString().split(",") : new String[0];
			    	String[] dscF = (reg[17] != null) ? reg[17].toString().split(",") : new String[0];
			    	String[] peso = (reg[18] != null) ? reg[18].toString().split(",") : new String[0];
			    	// El campo elementos_por_factor es el 19
			    	String elementosRaw = (reg[19] != null) ? reg[19].toString() : "SIN_ELEMENTOS";
			        String[] rawE = elementosRaw.split(";");

			        for (int i = 0; i < idsF.length; i++) {
			                if (idsF[i].trim().isEmpty() || idsF[i].trim().equals("0")) continue;

			            RiskFactorsEntryRecordDto2 rf = new RiskFactorsEntryRecordDto2();
			            rf.setId(Integer.parseInt(idsF[i].trim()));
			            rf.setName(nomF.length > i ? nomF[i] : "");
			            rf.setDsc(dscF.length > i ? dscF[i] : "");
			            rf.setWeight(new BigDecimal(peso[i]));
			            StatusDto2 sF = new StatusDto2();

			                // --- ELEMENTOS (CORRECCIÓN CRÍTICA AQUÍ) ---
			            List<RiskFactorsElementDto> listaE = new ArrayList<>();
			                if (i < rawE.length && !rawE[i].equals("SIN_ELEMENTOS") && !rawE[i].isEmpty()) {
			                    // EL ESCAPE \\| ES OBLIGATORIO
			                String[] items = rawE[i].split("\\|");
			                for (String it : items) {
			                    String[] p = it.split(":");
			                        // DEBE SER >= 6 PORQUE ACCEDES HASTA P[5]
			                        if (p.length >= 6) { 
			                            try {
			                        RiskFactorsElementDto e = new RiskFactorsElementDto();
			                        e.setId(Integer.parseInt(p[0]));
			                        e.setName(p[1]);
			                        e.setProbability(new BigDecimal(p[2]));
			                        e.setImpact(new BigDecimal(p[3]));
			                        e.setActive(new BigDecimal(p[4]));
			                        e.setWeight(new BigDecimal(p[5]));
			                        listaE.add(e);
			                            } catch (Exception ex) {
			                                System.err.println("Error parseando elemento: " + it);
			                            }
			                    }
			                }
			            }
			            rf.setElements(listaE);
			            listaF.add(rf);
			        }
			        
			    } catch (Exception e) {
			        System.err.println("Error general en factores: " + e.getMessage());
			        e.printStackTrace();
			    }

			    entryLocal.setRiskfactors(listaF);
			    entryRiskEvaluationsDto.setEntry(entryLocal);
			}

			String SetenciaSceneries = "";
			SetenciaSceneries = " SELECT  elemento ->> 'dsc' AS descr,elemento ->> 'value' AS valor "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCENERIES' ORDER BY valor ASC ";

			Query queryTypes = entityManager.createNativeQuery(SetenciaSceneries);
			List<Object[]> listasceneries = queryTypes.getResultList();
			SceneryDto2 scene;
			for (Object[] secener : listasceneries) {
				scene = new SceneryDto2();
				scene.setDsc(secener[0] != null ? secener[0].toString() : "");
				scene.setValue(secener[1] != null ? secener[1].toString() : "");
				sceneries.add(scene);
			}

			//scalesDtoAll detalleImpact;
			scalesDtoAll detalleImpact = new scalesDtoAll();
			String SetenciascalesImpact = "";
			/*Setenciascales =  " SELECT elemento ->> 'dsc' AS descr,"
					          + "      elemento ->> 'value' AS valor,"
					          + "      elemento ->> 'filter' AS lng "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCALE' ORDER BY valor ASC ";*/
			SetenciascalesImpact =  " SELECT elemento ->> 'dsc' AS descr,"
			          + "      elemento ->> 'value' AS valor,"
			          + "      elemento ->> 'filter' AS lng "
			          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
			          + " WHERE paramname = 'RISK_SCALEIMPACT' ORDER BY valor ASC ";
			          
			Query queryScales = entityManager.createNativeQuery(SetenciascalesImpact);
			List<Object[]> listascales = queryScales.getResultList();
			ScalesDto scal;
			ScalesDto scal2;
			for (Object[] scales2 : listascales) {
				scal = new ScalesDto();
				scal.setDsc(scales2[0] != null ? scales2[0].toString() : "");
			    scal.setValue(scales2[1] != null ? scales2[1].toString() : "");
			    scal.setLng(scales2[2] != null ? scales2[2].toString() : ""); 
			    scales.add(scal);
			}
			
			detalleImpact.setImpact(scales);
			
			String SetenciascalesProb = "";
			/*Setenciascales =  " SELECT elemento ->> 'dsc' AS descr,"
					          + "      elemento ->> 'value' AS valor,"
					          + "      elemento ->> 'filter' AS lng "
					          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
					          + " WHERE paramname = 'RISK_SCALE' ORDER BY valor ASC ";*/
			SetenciascalesProb =  " SELECT elemento ->> 'dsc' AS descr,"
			          + "      elemento ->> 'value' AS valor,"
			          + "      elemento ->> 'filter' AS lng "
			          + " FROM main.params p, jsonb_array_elements(CAST(p.value AS jsonb)) AS elemento "
			          + " WHERE paramname = 'RISK_SCALEPROB' ORDER BY valor ASC ";
			          
			Query querySetenciascalesProb = entityManager.createNativeQuery(SetenciascalesProb);
			List<Object[]> listaProb= querySetenciascalesProb.getResultList();
			ScalesDto pro;
			for (Object[] scales2 : listaProb) {
				scal2 = new ScalesDto();
				scal2.setDsc(scales2[0] != null ? scales2[0].toString() : "");
				scal2.setValue(scales2[1] != null ? scales2[1].toString() : "");
				scal2.setLng(scales2[2] != null ? scales2[2].toString() : ""); 
				scalespro.add(scal2);
			}
			detalleImpact.setProbability(scalespro);
			
			entryRiskEvaluationsDto.setSceneries(sceneries);
			entryRiskEvaluationsDto.setScales(detalleImpact);
            System.out.println("llegue");
			return ResponseEntity.ok(entryRiskEvaluationsDto);

		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor", false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		return new ResponseEntity(respuesta, estatus);

	}

	
	
	@GetMapping("/riskevaluations/{riskevaluationid}/rebuild")
	public ResponseEntity<?> rebuildriskevaluation(HttpServletRequest request,
	        @PathVariable("riskevaluationid") final Integer riskevaluationid)
	        throws ParseException, UnsupportedEncodingException {

	    RespuestaDto respuesta = new RespuestaDto("", false);
	    HttpStatus estatus = HttpStatus.FORBIDDEN;
	    String sessionid = request.getHeader("Authorization");
	    Date fecha = new Date();
	    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    String dataFormattata = formatter.format(fecha);
	    Date fechaDate = formatter.parse(dataFormattata);
	    AuditRequestDto auditDto = new AuditRequestDto();
	    int idrol = 0;
	    Optional<Users> encontreSessionUsuario;

	    // --- VALIDACIÓN DE SESIÓN Y SEGURIDAD ---
	    if (sessionid == null) {
	        return new ResponseEntity(new RespuestaDto("Sesión expirada o inválida", false), HttpStatus.BAD_REQUEST);
	    } else {
	        sessionid = sessionid.substring(7);
	        encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
	        if (encontreSessionUsuario.isPresent()) {
	            idrol = encontreSessionUsuario.get().getRolid().getId();
	            int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);
	            if (rolisvalid == 0) return new ResponseEntity(new RespuestaMsgDto("No tiene los Privilegios"), HttpStatus.FORBIDDEN);
	        } else {
	            return new ResponseEntity(new RespuestaDto("Sesión expirada o inválida", false), HttpStatus.UNAUTHORIZED);
	        }
	    }

	    try {
	        Riskevaluations evaluacion = riskevaluationsRepository.findById(riskevaluationid)
	                .orElseThrow(() -> new RuntimeException("Evaluación no encontrada"));

	        // --- VALIDACIÓN DE PERMISO ESPECIAL Y FECHA LÍMITE ---
	        String valorparams = "RISK_EVALOPENLIMIT";
	        Optional<Params> paramDate = paramsRepository.findByParamname(valorparams);
	        if (paramDate.isPresent()) {
	            int limite = Integer.parseInt(paramDate.get().getValue());
	            java.util.Date d1Old = (java.util.Date) evaluacion.getEnddate();
	            java.time.LocalDate d1 = d1Old.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
	            java.time.LocalDate fechaFinal = d1.plusDays(limite);
	            java.time.LocalDate hoy = java.time.LocalDate.now();

	            if (!fechaFinal.isAfter(hoy) && !fechaFinal.isEqual(hoy)) {
	                int rolisvalid2 = auditRepository.getCantbyRolAndPrivi(idrol, 824);
	                if (rolisvalid2 == 0) {
	                    return new ResponseEntity(new RespuestaMsgDto("Periodo vencido para reconstruir la Evaluación"), HttpStatus.FORBIDDEN);
	                }
	            }
	        }

	        // --- 1. RESPALDAR DATOS ACTUALES ---
	        List<Riskevalfactors> factoresActuales = riskevalfactorsRepository.findByRiskevaluationid(riskevaluationid);
	        Map<Integer, Map<String, BigDecimal>> datosRecuperados = new HashMap<>();

	        for (Riskevalfactors factor : factoresActuales) {
	            List<Riskevalfactorelements> elementos = riskevalfactorelementsRepository.findByRiskevalfactorid(factor.getId());
	            for (Riskevalfactorelements elem : elementos) {
	                if (elem.getActive().intValue() == 1) {
	                    Map<String, BigDecimal> valores = new HashMap<>();
	                    valores.put("probability", elem.getProbability());
	                    valores.put("impact", elem.getImpact());
	                    datosRecuperados.put(elem.getRiskfactorelementid(), valores);
	                }
	            }
	        }

	        // --- 2. LIMPIAR FACTORES PARA RECONSTRUIR ---
	        riskevalfactorsRepository.deleteByRiskevaluationid(riskevaluationid);

	        // VARIABLES PARA NIVEL 2 (GLOBAL)
	        BigDecimal sumaPesosFactores = BigDecimal.ZERO;
	        BigDecimal sumaProbGlobalPonderada = BigDecimal.ZERO;
	        BigDecimal sumaImpGlobalPonderada = BigDecimal.ZERO;

	        // --- 3. RECONSTRUCCIÓN NIVEL 1 (ELEMENTOS -> FACTORES) ---
	        List<Instrumentriskfactors> factoresMaestros = instrumentriskfactorsRepository.findByInstrumentid(evaluacion.getInstrumentid());

	        for (Instrumentriskfactors mf : factoresMaestros) {
	            Riskfactors maestroRF = riskfactorsRepository.findById(mf.getRiskfactorid()).get();
	            
	            Riskevalfactors nuevoFactor = new Riskevalfactors();
	            nuevoFactor.setRiskevaluationid(riskevaluationid);
	            nuevoFactor.setRiskfactorid(mf.getRiskfactorid());
	            nuevoFactor.setWeight(mf.getWeight()); 
	            nuevoFactor.setRiskfactornam(maestroRF.getName());
	            nuevoFactor.setRiskfactordsc(maestroRF.getDsc());
	            Riskevalfactors factorGuardado = riskevalfactorsRepository.save(nuevoFactor);

	            // VARIABLES PARA NIVEL 1 (ELEMENTOS DEL FACTOR)
	            BigDecimal sumaPesosElementos = BigDecimal.ZERO;
	            BigDecimal sumaProbElemPonderada = BigDecimal.ZERO;
	            BigDecimal sumaImpElemPonderada = BigDecimal.ZERO;

	            List<Riskfactorelements> elemsMaestros = riskFactorElementsRepository.findByRiskfactorid(mf.getRiskfactorid());
	            for (Riskfactorelements em : elemsMaestros) {
	                Riskevalfactorelements nuevoElem = new Riskevalfactorelements();
	                nuevoElem.setRiskevalfactorid(factorGuardado.getId());
	                nuevoElem.setRiskfactorelementid(em.getId());
	                nuevoElem.setRiskfactorelementdsc(em.getName());
	                nuevoElem.setWeight(em.getWeight()); // Actualizamos peso del maestro

	                if (datosRecuperados.containsKey(em.getId())) {
	                    Map<String, BigDecimal> previos = datosRecuperados.get(em.getId());
	                    nuevoElem.setActive(1);
	                    nuevoElem.setProbability(previos.get("probability"));
	                    nuevoElem.setImpact(previos.get("impact"));

	                    // Acumulación Ponderada Nivel 1
	                    BigDecimal pesoE = em.getWeight();
	                    sumaPesosElementos = sumaPesosElementos.add(pesoE);
	                    sumaProbElemPonderada = sumaProbElemPonderada.add(pesoE.multiply(previos.get("probability")));
	                    sumaImpElemPonderada = sumaImpElemPonderada.add(pesoE.multiply(previos.get("impact")));
	                } else {
	                    nuevoElem.setActive(0);
	                    nuevoElem.setProbability(BigDecimal.ZERO);
	                    nuevoElem.setImpact(BigDecimal.ZERO);
	                }
	                riskevalfactorelementsRepository.save(nuevoElem);
	            }

	            // --- 4. CALCULAR RESULTADO DEL FACTOR Y ACUMULAR PARA NIVEL 2 ---
	            if (sumaPesosElementos.compareTo(BigDecimal.ZERO) > 0) {
	                BigDecimal probFactor = sumaProbElemPonderada.divide(sumaPesosElementos, 4, RoundingMode.HALF_UP);
	                BigDecimal impFactor = sumaImpElemPonderada.divide(sumaPesosElementos, 4, RoundingMode.HALF_UP);

	                // Acumulación Ponderada Nivel 2
	                BigDecimal pesoF = factorGuardado.getWeight();
	                sumaPesosFactores = sumaPesosFactores.add(pesoF);
	                sumaProbGlobalPonderada = sumaProbGlobalPonderada.add(pesoF.multiply(probFactor));
	                sumaImpGlobalPonderada = sumaImpGlobalPonderada.add(pesoF.multiply(impFactor));
	            }
	        }

	        // --- 5. CÁLCULO FINAL Y GUARDADO EN EVALUACIÓN ---
	        if (sumaPesosFactores.compareTo(BigDecimal.ZERO) > 0) {
	            BigDecimal probFinal = sumaProbGlobalPonderada.divide(sumaPesosFactores, 4, RoundingMode.HALF_UP);
	            BigDecimal impFinal = sumaImpGlobalPonderada.divide(sumaPesosFactores, 4, RoundingMode.HALF_UP);
	            
	            evaluacion.setProbability(probFinal);
	            evaluacion.setImpact(impFinal); // El impacto se calcula y guarda igual que la probabilidad
	        } else {
	            evaluacion.setProbability(BigDecimal.ZERO);
	            evaluacion.setImpact(BigDecimal.ZERO);
	        }

	        evaluacion.setAttenuator(new BigDecimal("100.00"));
	        evaluacion.setStatus(1);
	        riskevaluationsRepository.save(evaluacion);

	        // --- 6. AUDITORÍA ---
	        String module = "Evaluación de Riesgo";
	        String Descmodule = "Se reconstruyo la Evaluación de Riesgo con Id: " + riskevaluationid;
	        auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
	        String usryemail = encontreSessionUsuario.get().getUsr() + " (" + encontreSessionUsuario.get().getEmail() + ")";
	        auditDto.setUserref(usryemail);
	        auditDto.setModule(module);
	        auditDto.setDesc(Descmodule);
	        auditDto.setCreatedat(fechaDate);
	        usersService.registrarAuditSesion(auditDto);

	        return new ResponseEntity(new RespuestaValueDto(riskevaluationid), HttpStatus.OK);

	    } catch (Exception e) {
	        return new ResponseEntity(new RespuestaDto("Error: " + e.getMessage(), false), HttpStatus.INTERNAL_SERVER_ERROR);
	    } finally {
	        if (entityManager != null && entityManager.isOpen()) {
	            entityManager.close();
	        }
	    }
	}
	
	/*@GetMapping("/riskevaluations/{riskevaluationid}/rebuild")
	public ResponseEntity<?> rebuildriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		

		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		Date fechaDate = formatter.parse(dataFormattata);
		AuditRequestDto auditDto = new AuditRequestDto();
		RespuestaValueDto respuestaValueDto;
		int idrol;
		String fechaComoCadena;
		Date fecha2 = new Date();
		Optional<Users> encontreSessionUsuario;
		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
			respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Sesión expirada o inválida");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			 encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);
				
				if (rolisvalid == 0) {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
				}
				
				
				   // 2. Obtenemos el límite del repositorio
		       
		       
			} else {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				// Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			    
			  boolean existeEval =  riskevaluationsRepository.existsById(riskevaluationid);
			   if (!existeEval) {
		    	    String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					//respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("Evaluacion de Riesgo no encontrado"); 
					return new ResponseEntity(respuestaDto, HttpStatus.NOT_FOUND);
		    	  
		       } 	
		    	 
			//  Obtengo la evaluación y reseteo el atenuador a 100% (según apiary)
			   Riskevaluations evaluacion = riskevaluationsRepository.findById(riskevaluationid)
			            .orElseThrow(() -> new RuntimeException("Evaluación no encontrada"));
			    
			   
			   String valorparams = "RISK_EVALOPENLIMIT";
		        Optional<Params> paramDate = paramsRepository.findByParamname(valorparams);
		        if (paramDate.isPresent()) {
		            int limite = Integer.parseInt(paramDate.get().getValue());
		            java.util.Date d1Old = (java.util.Date) evaluacion.getEnddate();
			        java.time.LocalDate d1 = d1Old.toInstant()
			                                      .atZone(java.time.ZoneId.systemDefault())
			                                      .toLocalDate();
		            // 3. Sumamos los días
		            java.time.LocalDate fechaFinal = d1.plusDays(limite);

		            // 4. Obtenemos la fecha de hoy
		            java.time.LocalDate hoy = java.time.LocalDate.now();

		            // Aquí es donde comparamos...
		            //allowopen
		            
		            	     if (fechaFinal.isAfter(hoy)|| fechaFinal.isEqual(hoy)) {
		            	      String abrir = "Se puede abrir la evaluacion";
		            	    } else {
		            	    	int rolisvalid2 = auditRepository.getCantbyRolAndPrivi(idrol, 824);
		            	    	if (rolisvalid2 == 0) {
		        					String var = "";
		        					boolean bloked = false;
		        					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
		        					// respuestaDto.setBlocked(bloked);
		        					respuestaDto.setMsg("Periodo vencido para reconstruir la Evaluación");
		        					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
		        				}
		            	    	
		            	    }
		            
		        }
	       
			   //////
		        
		        // como recalculo la probabilidad
		      //  la probabilidad por el factor  la probabilidad por su peso y voy sumando, el total lo divido entre las suma de los pesos
		       // el impacto por el factor
		        
		        ///////
			   
		    // Asumiendo que el campo se llama 'attenuator' o similar en Riskevaluations
		    evaluacion.setAttenuator(new BigDecimal("100.00")); 
		    evaluacion.setStatus(1);
		    riskevaluationsRepository.save(evaluacion);

		    // Paso para Recordar los elementos marcados: Mapeamos riskfactorelementid -> estado active
		    // Esto guarda cuáles elementos el usuario ya había seleccionado anteriormente
		    List<Riskevalfactors> factoresActuales = riskevalfactorsRepository.findByRiskevaluationid(riskevaluationid);
		   // Map<Integer, Integer> elementosMarcados = new HashMap<>();
		    Map<Integer, Map<String, BigDecimal>> datosRecuperados = new HashMap<>();

		    for (Riskevalfactors factor : factoresActuales) {
		        List<Riskevalfactorelements> elementos = riskevalfactorelementsRepository.findByRiskevalfactorid(factor.getId());
		        for (Riskevalfactorelements elem : elementos) {
		            // Guardamos el ID del maestro y si estaba activo (1)
		            if (elem.getActive().intValue() == 1) {
		            	Map<String, BigDecimal> valores = new HashMap<>();
		            	valores.put("weight", elem.getWeight());
		                valores.put("probability", elem.getProbability());
		                valores.put("impact", elem.getImpact());
		               // elementosMarcados.put(elem.getRiskfactorelementid(), 1);
		                datosRecuperados.put(elem.getRiskfactorelementid(), valores);
		            }
		        }
		    }

		   //  Elimino los  factores actuales 
		    // El  DELETE CASCADE que creo Ander borrará  los riskevalfactorelements
		    riskevalfactorsRepository.deleteByRiskevaluationid(riskevaluationid);

		   //. Cargo de nuevo desde los instrumentos/maestros
		    // Buscamos qué factores debería tener el instrumento asociado a esta evaluación
		    List<Instrumentriskfactors> factoresMaestros = instrumentriskfactorsRepository.findByInstrumentid(evaluacion.getInstrumentid());

		    for (Instrumentriskfactors mf : factoresMaestros) {
		        Riskfactors maestroRF = riskfactorsRepository.findById(mf.getRiskfactorid()).get();
		        
		        // Inserto la  Cabecera del Factor en la Evaluación
		        Riskevalfactors nuevoFactor = new Riskevalfactors();
		        nuevoFactor.setRiskevaluationid(riskevaluationid);
		        nuevoFactor.setRiskfactorid(mf.getRiskfactorid());
		        nuevoFactor.setWeight(mf.getWeight());
		        nuevoFactor.setRiskfactornam(maestroRF.getName());
		        nuevoFactor.setRiskfactordsc(maestroRF.getDsc());
		        
		        Riskevalfactors factorGuardado = riskevalfactorsRepository.save(nuevoFactor);

		        // Cargar Elementos Maestros Base  y Recordar los que estaban  marcados
		        List<Riskfactorelements> elemsMaestros = riskFactorElementsRepository.findByRiskfactorid(mf.getRiskfactorid());
		        
		        for (Riskfactorelements em : elemsMaestros) {
		            Riskevalfactorelements nuevoElem = new Riskevalfactorelements();
		            nuevoElem.setRiskevalfactorid(factorGuardado.getId());
		            nuevoElem.setRiskfactorelementid(em.getId());
		            nuevoElem.setRiskfactorelementdsc(em.getName());

		            // Verificamos si el elemento ya existía y estaba marcado
		            if (datosRecuperados.containsKey(em.getId())) {
		                Map<String, BigDecimal> previos = datosRecuperados.get(em.getId());
		                
		                nuevoElem.setActive(1);
		                // Restauramos los valores que tenía antes de la reconstrucción
		                nuevoElem.setWeight(previos.get("weight"));
		                nuevoElem.setProbability(previos.get("probability"));
		                nuevoElem.setImpact(previos.get("impact"));
		            } else {
		                // Si es nuevo o no estaba marcado, valores por defecto
		                nuevoElem.setActive(0);
		                nuevoElem.setWeight(em.getWeight()); // Peso que viene del maestro
		                nuevoElem.setProbability(BigDecimal.ZERO);
		                nuevoElem.setImpact(BigDecimal.ZERO);
		            }
		            
		            riskevalfactorelementsRepository.save(nuevoElem);
		        }
		    }
		    
       //////////////////////////INSERCION BLOQUE DE AUDITORIA///////////////////
	        String module = "Evaluación de Riesgo";
	        // String Descmodule = "Actualización de parametro del Sistema con id: " +
	      // parmid ;
	        String Descmodule = "Se reconstruyo la Evaluación de Riesgo " +  " con Id: " + riskevaluationid ;

	         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(fechaDate);
	          usersService.registrarAuditSesion(auditDto);

	           respuestaValueDto = new RespuestaValueDto(riskevaluationid);
	estatus = HttpStatus.OK;
	return new ResponseEntity(respuestaValueDto, estatus);

		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor", false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		return new ResponseEntity(respuesta, estatus);

	}*/

	
	
	
	
	@GetMapping("/riskevaluations/{riskevaluationid}/checkintegrity")
	public ResponseEntity<?> checkintegrityriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;

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

		int idrol;
		String fechaComoCadena;
		Date fecha2 = new Date();

		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
			respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Sesión expirada o inválida");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 820);

				if (rolisvalid == 0) {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
				}

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				// Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Optional<Riskevaluations> riskevaluations = riskevaluationsRepository.findById(riskevaluationid);

			// Verifico si encontre la evaluación
			if (!riskevaluations.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			//PROCEDO A VERIFICAR LA INTEGRIDAD DE LA EVALUACIÔN
			//CHEQUEO EL ID DE INSTRUMENTO
			int idInstrumento=riskevaluations.get().getInstrumentid();
			
			Optional<Instruments> instruments = instrumentsRepository.findById(idInstrumento);
			
			FailDto fail = new FailDto();
			
			//Chequeo el instrumento
			if (!instruments.isPresent()) {
				fail.setFail(2);
				return ResponseEntity.ok(fail);
			}
			
			//Chequeo los riskfactors de la evaluación
			List<Riskevalfactors> riskEvalfactors= riskevalfactorsRepository.findRiskevalfactors2(riskevaluationid);
			
			for (Riskevalfactors rel : riskEvalfactors) {
		       
		        Optional<Instrumentriskfactors> opRf = instrumentriskfactorsRepository.findInstrumeFactores(instruments.get().getId(),rel.getRiskfactorid());
		        
		        if (!opRf.isPresent()) {
		        	fail.setFail(1);
					return ResponseEntity.ok(fail);
		        }else {
		        	List<Riskevalfactorelements> list=riskevalfactorelementsRepository.findByRiskevalfactorid(riskevaluationid);
		        	for (Riskevalfactorelements rel2 : list) {
		        		Optional<Riskfactorelements> opRf2 = riskFactorElementsRepository.findById(rel2.getId());
		        		 if (!opRf2.isPresent()) {
		 		        	fail.setFail(1);
		 					return ResponseEntity.ok(fail);
		        		 }	
		        	}
		        }
		    }
			
			//busco todos los factores que estan asociados en el catàlogo de instrumentos de factores
			List<Instrumentriskfactors> listado = instrumentriskfactorsRepository.findByInstrumentid(instruments.get().getId());
			for (Instrumentriskfactors rel : listado) {
		       
				//Los busco en la evaluación
		        Optional<Riskevalfactors> opRf = riskevalfactorsRepository.findByRiskevaluationidAndRiskfactorid(riskevaluationid, rel.getRiskfactorid());
		        
		        if (!opRf.isPresent()) {
		        	fail.setFail(1);
					return ResponseEntity.ok(fail);
		        }else {
		        	List<Riskfactorelements> list3= riskFactorElementsRepository.findByRiskfactorid(opRf.get().getRiskfactorid());
		        	for (Riskfactorelements rel2 : list3) {
		        		Optional<Riskevalfactorelements> opRf3 = riskevalfactorelementsRepository.findByRiskevalfactoridAndRiskfactorelementid(opRf.get().getId(), rel2.getId());
		        		 if (!opRf3.isPresent()) {
		 		        	fail.setFail(1);
		 					return ResponseEntity.ok(fail);
		        		 }	
		        	}
		        }
		    }
			
			fail.setFail(0);
			return ResponseEntity.ok(fail);

		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor", false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}

		return new ResponseEntity(respuesta, estatus);

	}

	
	
	@DeleteMapping("/riskevaluations/{riskevaluationid}")
	@Transactional
	public ResponseEntity<?> eliminarriskevaluation(HttpServletRequest request,
			@PathVariable("riskevaluationid") final Integer riskevaluationid)
			throws ParseException, UnsupportedEncodingException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		RespuestaValueDto respuestaValueDto;
		String sessionid = request.getHeader("Authorization");
		Date fecha = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata = formatter.format(fecha);
		Date fechaDate = formatter.parse(dataFormattata);
		AuditRequestDto auditDto = new AuditRequestDto();
		String module = "";
		String Descmodule = "";
		Optional<Users> encontreSessionUsuario;
		
		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);
		
		int idrol;
		String fechaComoCadena;
		Date fecha2 = new Date();

		if (sessionid == null) {
			String var = "";
			boolean bloked = false;
			RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
			respuestaDto.setBlocked(bloked);
			respuestaDto.setMsg("Sesión expirada o inválida");
			// Error 400
			return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
		} else {

			sessionid = sessionid.substring(7);
			encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) {
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 823);

				if (rolisvalid == 0) {
					String var = "";
					boolean bloked = false;
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					// respuestaDto.setBlocked(bloked);
					respuestaDto.setMsg("No tiene los Privilegios");
					return new ResponseEntity(respuestaDto, HttpStatus.FORBIDDEN);
				}

			} else {
				String var = "";
				boolean bloked = false;
				RespuestaDto respuestaDto = new RespuestaDto(var, bloked);
				respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Sesión expirada o inválida");
				// Error 400
				return new ResponseEntity(respuestaDto, HttpStatus.UNAUTHORIZED);
			}
		}

		try {

			Optional<Riskevaluations> riskevaluations = riskevaluationsRepository.findById(riskevaluationid);

			// Verifico si encontre la aplicación
			if (!riskevaluations.isPresent()) {
				respuesta.setMsg("Registro no encontrado");
				return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			}
			
			//Se procede a borrar la evaluación de riesgo
			riskevaluationsRepository.deleteById(riskevaluationid);
			
			Optional<Riskevaluations> riskevaluations2 = riskevaluationsRepository.findById(riskevaluationid);

			if (!riskevaluations2.isPresent()) {//Fue borrado y paso a la auditoria
				module = "Evaluación de Riesgo";
				Descmodule = "Se borró la evaluación de riesgo con id: " + riskevaluationid;
				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= new RespuestaValueDto(riskevaluationid);

				estatus=HttpStatus.OK;
				return new ResponseEntity(respuestaValueDto, estatus);
			}else {
				respuesta.setMsg("No se pudo borrar por alguna razón");
				estatus = HttpStatus.CONFLICT;
				return new ResponseEntity(respuesta, estatus);
			}

		} catch (Exception e) {
			// Manejo de excepciones
			respuesta = new RespuestaDto("Error interno del servidor", false);
			estatus = HttpStatus.INTERNAL_SERVER_ERROR;
		} 

		return new ResponseEntity(respuesta, estatus);

	}



}
