package com.dacrt.SBIABackend.controler;

import java.net.URI;
import java.sql.Connection;
import java.text.ParseException;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
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 javax.validation.constraints.NotNull;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dacrt.SBIABackend.dto.AppTypeDto;
import com.dacrt.SBIABackend.dto.ApplicationActualizarDto;
import com.dacrt.SBIABackend.dto.ApplicationDto;
import com.dacrt.SBIABackend.dto.ApplicationDto2;
import com.dacrt.SBIABackend.dto.ApplicationExtDto;
import com.dacrt.SBIABackend.dto.ApplicationResponseDto2;
import com.dacrt.SBIABackend.dto.AppyesnoDto;
import com.dacrt.SBIABackend.dto.CampaignFormat2Dto;
import com.dacrt.SBIABackend.dto.ChannelDto;
import com.dacrt.SBIABackend.dto.ChannelDto2;
import com.dacrt.SBIABackend.dto.ChannelsDtoStatus;
import com.dacrt.SBIABackend.dto.DrptestDto;
import com.dacrt.SBIABackend.dto.EntryApplicationDto;
import com.dacrt.SBIABackend.dto.EntryApplicationDto2;
import com.dacrt.SBIABackend.dto.FacilityDto;
import com.dacrt.SBIABackend.dto.FacilityDto2;
import com.dacrt.SBIABackend.dto.Mensaje;
import com.dacrt.SBIABackend.dto.OperationActualizarDto;
import com.dacrt.SBIABackend.dto.OperationlineDto;
import com.dacrt.SBIABackend.dto.PeriodParResponseDto;
import com.dacrt.SBIABackend.dto.PeriodsResponseDto;
import com.dacrt.SBIABackend.dto.ProcessTypeDto;
import com.dacrt.SBIABackend.dto.RecordCatalogoResponseDto;
import com.dacrt.SBIABackend.dto.RecuperationDto;
import com.dacrt.SBIABackend.dto.RegisteredDto;
import com.dacrt.SBIABackend.dto.ResultDto;
import com.dacrt.SBIABackend.dto.ServiceOffers6Dto;
import com.dacrt.SBIABackend.dto.ServiceOffersDescDto;
import com.dacrt.SBIABackend.dto.StatusDto;
import com.dacrt.SBIABackend.dto.StatusDto2;
import com.dacrt.SBIABackend.dto.SuppliersDto;
import com.dacrt.SBIABackend.dto.SuppliersDtoStatus;
import com.dacrt.SBIABackend.dto.TestedDto;
import com.dacrt.SBIABackend.dto.TestresultsDto;
import com.dacrt.SBIABackend.dto.TesttypesDto;
import com.dacrt.SBIABackend.dto.TypeDto;
import com.dacrt.SBIABackend.dto.UnitsDto;
import com.dacrt.SBIABackend.dto.UnitsUsersDto;
import com.dacrt.SBIABackend.dto.responseDto.ApplicationResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.ChannelsResponseDto;
import com.dacrt.SBIABackend.dto.responseDto.SuppliersRespondeDto;
import com.dacrt.SBIABackend.entity.Applications;
import com.dacrt.SBIABackend.entity.Facilities;
import com.dacrt.SBIABackend.entity.Suppliers;
import com.dacrt.SBIABackend.entity.Units;
import com.dacrt.SBIABackend.entity.Userunits;
import com.dacrt.SBIABackend.entity.Workers;
import com.dacrt.SBIABackend.repository.ApplicationsRepository;
import com.dacrt.SBIABackend.repository.FacilitiesRepository;
import com.dacrt.SBIABackend.repository.SuppliersRepository;
import com.dacrt.SBIABackend.repository.UnitsRepository;
import com.dacrt.SBIABackend.security.dto.AuditAllDto;
import com.dacrt.SBIABackend.security.dto.AuditRequestDto;
import com.dacrt.SBIABackend.security.dto.EntryDto;
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.RoleDto;
import com.dacrt.SBIABackend.security.dto.RolesResponseDto;
import com.dacrt.SBIABackend.security.dto.RolesUserDto;
import com.dacrt.SBIABackend.security.dto.SuppliersUsersDto;
import com.dacrt.SBIABackend.security.dto.UserDetailsResponseDto;
import com.dacrt.SBIABackend.security.dto.UserListDto;
import com.dacrt.SBIABackend.security.dto.UsersListDto;
import com.dacrt.SBIABackend.security.dto.UsersUnitDto;
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.enums.RolNombre;
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.RolesRepository;
import com.dacrt.SBIABackend.security.repository.UsersRepository;
import com.dacrt.SBIABackend.security.service.RolesService;
import com.dacrt.SBIABackend.security.service.SecurityService;
import com.dacrt.SBIABackend.security.service.MenuService;
import com.dacrt.SBIABackend.security.service.ParamsService;
import com.dacrt.SBIABackend.security.service.UsersService;
import com.dacrt.SBIABackend.service.SuppliersService;
import com.dacrt.SBIABackend.service.WorkersService;
import com.dacrt.SBIABackend.utils.HttpReqRespUtils;

@RestController
//@RequestMapping("/units")   
@CrossOrigin(origins = "*")
public class ApplicationsController {

	@Autowired
	private ParamsRepository paramsRepository;

	@Autowired
	private UsersRepository usersRepository;

	@Autowired
	private AuditRepository auditRepository;

	@Autowired
	private RolesPrivilegesRepository rolesPrivilegesRepository;

	@Autowired
	UsersService usersService;

	@Autowired
	ParamsService paramsService;

	@Autowired
	SecurityService securityService;

	@Autowired
	MenuService menuService;

	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	SuppliersRepository suppliersRepository;
	
	@Autowired
	ApplicationsRepository applicationsRepository;
	
	@Autowired
	FacilitiesRepository facilitiesRepository;

	@PostMapping("/applications")
	public ResponseEntity<?> applications(HttpServletRequest request, @RequestBody UsersListDto tiposfiltros)
			throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ApplicationResponseDto applicationResponseDto = new ApplicationResponseDto();
		ApplicationResponseDto2 applicationResponseDto2 = new ApplicationResponseDto2();
		RecordCatalogoResponseDto appFormatResponseDto = new RecordCatalogoResponseDto();
		// ParamsDto detalleParams;
		ApplicationDto detalleApplication;
		ApplicationDto2 detalleApplication2;
		StatusDto detalleStatus;
		PrivilegesAllDto detallePrivilege;
		FacilityDto2 detallefacility;
		Long cuantosregistro = (long) 0;
		CampaignFormat2Dto detalleCompaing2;

