excel_upload
parent
90c7688af1
commit
1bfa6a6ade
@ -0,0 +1,2 @@
|
||||
MYSQL_DATABASE=data_admision
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
||||
@ -0,0 +1,18 @@
|
||||
# Usa Maven y JDK para compilar y correr código
|
||||
FROM maven:3.9.2-eclipse-temurin-17
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copia solo pom.xml primero para cache
|
||||
COPY pom.xml .
|
||||
|
||||
# Pre-descarga dependencias
|
||||
RUN mvn dependency:go-offline
|
||||
|
||||
# Copia el código fuente
|
||||
COPY src ./src
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Ejecuta Spring Boot directamente (hot reload)
|
||||
CMD ["mvn", "spring-boot:run"]
|
||||
@ -1,23 +1,34 @@
|
||||
services:
|
||||
|
||||
postgres:
|
||||
image: postgres:15
|
||||
container_name: postgres_admision
|
||||
mysql:
|
||||
image: mysql:8
|
||||
container_name: mysql_admision_dev
|
||||
environment:
|
||||
POSTGRES_DB: data_admision
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: 1234
|
||||
MYSQL_DATABASE: admision_db
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||
ports:
|
||||
- "5432:5432"
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
backend:
|
||||
build: .
|
||||
container_name: spring_admision
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev # Dockerfile que corre mvn spring-boot:run
|
||||
container_name: spring_admision_dev
|
||||
depends_on:
|
||||
- postgres
|
||||
- mysql
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/app # Monta tu código para ver cambios sin rebuild
|
||||
- ~/.m2:/root/.m2 # Cache de Maven para no bajar deps siempre
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/data_admision
|
||||
SPRING_DATASOURCE_USERNAME: postgres
|
||||
SPRING_DATASOURCE_PASSWORD: 1234
|
||||
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/admision_db?useSSL=false&serverTimezone=UTC
|
||||
SPRING_DATASOURCE_USERNAME: root
|
||||
SPRING_DATASOURCE_PASSWORD: ""
|
||||
command: mvn spring-boot:run # Ejecuta Spring directamente
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
@ -0,0 +1,27 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8
|
||||
container_name: mysql_admision
|
||||
environment:
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: ${MYSQL_ALLOW_EMPTY_PASSWORD}
|
||||
ports:
|
||||
- "3306:3306"
|
||||
restart: unless-stopped
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: spring_admision
|
||||
depends_on:
|
||||
- mysql
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=UTC
|
||||
SPRING_DATASOURCE_USERNAME: root
|
||||
SPRING_DATASOURCE_PASSWORD: ""
|
||||
restart: unless-stopped
|
||||
@ -0,0 +1,32 @@
|
||||
package com.service.ingresantes.controller;
|
||||
|
||||
import com.service.ingresantes.service.ExcelService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/excel")
|
||||
public class ExcelController {
|
||||
|
||||
private final ExcelService excelService;
|
||||
|
||||
public ExcelController(ExcelService excelService) {
|
||||
this.excelService = excelService;
|
||||
}
|
||||
|
||||
@PostMapping("/upload")
|
||||
public ResponseEntity<String> uploadExcel(@RequestParam("file") MultipartFile file) {
|
||||
try {
|
||||
excelService.importarExcel(file);
|
||||
return ResponseEntity.ok("Archivo subido y procesado correctamente!");
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.badRequest().body("Error al procesar el archivo: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/ping")
|
||||
public String ping() {
|
||||
return "API funcionando123456!";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.service.ingresantes.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "asignaturas")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Asignatura {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private Integer codigo;
|
||||
|
||||
private String nombre;
|
||||
|
||||
private Integer cantidadPreguntas;
|
||||
|
||||
private Double ponderacion;
|
||||
|
||||
// Nuevo campo: puntaje por pregunta
|
||||
private Double puntajePorPregunta;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "area_id")
|
||||
private Area area;
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.service.ingresantes.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "carpeta_examen")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class CarpetaExamen {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String tipo; // claves, ids, respuestas
|
||||
|
||||
private String ruta;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "proceso_id")
|
||||
private Proceso proceso;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "area_id")
|
||||
private Area area;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.service.ingresantes.repository;
|
||||
|
||||
import com.service.ingresantes.entity.Asignatura;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface AsignaturaRepository extends JpaRepository<Asignatura, Long> {
|
||||
// Aquí puedes agregar consultas personalizadas si lo necesitas
|
||||
// Ejemplo: List<Asignatura> findByNombre(String nombre);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.service.ingresantes.repository;
|
||||
|
||||
import com.service.ingresantes.entity.CarpetaExamen;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
|
||||
public interface CarpetaExamenRepository extends JpaRepository<CarpetaExamen, Long> {
|
||||
|
||||
List<CarpetaExamen> findByProcesoIdAndAreaId(Long procesoId, Long areaId);
|
||||
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
package com.service.ingresantes.repository;
|
||||
|
||||
import com.service.ingresantes.entity.Inscripcion;
|
||||
import com.service.ingresantes.entity.Postulante;
|
||||
import com.service.ingresantes.entity.Proceso;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
|
||||
public interface InscripcionRepository extends JpaRepository<Inscripcion, Long> {
|
||||
|
||||
List<Inscripcion> findByProcesoId(Long procesoId);
|
||||
// Método para verificar si existe una inscripción de un postulante a un proceso
|
||||
boolean existsByPostulanteAndProceso(Postulante postulante, Proceso proceso);
|
||||
|
||||
}
|
||||
@ -0,0 +1,190 @@
|
||||
package com.service.ingresantes.service;
|
||||
|
||||
import com.service.ingresantes.entity.*;
|
||||
import com.service.ingresantes.repository.*;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class ExcelService {
|
||||
|
||||
private final PostulanteRepository postulanteRepo;
|
||||
private final ProcesoRepository procesoRepo;
|
||||
private final ProgramaRepository programaRepo;
|
||||
private final ModalidadRepository modalidadRepo;
|
||||
private final InscripcionRepository inscripcionRepo;
|
||||
|
||||
public ExcelService(PostulanteRepository postulanteRepo,
|
||||
ProcesoRepository procesoRepo,
|
||||
ProgramaRepository programaRepo,
|
||||
ModalidadRepository modalidadRepo,
|
||||
InscripcionRepository inscripcionRepo) {
|
||||
this.postulanteRepo = postulanteRepo;
|
||||
this.procesoRepo = procesoRepo;
|
||||
this.programaRepo = programaRepo;
|
||||
this.modalidadRepo = modalidadRepo;
|
||||
this.inscripcionRepo = inscripcionRepo;
|
||||
}
|
||||
|
||||
// --- Método auxiliar para leer cualquier celda como String ---
|
||||
private String getCellStringValue(Cell cell) {
|
||||
if (cell == null) return "";
|
||||
switch (cell.getCellType()) {
|
||||
case STRING:
|
||||
return cell.getStringCellValue().trim();
|
||||
case NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
return cell.getLocalDateTimeCellValue().toLocalDate().toString();
|
||||
} else {
|
||||
return String.valueOf((long) cell.getNumericCellValue());
|
||||
}
|
||||
case BOOLEAN:
|
||||
return String.valueOf(cell.getBooleanCellValue());
|
||||
case FORMULA:
|
||||
return cell.getCellFormula();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void importarExcel(MultipartFile file) throws Exception {
|
||||
InputStream is = file.getInputStream();
|
||||
Workbook workbook = WorkbookFactory.create(is);
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
DateTimeFormatter fechaHoraFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
for (Row row : sheet) {
|
||||
if (row.getRowNum() == 0) continue; // Saltar encabezado
|
||||
|
||||
String dni = getCellStringValue(row.getCell(0));
|
||||
if (dni.isEmpty()) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": DNI vacío, se omite");
|
||||
continue;
|
||||
}
|
||||
|
||||
Postulante postulante = postulanteRepo.findById(dni).orElseGet(() -> {
|
||||
try {
|
||||
Postulante p = new Postulante();
|
||||
p.setDni(dni);
|
||||
p.setPaterno(getCellStringValue(row.getCell(1)));
|
||||
p.setMaterno(getCellStringValue(row.getCell(2)));
|
||||
p.setNombres(getCellStringValue(row.getCell(3)));
|
||||
p.setSexo(getCellStringValue(row.getCell(4)));
|
||||
|
||||
String fechaNacStr = getCellStringValue(row.getCell(5));
|
||||
if (!fechaNacStr.isEmpty()) {
|
||||
try { p.setFechaNacimiento(LocalDate.parse(fechaNacStr)); } catch (Exception e) {}
|
||||
}
|
||||
|
||||
String edadStr = getCellStringValue(row.getCell(6));
|
||||
if (!edadStr.isEmpty()) {
|
||||
try { p.setEdad(Integer.parseInt(edadStr)); } catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
p.setUbigeoResidencia(getCellStringValue(row.getCell(7)));
|
||||
p.setDepartamentoResidencia(getCellStringValue(row.getCell(8)));
|
||||
p.setProvinciaResidencia(getCellStringValue(row.getCell(9)));
|
||||
p.setDistritoResidencia(getCellStringValue(row.getCell(10)));
|
||||
|
||||
String egresoStr = getCellStringValue(row.getCell(11));
|
||||
if (!egresoStr.isEmpty()) {
|
||||
try { p.setEgreso(Integer.parseInt(egresoStr)); } catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
p.setCodModular(getCellStringValue(row.getCell(12)));
|
||||
p.setUbigeoColegio(getCellStringValue(row.getCell(13)));
|
||||
p.setDepartamentoColegio(getCellStringValue(row.getCell(14)));
|
||||
p.setProvinciaColegio(getCellStringValue(row.getCell(15)));
|
||||
p.setDistritoColegio(getCellStringValue(row.getCell(16)));
|
||||
|
||||
System.out.println("Fila " + row.getRowNum() + ": Postulante creado -> " + dni);
|
||||
return postulanteRepo.save(p);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Error guardando postulante " + dni + " -> " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (postulante == null) continue;
|
||||
|
||||
String fechaInsStr = getCellStringValue(row.getCell(17));
|
||||
LocalDateTime fechaInscripcion;
|
||||
if (!fechaInsStr.isEmpty()) {
|
||||
try {
|
||||
fechaInscripcion = LocalDateTime.parse(fechaInsStr, fechaHoraFormatter);
|
||||
} catch (Exception e) {
|
||||
try { fechaInscripcion = LocalDate.parse(fechaInsStr).atStartOfDay(); }
|
||||
catch (Exception ex) { fechaInscripcion = LocalDateTime.now(); }
|
||||
}
|
||||
} else {
|
||||
fechaInscripcion = LocalDateTime.now();
|
||||
}
|
||||
|
||||
String procesoStr = getCellStringValue(row.getCell(18));
|
||||
if (procesoStr.isEmpty()) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Proceso vacío, se omite");
|
||||
continue;
|
||||
}
|
||||
Long procesoId;
|
||||
try { procesoId = Long.parseLong(procesoStr); }
|
||||
catch (NumberFormatException e) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Proceso inválido -> " + procesoStr);
|
||||
continue;
|
||||
}
|
||||
Optional<Proceso> procesoOpt = procesoRepo.findById(procesoId);
|
||||
if (procesoOpt.isEmpty()) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Proceso no encontrado -> " + procesoId);
|
||||
continue;
|
||||
}
|
||||
Proceso proceso = procesoOpt.get();
|
||||
|
||||
String programaStr = getCellStringValue(row.getCell(19));
|
||||
Optional<ProgramaEstudio> programaOpt = programaRepo.findById(Long.parseLong(programaStr));
|
||||
if (programaOpt.isEmpty()) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Programa no encontrado -> " + programaStr);
|
||||
continue;
|
||||
}
|
||||
ProgramaEstudio programa = programaOpt.get();
|
||||
|
||||
String modalidadStr = getCellStringValue(row.getCell(20));
|
||||
Optional<Modalidad> modalidadOpt = modalidadRepo.findById(Long.parseLong(modalidadStr));
|
||||
if (modalidadOpt.isEmpty()) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Modalidad no encontrada -> " + modalidadStr);
|
||||
continue;
|
||||
}
|
||||
Modalidad modalidad = modalidadOpt.get();
|
||||
|
||||
boolean existe = inscripcionRepo.existsByPostulanteAndProceso(postulante, proceso);
|
||||
if (existe) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": La inscripción ya existe para el postulante " + dni);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Inscripcion inscripcion = new Inscripcion();
|
||||
inscripcion.setFechaInscripcion(fechaInscripcion);
|
||||
inscripcion.setPostulante(postulante);
|
||||
inscripcion.setProceso(proceso);
|
||||
inscripcion.setPrograma(programa);
|
||||
inscripcion.setModalidad(modalidad);
|
||||
inscripcionRepo.save(inscripcion);
|
||||
System.out.println("Fila " + row.getRowNum() + ": Inscripción guardada -> " + dni);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fila " + row.getRowNum() + ": Error guardando inscripción -> " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
workbook.close();
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue