package com.dacrt.SBIABackend.controler;

import java.math.BigInteger;
import java.net.URI;
import java.sql.Array;
import java.text.ParseException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletRequest;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.ChannelDto;
import com.dacrt.SBIABackend.dto.EntryProcessDto;
import com.dacrt.SBIABackend.dto.OperationlineDto;
import com.dacrt.SBIABackend.dto.ProceResponseDto;
import com.dacrt.SBIABackend.dto.ProcessActualizarDto;
import com.dacrt.SBIABackend.dto.ProcessRemoteDto;
import com.dacrt.SBIABackend.dto.ProcessResponDto2;
import com.dacrt.SBIABackend.dto.ProcessResponseDto;
import com.dacrt.SBIABackend.dto.ProcessTypeDto;
import com.dacrt.SBIABackend.dto.ProcessesListDto;
import com.dacrt.SBIABackend.dto.ProcessesResponseDto;
import com.dacrt.SBIABackend.dto.ProcessesResponseDto2;
import com.dacrt.SBIABackend.dto.ServiceoffersDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.UnidadResponseRelatedDto;
import com.dacrt.SBIABackend.entity.Processchannels;
import com.dacrt.SBIABackend.entity.Processes;
import com.dacrt.SBIABackend.entity.Processserviceoffers;
import com.dacrt.SBIABackend.entity.Serviceoffers;
import com.dacrt.SBIABackend.repository.ChannelsRepository;
import com.dacrt.SBIABackend.repository.OperationlinesRepository;
import com.dacrt.SBIABackend.repository.ProcesschannelsRepository;
import com.dacrt.SBIABackend.repository.ProcessesRepository;
import com.dacrt.SBIABackend.repository.ProcessserviceoffersRepository;
import com.dacrt.SBIABackend.repository.ServiceoffersRepository;
import com.dacrt.SBIABackend.repository.UnitprocessesRepository;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.PrivilegesAllDto;
import com.dacrt.SBIABackend.security.dto.RespuestaMsgDto;
import com.dacrt.SBIABackend.security.dto.RespuestaValueDto;
import com.dacrt.SBIABackend.security.dto.RolNameDto;
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.PrivilegesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.MenuService;
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 ProcessesControler {
	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	private PrivilegesRepository privilegesRepository;
	
	@Autowired
	private ProcessesRepository processesRepository;
	
	@Autowired
	private ProcesschannelsRepository processchannelsRepository;
	
	@Autowired
	private ProcessserviceoffersRepository processserviceoffersRepository;
	
	@Autowired
	private UnitprocessesRepository unitprocessesRepository;
	
	@Autowired
	private OperationlinesRepository operationlinesRepository;
	
	@Autowired
	private ServiceoffersRepository serviceoffersRepository;
	
	@Autowired
	private ChannelsRepository channelsRepository;
	
	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	MenuService menuService;

	@Autowired
	SecurityService securityService;

	@Autowired
	UsersService usersService;

	Logger logger = LoggerFactory.getLogger(ProcessesControler.class);

	@PostMapping("/processes")
	public ResponseEntity<?> listarProcesses(HttpServletRequest request, @RequestBody ProcessesListDto tiposfiltros)
			throws ParseException {

		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

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

		String searchIn = "";
		int statusIn = 0;
		Integer processRemoteIn = 0;
		Integer processTypeIn = 0;
		String searchListUnit = "";
		int operationLineIdIn = 0;
		int channelIdIn;
		int formatList=0;

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

		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Este proceso permite obtener un listado de los procesos. (Priv 120)
				   formatList = tiposfiltros.getFormat();
				   Roles roles = encontreSessionUsuario.get().getRolid();
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 120);
				   if (formatList!=2) {
				       if (rolisvalid==0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}
				   }   
				

				// Obtengo los datos del Body
				searchIn = tiposfiltros.getFilters().getSearch();// dato de busqueda por nombre
				
				
			    String Salida = usersService.verificarCaracteresValidosConRegex(searchIn);
				  
				  if (Salida=="NOOK") {
					  String var = "";
						boolean bloked = false;
						RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
						//respuestaDto.setBlocked(bloked);
						respuestaDto.setMsg("Caracteres no permitidos en la busqueda"); 
						return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				  }
				   
				  
				  
				statusIn = tiposfiltros.getFilters().getStatus();// dato de busqueda por status
				searchListUnit = tiposfiltros.getFilters().getUnitidlist();
				processRemoteIn = tiposfiltros.getFilters().getProcessremote()==""? 0: Integer.parseInt(tiposfiltros.getFilters().getProcessremote());// dato de busqueda por proceso remoto
				processTypeIn = tiposfiltros.getFilters().getProcesstype()==""? 0:Integer.parseInt(tiposfiltros.getFilters().getProcesstype());// dato de busqueda por tipo de proceso
				operationLineIdIn = tiposfiltros.getFilters().getOperationlineid();// dato de busqueda por linea de
																					// operación
				channelIdIn = tiposfiltros.getFilters().getChannelid(); // dato de busqueda por canales

				orderIn = tiposfiltros.getOrder(); // Orden Ascedente o Descendente
				offsetIn = tiposfiltros.getOffset();// Primer registro a mostrar
				numofrecordsIn = tiposfiltros.getNumofrecords();// Número de registros a mostrar
				contentIn = tiposfiltros.getContent();
				// Verifico los Shorcouts
				if (contentIn != null && contentIn != "")
					menuService.iscontentdiffnull(contentIn, encontreSessionUsuario.get().getId());

			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}

			// Aqui empieza la carga de la data de respuesta

			ProcessResponseDto procesResponseDto = new ProcessResponseDto();
			ProcessesResponseDto2 procesResponseDto2 = new ProcessesResponseDto2();
			ProcessResponDto2 processResponDto2 = new ProcessResponDto2();
			StatusDto2 statusDto2 = new StatusDto2();
			List<ProcessResponDto2> processResponDto2List = new ArrayList();
			OperationlineDto operationlineDto = new OperationlineDto();
			ProcessTypeDto tipoProceso = new ProcessTypeDto();
			List<ProcessTypeDto> tipoProcesoList = new ArrayList();
			List<ProcessTypeDto> tipoProcesoList2 = new ArrayList();
			List<ProcessRemoteDto> tipoRemoteList = new ArrayList();
			List<ProcessRemoteDto> tipoRemoteList2 = new ArrayList();
			StatusDto statusDto = new StatusDto();
			ProcessRemoteDto tipoRemoto = new ProcessRemoteDto();
			List<ProcessResponseDto> processResultado = new ArrayList();
			ProcessesResponseDto processesResponseDto = new ProcessesResponseDto();
			PrivilegesAllDto detallePrivilege = new PrivilegesAllDto();
			UnidadResponseRelatedDto unidad = new UnidadResponseRelatedDto();
			try {
				// Sentencia General
				String QueryTotal = "";
				
				
		
				String SentenciaBase="";
				if (formatList==2) {	
						if (searchListUnit!="" && searchListUnit!=null) {
							SentenciaBase = "SELECT        p.id,  p.name, "
									+ "					   CASE "
									+ "					   WHEN p.status = 1 AND MAX(up.deleted) IS NOT NULL THEN 0 "
									+ "					   WHEN p.status = 1 AND MAX(up.deleted) IS NULL THEN 1 "
									+ "					   WHEN p.status = 0 AND MAX(up.deleted) IS NULL THEN 0 "
									+ "					   WHEN p.status = 0 AND MAX(up.deleted) IS NOT NULL THEN 0 "
									+ "					   END AS status, "
									+ "                    CASE "
									+ "                    WHEN p.status = 1 AND MAX(up.deleted) IS NOT NULL THEN 'Inactivo' "
									+ "                    WHEN p.status = 1 AND MAX(up.deleted) IS NULL THEN 'Activo' "
									+ "                    WHEN p.status = 0 AND MAX(up.deleted) IS NULL THEN 'Inactivo' "
									+ "                    WHEN p.status = 0 AND MAX(up.deleted) IS NOT NULL THEN 'Inactivo' "
									+ "                    END AS descStatus, "
									+ "                    pr.descr nombreremote,pt.descr nombretipo, "
									+ "			           ol.name AS nombreoperation,"
									+ "                    u.id as idUnidad,u.name as nameUnidad,CASE WHEN up.deleted IS NULL then false  "
									+ "								                                  WHEN up.deleted is not null then true  "
									+ "								                             END as deletedUnidad,up.id as unitprocessid "
									+ "	FROM main.processes p "
									+ " LEFT JOIN       main.operationlines       ol ON p.operationlineid = ol.id "
									+ " LEFT JOIN       main.processchannels      pc ON p.id = pc.processid "
									+ " LEFT JOIN       main.channels             c  ON pc.channelid = c.id "
									+ " LEFT JOIN       main.processserviceoffers ps ON p.id = ps.processid "
									+ " LEFT JOIN       main.serviceoffers        s  ON ps.serviceofferid = s.id "
									+ " LEFT JOIN       (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 = 'PROCESS_REMOTE' ) pr ON p.processremotepar = CAST(pr.valor AS integer)"
			                        + " LEFT JOIN       (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 = 'PROCESS_TYPE' ) pt ON p.processtypepar = CAST(pt.valor AS integer) ";

						}else {
					  SentenciaBase = "SELECT  p.id,  p.name, p.status, "
								+ "	           CASE WHEN p.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatu, "
								+ "            pr.descr nombreremote,pt.descr nombretipo, "
								+ "			   ol.name AS nombreoperation,"
								+ "            0 as idUnidad,' ' as nameUnidad,false as deletedUnidad,0 as unitprocessid "
								+ "	FROM main.processes p "
								+ " LEFT JOIN       main.operationlines       ol ON p.operationlineid = ol.id "
								+ " LEFT JOIN       main.processchannels      pc ON p.id = pc.processid "
								+ " LEFT JOIN       main.channels             c  ON pc.channelid = c.id "
								+ " LEFT JOIN       main.processserviceoffers ps ON p.id = ps.processid "
								+ " LEFT JOIN       main.serviceoffers        s  ON ps.serviceofferid = s.id "
								+ " LEFT JOIN       (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 = 'PROCESS_REMOTE' ) pr ON p.processremotepar = CAST(pr.valor AS integer)"
		                        + " LEFT JOIN       (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 = 'PROCESS_TYPE' ) pt ON p.processtypepar = CAST(pt.valor AS integer) ";
	
						}
					 					
					} else { 
						if (searchListUnit!="" && searchListUnit!=null) {
							SentenciaBase =	"SELECT        p.id, p.name, p.dsc, p.ref, p.processremotepar, "
									+ "                    pr.descr nombreremote, "
									+ "					   CASE "
									+ "					   WHEN p.status = 1 AND MAX(up.deleted) IS NOT NULL THEN 0 "
									+ "					   WHEN p.status = 1 AND MAX(up.deleted) IS NULL THEN 1 "
									+ "					   WHEN p.status = 0 AND MAX(up.deleted) IS NULL THEN 0 "
									+ "					   WHEN p.status = 0 AND MAX(up.deleted) IS NOT NULL THEN 0 "
									+ "					   END AS status, "
									+ "                    CASE "
									+ "                    WHEN p.status = 1 AND MAX(up.deleted) IS NOT NULL THEN 'Inactivo' "
									+ "                    WHEN p.status = 1 AND MAX(up.deleted) IS NULL THEN 'Activo' "
									+ "                    WHEN p.status = 0 AND MAX(up.deleted) IS NULL THEN 'Inactivo' "
									+ "                    WHEN p.status = 0 AND MAX(up.deleted) IS NOT NULL THEN 'Inactivo' "
									+ "                    END AS descStatus,  "									
									+ "                    p.processtypepar, pt.descr nombretipo, "
									+ "                    p.operationlineid, ol.name AS nombreoperation, "
									+ "                    STRING_AGG(distinct CAST(pc.channelid AS TEXT), ',') channels, STRING_AGG(s.id || ':' || s.name, ';') serviceoffers, "
								    + "                    count(DISTINCT(pc.channelid)) AS cantidad,"
								    + "                    u.id as idUnidad,u.name as nameUnidad,CASE WHEN up.deleted IS NULL then false  "
								    + "														          WHEN up.deleted is not null then true "
								    + "															 END as deletedUnidad,up.id as unitprocessid "
									+ " FROM            main.processes            p "
									+ " LEFT JOIN       main.operationlines       ol ON p.operationlineid = ol.id "
									+ " LEFT JOIN       main.processchannels      pc ON p.id = pc.processid "
									+ " LEFT JOIN       main.channels             c  ON pc.channelid = c.id "
									+ " LEFT JOIN       main.processserviceoffers ps ON p.id = ps.processid "
									+ " LEFT JOIN       main.serviceoffers        s  ON ps.serviceofferid = s.id "
									+ " LEFT JOIN       (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 = 'PROCESS_REMOTE' ) pr ON p.processremotepar = CAST(pr.valor AS integer)"
			                        + " LEFT JOIN       (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 = 'PROCESS_TYPE' ) pt ON p.processtypepar = CAST(pt.valor AS integer) ";
			                        //+ " GROUP BY        p.id, p.name, p.dsc, p.ref, p.processremotepar, nombreremote, p.processtypepar, nombretipo,p.operationlineid,nombreoperation";

						}else {
						SentenciaBase =	"SELECT p.id, p.name, p.dsc, p.ref, p.processremotepar, "
						+ "                     pr.descr nombreremote, p.status, "
						+ "                     CASE WHEN p.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS descStatus,"
						+ "                     p.processtypepar, pt.descr nombretipo, "
						+ "                     p.operationlineid, ol.name AS nombreoperation, "
						+ "                     STRING_AGG(distinct CAST(pc.channelid AS TEXT), ',') channels, STRING_AGG(s.id || ':' || s.name, ';') serviceoffers, "
					    + "                     count(DISTINCT(pc.channelid)) AS cantidad,"
					    + "                     0 as idUnidad,' ' as nameUnidad,false as deletedUnidad,0 as unitprocessid "
						+ " FROM            main.processes            p "
						+ " LEFT JOIN       main.operationlines       ol ON p.operationlineid = ol.id "
						+ " LEFT JOIN       main.processchannels      pc ON p.id = pc.processid "
						+ " LEFT JOIN       main.channels             c  ON pc.channelid = c.id "
						+ " LEFT JOIN       main.processserviceoffers ps ON p.id = ps.processid "
						+ " LEFT JOIN       main.serviceoffers        s  ON ps.serviceofferid = s.id "
						+ " LEFT JOIN       (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 = 'PROCESS_REMOTE' ) pr ON p.processremotepar = CAST(pr.valor AS integer)"
                        + " LEFT JOIN       (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 = 'PROCESS_TYPE' ) pt ON p.processtypepar = CAST(pt.valor AS integer) ";
                        //+ " GROUP BY        p.id, p.name, p.dsc, p.ref, p.processremotepar, nombreremote, p.processtypepar, nombretipo,p.operationlineid,nombreoperation";

						}
					}
				
				System.out.println(SentenciaBase);
				
				if (searchListUnit!=null) {
					switch (searchListUnit) { 
					    case "":  QueryTotal = SentenciaBase;
					     		  break;
					  
					    default:  QueryTotal = SentenciaBase  + " JOIN       main.unitprocesses up ON up.processid=p.id AND up.unitid in (" + searchListUnit + ") "
					    		                              + " JOIN       main.units u ON u.id=up.unitid ";
					    		  break;
					    	
			         }
				 }else {
					 respuesta.setMsg("Llamada al servicio malformado");
					 estatus = HttpStatus.BAD_REQUEST;
					 return new ResponseEntity(respuesta, estatus);
			 	 }
				
				String canal ="";
					switch (channelIdIn) {
						case 0:
							QueryTotal = QueryTotal + " WHERE 1=1 ";
							break;
						default: // viene con el parametro para buscar por el canal
							QueryTotal = QueryTotal + " WHERE pc.channelid = " + channelIdIn;
							break;
					}
				
				
				switch (processRemoteIn) {
				case 0:
					QueryTotal = QueryTotal + " AND 1=1 ";
					break;
				default: // viene con el parametro para buscar por el tipo de proceso remoto
					QueryTotal = QueryTotal + " AND p.processremotepar = " + processRemoteIn;
					break;
				}

				switch (processTypeIn) {
				case 0:
					QueryTotal = QueryTotal + " AND 1=1 ";
					break;
				default: // viene con el parametro para buscar por el tipo de proceso
					QueryTotal = QueryTotal + " AND p.processtypepar = " + processTypeIn;
					break;
				}

				String ids = "p.id"; // id de procesos
				String name = "p.name"; // buscar por nombre
				String status = "p.status"; // buscar por status
				String processremote = "p.processremotepar"; // buscar por proceso remoto
				String processtype = "p.processtypepar"; // buscar por tipo de proceso
				String operationlineid = "nombreoperation";// buscar por la linea de operacion
				String cantidad = "cantidad";// cantidad de canales
				String channelid = "pc.channelid";// buscar por el canal

				String lowername = "main.sinacentos(LOWER(p.name))"; // se convierte en minúscula
				String lowerref = "main.sinacentos(LOWER(p.ref))"; // se convierte en minúscula
				String lowerdsc = "main.sinacentos(LOWER(p.dsc))"; // se convierte en minúscula

				
				// Se verifica si viene dato en el campo search para efectuar la búsqueda
				if (searchIn!=null) {
					String LowerSearch = searchIn.toLowerCase(); // se convierte en minúscula

					switch (searchIn) {
					case "":
						QueryTotal = QueryTotal + " AND " + " 1=1 ";
						break;
					default: // viene con el parametro para buscar por el like
						QueryTotal = QueryTotal + " AND (" + lowername + " LIKE  main.sinacentos(" + "'%" + LowerSearch + "%')" + " OR "
								+ lowerref + " LIKE main.sinacentos(" + "'%" + LowerSearch + "%')" + " OR " + lowerdsc + " LIKE main.sinacentos(" + "'%"
								+ LowerSearch + "%')" + " OR " + lowerdsc + " LIKE main.sinacentos(" + "'%" + LowerSearch + "%')" + " ) ";
						break;
					}
				}else {
					respuesta.setMsg("Llamada al servicio malformado");
					 estatus = HttpStatus.BAD_REQUEST;
					 return new ResponseEntity(respuesta, estatus);
				}
				
				switch (statusIn) {
				case 0:
					QueryTotal = QueryTotal + " AND 1=1 ";
					break;
				case 1:
					QueryTotal = QueryTotal + " AND p.status = 1 ";
					break;
				case 2:
					QueryTotal = QueryTotal + " AND p.status = 0 ";
					break;
				default:
					respuesta.setMsg("Error el ordenamiento no es el correcto");
					estatus = HttpStatus.BAD_REQUEST;
					return new ResponseEntity(respuesta, estatus);
				}

				switch (operationLineIdIn) {
				case 0:
					QueryTotal = QueryTotal + " AND 1=1 ";
					break;
				default: // viene con el parametro para buscar por el status
					QueryTotal = QueryTotal + " AND ol.id = "+ operationLineIdIn;
					break;
				}

				QueryTotal = QueryTotal + " GROUP BY p.id, p.name, p.dsc, p.ref, p.processremotepar,nombreremote, p.status, p.processtypepar, nombretipo, p.operationlineid, nombreoperation,idUnidad,nameUnidad,deletedUnidad,unitprocessid ";

				switch (orderIn) {
				case 1: // ordena por name ascendente
					QueryTotal = QueryTotal + " ORDER BY " + name + " ASC";
					break;

				case 2:// ordena por status ascendente
					QueryTotal = QueryTotal + " ORDER BY " + status + " ASC";
					break;

				case 3: // ordena por processtype ascendente
					QueryTotal = QueryTotal + " ORDER BY " + processtype + " ASC";
					break;
				
				case 4: // ordena por processremote ascendente
					QueryTotal = QueryTotal + " ORDER BY " + processremote + " ASC";
					break;
				
				case 5: // ordena por nombre de linea de operaciones ascendente
					QueryTotal = QueryTotal + " ORDER BY " + operationlineid + " ASC";
					break;
					
				case 6: // ordena por la cantidad de canales ascendente
					QueryTotal = QueryTotal + " ORDER BY " + cantidad + " ASC";
					break;
					
				case 99: // ordena por el id de proceso ascendente
					QueryTotal = QueryTotal + " ORDER BY " + ids + " ASC";
					break;

				case -1:// ordena por name descendente
					QueryTotal = QueryTotal + " ORDER BY " + name + " DESC";
					break;

				case -2:// ordena por estatus descendente
					QueryTotal = QueryTotal + " ORDER BY " + status + " DESC";
					break;

				case -3:// ordena por tipo de proceso descendente
					QueryTotal = QueryTotal + " ORDER BY " + processtype+ " DESC";
					break;
			    
				case -4:// ordena por proceso remoto descendente
					QueryTotal = QueryTotal + " ORDER BY " + processremote+ " DESC";
					break;
					
				case -5: // ordena por nombre de linea de operaciones descendente
					QueryTotal = QueryTotal + " ORDER BY " + operationlineid + " DESC";
					break;

			    case -6: // ordena por la cantidad de canales ascendente
					QueryTotal = QueryTotal + " ORDER BY " + cantidad + " DESC";
					break;
					
				case -99: // ordena por el id de proceso descendente
					QueryTotal = QueryTotal + " ORDER BY " + ids + " DESC";
					break;
					
				default:
					respuesta.setMsg("Error el ordenamiento no es el correcto");
					estatus = HttpStatus.BAD_REQUEST;
					return new ResponseEntity(respuesta, estatus);
				}
				
				// Se mapea la entidad se le pasa el query y lo bota como un tipo de objeto
				// ParamDto-Buscar en los DTO

				Query query;
				Query query3;
				Query query4;

				
				String QueryTypes = "SELECT CAST(elem AS TEXT) " 
				        + "	FROM main.params pa, "
						+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ "	WHERE pa.paramname = 'PROCESS_TYPE' ";

				String QueryRemote = "SELECT CAST(elem AS TEXT) " 
				        + "	FROM main.params pa, "
						+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ "	WHERE pa.paramname = 'PROCESS_REMOTE' ";

								
				System.out.println(QueryTotal);
				query = entityManager.createNativeQuery(QueryTotal);
				cuantosregistro = (long) query.getResultList().size();
				if (formatList!=2) { 
				query.setFirstResult(offsetIn);
				query.setMaxResults(numofrecordsIn);
				}
				
				
				List<Integer> can = new ArrayList<>();
				List<ServiceoffersDto> oferList = new ArrayList();
				ServiceoffersDto serviceoffersDto = new ServiceoffersDto();
				List<Object[]> resultados = query.getResultList();
				List<Object[]> resultadosTypes;
				List<Object[]> resultadosRemote;

				if (formatList!=2) { 
				if (cuantosregistro > 0) {
					// 4. Recorrer la lista y procesar los resultados
					for (Object[] fila : resultados) {
						procesResponseDto.setId((int) fila[0]);
						procesResponseDto.setName((String) fila[1]);
						procesResponseDto.setDsc((String) fila[2]);
						procesResponseDto.setRef((String) fila[3]);
						tipoRemoto.setDsc((String) fila[5]);
						tipoRemoto.setValue(fila[4].toString());
						tipoRemoteList.add(tipoRemoto);
						
						unidad.setId((Integer) fila[15]);
						unidad.setName((String) fila[16]);
						unidad.setRelationdeleted((boolean) fila[17]);
						unidad.setUnitprocessid((Integer) fila[18]);
						procesResponseDto.setUnit(unidad);
						/*String jsonStringRemote = (String) fila[5]; // Recupera el JSON como String
						JSONObject jsonObject;
						String dsc="";
						String value="";
						
						if (jsonStringRemote != null) {
							try {
								jsonObject = new JSONObject(jsonStringRemote); // Convierte String a JSONObject
								// Extrae los valores del JSONObject
								dsc = jsonObject.getString("dsc");
								value = jsonObject.getString("value");

								tipoRemoto.setDsc(dsc);
								tipoRemoto.setValue(value);
								tipoRemoteList.add(tipoRemoto);
							}catch(JSONException  e) {
								System.err.println("Error al procesar JSON remoto: " + e.getMessage());
			                    // Manejar el error o establecer valores predeterminados
							}
						}*/
						
						//codigo neldy
						statusDto.setId((int) fila[6]);
						statusDto.setName((String) fila[7]);
                  
						tipoProceso.setDsc((String) fila[9]);
						tipoProceso.setValue(fila[8].toString());
						tipoProcesoList.add(tipoProceso);
						
						/*String jsonStringTipo = (String) fila[9]; // Recupera el JSON como String
						if (jsonStringTipo != null) {
							try {
								jsonObject = new JSONObject(jsonStringTipo); // Convierte String a JSONObject
								// Extrae los valores del JSONObject
								dsc = jsonObject.getString("dsc");
								value = jsonObject.getString("value");

								tipoProceso.setDsc(dsc);
								tipoProceso.setValue(value);
								tipoProcesoList.add(tipoProceso);
							}catch(JSONException  e) {
								System.err.println("Error al procesar JSON Tipo Proceso: " + e.getMessage());
			                    // Manejar el error o establecer valores predeterminados
							}
						}*/
						
						// operationlineDto.setDsc((String)fila[11]);
						operationlineDto.setName((String) fila[11]);
						operationlineDto.setId((int) fila[10]);

						/*if (channelIdIn != 0)
							QueryCanal2 = QueryCanal + " AND c.processid = " + (int) fila[0] + " AND c.channelid = "
									+ channelIdIn;
						else
							QueryCanal2 = QueryCanal + " AND c.processid = " + (int) fila[0];

						query2 = entityManager.createNativeQuery(QueryCanal2);

						resultadosCanal = query2.getResultList();

						if (resultadosCanal.size() > 0) {
							for (Object canales : resultadosCanal) {
								can.add((Integer) canales);
							}
						}else
							can=new ArrayList<>();*/
						
						// Procesar los canales
					    String canalesString = (String) fila[12]; // Asumiendo que 'canales' es la columna 13
					    if (canalesString != null && !canalesString.isEmpty()) {
					        String[] canalesIds = canalesString.split(",");
					        for (String canalId : canalesIds) {
					        	can.add(Integer.parseInt(canalId));
					        }
					    }else
							can=new ArrayList<>();

						/*QueryOfertas2 = QueryOfertas + " AND ps.serviceofferid=s.id AND ps.processid = " + (int) fila[0];
						query5 = entityManager.createNativeQuery(QueryOfertas2);
						resultadosOfertas = query5.getResultList();

						if (resultadosOfertas.size() > 0) {
							for (Object[] ofertas : resultadosOfertas) {
								serviceoffersDto.setId((int)ofertas[0]);
								serviceoffersDto.setName((String)ofertas[1]);
								oferList.add(serviceoffersDto);
								serviceoffersDto = new ServiceoffersDto();
							}
						}else
							oferList=new ArrayList();*/
						
						// Procesar las ofertas
					    String ofertasString = (String) fila[13]; // Asumiendo que 'ofertas' es la columna 14
					    
					    if (ofertasString != null && !ofertasString.isEmpty()) {
					        String[] ofertasParts = ofertasString.split(";");
					        for (String ofertaPart : ofertasParts) {
					            String[] ofertaData = ofertaPart.split(":");
					            ServiceoffersDto ofertaDto = new ServiceoffersDto();
					            ofertaDto.setId(Integer.parseInt(ofertaData[0]));
					            ofertaDto.setName(ofertaData[1]);
					            oferList.add(ofertaDto);
					        }
					    }else
							oferList=new ArrayList();
						
						procesResponseDto.setServiceoffers(oferList);
						procesResponseDto.setChannels(can);
						procesResponseDto.setStatus(statusDto);
						procesResponseDto.setType(tipoProceso);
						procesResponseDto.setRemote(tipoRemoto);
						procesResponseDto.setOperationline(operationlineDto);

						processResultado.add(procesResponseDto);
						procesResponseDto = new ProcessResponseDto();
						unidad = new UnidadResponseRelatedDto();
						tipoRemoto = new ProcessRemoteDto();
						tipoProceso = new ProcessTypeDto();
						operationlineDto = new OperationlineDto();
						can = new ArrayList();
						oferList=new ArrayList();
						statusDto = new StatusDto();
					}

					// Se construye el Dto de Roles de Respuesta según los privilegios que
					// tenga el usuario
					rolisvalid=0;
					detallePrivilege = new PrivilegesAllDto();
					rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 121);
					if (rolisvalid>0)
						detallePrivilege.setUpdate(true);
					else
						detallePrivilege.setUpdate(false);

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

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

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

					query3 = entityManager.createNativeQuery(QueryTypes);

					resultadosTypes = query3.getResultList();
					JSONObject jsonObject;
					String jsonStringTipo = "";
					if (resultadosTypes.size() > 0) {
						for (Object tipos : resultadosTypes) {
							jsonStringTipo = (String) tipos; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringTipo); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							tipoProceso.setDsc(dsc);
							tipoProceso.setValue(value);
							tipoProcesoList2.add(tipoProceso);
							tipoProceso = new ProcessTypeDto();
						}
					}

					query4 = entityManager.createNativeQuery(QueryRemote);
					resultadosRemote = query4.getResultList();
					String jsonStringRemote = "";
					if (resultadosRemote.size() > 0) {
						for (Object tipoRemote : resultadosRemote) {
							jsonStringRemote = (String) tipoRemote; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringRemote); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							tipoRemoto.setDsc(dsc);
							tipoRemoto.setValue(value);
							tipoRemoteList2.add(tipoRemoto);
							tipoRemoto = new ProcessRemoteDto();
						}
					}

					processesResponseDto.setNumofrecords(cuantosregistro);
					processesResponseDto.setRecords(processResultado);
					processesResponseDto.setSessionvalidthru(fechaComoCadena);
					processesResponseDto.setTypes(tipoProcesoList2);
					processesResponseDto.setRemote(tipoRemoteList2);
					processesResponseDto.setPrivileges(detallePrivilege);

					return new ResponseEntity(processesResponseDto, HttpStatus.OK);
				} else {

					query3 = entityManager.createNativeQuery(QueryTypes);

					resultadosTypes = query3.getResultList();
					JSONObject jsonObject;
					String jsonStringTipo = "";
					if (resultadosTypes.size() > 0) {
						for (Object tipos : resultadosTypes) {
							jsonStringTipo = (String) tipos; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringTipo); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							tipoProceso.setDsc(dsc);
							tipoProceso.setValue(value);
							tipoProcesoList2.add(tipoProceso);
							tipoProceso = new ProcessTypeDto();
						}
					}

					query4 = entityManager.createNativeQuery(QueryRemote);
					resultadosRemote = query4.getResultList();
					String jsonStringRemote = "";
					if (resultadosRemote.size() > 0) {
						for (Object tipoRemote : resultadosRemote) {
							jsonStringRemote = (String) tipoRemote; // Recupera el JSON como String
							jsonObject = new JSONObject(jsonStringRemote); // Convierte String a JSONObject
							// Extrae los valores del JSONObject
							String dsc = jsonObject.getString("dsc");
							String value = jsonObject.getString("value");

							tipoRemoto.setDsc(dsc);
							tipoRemoto.setValue(value);
							tipoRemoteList2.add(tipoRemoto);
							tipoRemoto = new ProcessRemoteDto();
						}
					}

					// Se construye el Dto de Roles de Respuesta según los privilegios que
					// tenga el usuario
					rolisvalid=0;
					detallePrivilege = new PrivilegesAllDto();
					rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 121);
					if (rolisvalid>0)
						detallePrivilege.setUpdate(true);
					else
						detallePrivilege.setUpdate(false);

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

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

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

					processesResponseDto.setNumofrecords(cuantosregistro);
					processesResponseDto.setRecords(processResultado);
					processesResponseDto.setSessionvalidthru(fechaComoCadena);
					processesResponseDto.setTypes(tipoProcesoList2);
					processesResponseDto.setRemote(tipoRemoteList2);
					processesResponseDto.setPrivileges(detallePrivilege);
					return new ResponseEntity(processesResponseDto, HttpStatus.OK);
				}//fin
				}else {
					procesResponseDto2 = new ProcessesResponseDto2();
					processResponDto2 = new ProcessResponDto2();
					processResponDto2List = new ArrayList();
					
					query = entityManager.createNativeQuery(QueryTotal);
					cuantosregistro = (long) query.getResultList().size();					
					resultados = query.getResultList();
					if (cuantosregistro > 0) {
						// 4. Recorrer la lista y procesar los resultados
						for (Object[] fila : resultados) {
							 statusDto2 = new StatusDto2();
							processResponDto2.setId((int) fila[0]);
							processResponDto2.setName((String) fila[1]);
							statusDto2.setId((int) fila[2]);
							statusDto2.setName((String) fila[3]);
							
							unidad.setId((Integer) fila[7]);
							unidad.setName((String) fila[8]);
							unidad.setRelationdeleted((boolean) fila[9]);
							unidad.setUnitprocessid((Integer) fila[10]);
							processResponDto2.setUnit(unidad);
							
							processResponDto2.setStatus(statusDto2);
							processResponDto2List.add(processResponDto2);
							processResponDto2=new ProcessResponDto2();
							unidad = new UnidadResponseRelatedDto();
						}
					}
					procesResponseDto2.setRecords(processResponDto2List);
					procesResponseDto2.setSessionvalidthru(fechaComoCadena);
					return new ResponseEntity(procesResponseDto2, HttpStatus.OK);
				}

				

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

	@GetMapping("/processes/{processid}")
	public ResponseEntity<?> obtenerUnProcesses(HttpServletRequest request,
			@PathVariable("processid") final Integer processid) throws ParseException {

		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

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

		String searchIn = "";
		int statusIn = 0;
		String processRemoteIn = "";
		String processTypeIn = "";
		int operationLineIdIn = 0;
		int channelIdIn = 0;

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

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

		// Verifico la session
		if (sessionid == null) {
			respuesta.setMsg("Llamada al servicio malformado");
			estatus = HttpStatus.BAD_REQUEST;
			return new ResponseEntity(respuesta, estatus);
		} else {
			sessionid = sessionid.substring(7);
			// verifico si la sesión del usuario existe.
			Optional<Users> encontreSessionUsuario = usersRepository.getBySessionid(sessionid);
			if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
				Date FechaReg = encontreSessionUsuario.get().getValidthru();
				// Llamada a la funcion que validad el tiempo de Session, retorna la fecha
				// sumandole el tiempo de session activa, y vacio si no esta activa
				fechaComoCadena = securityService.consultarSessionActiva(FechaReg, fecha2,
						encontreSessionUsuario.get().getId());

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

				// Obtengo el rol de usuario y verifico si corresponde al privilegio del usuario
				int rolisvalid = 0;
				rolisvalid = auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 120);
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios");
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus);
				}

			} else { // Si la sesión que viene es inválida
				respuesta.setMsg("Sesión expirada o inválida");
				estatus = HttpStatus.BAD_REQUEST;
				return new ResponseEntity(respuesta, estatus);
			}

			// Aqui empieza la carga de la data de respuesta

			ProceResponseDto procesResponseDto = new ProceResponseDto();
			OperationlineDto operationlineDto = new OperationlineDto();
			ProcessTypeDto tipoProceso = new ProcessTypeDto();
			ChannelDto canal = new ChannelDto();
			List<ChannelDto> listCanales = new ArrayList();
			
			StatusDto statusDto = new StatusDto();
			ProcessRemoteDto tipoRemoto = new ProcessRemoteDto();
			List<ProceResponseDto> processResultado = new ArrayList();
			EntryProcessDto entryProcessDto = new EntryProcessDto();
			// PrivilegesAllDto detallePrivilege = new PrivilegesAllDto();

			try {
				Query query;
				Query query2;
				Query query5;
				// Sentencia General
				String SentenciaBase = "SELECT p.id,p.name,p.dsc,p.ref,p.processremotepar, "
						+ "( SELECT CAST(elem AS TEXT) " + " FROM main.params pa, "
						+ " jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ " WHERE (elem ->> 'value') = CAST(p.processremotepar AS text)  "
						+ " AND pa.paramname = 'PROCESS_REMOTE' ) nombreremote, " + "  p.status,  "
						+ " CASE WHEN p.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS descStatus, "
						+ " p.processtypepar," + "( SELECT CAST(elem AS TEXT) " + " FROM main.params pa, "
						+ " jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ " WHERE (elem ->> 'value') = CAST(p.processtypepar AS text) "
						+ " AND pa.paramname = 'PROCESS_TYPE' ) nombretipo, " + " p.operationlineid, "
						+ "( SELECT e.name " + " FROM main.operationlines e "
						+ " WHERE e.id = p.operationlineid ) nombreoperation " + " FROM main.processes p "
						+ " WHERE p.id = :processid ";
				query = entityManager.createNativeQuery(SentenciaBase);
				query.setParameter("processid", processid);

				String QueryCanal = "SELECT c.id,c.name " 
				        + " FROM main.processchannels p,main.channels c "
						+ " WHERE p.processid = :processid " 
				        + " AND p.channelid = c.id ";

				String QueryOfertas = "SELECT s.id, s.name " 
				        + " FROM main.serviceoffers s, main.processserviceoffers ps " 
						+ " WHERE 1=1 ";
				
				cuantosregistro = (long) query.getResultList().size();
				query.setFirstResult(offsetIn);
				query.setMaxResults(numofrecordsIn);

				// List<ProceResponseDto> processList = query.getResultList();
				List<Integer[]> resultadosCanal;
				List<Integer> can = new ArrayList<>();
				List<Object[]> resultadosOfertas;
				String QueryCanal2 = "";
				String QueryOfertas2 = "";
				List<Object[]> resultados = query.getResultList();
				List<Object[]> resultadosTypes;
				List<Object[]> resultadosRemote;
				List<ServiceoffersDto> oferList = new ArrayList();
				ServiceoffersDto serviceoffersDto = new ServiceoffersDto();

				if (cuantosregistro > 0) {
					// 4. Recorrer la lista y procesar los resultados
					for (Object[] fila : resultados) {
						procesResponseDto.setId((int) fila[0]);
						procesResponseDto.setName((String) fila[1]);
						procesResponseDto.setDsc((String) fila[2]);
						procesResponseDto.setRef((String) fila[3]);
						String jsonStringRemote = (String) fila[5]; // Recupera el JSON como String

						statusDto.setId((int) fila[6]);
						statusDto.setName((String) fila[7]);

						JSONObject jsonObject = new JSONObject(jsonStringRemote); // Convierte String a JSONObject
						// Extrae los valores del JSONObject
						String dsc = jsonObject.getString("dsc");
						String value = jsonObject.getString("value");

						tipoRemoto.setDsc(dsc);
						tipoRemoto.setValue(value);
						// tipoRemoteList.add(tipoRemoto);

						String jsonStringTipo = (String) fila[9]; // Recupera el JSON como String
						jsonObject = new JSONObject(jsonStringTipo); // Convierte String a JSONObject
						// Extrae los valores del JSONObject
						dsc = jsonObject.getString("dsc");
						value = jsonObject.getString("value");

						tipoProceso.setDsc(dsc);
						tipoProceso.setValue(value);
						// tipoProcesoList.add(tipoProceso);

						operationlineDto.setName((String) fila[11]);
						operationlineDto.setId((int) fila[10]);

						query2 = entityManager.createNativeQuery(QueryCanal);
						query2.setParameter("processid", processid);
						resultadosCanal = query2.getResultList();

						if (resultadosCanal.size() > 0) {
							for (Object[] canales : resultadosCanal) {
								can.add((Integer) canales[0]);
								canal.setId((Integer) canales[0]);
								canal.setName((String) canales[1]);
								listCanales.add(canal);
								canal = new ChannelDto();
							}
						}else
							can=new ArrayList<>();

						QueryOfertas2 = QueryOfertas + " AND ps.serviceofferid=s.id AND ps.processid = " + (int) fila[0];
						query5 = entityManager.createNativeQuery(QueryOfertas2);
						resultadosOfertas = query5.getResultList();

						if (resultadosOfertas.size() > 0) {
							for (Object[] ofertas : resultadosOfertas) {
								serviceoffersDto.setId((int)ofertas[0]);
								serviceoffersDto.setName((String)ofertas[1]);
								oferList.add(serviceoffersDto);
								serviceoffersDto = new ServiceoffersDto();
							}
						}else
							oferList=new ArrayList();
						
						procesResponseDto.setServiceoffers(oferList);
						procesResponseDto.setChannels(can);
						procesResponseDto.setChannelss(listCanales);
						procesResponseDto.setStatus(statusDto);
						procesResponseDto.setType(tipoProceso);
						procesResponseDto.setRemote(tipoRemoto);
						procesResponseDto.setOperationline(operationlineDto);

						processResultado.add(procesResponseDto);
						// procesResponseDto = new ProceResponseDto();
						tipoRemoto = new ProcessRemoteDto();
						operationlineDto = new OperationlineDto();
						can = new ArrayList();
						oferList = new ArrayList();
						QueryCanal2 = "";
						QueryOfertas2 = "";
					}

					entryProcessDto.setEntry(procesResponseDto);
					entryProcessDto.setSessionvalidthru(fechaComoCadena);
					

				} else {
					respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				}
				return new ResponseEntity(entryProcessDto, HttpStatus.OK);

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

	
	  @PostMapping("/processes/{processid}") 
	  public ResponseEntity<?> actualizarProcesses(HttpServletRequest request,@RequestBody
	  ProcessActualizarDto processActualizarDto, @PathVariable("processid") final Integer processid) throws ParseException {
	  
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

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

		AuditRequestDto auditDto = new AuditRequestDto();
		String module ="";
		String Descmodule="";
		
		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);
		
		Optional<Operationlines> operationLines;
		
		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);
		
		 // Verifico la session 
		if (sessionid == null) {
		  respuesta.setMsg("Llamada al servicio malformado");
		  estatus =HttpStatus.BAD_REQUEST; 
		  return new ResponseEntity(respuesta, estatus); 
		} else{ 
			sessionid = sessionid.substring(7); // verifico si la sesión del usuario existe.
		  
		Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
		if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
		  Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
		  // Llamada a la funcion que validad el tiempo de Session, retorna la fecha 
		  // sumandole el tiempo de session activa, y vacio si no esta activa 
		  fechaComoCadena =securityService.consultarSessionActiva(FechaReg, fecha2,encontreSessionUsuario.get().getId());
		  if (fechaComoCadena == "") { 
			  RespuestaMsgDto respuestaDto2;
			  String var2 = "";
			  boolean bloked2 = false;
			  respuestaDto2 = new RespuestaMsgDto(var2);
			  respuestaDto2.setMsg("Sesión expirada o inválida");
			  return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
		  }
			
		  int rolisvalid = 0; 
		  if (processid!=0) {//actualizar proceso
			  
			  try  {
				//verifico si tiene el privilegio
				rolisvalid =	auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 121); 
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios"); 
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus); 
				}
				
				    String SalidaName= usersService.verificarCaracteresValidosConRegex(processActualizarDto.getName());
				    String SalidaDesc = usersService.verificarCaracteresValidosConRegex(processActualizarDto.getDsc());
				    String SalidaCod = usersService.verificarCaracteresValidosConRegex(processActualizarDto.getRef());
				    
				    if (SalidaName=="NOOK" || SalidaDesc=="NOOK" || SalidaCod=="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);
					  }
			    //Verificar si el campo nombre no puede ser vacío
				if (processActualizarDto.getName()=="") {
					String var = "";
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					respuestaDto.setMsg("El campo nombre no puede ser vacío");
					return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				}
					 
				///Verificar si el campo ref no puede ser vacìo
				if (processActualizarDto.getRef()=="") {
					String var = "";
					RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				    respuestaDto.setMsg("El campo ref no puede ser vacío");
				    return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				}
					 
				//Verifico si existe el id de proceso en la base de datos
			    Optional<Processes> obtproceso=processesRepository.findById(processid);
			    Processes proceso=new Processes();
			    Processes proceso3=new Processes();
			    //Verifico si encontre el proceso
			    if (obtproceso!=null) {
			    	proceso=obtproceso.get();
			    }else {
			    	respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			    }
			    
				//Verificar si el nombre del proceso existe en la base de datos 
			    if (processesRepository.existsByName(processActualizarDto.getName()) 
			    		&& processesRepository.getByName(processActualizarDto.getName()).get().getId() != processid) {			    
					respuesta.setMsg("Registro Duplicado");
					return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
				} 
				
			   //Verificar si el ref del proceso existe en la base de datos 
			    if (processesRepository.existsByRef(processActualizarDto.getRef()) 
			    		&& processesRepository.getByRef(processActualizarDto.getRef()).get().getId() != processid) {			    
					respuesta.setMsg("Registro Duplicado");
					return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
				} 
			    
			     //Construyo los datos de la entidad de procesos			 
				 proceso.setStatus(processActualizarDto.getStatus());
				 proceso.setName(processActualizarDto.getName());
				 proceso.setDsc(processActualizarDto.getDsc());
				 proceso.setRef(processActualizarDto.getRef());
				 proceso.setProcessremotepar(processActualizarDto.getProcessremotepar());
				 proceso.setProcesstypepar(processActualizarDto.getProcesstypepar());
				 proceso.setModifiedat(fecha2);
				 if (!operationlinesRepository.existsById(processActualizarDto.getOperationlineid())){
					 respuesta.setMsg("Registro de linea de operación no encontrado");
					 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				 }else{
					 proceso.setOperationlineid(operationlinesRepository.findById(processActualizarDto.getOperationlineid()).get());
				 }
				 
				 proceso3=processesRepository.save(proceso);  
				  
				 if (proceso3!=null) {
					 //Borro las ofertas y canales existentes del proceso
					 processchannelsRepository.borrarProcesschannels(proceso3.getId());
					 processserviceoffersRepository.borrarProcessesserviceoffers(proceso3.getId());
					 //inserto las ofertas y canales recibidos del proceso
					 Optional<Processes> proceso2=processesRepository.findByName(processActualizarDto.getName());
					 
					 if (processActualizarDto.getChannels()!=null) {
						 //Verificar si existen los canales
						 /*for(Integer can:processActualizarDto.getChannels()) {
							 if (!channelsRepository.existsById(can)){
								 respuesta.setMsg("Registro de canal no encontrado con id: "+can);
								 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
							 }
						 }*/
						 
						 //inserta los canales
						 Processchannels processchannels = new Processchannels();
						 for(Integer can:processActualizarDto.getChannels()) {
							 processchannels.setChannelid(can);
							 processchannels.setProcessid(proceso2.get().getId());
							 processchannelsRepository.save(processchannels);
							 processchannels = new Processchannels();
						 }
					 }
					 
					 if (processActualizarDto.getServiceoffers()!=null) {
						 //Verificar si existen los servicios
						 /*for(Integer ser:processActualizarDto.getServiceoffers()) {
							 if (!serviceoffersRepository.existsById(ser)){
								 respuesta.setMsg("Registro de oferta de servicio no encontrado con id: "+ser);
								 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
							 }
						 }*/
						 
						 Processserviceoffers processserviceoffers = new Processserviceoffers();
						 for(Integer ser:processActualizarDto.getServiceoffers()) {
							 processserviceoffers.setProcessid(proceso2.get().getId());
							 processserviceoffers.setServiceofferid(ser);
							 processserviceoffersRepository.save(processserviceoffers);
							 processserviceoffers = new Processserviceoffers();
						 }
					 }
				 }
				 
				 module = "Procesos";
			     Descmodule = "Se actualizó el proceso: " + proceso.getName();
				 auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
				 String singo1 = "(";
				 String singo2 = ")";
				 String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
							.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
				 auditDto.setUserref(usryemail);
				 auditDto.setModule(module);
				 auditDto.setDesc(Descmodule);
				 auditDto.setCreatedat(fechaDate2);
				 usersService.registrarAuditSesion(auditDto);
				 
				 RespuestaValueDto respuestaValueDto = new RespuestaValueDto(processid); 
				 URI location = URI.create("/processes/"+processid); // O la URL correcta para // tu recurso
				 
				 return ResponseEntity.created(location).body(respuestaValueDto);
			}catch(Exception e) {
				 respuesta.setMsg("Error interno del servidor ");
			     estatus = HttpStatus.INTERNAL_SERVER_ERROR;
			}
		  }else { //incluir proceso 
			  
			try{ 
				rolisvalid=auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 122); 
				 if (rolisvalid == 0) {
					 respuesta.setMsg("No tiene los Privilegios"); 
					 estatus = HttpStatus.FORBIDDEN;
					 return new ResponseEntity(respuesta, estatus); 
			     }
				 
				 //Verificar si el campo nombre no puede ser vacío
				 if (processActualizarDto.getName()=="") {
					 String var = "";
				     RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					 respuestaDto.setMsg("El campo nombre no puede ser vacío");
					 return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				 }
				 
				///Verificar si el campo ref no puede ser vacìo
				 if (processActualizarDto.getRef()=="") {
					 String var = "";
				     RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					 respuestaDto.setMsg("El campo ref no puede ser vacío");
					 return new ResponseEntity(respuestaDto, HttpStatus.BAD_REQUEST);
				 }
				 
				 //Verificar si el registro está duplicado el nombre en la base de datos
				 if (processesRepository.existsByName(processActualizarDto.getName())) {
					 String var = "";
				     RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					 respuestaDto.setMsg("Registro Duplicado");
					 return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
				 }
				 
				///Verificar si el registro está duplicado el ref en la base de datos
				 if (processesRepository.existsByRef(processActualizarDto.getRef())) {
					 String var = "";
				     RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
					 respuestaDto.setMsg("Registro Duplicado");
					 return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
				 }
				 
				 //Construyo los datos de la entidad de procesos			 
				 Processes proceso= new Processes();
				 Processes proceso3= new Processes();
				 proceso.setStatus(processActualizarDto.getStatus());
				 proceso.setName(processActualizarDto.getName());
				 proceso.setDsc(processActualizarDto.getDsc());
				 proceso.setRef(processActualizarDto.getRef());
				 proceso.setProcessremotepar(processActualizarDto.getProcessremotepar());
				 proceso.setProcesstypepar(processActualizarDto.getProcesstypepar());
				 proceso.setCreatedat(fecha2);
				 proceso.setModifiedat(fecha2);
				 if (!operationlinesRepository.existsById(processActualizarDto.getOperationlineid())){
					 respuesta.setMsg("Registro de linea de operación no encontrado");
					 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
				 }else{
					 proceso.setOperationlineid(operationlinesRepository.findById(processActualizarDto.getOperationlineid()).get());
				 }
				 
				 proceso3=processesRepository.save(proceso);
				 try {
					 if (proceso3!=null) {
						 Optional<Processes> proceso2=processesRepository.findByName(processActualizarDto.getName());
						 
						 if (processActualizarDto.getChannels()!=null) {
							//Verificar si existen los canales
							 /*for(Integer can:processActualizarDto.getChannels()) {
								 if (!channelsRepository.existsById(can)){
									 respuesta.setMsg("Registro de canal no encontrado con id: "+can);
									 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
								 }
							 }*/
							 
							 Processchannels processchannels = new Processchannels();
							 for(Integer can:processActualizarDto.getChannels()) {
								 processchannels.setChannelid(can);
								 processchannels.setProcessid(proceso2.get().getId());
								 processchannelsRepository.save(processchannels);
								 processchannels = new Processchannels();
							 }
						 }
						 
						 if (processActualizarDto.getServiceoffers()!=null) {
							//Verificar si existen las ofertas
							 /*for(Integer ser:processActualizarDto.getServiceoffers()) {
								 if (!serviceoffersRepository.existsById(ser)){
									 respuesta.setMsg("Registro de oferta de servicio no encontrado con id: "+ser);
									 return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
								 }
							 }*/
							 
							 Processserviceoffers processserviceoffers = new Processserviceoffers();
							 /*String ofertasId = arrayAParentesis(processActualizarDto.getServiceoffers());
							 String sql = "INSERT INTO main.processserviceoffers (processid,serviceofferid) SELECT " + id +", id " + " FROM main.serviceoffers  WHERE id IN " + procesos;*/
							 for(Integer ser:processActualizarDto.getServiceoffers()) {
								 processserviceoffers.setProcessid(proceso2.get().getId());
								 processserviceoffers.setServiceofferid(ser);
								 processserviceoffersRepository.save(processserviceoffers);
								 processserviceoffers = new Processserviceoffers();
							 }
						 }
						
						 module = "Procesos";
					     Descmodule = "Se insertó el proceso: " + proceso.getName();
						 auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
						 String singo1 = "(";
						 String singo2 = ")";
						 String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
									.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
						 auditDto.setUserref(usryemail);
						 auditDto.setModule(module);
						 auditDto.setDesc(Descmodule);
						 auditDto.setCreatedat(fechaDate2);
						 usersService.registrarAuditSesion(auditDto);
							
						RespuestaValueDto respuestaValueDto = new RespuestaValueDto(proceso2.get().getId()); 
						URI location = URI.create("/processes/"+proceso2.get().getId()); // O la URL correcta para // tu recurso
						return ResponseEntity.created(location).body(respuestaValueDto);
					 }else {
						 respuesta.setMsg("No se pudo actualizar por alguna razón");
				     	 estatus = HttpStatus.CONFLICT;
				     	 return new ResponseEntity(respuesta, estatus);
					 }
				 }catch(Exception e) {
					 respuesta.setMsg("Error interno.  Descripción del error"+e.getMessage());
				     estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				     return new ResponseEntity(respuesta, estatus);
				 }
				 
			  }catch(Exception e){
					 respuesta.setMsg("Error interno.  Descripción del error"+ e.getMessage());
				     estatus = HttpStatus.INTERNAL_SERVER_ERROR;
				     return new ResponseEntity(respuesta, estatus);
			  }
		  }
	    }
		
		return new ResponseEntity(respuesta, HttpStatus.OK);
	  
		}
		
	 }

	  @DeleteMapping("/processes/{processid}") 
	  public ResponseEntity<?> borrarProcesses(HttpServletRequest request,@PathVariable("processid") final Integer processid) throws ParseException {
	  
		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;

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

		AuditRequestDto auditDto = new AuditRequestDto();
		String module ="";
		String Descmodule="";
		
		Date fecha3 = new Date();
		SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataFormattata2 = formatter.format(fecha3);
		Date fechaDate2 = formatter.parse(dataFormattata2);
		
		Optional<Params> deSessDuration = paramsRepository.findByParamname("SESSION_DURATION");
		String SessionDuration = deSessDuration.get().getValue();
		int duracionSession = Integer.parseInt(SessionDuration);
		Date fecha2 = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(fecha2); // tuFechaBase es un Date;
		// calendar.add(Calendar.MINUTE, minutosASumar); //minutosASumar es int.
		calendar.add(Calendar.MINUTE, duracionSession); // horasASumar es int.
		// lo que más quieras sumar
		Date ValidThrufechaSalida = calendar.getTime(); // Y ya tienes la fecha sumada.
		SimpleDateFormat salida = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 2024-12-23 23:00
		String fechaComoCadena = salida.format(ValidThrufechaSalida);
		System.out.println(fechaComoCadena);
		
		 // Verifico la session 
		if (sessionid == null) {
		  respuesta.setMsg("Llamada al servicio malformado");
		  estatus =HttpStatus.BAD_REQUEST; 
		  return new ResponseEntity(respuesta, estatus); 
		} else{ 
			sessionid = sessionid.substring(7); // verifico si la sesión del usuario existe.
		  
		Optional<Users> encontreSessionUsuario =usersRepository.getBySessionid(sessionid);
		if (encontreSessionUsuario.isPresent()) { // si la sesión del usuario existe
		  Date FechaReg = encontreSessionUsuario.get().getValidthru(); 
		  // Llamada a la funcion que validad el tiempo de Session, retorna la fecha 
		  // sumandole el tiempo de session activa, y vacio si no esta activa 
		  fechaComoCadena =securityService.consultarSessionActiva(FechaReg, fecha2,encontreSessionUsuario.get().getId());
		  if (fechaComoCadena == "") { 
			  RespuestaMsgDto respuestaDto2;
			  String var2 = "";
			  boolean bloked2 = false;
			  respuestaDto2 = new RespuestaMsgDto(var2);
			  respuestaDto2.setMsg("Sesión expirada o inválida");
			  return new ResponseEntity(respuestaDto2, HttpStatus.UNAUTHORIZED);
		  }
			
		  int rolisvalid = 0; 
			  
			  try  {
				//verifico si tiene el privilegio
				rolisvalid =	auditRepository.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 123); 
				if (rolisvalid == 0) {
					respuesta.setMsg("No tiene los Privilegios"); 
					estatus = HttpStatus.FORBIDDEN;
					return new ResponseEntity(respuesta, estatus); 
				}
				
				//Verifico si existe el id de proceso en la base de datos
			    Optional<Processes> obtproceso=processesRepository.findById(processid);
			    Processes proceso=new Processes();
			    //Verifico si encontre el proceso
			    if (obtproceso!=null) {
			    	proceso=obtproceso.get();
			    }else {
			    	respuesta.setMsg("Registro no encontrado");
					return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
			    }
			    
			    try {
				    //Se borra la relación de canales y ofertas
				    if (processchannelsRepository.existsByProcessid(proceso.getId()))
				    	processchannelsRepository.borrarProcesschannels(proceso.getId());
				    
				    if (processserviceoffersRepository.existsByProcessid(proceso.getId()))
				    	processserviceoffersRepository.borrarProcessesserviceoffers(proceso.getId());
				    
				    if (unitprocessesRepository.existsByProcessid(proceso.getId()))
				    	unitprocessesRepository.borrarProcessesUnits(proceso.getId());
				    
				    
					processesRepository.borrarProcess(proceso.getId());
					
					module = "Procesos";
					Descmodule = "Se borró el proceso: " + proceso.getName();
					auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
					String singo1 = "(";
					String singo2 = ")";
					String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
							.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
					auditDto.setUserref(usryemail);
					auditDto.setModule(module);
					auditDto.setDesc(Descmodule);
					auditDto.setCreatedat(fechaDate2);
					usersService.registrarAuditSesion(auditDto);
					
					RespuestaValueDto respuestaValueDto = new RespuestaValueDto(processid); 
					URI location = URI.create("/processes/"+processid); // O la URL correcta para // tu recurso
					 
					 return ResponseEntity.created(location).body(respuestaValueDto);
			    }catch(Exception e) {
					 respuesta.setMsg("No se pudo borrar por alguna razón");
				     estatus = HttpStatus.CONFLICT;
				     return new ResponseEntity(respuesta, estatus);
				} 
			}catch(Exception e) {
				 respuesta.setMsg("Error interno. Descripción del error "+e.getMessage());
			     estatus = HttpStatus.INTERNAL_SERVER_ERROR;
			     return new ResponseEntity(respuesta, estatus);
			}
		  
	    }
		
		return new ResponseEntity(respuesta, HttpStatus.OK);
	  
		}
		
	 }
	  
	  public String arrayAParentesis(List<Integer> lista) {
			
		    if (lista == null || lista.isEmpty()) {
		        return "()";
		    }
		    StringBuilder sb = new StringBuilder("(");
		    for (int i = 0; i < lista.size(); i++) {
		        sb.append(lista.get(i));
		        if (i < lista.size() - 1) {
		            sb.append(", ");
		        }
		    }
		    sb.append(")");
		    return sb.toString();
		}
}