		List<PrivilegesAllDto> listasPrivelege = 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 drptestyesnoparSearch = "";
		String apptypeSearch = "";
		String contentIn = "";
		int serviceofferidIn=0;
		int searchStatus = 0;
		int facilityIn = 0;
		int formatList = 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);
			// String usuarioIN = encontreSessionUsuario.get().getUsr();
			// int position = usuarioIN.indexOf('(');

			if (encontreSessionUsuario.isPresent()) {

				Date FechaReg = encontreSessionUsuario.get().getValidthru();

				// 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);

				}
				// Este proceso permite obtener un listado de los proveedores. (Priv 440)
				formatList = tiposfiltros.getFormat();
				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 400);
				if (formatList != 2) {
					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);
				  }
				searchStatus = tiposfiltros.getFilters().getStatus();
				orderIn = tiposfiltros.getOrder();
				apptypeSearch = tiposfiltros.getFilters().getApptypepar();
				try {
					drptestyesnoparSearch = tiposfiltros.getFilters().getDrptestyesnopar();
				} catch (Exception e) {
					drptestyesnoparSearch = "";
				}
				
				
				
				if (drptestyesnoparSearch==null) {
					drptestyesnoparSearch = "";
				}
				   
				 try {
				   serviceofferidIn = tiposfiltros.getFilters().getServiceofferid();
				 } catch (Exception e) {
					 serviceofferidIn = 0;
				 }
			
				facilityIn = tiposfiltros.getFilters().getFacility();
				offsetIn = tiposfiltros.getOffset();
				numofrecordsIn = tiposfiltros.getNumofrecords();
				contentIn = tiposfiltros.getContent();
				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 = "";
			Query query;

			if (formatList != 2) {
				
				SentenciaBase = "SELECT DISTINCT u.id, "
						+ "    u.name, "
						+ "    u.status, "
						+ "    CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus, "
						+ "    u.dsc, "
						+ "    f.id AS idinsta, "
						+ "    f.name AS nameinstala, "
						+ "    CAST(u.recuperation AS INTEGER), "
						+ "    CAST(u.recuperationperiod AS INTEGER), "
						+ "    pn.descr AS nombre_periodo_recuperacion, "
						+ "    CAST(u.registered AS INTEGER), "
						+ "    u.registeredperiod, "
						+ "    po.descr AS nombre_registro_periodo, "
						+ "    u.drptestedpar, "
						+ "    pr.descr AS nombre_tested, "
						+ "    u.drptestdate, "
						+ "    cast(u.drptesttypepar as integer), "
						+ "    pt.descr AS tipo_tested, "
						+ "    cast(u.drptestresultpar as integer), "
						+ "    pq.descr AS tipo_tested_resultado, "
						+ "    u.serviceoffers, "
						+ "    u.channelids, "
						+ "    services_agg.nombres_ofertas_servicio_agrupados, "
						+ "    coalesce(services_agg.estado_horario_agrupado,'NO') estado_horario_agrupado, "
						+ "    STRING_AGG(c.name, ', ' ORDER BY channel_ids.ord) AS nombres_channels_agrupados, "
						+ "    cast(u.apptypepar as integer),  "
						+ "    ptype.descr AS tipo_type, "
						+ "  coalesce( CAST(NULLIF( REPLACE(REPLACE(u.serviceoffers, ',', ''), ' ', ''), '') AS INTEGER), 0) AS servicios, "
						+ "     pn.filter AS filterRecu, "
						+ "     po.filter AS filterReg "
						+ "FROM "
						+ "    main.applications u "
						+ "LEFT JOIN "
						+ "    main.facilities f ON u.facilityid = f.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 = 'APPS_YESNO' "
						+ "    ) pr ON u.drptestedpar = 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 = 'APPS_TESTTYPE' "
						+ "    ) pt ON u.drptesttypepar = CAST(pt.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 = 'APPS_TYPE' "
						+ "    ) ptype ON u.apptypepar = ptype.valor "
						+ "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 = 'APPS_TESTRESULT' "
						+ "    ) pq ON u.drptestresultpar = CAST(pq.valor AS integer) "
						+ "LEFT JOIN "
						+ "    (SELECT elemento ->> 'filter' AS filter,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 = 'EVALPROC_PERIOD') pn ON u.recuperationperiod = CAST(pn.valor AS integer) "
						+ "LEFT JOIN "
						+ "    (SELECT elemento ->> 'filter' AS filter,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 = 'EVALPROC_PERIOD') po ON u.registeredperiod = CAST(po.valor AS integer) "
						+ "LEFT JOIN LATERAL ( "
						+ "    SELECT "
						+ "        STRING_AGG(s.name, ', ' ORDER BY t.ord) AS nombres_ofertas_servicio_agrupados, "
						+ "        STRING_AGG(CASE WHEN s.offer_full = 1 THEN 'SI' ELSE 'NO' END, ', ' ORDER BY t.ord) AS estado_horario_agrupado "
						+ "    FROM "
						+ "        UNNEST(CAST(string_to_array(u.serviceoffers, ',') AS INTEGER[])) WITH ORDINALITY AS t(service_id, ord) "
						+ "    JOIN "
						+ "        main.serviceoffers s ON s.id = t.service_id "
						+ ") AS services_agg ON TRUE "
						+ "LEFT JOIN LATERAL ( "
						+ "    SELECT channel_id,ord "
						+ "    FROM UNNEST(CAST(string_to_array(u.channelids, ',') AS INTEGER[])) WITH ORDINALITY AS t(channel_id, ord) "
						+ ") AS channel_ids ON TRUE "
						+ "LEFT JOIN "
						+ "    main.channels c ON c.id = channel_ids.channel_id ";
						
						
			} else {
				SentenciaBase = "SELECT  u.id,  u.name, u.status, "
						+ "	 CASE WHEN u.status = 1 THEN 'Activo' ELSE 'Inactivo' END AS estatus,"
						+ "  f.id idFaci, f.name nombreInst,u.dsc "
						+ "	 FROM main.applications u "
						+ "  LEFT JOIN main.facilities f ON u.facilityid = f.id";
			}
			
			String groupby =  " GROUP BY "
					+ "    u.id, "
					+ "    u.name, "
					+ "    u.status, "
					+ "    u.dsc, "
					+ "    f.id, "
					+ "    f.name, "
					+ "    u.recuperation, "
					+ "    u.recuperationperiod, "
					+ "    pn.descr, "
					+ "    u.registered, "
					+ "    u.registeredperiod, "
					+ "    po.descr, "
					+ "    u.drptestedpar, "
					+ "    pr.descr, "
					+ "    u.drptestdate, "
					+ "    u.drptesttypepar, "
					+ "    pt.descr, "
					+ "    u.drptestresultpar, "
					+ "    pq.descr, "
					+ "    u.serviceoffers, "
					+ "    u.channelids, "
					+ "    services_agg.nombres_ofertas_servicio_agrupados, "
					+ "    services_agg.estado_horario_agrupado, "
					+ "    u.apptypepar, "
					+ "    ptype.descr, "
					+ "	   pn.filter, "
					+ "	   po.filter ";  

			String QueryTotal = "";
			String name = "u.name";
			String status = "u.status";
			String lowername = "LOWER(u.name)";
			String lowerdesc = "LOWER(u.dsc)";
			String LowerSearch = searchIn.toLowerCase();

			switch (searchIn) {
			case "": // viene sin busqueda por el like
				// QueryTotal = SentenciaBase;
				// QueryTotal = SentenciaBase + " WHERE " + lowername + " LIKE " + "'%" + "" +
				// "%'";
				QueryTotal = SentenciaBase + " WHERE TRUE = TRUE";
				break;

			default: // viene con el parametro para buscar por el like
				QueryTotal = SentenciaBase + " WHERE (" + lowername + " LIKE  " + "'%" + LowerSearch + "%'" + " OR "
						+ lowerdesc + " LIKE " + "'%" + LowerSearch + "%'" + ")";

			}
		if (formatList != 2) {
			switch (serviceofferidIn) {
			case 0: 
				QueryTotal = QueryTotal + " AND TRUE = TRUE";
				break;

			default: // viene con el parametro para buscar por el like
				QueryTotal = QueryTotal + " AND CAST(string_to_array(u.serviceoffers, ',') AS INTEGER[]) @> ARRAY["+serviceofferidIn+"] " ;

			}

			
			     switch (drptestyesnoparSearch) {
			     case "": // viene sin busqueda por el like
			   	   // QueryTotal = SentenciaBase;
				   // QueryTotal = SentenciaBase + " WHERE " + lowername + " LIKE " + "'%" + "" +
				   // "%'";
				  QueryTotal = QueryTotal + " AND TRUE = TRUE";
				   break;

			      default: // viene con el parametro para buscar por el like
				  QueryTotal = QueryTotal + " AND u.drptestedpar = " + drptestyesnoparSearch;

			 }
			}  
			
			switch (facilityIn) {
			case 0: 
				QueryTotal = QueryTotal;
				break;

			default: // viene con el parametro para buscar por el like
				QueryTotal = QueryTotal + " AND u.facilityid = " + facilityIn;

			}
			
			switch (apptypeSearch) {
			case "": // viene sin busqueda por el like

				QueryTotal = QueryTotal;
				break;

			default: // viene con el parametro para buscar por el like
				QueryTotal = QueryTotal + " AND u.apptypepar = " + "'" + apptypeSearch + "'";

			}

			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 + " = " + searchStatus;
				QueryTotal = QueryTotal + " AND " + status + " = " + 0;
				break;

			default: // viene con el parametro para buscar por el like
				String var = "";
				boolean bloked = false;
				RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
				// respuestaDto.setBlocked(bloked);
				respuestaDto.setMsg("Llamada al servicio malformado");
				// Error 400

			}

			String ordena = "";
			if (orderIn == 1 || orderIn == 2 || orderIn == 3 || orderIn == 4 || orderIn == 5 || orderIn == 6 || orderIn == 99) {
				ordena = " ASC";
			} else if (orderIn == -1 || orderIn == -2 || orderIn == -3 || orderIn == -4 || orderIn == -5 || orderIn == -6
					|| orderIn == -99) {
				ordena = " DESC";
			} else {
				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);
			}

			int absolutoOrden = Math.abs(orderIn);

			if (formatList != 2) {
				QueryTotal = QueryTotal + groupby;
			}
			
			switch (absolutoOrden) {
			case 1: // ordena por name ascendente

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

				QueryTotal = QueryTotal + " ORDER BY " + status + ordena;
				break;
			case 3:// ordena por dsc
				QueryTotal = QueryTotal + " ORDER BY " + " u.dsc " + ordena;
				break;
			case 4:// ordena por offer_full
				QueryTotal = QueryTotal + " ORDER BY " + " estado_horario_agrupado " + ordena;
				break;
			case 5:// ordena por facility
				QueryTotal = QueryTotal + " ORDER BY " + " f.name " + ordena;
				break;
			case 6:// ordena por type
				QueryTotal = QueryTotal + " ORDER BY " + " cast(u.apptypepar as integer) " + ordena;
				break;
			case 99: // ordena por status ascendente

				QueryTotal = QueryTotal + " ORDER BY " + " u.id " + ordena;
				break;
			default:
				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);
			}

			TestedDto testedDto = new TestedDto();
			TypeDto typeDto = new TypeDto();
			ResultDto resultDto = new ResultDto();
			DrptestDto drptestDto = new DrptestDto();
			RecuperationDto recuperationDto = new RecuperationDto();
			RegisteredDto registeredDto = new RegisteredDto();
			ServiceOffers6Dto serviceOffers6Dto = new ServiceOffers6Dto();
			ChannelDto2 channelDto2 = new ChannelDto2();
			PeriodParResponseDto periodParResponseDto = new PeriodParResponseDto();
			List<ServiceOffers6Dto> serviceoffersDto = new ArrayList();
			ServiceOffers6Dto detalleserviceoffers;
			ChannelDto detallechannel = new ChannelDto();
			List<ChannelDto2> channelsDto = new ArrayList();
			List<ServiceOffers6Dto> listasOfertas = new ArrayList<>();
			List<ChannelDto> listasChannel = new ArrayList<>();
			Query query3;
			Query query4;
			List<Object[]> resultadosTypes;
			List<Object[]> resultadosTypes2;
			AppTypeDto appTypeDto = new AppTypeDto();
			AppTypeDto appTypeYesNoDto = new AppTypeDto();
			StatusDto2 appTypeDto2 = new StatusDto2();

			List<AppTypeDto> tipoAppList = new ArrayList();
			List<AppTypeDto> tipoAppYesnoList = new ArrayList();
			
			if (formatList != 2) {
				 
				String QueryTypes = "SELECT CAST(elem AS TEXT) " + "	FROM main.params pa, "
						+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ "	WHERE pa.paramname = 'APPS_TYPE' ";
				
				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");

						appTypeDto.setDsc(dsc);
						appTypeDto.setValue(value);
						tipoAppList.add(appTypeDto);
						appTypeDto = new AppTypeDto();
					}
				}
				
				String QueryTypes2 = "SELECT CAST(elem AS TEXT) " + "	FROM main.params pa, "
						+ "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elem "
						+ "	WHERE pa.paramname = 'APPS_YESNO' ";
				
				query4 = entityManager.createNativeQuery(QueryTypes2);

				resultadosTypes2 = query4.getResultList();
				JSONObject jsonObject2;
				String jsonStringTipo2 = "";
				if (resultadosTypes2.size() > 0) {
					for (Object tipos2 : resultadosTypes2) {
						jsonStringTipo2 = (String) tipos2; // Recupera el JSON como String
						jsonObject2 = new JSONObject(jsonStringTipo2); // Convierte String a JSONObject
						// Extrae los valores del JSONObject
						String dsc = jsonObject2.getString("dsc");
						String value = jsonObject2.getString("value");

						appTypeYesNoDto.setDsc(dsc);
						appTypeYesNoDto.setValue(value);
						tipoAppYesnoList.add(appTypeYesNoDto);
						appTypeYesNoDto = new AppTypeDto();
					}
				}
				
				
				
				 query = entityManager.createNativeQuery(QueryTotal);
				 cuantosregistro = (long) query.getResultList().size();
				 query.setFirstResult(offsetIn);
				 query.setMaxResults(numofrecordsIn);
				// Se mapea la entidad se le pasa el query y lo bota como un tipo de objeto
				// ParamDto-Buscar en los DTO
				/*
				 * TypedQuery<ApplicationExtDto> channels =
				 * entityManager.createQuery(QueryTotal, ApplicationExtDto.class);
				 * channels.setFirstResult(offsetIn); channels.setMaxResults(numofrecordsIn);
				 */

				List<Object[]> listacompleta = query.getResultList();
				List<ApplicationDto> listasApplication = new ArrayList<>();
				detalleApplication = new ApplicationDto();
				// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
				// estatus
				for (Object[] fila : listacompleta) {
					
					// indice = 
					 System.out.print((int) fila[0]);
					detalleApplication = new ApplicationDto();
					detallefacility = new FacilityDto2();
					detalleStatus = new StatusDto();
					testedDto = new TestedDto();
					typeDto = new TypeDto();
					resultDto = new ResultDto();
					drptestDto = new DrptestDto();
					recuperationDto = new RecuperationDto();
					registeredDto = new RegisteredDto();
					periodParResponseDto = new PeriodParResponseDto();
					appTypeDto2 = new StatusDto2();

					detalleApplication.setId((int) fila[0]);
					detalleApplication.setName((String) fila[1]);
					detalleApplication.setDsc((String) fila[4]);

					detalleStatus.setId((int) fila[2]);
					detalleStatus.setName((String) fila[3]);

					detallefacility.setId((int) fila[5]);
					detallefacility.setName((String) fila[6]);

					detalleApplication.setStatus(detalleStatus);
					detalleApplication.setFacility(detallefacility);

					testedDto.setId((java.math.BigDecimal) fila[13]);
					testedDto.setName((String) fila[14]);

					typeDto.setId(fila[16] == null ? 0 : (Integer) fila[16]);
					typeDto.setName((String) fila[17] == null ? "" : (String) fila[17]);

					resultDto.setId(fila[18] == null ? 0: (Integer) fila[18]);
					resultDto.setName((String) fila[19] == null ? "" : (String) fila[19]);

					Date drpTestDate=fila[15] == null ? new Date(0) : (Date) fila[15];
					SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
					String formattedDateString = formatter1.format(drpTestDate);
					Date parsedDate = formatter1.parse(formattedDateString);
					drptestDto.setDate(fila[15] == null ? new Date(0) : parsedDate);
					
					drptestDto.setResult(resultDto);
					drptestDto.setTested(testedDto);
					drptestDto.setType(typeDto);
					detalleApplication.setDrptest(drptestDto);

					recuperationDto.setQty((Integer)fila[7]/Integer.parseInt((String)fila[28]));
					periodParResponseDto.setId(((Integer) fila[8]).toString());
					periodParResponseDto.setName((String) fila[9]);
					recuperationDto.setPeriod(periodParResponseDto);
					periodParResponseDto = new PeriodParResponseDto();

					registeredDto.setQty((Integer) fila[8]/Integer.parseInt((String)fila[29]));
					periodParResponseDto.setId(((Integer) fila[8]).toString());
					periodParResponseDto.setName((String) fila[9]);
					registeredDto.setPeriod(periodParResponseDto);

					detalleApplication.setRecuperation(recuperationDto);
					detalleApplication.setRegistered(registeredDto);

					String Idoffers = (String) fila[20]; // AQUI VIENEN LOS ID DE LAS OFERTAS ASOCIADAS
					String Nameoffers = (String) fila[22]; // AQUI VIENEN LOS NOMBRES DE LAS OFERTAS ASOCIADAS
					String Tipooffers = (String) fila[23]; // AQUI VIENEN LOS TIPOS DE OFERTAS ASOCIADAS, INDICATIVO DE
															// SI SON 24X7

					listasOfertas = new ArrayList<>();
					if (Idoffers != null && !Idoffers.isEmpty() && Nameoffers != null && !Nameoffers.isEmpty() 
							&& Tipooffers != null && !Tipooffers.isEmpty()) {

						String[] IdOffers = Idoffers.split(",");
						String[] NameOffers = Nameoffers.split(",");
						String[] TypeOffers = Tipooffers.split(",");
						int i = 0;
						
						for (String ofeId : IdOffers) {
							detalleserviceoffers = new ServiceOffers6Dto();
							String NombreOf = NameOffers[i];
							String TipoOf = TypeOffers[i];
							TipoOf = TipoOf.replace(" ", "");
							ofeId= ofeId.replace(" ", "");
							detalleserviceoffers.setId(ofeId == null ? 0 : Integer.parseInt(ofeId));
							detalleserviceoffers.setName(NombreOf == null ? "" : NombreOf);
							boolean estatustype;
							if (TipoOf.equals("SI")) {
								estatustype = true;
							} else {
								estatustype = false;
							}
							detalleserviceoffers.setOffer_full(estatustype);

							listasOfertas.add(detalleserviceoffers);
							i = i + 1;
						}
					} else {
						
						detalleserviceoffers = new ServiceOffers6Dto();
						detalleserviceoffers.setId(0);
						detalleserviceoffers.setName("");
						detalleserviceoffers.setOffer_full(false);
						listasOfertas.add(detalleserviceoffers);
					}

					/* CANALES */
					String IdChannel = (String) fila[21]; 
					String NameChannel = (String) fila[24]; 

					listasChannel = new ArrayList<>();
					if (IdChannel != null && !IdChannel.isEmpty() && NameChannel != null && !NameChannel.isEmpty()) {

						String[] IdChan = IdChannel.split(",");
						String[] nombreChannel = NameChannel.split(",");
						int i = 0;
						
						for (String id : IdChan) {
							detallechannel = new ChannelDto();
							String NombreChan = nombreChannel[i];
							id= id.replace(" ", "");
							detallechannel.setId(id == null ? 0 : Integer.parseInt(id));
							detallechannel.setName(NombreChan == null ? "" : NombreChan);

							listasChannel.add(detallechannel);
							i = i + 1;
						}
					} else {
						
						detallechannel = new ChannelDto();
						detallechannel.setId(0);
						detallechannel.setName("");
						listasChannel.add(detallechannel);
					}

				//	appTypeDto2.setDsc((String) fila[25]);
				//	appTypeDto2.setValue((String) fila[26]);
					//int apptype  = Integer.parseInt((String) fila[25]);
					appTypeDto2.setId((int) fila[25]);
					appTypeDto2.setName((String) fila[26]);
					detalleApplication.setType(appTypeDto2);
					detalleApplication.setChannels(listasChannel);
					detalleApplication.setServiceoffers(listasOfertas);
					listasApplication.add(detalleApplication);
				}

				detallePrivilege = new PrivilegesAllDto();
				boolean tieneView = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 400);
				boolean tieneUpdate = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 401);
				boolean tieneAdd = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 402);
				boolean tieneDelete = rolesPrivilegesRepository.existsByRolidAndPrivilegeid(idrol, 403);

				detallePrivilege.setView(tieneView);
				detallePrivilege.setUpdate(tieneUpdate);
				detallePrivilege.setAdd(tieneAdd);
				detallePrivilege.setDelete(tieneDelete);

				applicationResponseDto.setNumofrecords(cuantosregistro);
				applicationResponseDto.setSessionvalidthru(fechaComoCadena);
				applicationResponseDto.setRecords(listasApplication);
				applicationResponseDto.setApptype(tipoAppList);
				applicationResponseDto.setAppyesno(tipoAppYesnoList);
			//	tipoAppYesnoList
				applicationResponseDto.setPrivileges(detallePrivilege);

				return ResponseEntity.ok(applicationResponseDto);
			} else {

				query = entityManager.createNativeQuery(QueryTotal);
				cuantosregistro = (long) query.getResultList().size();
				List<Object[]> listacompleta = query.getResultList();
				List<ApplicationDto2> listasApplication = new ArrayList<>();
				FacilityDto2 facility = new FacilityDto2();
				// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
				// estatus
				for (Object[] fila : listacompleta) {
					detalleApplication2 = new ApplicationDto2();
					facility = new FacilityDto2();
					detalleStatus = new StatusDto();
					detalleApplication2.setId((int) fila[0]);
					detalleApplication2.setName((String) fila[1]);
					detalleApplication2.setDsc((String) fila[6]);
					facility.setId((int) fila[4]);
					facility.setName((String) fila[5]);
					detalleApplication2.setFacility(facility);
					detalleStatus.setId((int) fila[2]);
					detalleStatus.setName((String) fila[3]);

					detalleApplication2.setStatus(detalleStatus);

					listasApplication.add(detalleApplication2);
				}

				applicationResponseDto2.setSessionvalidthru(fechaComoCadena);
				applicationResponseDto2.setRecords(listasApplication);

				return ResponseEntity.ok(applicationResponseDto2);

			}

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

		return new ResponseEntity(respuesta, estatus);

	}

	@GetMapping("/applications/{applicationid}")
	public ResponseEntity<?> obtenerUnoApplications(HttpServletRequest request,
			@PathVariable("applicationid") final Integer applicationid) throws ParseException {
		RespuestaDto respuesta = new RespuestaDto("", false);
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		ApplicationResponseDto applicationResponseDto = new ApplicationResponseDto();
		ApplicationResponseDto2 applicationResponseDto2 = new ApplicationResponseDto2();
		RecordCatalogoResponseDto appFormatResponseDto = new RecordCatalogoResponseDto();
		// ParamsDto detalleParams;
		ApplicationDto detalleApplication;
		ApplicationDto2 detalleApplication2;
		StatusDto detalleStatus;
		PrivilegesAllDto detallePrivilege;
		FacilityDto2 detallefacility;
		Long cuantosregistro = (long) 0;
		CampaignFormat2Dto detalleCompaing2;

		List<PrivilegesAllDto> listasPrivelege = 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 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);
				}

				Roles roles = encontreSessionUsuario.get().getRolid();
				idrol = roles.getId();
				int rolisvalid = auditRepository.getCantbyRolAndPrivi(idrol, 400);
				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 {

			String SentenciaBase = "";
			Query query;

			SentenciaBase = "SELECT u.id, " + "     u.name, " + "     u.status, "
					+ "		CASE WHEN u.status = 1 then 'Activo' ELSE 'Inactivo' END AS estatus, " + "		u.dsc, "
					+ "		f.id AS idinsta, " + "		f.name AS nameinstala, " + "		CAST(u.recuperation AS INTEGER), "
					+ "		CAST(u.recuperationperiod AS INTEGER), " + "		pn.descr nombre_periodo_recuperacion, "
					+ "		CAST(u.registered AS INTEGER), " + "		CAST(u.registeredperiod AS INTEGER), " + "		po.descr nombre_registro_periodo, "
					+ "		coalesce(u.drptestedpar,0) as  drptestedpar, " + "		pr.descr nombre_tested, " + "		u.drptestdate, "
					+ "		coalesce(CAST(u.drptesttypepar AS INTEGER),0) as drptesttypepar, " + "		pt.descr tipo_tested, " + "  coalesce(CAST(u.drptestresultpar AS INTEGER),0) as drptestresultpar, "
					+ "		pq.descr tipo_tested_resultado, " + "		u.serviceoffers, " + "		u.channelids, "
					+ "     STRING_AGG(s.name, ', ' ORDER BY service_ids.ord) AS nombres_ofertas_servicio_agrupados, "
					+ "	    STRING_AGG(CASE WHEN s_horario.offer_full = 1 THEN 'SI' ELSE 'NO' END, ', ' ORDER BY service_ids.ord) AS estado_horario_agrupado,"
					+ "     STRING_AGG(c.name, ', ' ORDER BY channel_ids.ord) AS nombres_channels_agrupados, "
					+ "     u.apptypepar, "
					+ "     ptype.descr AS tipo_type, "
					+ "     pn.filter AS filterRecu, "
					+ "     po.filter AS filterReg "
					+ " FROM main.applications u  " + " LEFT JOIN main.facilities f ON u.facilityid = f.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 = 'APPS_YESNO' ) pr ON u.drptestedpar = 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 = 'APPS_TESTTYPE' ) pt ON u.drptesttypepar = CAST(pt.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 = 'APPS_TYPE' "
					+ "    ) ptype ON u.apptypepar = ptype.valor "
					+ " 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 = 'APPS_TESTRESULT' ) pq ON u.drptestresultpar = CAST(pq.valor AS integer) "
					+ " LEFT JOIN (SELECT elemento ->> 'filter' AS filter,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 = 'EVALPROC_PERIOD') pn ON u.recuperationperiod = CAST(pn.valor  AS integer) "
					+ " LEFT JOIN (SELECT elemento ->> 'filter' AS filter,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 = 'EVALPROC_PERIOD') po ON u.registeredperiod = CAST(po.valor  AS integer) "
					+ " LEFT JOIN LATERAL (SELECT service_id, ord "
					+ "                    FROM UNNEST(CAST(string_to_array(u.serviceoffers, ',') AS INTEGER[])) WITH ORDINALITY AS t(service_id, ord)) AS service_ids ON TRUE "
					+ " LEFT JOIN main.serviceoffers s ON s.id = service_ids.service_id  "
					+ " LEFT JOIN main.serviceoffers s_horario ON s_horario.id = service_ids.service_id "
					+ " LEFT JOIN LATERAL (SELECT channel_id,ord  "
					+ "                    FROM UNNEST(CAST(string_to_array(u.channelids, ',') AS INTEGER[])) WITH ORDINALITY AS t(channel_id, ord)) AS channel_ids ON TRUE  "
					+ " LEFT JOIN main.channels c ON c.id = channel_ids.channel_id" + " WHERE u.id = :applicationid ";

			String groupby = " GROUP BY " + "    u.id, " + "    u.name, " + "    u.status, " + "    u.dsc, "
					+ "    f.id, " + "    f.name, " + "    u.recuperation, " + "    u.recuperationperiod, "
					+ "    pn.descr, " + "    u.registered, " + "    u.registeredperiod, " + "    po.descr, "
					+ "    u.drptestedpar, " + "    pr.descr, " + "    u.drptestdate, " + "    u.drptesttypepar, "
					+ "    pt.descr, " + "    u.drptestresultpar, " + "    pq.descr, " + "    u.serviceoffers, "
					+ "    u.channelids, "
					+ "    u.apptypepar, "
					+ "    ptype.descr,"
					+ "    pn.filter,"
					+ "    po.filter "; 

			TestedDto testedDto = new TestedDto();

			TypeDto typeDto = new TypeDto();
			ResultDto resultDto = new ResultDto();
			DrptestDto drptestDto = new DrptestDto();
			RecuperationDto recuperationDto = new RecuperationDto();
			RegisteredDto registeredDto = new RegisteredDto();
			ServiceOffers6Dto serviceOffers6Dto = new ServiceOffers6Dto();
			ChannelDto2 channelDto2 = new ChannelDto2();
			PeriodParResponseDto periodParResponseDto = new PeriodParResponseDto();
			List<ServiceOffers6Dto> serviceoffersDto = new ArrayList();
			ServiceOffers6Dto detalleserviceoffers;
			ChannelDto detallechannel = new ChannelDto();
			List<ChannelDto2> channelsDto = new ArrayList();
			List<ServiceOffers6Dto> listasOfertas = new ArrayList<>();
			List<ChannelDto> listasChannel = new ArrayList<>();
			Query query3;
			Query query4;
			Query query5;
			Query query6;
			Query query7;
			List<Object[]> resultadosTypes;
			List<Object[]> resultadosAppsYesNo;
			List<Object[]> resultadosPeriods;
			List<Object[]> resultadosTesttypes;
			List<Object[]> resultadosTestresults;

			AppTypeDto appTypeDto = new AppTypeDto();
			AppTypeDto appTypeDto2 = new AppTypeDto();
			StatusDto2 detalleTypeDto = new StatusDto2();
			AppyesnoDto appyesnoDto = new AppyesnoDto();
			PeriodsResponseDto periodsResponseDto = new PeriodsResponseDto();
			TesttypesDto testtypesDto = new TesttypesDto();
			TestresultsDto testresultsDto = new TestresultsDto();

			List<AppTypeDto> tipoAppList = new ArrayList();
			List<AppyesnoDto> appsYesNoList = new ArrayList();
			List<PeriodsResponseDto> periodsResponseList = new ArrayList();
			List<TesttypesDto> testtypesList = new ArrayList();
			List<TestresultsDto> testresultsList = new ArrayList();

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

			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");

					appTypeDto.setDsc(dsc);
					appTypeDto.setValue(value);
					tipoAppList.add(appTypeDto);
					appTypeDto = new AppTypeDto();
				}
			}

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

			query4 = entityManager.createNativeQuery(QueryAppsYesNo);

			resultadosAppsYesNo = query4.getResultList();

			jsonStringTipo = "";
			jsonObject = new JSONObject();
			if (resultadosAppsYesNo.size() > 0) {
				for (Object tipos : resultadosAppsYesNo) {
					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");

					appyesnoDto.setDsc(dsc);
					appyesnoDto.setValue(value);
					appsYesNoList.add(appyesnoDto);
					appyesnoDto = new AppyesnoDto();
				}
			}

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

			query5 = entityManager.createNativeQuery(QueryPeriods);

			resultadosPeriods = query5.getResultList();

			jsonStringTipo = "";
			jsonObject = new JSONObject();
			if (resultadosPeriods.size() > 0) {
				for (Object tipos : resultadosPeriods) {
					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");

					periodsResponseDto.setDsc(dsc);
					periodsResponseDto.setValue(value);
					periodsResponseList.add(periodsResponseDto);
					periodsResponseDto = new PeriodsResponseDto();
				}
			}

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

			query6 = entityManager.createNativeQuery(QueryTesttypes);

			resultadosTesttypes = query6.getResultList();

			jsonStringTipo = "";
			jsonObject = new JSONObject();
			if (resultadosTesttypes.size() > 0) {
				for (Object tipos : resultadosTesttypes) {
					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");

					testtypesDto.setDsc(dsc);
					testtypesDto.setValue(value);
					testtypesList.add(testtypesDto);
					testtypesDto = new TesttypesDto();
				}
			}

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

			query7 = entityManager.createNativeQuery(QueryTestresults);

			resultadosTestresults = query7.getResultList();

			jsonStringTipo = "";
			jsonObject = new JSONObject();
			if (resultadosTestresults.size() > 0) {
				for (Object tipos : resultadosTestresults) {
					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");

					testresultsDto.setDsc(dsc);
					testresultsDto.setValue(value);
					testresultsList.add(testresultsDto);
					testresultsDto = new TestresultsDto();
				}
			}

			SentenciaBase =SentenciaBase+groupby;
			query = entityManager.createNativeQuery(SentenciaBase);
			query.setParameter("applicationid", applicationid);
			cuantosregistro = (long) query.getResultList().size();

			List<Object[]> listacompleta = query.getResultList();
			List<EntryApplicationDto2> listasApplication = new ArrayList<>();
			EntryApplicationDto entryApplicationDto = new EntryApplicationDto();
			EntryApplicationDto2 entryApplicationDto2 = new EntryApplicationDto2();
			Date fecha12;
			SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
			Date formattedDateString;
			// Se de be hacer el ciclo para poder llenar el objeto de la descripcion del
			// estatus
			if (cuantosregistro > 0) {
				for (Object[] fila : listacompleta) {
					entryApplicationDto = new EntryApplicationDto();
					detallefacility = new FacilityDto2();
					detalleStatus = new StatusDto();
					testedDto = new TestedDto();
					detalleTypeDto = new StatusDto2();
					typeDto = new TypeDto();
					resultDto = new ResultDto();
					drptestDto = new DrptestDto();
					recuperationDto = new RecuperationDto();
					registeredDto = new RegisteredDto();
					periodParResponseDto = new PeriodParResponseDto();

					entryApplicationDto2.setId((int) fila[0]);
					entryApplicationDto2.setName((String) fila[1]);
					entryApplicationDto2.setDsc((String) fila[4]);

					detalleStatus.setId((int) fila[2]);
					detalleStatus.setName((String) fila[3]);

					detallefacility.setId((int) fila[5]);
					detallefacility.setName((String) fila[6]);

					entryApplicationDto2.setStatus(detalleStatus);
					entryApplicationDto2.setFacility(detallefacility);

					testedDto.setId((java.math.BigDecimal) fila[13]);
					testedDto.setName((String) fila[14]);

					//typeDto.setId(fila[16] == null ? 0 : (Integer)fila[16]);
					typeDto.setId((Integer) fila[16]);
					typeDto.setName((String) fila[17] == null ? "" : (String)fila[17]);

					resultDto.setId(fila[18] == null ? 0 : (Integer)fila[18]);
					resultDto.setName((String) fila[19] == null ? "" : (String) fila[19]);

					
					fecha12=(Date)fila[15];					
					drptestDto.setDate(fecha12== null ? new Date(0) : fecha12);
					
					drptestDto.setResult(resultDto);
					drptestDto.setTested(testedDto);
					drptestDto.setType(typeDto);
					entryApplicationDto2.setDrptest(drptestDto);

					recuperationDto.setQty((Integer)fila[7]/Integer.parseInt((String)fila[27]));
					periodParResponseDto.setId(((Integer) fila[8]).toString());
					periodParResponseDto.setName((String) fila[9]);
					recuperationDto.setPeriod(periodParResponseDto);
					periodParResponseDto = new PeriodParResponseDto();

					registeredDto.setQty((Integer)fila[10]/Integer.parseInt((String)fila[28]));
					periodParResponseDto.setId(((Integer) fila[11]).toString());
					periodParResponseDto.setName((String) fila[12]);
					registeredDto.setPeriod(periodParResponseDto);

					//appTypeDto2.setDsc((String) fila[25]);
					//appTypeDto2.setValue((String) fila[26]);
					
					int apptype  = Integer.parseInt((String) fila[25]);
					detalleTypeDto.setId(apptype);
					detalleTypeDto.setName((String) fila[26]);
					
					//entryApplicationDto2.setApptype(appTypeDto2);
					entryApplicationDto2.setType(detalleTypeDto);
					
					entryApplicationDto2.setRecuperation(recuperationDto);
					entryApplicationDto2.setRegistered(registeredDto);

					String Idoffers = (String) fila[20]; // AQUI VIENEN LOS ID DE LAS OFERTAS ASOCIADAS
					String Nameoffers = (String) fila[22]; // AQUI VIENEN LOS NOMBRES DE LAS OFERTAS ASOCIADAS
					String Tipooffers = (String) fila[23]; // AQUI VIENEN LOS TIPOS DE OFERTAS ASOCIADAS, INDICATIVO DE
															// SI SON 24X7

					listasOfertas = new ArrayList<>();
					if (Idoffers != null && !Idoffers.isEmpty()) {

						String[] IdOffers = Idoffers.split(",");
						String[] NameOffers = Nameoffers.split(",");
						String[] TypeOffers = Tipooffers.split(",");
						int i = 0;

						for (String ofeId : IdOffers) {
							detalleserviceoffers = new ServiceOffers6Dto();
							ofeId = ofeId.replace(" ", "");
							String NombreOf = NameOffers[i];
							String TipoOf = TypeOffers[i];
							TipoOf = TipoOf.replace(" ", "");

							detalleserviceoffers.setId(ofeId == null ? 0 : Integer.parseInt(ofeId));
							detalleserviceoffers.setName(NombreOf == null ? "" : NombreOf);
							boolean estatustype;
							if (TipoOf.equals("SI")) {
								estatustype = true;
							} else {
								estatustype = false;
							}
							detalleserviceoffers.setOffer_full(estatustype);

							listasOfertas.add(detalleserviceoffers);
							i = i + 1;
						}
					} else {

						detalleserviceoffers = new ServiceOffers6Dto();
						detalleserviceoffers.setId(0);
						detalleserviceoffers.setName("");
						detalleserviceoffers.setOffer_full(false);
						listasOfertas.add(detalleserviceoffers);
					}

					/* CANALES */
					String IdChannel = (String) fila[21];
					String NameChannel = (String) fila[24];

					listasChannel = new ArrayList<>();
					if (IdChannel != null && !IdChannel.isEmpty()) {

						String[] IdChan = IdChannel.split(",");
						String[] nombreChannel = NameChannel.split(",");
						int i = 0;

						for (String id : IdChan) {
							detallechannel = new ChannelDto();
							String NombreChan = nombreChannel[i];
							id = id.replace(" ", "");
							detallechannel.setId(id == null ? 0 : Integer.parseInt(id));
							detallechannel.setName(NombreChan == null ? "" : NombreChan);

							listasChannel.add(detallechannel);
							i = i + 1;
						}
					} else {

						detallechannel = new ChannelDto();
						detallechannel.setId(0);
						detallechannel.setName("");
						listasChannel.add(detallechannel);
					}

					entryApplicationDto2.setChannels(listasChannel);
					entryApplicationDto2.setServiceoffers(listasOfertas);
				}

				entryApplicationDto.setEntry(entryApplicationDto2);
				entryApplicationDto.setApptype(tipoAppList);
				entryApplicationDto.setAppyesno(appsYesNoList);
				entryApplicationDto.setPeriods(periodsResponseList);
				entryApplicationDto.setTestresults(testresultsList);
				entryApplicationDto.setTesttypes(testtypesList);

				return ResponseEntity.ok(entryApplicationDto);

			} else {
				
					entryApplicationDto = new EntryApplicationDto();
					detallefacility = new FacilityDto2();
					detalleStatus = new StatusDto();
					testedDto = new TestedDto();
					typeDto = new TypeDto();
					resultDto = new ResultDto();
					drptestDto = new DrptestDto();
					recuperationDto = new RecuperationDto();
					registeredDto = new RegisteredDto();
					periodParResponseDto = new PeriodParResponseDto();

					entryApplicationDto2.setId(0);
					entryApplicationDto2.setName("");
					entryApplicationDto2.setDsc("");

					detalleStatus.setId(0);
					detalleStatus.setName("");

					detallefacility.setId(-1);
					detallefacility.setName("No Definido");

					entryApplicationDto2.setStatus(detalleStatus);
					entryApplicationDto2.setFacility(detallefacility);

					testedDto.setId((new java.math.BigDecimal(0)));
					testedDto.setName("");

					typeDto.setId(0);
					typeDto.setName("");

					resultDto.setId(0);
					resultDto.setName("");

					drptestDto.setDate(new Date(0));
					
					drptestDto.setResult(resultDto);
					drptestDto.setTested(testedDto);
					drptestDto.setType(typeDto);
					entryApplicationDto2.setDrptest(drptestDto);

					recuperationDto.setQty(0);
					periodParResponseDto.setId("0");
					periodParResponseDto.setName("");
					recuperationDto.setPeriod(periodParResponseDto);
					periodParResponseDto = new PeriodParResponseDto();

					registeredDto.setQty(0);
					periodParResponseDto.setId("0");
					periodParResponseDto.setName("");
					registeredDto.setPeriod(periodParResponseDto);

					entryApplicationDto2.setRecuperation(recuperationDto);
					entryApplicationDto2.setRegistered(registeredDto);

					detalleserviceoffers = new ServiceOffers6Dto();
					detalleserviceoffers.setId(0);
					detalleserviceoffers.setName("");
					detalleserviceoffers.setOffer_full(false);
					listasOfertas.add(detalleserviceoffers);
					
					detallechannel = new ChannelDto();
					detallechannel.setId(0);
					detallechannel.setName("");
					listasChannel.add(detallechannel);
					
					entryApplicationDto2.setChannels(listasChannel);
					entryApplicationDto2.setServiceoffers(listasOfertas);
				

				entryApplicationDto.setEntry(entryApplicationDto2);
				entryApplicationDto.setApptype(tipoAppList);
				entryApplicationDto.setAppyesno(appsYesNoList);
				entryApplicationDto.setPeriods(periodsResponseList);
				entryApplicationDto.setTestresults(testresultsList);
				entryApplicationDto.setTesttypes(testtypesList);

				return ResponseEntity.ok(entryApplicationDto);
			}

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

		return new ResponseEntity(respuesta, estatus);

	}
	
	@PostMapping("/applications/{applicationid}")
	public ResponseEntity<?> actualizarApplications(HttpServletRequest request,
			@RequestBody ApplicationActualizarDto applicationActualizarDto,
			@PathVariable("applicationid") final Integer applicationid) throws ParseException {

		RespuestaMsgDto respuesta = new RespuestaMsgDto("");
		HttpStatus estatus = HttpStatus.FORBIDDEN;
		long cuantosregistro = 0;
		long cuantosregistro2 = 0;
		long cuantosregistro3 = 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);
				}
				
				
				 String Salida = usersService.verificarCaracteresValidosConRegex(applicationActualizarDto.getName());
				  
				  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);
				  }
				  
                 String SalidaDsc = usersService.verificarCaracteresValidosConRegex(applicationActualizarDto.getDsc());
				  
				  if (SalidaDsc=="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);
				  }
				  
				  

				Query query2;
				String periodRecu = applicationActualizarDto.getRecperiod().toString();
				String QueryPeriod = "SELECT elemento ->> 'filter' AS filter,elemento ->> 'value' AS valor " 
						+ "	FROM main.params pa, " + "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elemento "
						+ "	WHERE pa.paramname = 'EVALPROC_PERIOD' " + " AND elemento ->> 'value' = :periodRecu ";
			    query2 = entityManager.createNativeQuery(QueryPeriod);
			    query2.setParameter("periodRecu", periodRecu);
				List<Object[]> resultadosPeriod = query2.getResultList();
					cuantosregistro2 = query2.getResultList().size();
					Integer filterRecu = 0;
				if (cuantosregistro2 > 0) {
					for (Object[] fila : resultadosPeriod) {
							filterRecu = Integer.parseInt((String) fila[0]);
					}
				}
				
				Query query3;
				String periodReg = applicationActualizarDto.getRegperiod().toString();
				String QueryPeriodReg = "SELECT elemento ->> 'filter' AS filter,elemento ->> 'value' AS valor " 
						+ "	FROM main.params pa, " + "	jsonb_array_elements(CAST(pa.value AS jsonb)) AS elemento "
						+ "	WHERE pa.paramname = 'EVALPROC_PERIOD' " + " AND elemento ->> 'value' = :periodReg ";
			    query3 = entityManager.createNativeQuery(QueryPeriodReg);
			    query3.setParameter("periodReg", periodReg);
				List<Object[]> resultadosPeriodReg = query3.getResultList();
					cuantosregistro3 = query3.getResultList().size();
					Integer filterReg = 0;
				if (cuantosregistro3 > 0) {
					for (Object[] fila : resultadosPeriodReg) {
							filterReg = Integer.parseInt((String) fila[0]);
					}
				}
				
				
				int rolisvalid = 0;
				
				if (applicationid != 0) {// actualizar las aplicaciones

					try {
						
						
						// verifico si tiene el privilegio
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 401);
						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 (applicationActualizarDto.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);
						}

						// Verifico si existe el id de la aplicación en la base de datos
						Optional<Applications> applications= applicationsRepository.obtenerAplicacion(applicationid);

						Applications applications1 = new Applications();
						Applications applications2 = new Applications();
						// Verifico si encontre la aplicación
						if (!applications.isPresent()) {
							respuesta.setMsg("Registro no encontrado");
							return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
						}

						// Verificar si el nombre de la aplicación existe en la base de datos
						if (applicationsRepository.existsByName(applicationActualizarDto.getName()) && applicationsRepository
								.getByName(applicationActualizarDto.getName()).get().getId().intValue()!=applicationid) {
							respuesta.setMsg("Registro Duplicado");
							return new ResponseEntity(respuesta, HttpStatus.CONFLICT);
						}
						applications1=applications.get();
						Facilities facility=new Facilities();
						facility=facilitiesRepository.getById(applicationActualizarDto.getFacilityid());
						// Construyo los datos de la entidad de Aplicaciones
						applications1.setStatus(applicationActualizarDto.getStatus());
						applications1.setName(applicationActualizarDto.getName());
						applications1.setDsc(applicationActualizarDto.getDsc());
						applications1.setApptypepar(applicationActualizarDto.getType());
						int cuantoschannels = applicationActualizarDto.getChannels().size();
						if (cuantoschannels>0) {
							applications1.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						 } else {
							 applications1.setChannelids(null);
							//applications1.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						 }
						//applications1.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						
						applications1.setDrptestdate(applicationActualizarDto.getDrptest().getDate());
						applications1.setDrptestedpar(applicationActualizarDto.getDrptest().getTested());
						applications1.setDrptesttypepar(applicationActualizarDto.getDrptest().getType());
						applications1.setDrptestresultpar(applicationActualizarDto.getDrptest().getResult());
						applications1.setFacilityid(facility);
						applications1.setRecuperation(applicationActualizarDto.getRecuperation()*filterRecu);
						applications1.setRecuperationperiod(applicationActualizarDto.getRecperiod());
						applications1.setRegistered(applicationActualizarDto.getRegistered()*filterReg);
						applications1.setRegisteredperiod(applicationActualizarDto.getRegperiod());
						//applications1.setServiceoffers((applicationActualizarDto.getServiceoffers().toString().replace("[", "")).replace("]", ""));
						int cuantosprocesos = applicationActualizarDto.getServiceoffers().size();
						if (cuantosprocesos>0) {
							applications1.setServiceoffers((applicationActualizarDto.getServiceoffers().toString().replace("[", "")).replace("]", ""));
						 } else {
							 applications1.setServiceoffers(null);
						 }
						applications1.setModifiedat(fecha2);
						

						applications1 = applicationsRepository.save(applications1);

						if (applications1 != null) {
							
							module = "Aplicaciones";
							Descmodule = "Se actualizó la Aplicación: " + applications1.getName() + " con id: "+applications1.getId();
							auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
							String singo1 = "(";
							String singo2 = ")";
							String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
									.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
							auditDto.setUserref(usryemail);
							auditDto.setModule(module);
							auditDto.setDesc(Descmodule);
							auditDto.setCreatedat(fechaDate2);
							usersService.registrarAuditSesion(auditDto);

							RespuestaValueDto respuestaValueDto = new RespuestaValueDto(applications1.getId());
							URI location = URI.create("/operationlines/" + applications1.getId()); // O la URL correcta para // tu
																					// recurso

							return ResponseEntity.created(location).body(respuestaValueDto);
						}
					} catch (Exception e) {
						respuesta.setMsg("Error interno del servidor "+e.getMessage());
						estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					}

				} else { // incluir línea de operación

					try {
						rolisvalid = auditRepository
								.getCantbyRolAndPrivi(encontreSessionUsuario.get().getRolid().getId(), 402);
						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 (applicationActualizarDto.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 registro está duplicado el nombre en la base de datos
						if (applicationsRepository.existsByName(applicationActualizarDto.getName())) {
							String var = "";
							RespuestaMsgDto respuestaDto = new RespuestaMsgDto(var);
							respuestaDto.setMsg("Registro Duplicado");
							return new ResponseEntity(respuestaDto, HttpStatus.CONFLICT);
						}

						
						Applications applications=new Applications();
						Applications applications1=new Applications();
						// Construyo los datos de la entidad de Aplicaciones
						Facilities facility=new Facilities();
						facility=facilitiesRepository.getById(applicationActualizarDto.getFacilityid());
						// Construyo los datos de la entidad de Aplicaciones
						applications.setStatus(applicationActualizarDto.getStatus());
						applications.setName(applicationActualizarDto.getName());
						applications.setDsc(applicationActualizarDto.getDsc());
						applications.setApptypepar(applicationActualizarDto.getType());
						//applications.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						int cuantoschannels = applicationActualizarDto.getChannels().size();
						if (cuantoschannels>0) {
							applications.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						 } else {
							 applications.setChannelids(null);
							//applications1.setChannelids((applicationActualizarDto.getChannels().toString().replace("[", "")).replace("]", ""));
						 }
						applications.setDrptestdate(applicationActualizarDto.getDrptest().getDate());
						applications.setDrptestedpar(applicationActualizarDto.getDrptest().getTested());
						applications.setDrptesttypepar(applicationActualizarDto.getDrptest().getType());
						applications.setDrptestresultpar(applicationActualizarDto.getDrptest().getResult());
						applications.setFacilityid(facility);
						applications.setRecuperation(applicationActualizarDto.getRecuperation()*filterRecu);
						applications.setRecuperationperiod(applicationActualizarDto.getRecperiod());
						applications.setRegistered(applicationActualizarDto.getRegistered()*filterReg);
						applications.setRegisteredperiod(applicationActualizarDto.getRegperiod());
						 int cuantosprocesos = applicationActualizarDto.getServiceoffers().size();
						 if (cuantosprocesos>0) {
							 applications.setServiceoffers((applicationActualizarDto.getServiceoffers().toString().replace("[", "")).replace("]", ""));
						 } else {
							 applications.setServiceoffers(null);
						 }
						/*if (applicationActualizarDto.getServiceoffers().equals("[]")) {
							
							
						} else {
							applications.setServiceoffers((applicationActualizarDto.getServiceoffers().toString().replace("[", "")).replace("]", ""));
						}*/
						
						applications.setModifiedat(fecha2);
						applications.setCreatedat(fecha2);
						
						applications1 = applicationsRepository.save(applications);

						try {
							if (applications1 != null) {
								
								module = "Aplicaciones";
								Descmodule = "Se insertó la Aplicación: " + applications1.getName() + " con id: "+applications1.getId();
								auditDto.setIpaddr(HttpReqRespUtils.getClientIpAddressIfServletRequestExist());
								String singo1 = "(";
								String singo2 = ")";
								String usryemail = encontreSessionUsuario.get().getUsr().concat(" ").concat(singo1)
										.concat(encontreSessionUsuario.get().getEmail().concat(singo2));
								auditDto.setUserref(usryemail);
								auditDto.setModule(module);
								auditDto.setDesc(Descmodule);
								auditDto.setCreatedat(fechaDate2);
								usersService.registrarAuditSesion(auditDto);

								RespuestaValueDto respuestaValueDto = new RespuestaValueDto(applications1.getId());
								URI location = URI.create("/operationline/" + applications1.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);
					}
					finally {
						if (entityManager != null && entityManager.isOpen()) {
							entityManager.close();
						}
					}
				}
			}

			return new ResponseEntity(respuesta, HttpStatus.OK);

		}
	}

	@DeleteMapping("/applications/{applicationid}")
	public ResponseEntity<?> borrarApplications(HttpServletRequest request,
			@PathVariable("applicationid") final Integer applicationid) 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(),
							403);
					if (rolisvalid == 0) {
						respuesta.setMsg("No tiene los Privilegios");
						estatus = HttpStatus.FORBIDDEN;
						return new ResponseEntity(respuesta, estatus);
					}

					// Verifico si existe el id de la aplicación en la base de datos
					Optional<Applications> applications= applicationsRepository.obtenerAplicacion(applicationid);
					
					Applications applications1 = new Applications();
					Applications applications2 = new Applications();
					// Verifico si encontre la aplicación
					if (!applications.isPresent()) {
						respuesta.setMsg("Registro no encontrado");
						return new ResponseEntity(respuesta, HttpStatus.NOT_FOUND);
					}

					applications1=applications.get();
					try {
						    // Se borra la Aplicación
						applicationsRepository.deleteById(applicationid);
						
							module = "Aplicaciones";
							Descmodule = "Se borró la Aplicación: " + applications1.getName() + " con id: "+applicationid;
							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(applicationid);
							URI location = URI.create("/operationlines/" + applicationid); // 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);
					}
					finally {
						if (entityManager != null && entityManager.isOpen()) {
							entityManager.close();
						}
					}
				} catch (Exception e) {
					respuesta.setMsg("Error interno. Descripción del error " + e.getMessage());
					estatus = HttpStatus.INTERNAL_SERVER_ERROR;
					return new ResponseEntity(respuesta, estatus);
				}
				finally {
					if (entityManager != null && entityManager.isOpen()) {
						entityManager.close();
					}
				}

			}

			return new ResponseEntity(respuesta, HttpStatus.OK);

		}

	}

}
