Commit 91d8e43b by Cesar Giulano Gonzalez Maqueda

merge con joel

parents fc14b503 ea8da093
......@@ -92,24 +92,7 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>7.1.12</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- <version>2.6.0</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.poi</groupId>
......@@ -117,6 +100,12 @@
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
</dependencies>
......
......@@ -42,6 +42,7 @@ public class CurriculumsearchApplication {
guardarJson(convR,"/json/convocatoria.json",ConvocatoriaCargo.class);
guardarJson(depR,"/json/Departamento.json",Departamento.class);
guardarJson(ciudR,"/json/Ciudad.json",Ciudad.class);
guardarJson(tecRepo,"/json/tecnologia.json",Tecnologia.class);
guardarJson(postRepo,"/json/postulante.json",Postulante.class);
String password = new BCryptPasswordEncoder().encode("test");
......
......@@ -114,10 +114,7 @@ public class PostulanteController {
DBFile cv = Helper.createFile(file);
if(cv!=null) cv.setPostulante(postulante);
postulante.setCvFile(cv);
}
postulante.getTecnologias().stream().filter(tec -> tec.getTecnologia().getId() != 0)
.forEach(tec -> tec.setTecnologia(tecRepo.getById(tec.getTecnologia().getId())));
}
for(Estudio estudio: postulante.getEstudios()){
String nombreIns = "";
nombreIns = estudio.getInstitucion().getNombre().toLowerCase();
......
......@@ -26,6 +26,7 @@ import com.roshka.repositorio.ExperienciaRepository;
import com.roshka.repositorio.InstitucionRepository;
import com.roshka.repositorio.PostulanteRepository;
import com.roshka.repositorio.TecnologiaRepository;
import com.roshka.service.PdfGenerator;
import com.roshka.utils.Helper;
......@@ -247,5 +248,26 @@ public class PostulanteRRHHController {
}
}
@GetMapping("/postulantes/{id}/pdf")
public ResponseEntity<Resource> downloadPDF(@PathVariable Long id) {
// Load file from database
PdfGenerator pdf = new PdfGenerator();
try {
Postulante postulante = post.findById(id)
.orElseThrow(() -> new Exception("Postulante no encontrado"));
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/pdf"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + postulante.getNroDocument() + ".pdf" + "\"")
.body(new ByteArrayResource(pdf.generatePdfReport(postulante)));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return ResponseEntity.notFound().build();
}
}
}
\ No newline at end of file
......@@ -96,6 +96,9 @@ public class Postulante {
@Column(name = "disponibilidad", length = 2)
private Disponibilidad disponibilidad;
@Column(name = "tecnologia_otros")
private String tecnologiaOtros;
@JsonManagedReference(value = "postulantetecnologia-postulante")
@OneToMany(mappedBy = "postulante",cascade = CascadeType.ALL)
private List<PostulanteTecnologia> tecnologias;
......
......@@ -31,7 +31,7 @@ public class PostulanteTecnologia {
@Min(value = 1)
@Max(value = 5)
private Long nivel;
@ManyToOne(cascade = {CascadeType.PERSIST},optional = false)
@ManyToOne()
@JoinColumn
private Tecnologia tecnologia;
......
package com.roshka.service;
import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.stream.Collectors;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import org.springframework.stereotype.Component;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.roshka.modelo.Estudio;
import com.roshka.modelo.Experiencia;
import com.roshka.modelo.Postulante;
import com.roshka.utils.Helper;
@Component("pdfGenerator")
public class PdfGenerator {
private static Font COURIER = new Font(Font.FontFamily.COURIER, 20, Font.BOLD);
private static Font COURIER_MEDIUM = new Font(Font.FontFamily.COURIER, 16, Font.BOLD);
private static Font COURIER_SMALL = new Font(Font.FontFamily.COURIER, 14, Font.UNDERLINE);
public byte[] generatePdfReport(Postulante postulante) {
Document document = new Document();
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
document.open();
addDocTitle(document, postulante);
createTable(document,postulante);
document.close();
System.out.println("------------------Your PDF Report is ready!-------------------------");
return byteArrayOutputStream.toByteArray();
} catch ( DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
private void addDocTitle(Document document, Postulante postulante) throws DocumentException {
Paragraph p1 = new Paragraph();
leaveEmptyLine(p1, 1);
p1.add(new Paragraph("Detalles del postulante", COURIER));
p1.setAlignment(Element.ALIGN_CENTER);
document.add(p1);
}
private void agregarEncabezado(Document document, String titulo) throws DocumentException {
Paragraph p1 = new Paragraph();
p1.setAlignment(Element.ALIGN_CENTER);
p1.add(new Paragraph(titulo, COURIER_MEDIUM));
document.add(p1);
}
private void agregarSubEncabezado(Document document, String titulo) throws DocumentException {
Paragraph p1 = new Paragraph();
p1.setAlignment(Element.ALIGN_CENTER);
p1.add(new Paragraph(titulo, COURIER_SMALL));
document.add(p1);
}
private void agregarLabelTexto(Document document, String label, Object texto) throws DocumentException{
if(texto == null) return;
if(texto instanceof Date) texto = Helper.formatDate((Date)texto, "dd-MM-yyyy");
Paragraph paragraph = new Paragraph();
paragraph.add(label + ": ");
paragraph.add(texto.toString());
document.add(paragraph);
}
private void createTable(Document document, Postulante postulante) throws DocumentException {
Paragraph paragraph = new Paragraph();
leaveEmptyLine(paragraph, 3);
//paragraph.add();
agregarEncabezado(document, "Datos personales");
agregarLabelTexto(document, "Nombre", postulante.getNombre() + " " + postulante.getApellido());
agregarLabelTexto(document, "Nro de Documento", postulante.getNroDocument());
agregarLabelTexto(document, "Correo", postulante.getCorreo());
agregarLabelTexto(document, "Direccion", postulante.getDireccion());
agregarLabelTexto(document, "Ciudad", postulante.getCiudad().getNombre());
agregarLabelTexto(document, "Telefono", postulante.getTelefono());
agregarLabelTexto(document, "Edad", Helper.calculateAge(postulante.getFechaNacimiento()) );
agregarLabelTexto(document, "Nivel de Ingles", postulante.getNivelIngles());
agregarLabelTexto(document, "Nacionalidad", postulante.getNacionalidad().getDescripcion());
agregarEncabezado(document, "Experiencias");
for(Experiencia ex : postulante.getExperiencias()){
agregarSubEncabezado(document, ex.getInstitucion());
agregarLabelTexto(document, "Fecha Inicio", ex.getFechaDesde());
agregarLabelTexto(document, "Fecha Fin", ex.getFechaHasta());
agregarLabelTexto(document, "Cargo", ex.getCargo());
agregarLabelTexto(document, "Tipo Experiencia", ex.getTipoExperiencia());
agregarLabelTexto(document, "Descripcion", ex.getDescripcion());
agregarLabelTexto(document, "Nombre Referencia", ex.getNombreReferencia());
agregarLabelTexto(document, "Telefono Referencia", ex.getTelefonoReferencia());
agregarLabelTexto(document, "Motivo Salida", ex.getMotivoSalida());
}
agregarEncabezado(document, "Estudios");
for(Estudio ex : postulante.getEstudios()){
agregarSubEncabezado(document, ex.getInstitucion().getNombre());
agregarLabelTexto(document, "Fecha Inicio", ex.getFechaDesde());
agregarLabelTexto(document, "Fecha Fin", ex.getFechaHasta());
agregarLabelTexto(document, "Tema de Estudio", ex.getTemaDeEstudio());
agregarLabelTexto(document, "Tipo de Estudio", ex.getTipoDeEstudio());
agregarLabelTexto(document, "Descripcion", ex.getEstado().toString());
}
agregarEncabezado(document, "Cargo al cual postula");
agregarList(postulante.getPostulaciones().stream()
.map(cc -> cc.getCargo().getNombre())
.collect(Collectors.toList()), document);
agregarEncabezado(document, "Tecnologias");
agregarList(postulante.getTecnologias().stream()
.map(cc -> cc.getTecnologia().getNombre())
.collect(Collectors.toList()),
document);
agregarEncabezado(document, "Referencias Personales");
agregarList(postulante.getReferencias().stream()
.map(cc -> "Nombre: " + cc.getNombre() + ". Relacion: " + cc.getRelacion() + ". Telefono: " + cc.getTelefono() )
.collect(Collectors.toList()),
document);
}
private void agregarList(java.util.List<String> items, Document document) throws DocumentException{
List list = new List(false);
for(String item : items){
list.add(new ListItem(item));
}
document.add(list);
}
private static void leaveEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
}
......@@ -3,9 +3,9 @@ package com.roshka.utils;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.TimeUnit;
......@@ -46,6 +46,31 @@ public class Helper {
return Math.round(diff/30.d) ;
}
public static LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) {
return new java.sql.Date(dateToConvert.getTime()).toLocalDate();
}
public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
if ((birthDate != null) && (currentDate != null)) {
return Period.between(birthDate, currentDate).getYears();
} else {
return 0;
}
}
public static int calculateAge(Date birthDate) {
LocalDate currentDate = LocalDate.now();
return calculateAge(convertToLocalDateViaSqlDate(birthDate),currentDate);
}
public static String formatDate(LocalDate fecha, String format){
if(fecha == null || format == null) return null;
return fecha.format(DateTimeFormatter.ofPattern(format));
}
public static String formatDate(Date fecha, String format){
return formatDate(convertToLocalDateViaSqlDate(fecha), format);
}
public static DBFile createFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
......
......@@ -40,19 +40,19 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "JAVA"
"id": 1
},
"nivel": 5
},
{
"tecnologia": {
"nombre": "Python"
"id": 2
},
"nivel": 4
},
{
"tecnologia": {
"nombre": "C"
"id": 3
},
"nivel": 5
}
......@@ -99,7 +99,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "Spring"
"id": 4
},
"nivel": 2
}
......@@ -146,7 +146,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "Django"
"id": 5
},
"nivel": 3
}
......@@ -193,7 +193,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "Flutter"
"id": 6
},
"nivel": 2
}
......@@ -240,7 +240,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "Switf"
"id": 3
},
"nivel": 5
}
......@@ -287,7 +287,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "SL"
"id": 2
},
"nivel": 4
}
......@@ -334,7 +334,7 @@
"tecnologias": [
{
"tecnologia": {
"nombre": "Scala"
"id": 5
},
"nivel": 5
}
......
......@@ -18,5 +18,17 @@
{
"id": 5,
"nombre": "spring"
},
{
"id": 6,
"nombre": "php"
},
{
"id": 7,
"nombre": "laravel"
},
{
"id": 8,
"nombre": "sqlserver"
}
]
\ No newline at end of file
......@@ -213,4 +213,9 @@ h4{
}
form[name="postulante"]{
color: #ffffff;
}
.form-check-input:checked {
background-color: #198754;
border-color: #0d6efd;
}
\ No newline at end of file
......@@ -20,40 +20,45 @@ contentType="text/html;charset=UTF-8" language="java" %>
</form>
<a href="/cargo">Agregar Nuevo Cargo</a>
</div>
<div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Cargo</th>
</tr>
</thead>
<tbody>
<c:forEach items="${cargos}" var="cargo" varStatus="sta">
<div class="card text-dark bg-light mt-3">
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="row">${sta.index+1}</th>
<td>${cargo.getNombre()}</td>
<td>
<a href="/convocatorias?cargoId=${cargo.id}"
>Ver Convocatorias</a
>
</td>
<td><a href="/cargo/${cargo.id}">Editar cargo</a></td>
<th scope="col">#</th>
<th scope="col">Cargo</th>
</tr>
</c:forEach>
</tbody>
</table>
</thead>
<tbody>
<c:forEach items="${cargos}" var="cargo" varStatus="sta">
<tr>
<th scope="row">${sta.index+1}</th>
<td>${cargo.getNombre()}</td>
<td>
<a href="/convocatorias?cargoId=${cargo.id}"
>Ver Convocatorias</a
>
</td>
<td><a href="/cargo/${cargo.id}">Editar cargo</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card-footer">
<div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<c:forEach begin="1" end="${pages}" var="nro">
<li class="page-item ${(param.nroPagina == null and nro == 1) or param.nroPagina == nro-1 ? 'active' : ''}"><a class="page-link" href="javascript:buscarPagina(${nro})">${nro}</a></li>
</c:forEach>
</ul>
</nav>
<div class="card-footer">
<div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<c:forEach begin="1" end="${pages}" var="nro">
<li class="page-item ${(param.nroPagina == null and nro == 1) or param.nroPagina == nro-1 ? 'active' : ''}"><a class="page-link" href="javascript:buscarPagina(${nro})">${nro}</a></li>
</c:forEach>
</ul>
</nav>
</div>
</div>
</div>
</div>
......
......@@ -2,6 +2,8 @@
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<layout:extends name="layouts/base.jsp">
<layout:put block="cssDeclaracion" type="APPEND"></layout:put>
<layout:put block="contents" type="REPLACE">
......@@ -25,12 +27,15 @@
<input type="submit" value="Buscar">
</form>
</div>
<div>
<a href="/convocatoria">Agregar Nueva Convocatoria</a>
<c:if test="${SUCCESS_MESSAGE != null}">
<a href="/convocatoria">Agregar Nueva Convocatoria</a>
<c:if test="${SUCCESS_MESSAGE != null}">
<div id="status_message">${SUCCESS_MESSAGE}</div>
</c:if>
<table class="table">
</c:if>
<div class="card text-dark bg-light mt-3">
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
......@@ -47,9 +52,9 @@
<th scope="row">${sta.index+1}</th>
<td>${convocatoria.getCargo().getNombre()}</td>
<td>${convocatoria.getEstado().getDescripcion()}</td>
<td>${convocatoria.getFechaInicio().toString().split(" ")[0]}</td>
<td>${convocatoria.getFechaFin().toString().split(" ")[0]}</td>
<td>Ver Postulantes</td>
<td><fmt:formatDate value="${convocatoria.getFechaInicio()}" pattern="dd-MM-yyyy" /></td>
<td><fmt:formatDate value="${convocatoria.getFechaFin()}" pattern="dd-MM-yyyy" /></td>
<td><a href="/postulantes?convId=${convocatoria.id}">Ver postulantes</a></td>
<td><button onclick=window.location.href="/convocatoria/${convocatoria.id}">Cerrar convocatoria</button></td>
</tr>
</c:forEach>
......@@ -57,8 +62,9 @@
</tbody>
</table>
</table>
</div>
</div>
</div>
</layout:put>
......
......@@ -145,6 +145,9 @@
</c:when>
</c:choose>
<div class="col">
<a class="btn btn-link" target="__blank" href="/postulantes/${postulante.id}/pdf">Obtener pdf</a>
</div>
</div>
</div>
......
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<layout:extends name="layouts/base.jsp">
<layout:put block="contents" type="REPLACE">
<h2 style="text-align: center;">
DETALLE POSTULANTE
</h2>
${postulante.nombre} ${postulante.apellido}
</layout:put>
</layout:extends>
......@@ -217,6 +217,27 @@
</div>
</div>
<!-- Button Otras tecnologias -->
<hr>
<div class="inputs mb-3 col-md-12">
<div class="row w-100 gy-2 mx-auto">
<div class="col-12 px-0">
<h4 class="text-start">Otras Tecnologias </h4>
</div>
<div class="col-6">
<div class="mb-3">
<textarea class="form-control" id="exampleFormControlTextarea1" name="tecnologiaOtros" placeholder="Si tienes alguna tecnologia que no figura en la seccion anterior. Escribelos aqui."></textarea>
</div>
</div>
</div>
</div>
<!-- Button Agregar Experiencia -->
<hr>
......@@ -238,7 +259,7 @@
<div class="inputs mb-3 col-md-12">
<div class="row w-100 gy-2 mx-auto">
<div class="col-12 px-0">
<h4 class="text-start">Referencia Personal <i class="bi bi-plus-square" data-bs-toggle="modal" data-bs-target="#referenciaForm"></i></h4>
<h4 class="text-start">Referencias Personales <i class="bi bi-plus-square" data-bs-toggle="modal" data-bs-target="#referenciaForm"></i></h4>
</div>
<div class="col-12">
<div class="mt-3 gap-2 row row-cols-4" id="referencia">
......@@ -371,7 +392,7 @@
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel" >tecnologia</h5>
<h5 class="modal-title" id="exampleModalLabel" >Tecnologia</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close" style="color:#21130d;">
<span aria-hidden="true">&times;</span>
</button>
......
......@@ -15,41 +15,47 @@
</form>
<a href="/tecnologia">Agregar Nueva Tecnologia</a>
</div>
<div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Tecnologia</th>
</tr>
</thead>
<tbody>
<c:forEach items="${tecnologias}" var="tecnologia" varStatus="sta">
<tr>
<th scope="row">${sta.index+1}</th>
<td>${tecnologia.getNombre()}</td>
<td><a href="/tecnologia/${tecnologia.id}">Editar tecnologia</a></td>
</tr>
</c:forEach>
<div class="card text-dark bg-light mt-3">
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Tecnologia</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<c:forEach items="${tecnologias}" var="tecnologia" varStatus="sta">
<tr>
<th scope="row">${sta.index+1}</th>
<td>${tecnologia.getNombre()}</td>
<td><a href="/tecnologia/${tecnologia.id}"><i class="bi bi-pencil-fill"></i></a></td>
</tr>
</c:forEach>
</tbody>
</tbody>
</table>
</div>
<div class="card-footer">
<div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<c:forEach begin="1" end="${pages}" var="nro">
<li class="page-item ${(param.nroPagina == null and nro == 1) or param.nroPagina == nro-1 ? 'active' : ''}"><a class="page-link" href="javascript:buscarPagina(${nro})">${nro}</a></li>
</c:forEach>
</ul>
</nav>
</div>
</div>
<div class="card-footer">
<div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<c:forEach begin="1" end="${pages}" var="nro">
<li class="page-item ${(param.nroPagina == null and nro == 1) or param.nroPagina == nro-1 ? 'active' : ''}"><a class="page-link" href="javascript:buscarPagina(${nro})">${nro}</a></li>
</c:forEach>
</ul>
</nav>
</div>
</div>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment