Browse Source

Endpoints VV

master
akirwana 3 months ago
parent
commit
d6e9b5d281
9 changed files with 429 additions and 7 deletions
  1. +2
    -0
      build.gradle
  2. +3
    -7
      src/main/java/jumapacelaya/gob/mx/infowall/servicio/InfowallServicio.java
  3. +76
    -0
      src/main/java/jumapacelaya/gob/mx/vv/controlador/VvControlador.java
  4. +37
    -0
      src/main/java/jumapacelaya/gob/mx/vv/dto/citaDTO.java
  5. +10
    -0
      src/main/java/jumapacelaya/gob/mx/vv/dto/horarioDisponibleDTO.java
  6. +32
    -0
      src/main/java/jumapacelaya/gob/mx/vv/dto/tramiteDTO.java
  7. +5
    -0
      src/main/java/jumapacelaya/gob/mx/vv/repositorio/VvRepositorio.java
  8. +253
    -0
      src/main/java/jumapacelaya/gob/mx/vv/servicio/VvServicio.java
  9. +11
    -0
      src/main/resources/application.yml

+ 2
- 0
build.gradle View File

@ -36,6 +36,8 @@ dependencies {
annotationProcessor("io.micronaut.data:micronaut-data-processor") annotationProcessor("io.micronaut.data:micronaut-data-processor")
implementation("io.micronaut.data:micronaut-data-jpa") implementation("io.micronaut.data:micronaut-data-jpa")
implementation("io.micronaut.data:micronaut-data-hibernate-jpa") implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
implementation("io.micronaut.email:micronaut-email:2.2.1")
implementation("io.micronaut.email:micronaut-email-javamail:2.2.1")
} }


+ 3
- 7
src/main/java/jumapacelaya/gob/mx/infowall/servicio/InfowallServicio.java View File

@ -9,13 +9,10 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.sql.DataSource; import javax.sql.DataSource;
import io.micronaut.data.annotation.Query;
import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.repository.CrudRepository;
import io.micronaut.transaction.annotation.Transactional;
import jakarta.inject.Singleton; import jakarta.inject.Singleton;
import io.micronaut.transaction.annotation.Transactional;
import jumapacelaya.gob.mx.infowall.repositorio.InfowallRepositorio;
import jumapacelaya.gob.mx.infowall.dto.cobFacVtaDiaDTO; import jumapacelaya.gob.mx.infowall.dto.cobFacVtaDiaDTO;
import jumapacelaya.gob.mx.infowall.dto.compCvDTO; import jumapacelaya.gob.mx.infowall.dto.compCvDTO;
import jumapacelaya.gob.mx.infowall.dto.otReconexDiaDTO; import jumapacelaya.gob.mx.infowall.dto.otReconexDiaDTO;
@ -23,7 +20,6 @@ import jumapacelaya.gob.mx.infowall.dto.otSuspensionDTO;
import jumapacelaya.gob.mx.infowall.dto.totalCobrosHoyDTO; import jumapacelaya.gob.mx.infowall.dto.totalCobrosHoyDTO;
import jumapacelaya.gob.mx.infowall.dto.totalPagosHoyDTO; import jumapacelaya.gob.mx.infowall.dto.totalPagosHoyDTO;
import jumapacelaya.gob.mx.infowall.dto.totalPagosMesDTO; import jumapacelaya.gob.mx.infowall.dto.totalPagosMesDTO;
import jumapacelaya.gob.mx.infowall.repositorio.InfowallRepositorio;
@Singleton @Singleton
public class InfowallServicio { public class InfowallServicio {


+ 76
- 0
src/main/java/jumapacelaya/gob/mx/vv/controlador/VvControlador.java View File

@ -0,0 +1,76 @@
package jumapacelaya.gob.mx.vv.controlador;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Post;
import jakarta.inject.Inject;
import jumapacelaya.gob.mx.vv.dto.citaDTO;
import jumapacelaya.gob.mx.vv.dto.horarioDisponibleDTO;
import jumapacelaya.gob.mx.vv.dto.tramiteDTO;
import jumapacelaya.gob.mx.vv.servicio.VvServicio;
@Controller("/vv")
public class VvControlador {
@Inject
VvServicio servicio;
@Get("/citas/getdiasdisponibles/{punto}/{dias}")
public HttpResponse<?> obtenerDiasDisponibles(@PathVariable Integer punto, @PathVariable Integer dias) {
try {
return HttpResponse.ok(servicio.obtenerDiasDisponibles(punto, dias));
} catch (Exception e) {
throw new RuntimeException("Error al obtener días disponibles", e);
}
}
@Get("/citas/gethorariosdisponibles/{punto}/{dia}")
public List<horarioDisponibleDTO> obtenerHorariosDisponibles(Integer punto, String dia) {
return servicio.obtenerHorariosDisponibles(punto, dia);
}
@Post(uri = "/citas/guardar", consumes = MediaType.APPLICATION_JSON)
public HttpResponse<?> guardarCita(@Body Map<String, Object> body) {
try {
int puntoId = Integer.parseInt(body.get("ppuntoid").toString());
int tipoTramite = Integer.parseInt(body.get("ptipotramite").toString());
String dia = body.get("pdia").toString(); // formato: dd/mm/yyyy
String horario = body.get("phorario").toString(); // formato: hh:mm
String telefono = body.get("ptelefono").toString();
String email = body.get("pemail").toString();
String resultado = servicio.guardarCita(puntoId, tipoTramite, dia, horario, telefono, email);
return HttpResponse.ok(Map.of(
"status", "200",
"message", "Cita generada",
"data", resultado
));
} catch (Exception e) {
return HttpResponse.serverError(Map.of(
"status", "500",
"message", "Error al generar cita",
"error", e.getMessage()
));
}
}
@Post("/citas/tramites/guardar")
public HttpResponse<?> guardarTramite(@Body tramiteDTO tramite) {
try {
String mensaje = servicio.guardarTramite(tramite);
return HttpResponse.ok().body(mensaje);
} catch (Exception e) {
return HttpResponse.serverError("Error al guardar trámite: " + e.getMessage());
}
}
}

+ 37
- 0
src/main/java/jumapacelaya/gob/mx/vv/dto/citaDTO.java View File

@ -0,0 +1,37 @@
package jumapacelaya.gob.mx.vv.dto;
import jakarta.validation.constraints.NotBlank;
public class citaDTO {
@NotBlank
private Integer ppuntoid;
@NotBlank
private String ptipotramite;
@NotBlank
private String pdia;
@NotBlank
private String phorario;
@NotBlank
private String ptelefono;
@NotBlank
private String pemail;
// Getters y setters
public Integer getPpuntoid() { return ppuntoid; }
public void setPpuntoid(Integer ppuntoid) { this.ppuntoid = ppuntoid; }
public String getPtipotramite() { return ptipotramite; }
public void setPtipotramite(String ptipotramite) { this.ptipotramite = ptipotramite; }
public String getPdia() { return pdia; }
public void setPdia(String pdia) { this.pdia = pdia; }
public String getPhorario() { return phorario; }
public void setPhorario(String phorario) { this.phorario = phorario; }
public String getPtelefono() { return ptelefono; }
public void setPtelefono(String ptelefono) { this.ptelefono = ptelefono; }
public String getPemail() { return pemail; }
public void setPemail(String pemail) { this.pemail = pemail; }
}

+ 10
- 0
src/main/java/jumapacelaya/gob/mx/vv/dto/horarioDisponibleDTO.java View File

@ -0,0 +1,10 @@
package jumapacelaya.gob.mx.vv.dto;
public class horarioDisponibleDTO {
private String horariosdisponibles;
public String getHorariosdisponibles() { return horariosdisponibles; }
public void setHorariosdisponibles(String horariosdisponibles) {
this.horariosdisponibles = horariosdisponibles;
}
}

+ 32
- 0
src/main/java/jumapacelaya/gob/mx/vv/dto/tramiteDTO.java View File

@ -0,0 +1,32 @@
package jumapacelaya.gob.mx.vv.dto;
import io.micronaut.core.annotation.Introspected;
@Introspected
public class tramiteDTO {
private int tipoTramite;
private int usuarioId;
private String telefono;
private Long predioId;
public int getTipoTramite() { return tipoTramite; }
public void setTipoTramite(int tipoTramite) {
this.tipoTramite = tipoTramite;
}
public int getUsuarioId() { return usuarioId; }
public void setUsuarioId(int usuarioId) {
this.usuarioId = usuarioId;
}
public String getTelefono() { return telefono; }
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public Long getPredioId() { return predioId; }
public void setPredioId(Long predioId) {
this.predioId = predioId;
}
}

+ 5
- 0
src/main/java/jumapacelaya/gob/mx/vv/repositorio/VvRepositorio.java View File

@ -0,0 +1,5 @@
package jumapacelaya.gob.mx.vv.repositorio;
public class VvRepositorio {
}

+ 253
- 0
src/main/java/jumapacelaya/gob/mx/vv/servicio/VvServicio.java View File

@ -0,0 +1,253 @@
package jumapacelaya.gob.mx.vv.servicio;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.sql.DataSource;
import jakarta.inject.Singleton;
import io.micronaut.transaction.annotation.ReadOnly;
import io.micronaut.transaction.annotation.Transactional;
import jumapacelaya.gob.mx.vv.dto.citaDTO;
import jumapacelaya.gob.mx.vv.dto.horarioDisponibleDTO;
import jumapacelaya.gob.mx.vv.dto.tramiteDTO;
import jumapacelaya.gob.mx.vv.repositorio.VvRepositorio;
@Singleton
public class VvServicio {
private final DataSource dataSource;
public VvServicio(DataSource dataSource) {
this.dataSource = dataSource;
}
@Transactional
public List<Map<String, Object>> obtenerDiasDisponibles(Integer punto, Integer dias) {
List<Map<String, Object>> resultado = new ArrayList<>();
String query =
"with dias as ( " +
" select sysdate as hoy, level as diasfaltantes, trunc(sysdate + level) as fechacita " +
" from dual connect by level <= ? " +
") " +
"select count(c.citaid) as citas, " +
" to_char(d.fechacita, 'dd/mm/yyyy', 'NLS_DATE_LANGUAGE = SPANISH') as fechacita, " +
" to_char(d.fechacita, 'fmDY', 'NLS_DATE_LANGUAGE = SPANISH') || ' ' || " +
" to_char(d.fechacita, 'dd/mm/yyyy', 'NLS_DATE_LANGUAGE = SPANISH') as sfechacita " +
"from dias d " +
"left join appmovcom.citas c on (trunc(c.fechora) = d.fechacita and c.estado in ('S', 'P') and c.puntoid = ?) " +
"where d.fechacita not in (select fecha from diasfestivos) " +
" and to_char(d.fechacita, 'fmDY', 'NLS_DATE_LANGUAGE = SPANISH') not in ('SÁB', 'DOM') " +
"group by d.fechacita " +
"order by d.fechacita";
try (Connection connection = dataSource.getConnection();
PreparedStatement stmt = connection.prepareStatement(query)) {
stmt.setInt(1, dias);
stmt.setInt(2, punto);
try (ResultSet rs = stmt.executeQuery()) {
ResultSetMetaData meta = rs.getMetaData();
int cols = meta.getColumnCount();
while (rs.next()) {
Map<String, Object> fila = new HashMap<>();
for (int i = 1; i <= cols; i++) {
fila.put(meta.getColumnLabel(i).toLowerCase(), rs.getObject(i));
}
resultado.add(fila);
}
}
} catch (SQLException e) {
throw new RuntimeException("Error al obtener días disponibles", e);
}
return resultado;
}
@ReadOnly
public List<horarioDisponibleDTO> obtenerHorariosDisponibles(Integer punto, String dia) {
List<horarioDisponibleDTO> lista = new ArrayList<>();
String horarios = "09:30,10:00,10:30,11:00,11:30,12:00,12:30,13:00,13:30,14:00,14:30";
String query = """
with horarios as (
select to_char(fechora, 'hh24:mi', 'NLS_DATE_LANGUAGE = SPANISH') hora
from appmovcom.citas
where trunc(fechora) = trunc(to_date(?, 'ddmmyyyy'))
and puntoid = ?
)
select column_value horariosdisponibles
from table(cobranza.splitvlt(?, ','))
where column_value not in (select * from horarios)
order by column_value
""";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(query)) {
ps.setString(1, dia);
ps.setInt(2, punto);
ps.setString(3, horarios);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
horarioDisponibleDTO dto = new horarioDisponibleDTO();
dto.setHorariosdisponibles(rs.getString("horariosdisponibles"));
lista.add(dto);
}
} catch (SQLException e) {
throw new RuntimeException("Error al obtener horarios disponibles", e);
}
return lista;
}
@Transactional
public String guardarCita(int puntoId, int tipoTramite, String dia, String horario, String telefono, String email) {
String fechaCita = dia + " " + horario;
String citaIdExistente = obtenerCitaExistente(puntoId, dia, horario);
if (citaIdExistente != null) {
return "Ya existe una cita en ese horario. Revisa disponibilidad nuevamente.";
}
String folioGenerado = generarFolio();
String insertQuery = "INSERT INTO appmovcom.citas (citaid, puntoid, fechora, tipotramid, email, telefono) " +
"VALUES (?, ?, TO_DATE(?, 'dd/mm/yyyy hh24:mi'), ?, ?, ?)";
try (Connection connection = dataSource.getConnection();
PreparedStatement ps = connection.prepareStatement(insertQuery)) {
ps.setString(1, folioGenerado);
ps.setInt(2, puntoId);
ps.setString(3, fechaCita);
ps.setInt(4, tipoTramite);
ps.setString(5, email);
ps.setString(6, telefono);
ps.executeUpdate();
} catch (Exception e) {
throw new RuntimeException("Error al guardar cita: " + e.getMessage(), e);
}
return "Se generó la cita con folio " + folioGenerado + " para la oficina " + nombrePunto(puntoId) +
" el día " + dia + " a las " + horario + " hrs.";
}
private String obtenerCitaExistente(int puntoId, String dia, String horario) {
String query = "SELECT citaid FROM appmovcom.citas WHERE puntoid = ? AND trunc(fechora) = TO_DATE(?, 'dd/mm/yyyy') AND TO_CHAR(fechora, 'hh24:mi') = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(query)) {
ps.setInt(1, puntoId);
ps.setString(2, dia);
ps.setString(3, horario);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return rs.getString("citaid");
}
}
} catch (Exception e) {
throw new RuntimeException("Error al verificar cita existente: " + e.getMessage(), e);
}
return null;
}
private String generarFolio() {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder sb = new StringBuilder();
Random random = new Random();
while (sb.length() < 7) {
sb.append(chars.charAt(random.nextInt(chars.length())));
}
return sb.toString();
}
private String nombrePunto(int puntoId) {
return switch (puntoId) {
case 1 -> "División del Norte";
case 2 -> "Parque Morelos";
case 3 -> "Cañitos";
case 5 -> "Parque Celaya";
default -> "Desconocida";
};
}
@Transactional
public String guardarTramite(tramiteDTO tramite) {
String tramiteExistente = obtenerTramite(tramite.getUsuarioId(), tramite.getTipoTramite());
if (tramiteExistente != null) {
return "Ya hay un trámite registrado para este usuario y tipo. Revisa tu email para dar seguimiento.";
}
String folio = generarFolio();
String insertQuery = """
INSERT INTO appmovcom.tramites (
tramiteid, tipotramid, usuarioid, email, telefono, estatus, predioid
) VALUES (
?, ?, ?, (SELECT email FROM appmovcom.usuarios WHERE usuarioid = ?), ?, 'NUEVO', ?
)
""";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(insertQuery)) {
ps.setString(1, folio);
ps.setInt(2, tramite.getTipoTramite());
ps.setInt(3, tramite.getUsuarioId());
ps.setInt(4, tramite.getUsuarioId());
ps.setString(5, tramite.getTelefono());
ps.setLong(6, tramite.getPredioId());
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Error al guardar trámite: " + e.getMessage(), e);
}
// Envío de correo (si lo deseas activar más adelante)
// enviaCorreo(folio, "G");
return "Se generó el Trámite con folio " + folio + ". Se te enviará un correo con la información necesaria.";
}
private String obtenerTramite(int usuarioId, int tipoTramite) {
String query = "SELECT tramiteid FROM appmovcom.tramites WHERE usuarioid = ? AND tipotramid = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(query)) {
ps.setInt(1, usuarioId);
ps.setInt(2, tipoTramite);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return rs.getString("tramiteid");
}
}
} catch (SQLException e) {
throw new RuntimeException("Error al verificar trámite existente: " + e.getMessage(), e);
}
return null;
}
}

+ 11
- 0
src/main/resources/application.yml View File

@ -1,6 +1,17 @@
micronaut: micronaut:
application: application:
name: API_ePay_Micronaut name: API_ePay_Micronaut
email:
from: noreply
smtp:
auth: true
starttls.enable: true
host: smtp.mailtrap.io
port: 2525
username: ${SMTP_USERNAME}
password: ${SMTP_PASSWORD}
ssl: false
tls: true
datasources: datasources:
default: default:


Loading…
Cancel
Save