From dc1fcd80fcb80f6c227dc59c0d1cb1cca2643482 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 17 Nov 2021 10:12:11 -0300 Subject: [PATCH] adjuntar archivo cv en form postulante --- curriculumsearch/src/main/java/com/roshka/configuration/WebSecurityConfig.java | 38 +++++++++++++++++++------------------- curriculumsearch/src/main/java/com/roshka/controller/PostulanteController.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------- curriculumsearch/src/main/java/com/roshka/controller/PostulanteRRHHController.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ curriculumsearch/src/main/java/com/roshka/modelo/DBFile.java | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ curriculumsearch/src/main/java/com/roshka/modelo/Postulante.java | 29 ++++++++++++++--------------- curriculumsearch/src/main/java/com/roshka/repositorio/DBFileRepository.java | 15 +++++++++++++++ curriculumsearch/src/main/resources/application.properties | 10 ++++++++++ curriculumsearch/src/main/resources/static/main.js | 20 ++++++++++++++++++-- curriculumsearch/src/main/webapp/jsp/detallepostulante.jsp | 15 +++++++++++---- curriculumsearch/src/main/webapp/jsp/index.jsp | 26 ++++++-------------------- curriculumsearch/src/main/webapp/jsp/layouts/base.jsp | 6 ++++-- curriculumsearch/src/main/webapp/jsp/postulante-form.jsp | 5 +++++ curriculumsearch/src/main/webapp/jsp/postulantes.jsp | 2 +- 13 files changed, 399 insertions(+), 161 deletions(-) create mode 100644 curriculumsearch/src/main/java/com/roshka/controller/PostulanteRRHHController.java create mode 100644 curriculumsearch/src/main/java/com/roshka/modelo/DBFile.java create mode 100644 curriculumsearch/src/main/java/com/roshka/repositorio/DBFileRepository.java diff --git a/curriculumsearch/src/main/java/com/roshka/configuration/WebSecurityConfig.java b/curriculumsearch/src/main/java/com/roshka/configuration/WebSecurityConfig.java index 40d1a40..bc82739 100644 --- a/curriculumsearch/src/main/java/com/roshka/configuration/WebSecurityConfig.java +++ b/curriculumsearch/src/main/java/com/roshka/configuration/WebSecurityConfig.java @@ -49,28 +49,28 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { http // .csrf().disable() .authorizeRequests() - .antMatchers("/").authenticated() - .antMatchers("/home").authenticated() - .antMatchers("/cargo*").authenticated() - .antMatchers("/convocatoria*").authenticated() - .antMatchers("/tecnologia*").authenticated() - .antMatchers("/postulantes").authenticated() - .antMatchers("/edit-user-data").authenticated() + .mvcMatchers("/").authenticated() + .mvcMatchers("/home").authenticated() + .mvcMatchers("/cargo*").authenticated() + .mvcMatchers("/convocatoria*").authenticated() + .mvcMatchers("/tecnologia*").authenticated() + .mvcMatchers("/postulantes","/postulantes/**").authenticated() + .mvcMatchers("/edit-user-data").authenticated() .anyRequest().permitAll() .and() - .formLogin() - .loginPage("/login") - .usernameParameter("email") - .defaultSuccessUrl("/home") - .permitAll() + .formLogin() + .loginPage("/login") + .usernameParameter("email") + .defaultSuccessUrl("/home") + .permitAll() .and() - .logout() - .logoutUrl("/logout") - .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) - .clearAuthentication(true) - .invalidateHttpSession(true) - .deleteCookies("JSESSIONID", "remember-me") - .logoutSuccessUrl("/login"); + .logout() + .logoutUrl("/logout") + .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) + .clearAuthentication(true) + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID", "remember-me") + .logoutSuccessUrl("/login"); } } \ No newline at end of file diff --git a/curriculumsearch/src/main/java/com/roshka/controller/PostulanteController.java b/curriculumsearch/src/main/java/com/roshka/controller/PostulanteController.java index 318c157..3a5e792 100644 --- a/curriculumsearch/src/main/java/com/roshka/controller/PostulanteController.java +++ b/curriculumsearch/src/main/java/com/roshka/controller/PostulanteController.java @@ -1,20 +1,16 @@ package com.roshka.controller; -import java.util.ArrayList; +import java.io.IOException; import java.util.Date; -import java.util.List; -import java.util.Locale; import javax.validation.ConstraintViolationException; -import com.roshka.DTO.PostulanteListaDTO; import com.roshka.modelo.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.roshka.modelo.Disponibilidad; -import com.roshka.modelo.EstadoPostulante; import com.roshka.modelo.EstadoCivil; import com.roshka.modelo.Nacionalidad; import com.roshka.modelo.Postulante; @@ -27,27 +23,20 @@ import com.roshka.repositorio.ExperienciaRepository; import com.roshka.repositorio.InstitucionRepository; import com.roshka.repositorio.PostulanteRepository; import com.roshka.repositorio.TecnologiaRepository; -import com.roshka.utils.Helper; import org.hibernate.jpa.TypedParameterValue; -import org.hibernate.type.StringType; import org.hibernate.type.IntegerType; import org.hibernate.type.LongType; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; +import org.springframework.util.StringUtils; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.*; - - +import org.springframework.web.multipart.MultipartFile; @Controller public class PostulanteController { @@ -59,7 +48,7 @@ public class PostulanteController { CiudadRepository ciuRepo; EstudioRepository estudioRepository; PostulanteTecnologiaRepository postulanteTecnologiaRepository; - ConvocatoriaRepository cargoRepo; + ConvocatoriaRepository convoRepo; CargoRepository carRepo; @Autowired @@ -68,7 +57,7 @@ public class PostulanteController { InstitucionRepository institucionRepository, DepartamentoRepository depRepo, CiudadRepository ciuRepo, EstudioRepository estudioRepository, PostulanteTecnologiaRepository postulanteTecnologiaRepository, - ConvocatoriaRepository cargoRepo, CargoRepository carRepo) { + ConvocatoriaRepository convoRepo, CargoRepository carRepo) { this.post = post; this.tecRepo = tecRepo; this.expRepo = expRepo; @@ -77,52 +66,12 @@ public class PostulanteController { this.ciuRepo = ciuRepo; this.estudioRepository = estudioRepository; this.postulanteTecnologiaRepository = postulanteTecnologiaRepository; - this.cargoRepo =cargoRepo; + this.convoRepo =convoRepo; this.carRepo=carRepo; } - @RequestMapping("/postulantes") - public String postulantes(Model model, - @RequestParam(required = false)Long tecId, - @RequestParam(required = false)String nombre, - @RequestParam(required = false)EstadoPostulante estado, - @RequestParam(required = false)Disponibilidad dispo, - @RequestParam(required = false)Long lvlEng, - @RequestParam(required = false)Long lvlTec, - @RequestParam(required = false)Long instId, - @RequestParam(required = false)Long expInMonths, - @RequestParam(required = false)Long cargoId, - @RequestParam(required = false)Long convId, - @RequestParam(defaultValue = "0")Integer nroPagina - ) { - final Integer CANTIDAD_POR_PAGINA = 5; - Pageable page = PageRequest.of(nroPagina,CANTIDAD_POR_PAGINA,Sort.by("id")); - model.addAttribute("tecnologias", tecRepo.findAll()); - model.addAttribute("disponibilidades", Disponibilidad.values()); - model.addAttribute("institucionesEducativas", institucionRepository.findAll()); - model.addAttribute("estadoP", EstadoPostulante.values()); - model.addAttribute("convocatoriaC", cargoRepo.findAll()); - Page postulantesPag = post.postulantesMultiFiltro(nombre == null || nombre.trim().isEmpty() ? new TypedParameterValue(StringType.INSTANCE,null) : new TypedParameterValue(StringType.INSTANCE,"%"+nombre+"%"),dispo, lvlEng, lvlTec, tecId, instId,cargoId,page,estado,convId); - List postulantes = postulantesPag.getContent(); - List postulantesDTO = new ArrayList<>(); - - for (Postulante postulante : postulantes) { - long expTotal = 0; - //Sumamos el tiempo de experiencia total en meses de cada postulante - //expTotal = postulante.getExperiencias().stream().mapToLong(e -> Helper.getMonthsDifference(e.getFechaDesde(), e.getFechaHasta())).sum(); - for (Experiencia experiencia : postulante.getExperiencias()) { - expTotal += Helper.getMonthsDifference(experiencia.getFechaDesde(), experiencia.getFechaHasta()); - } - if(expInMonths != null && expInMonths > expTotal) continue; - postulantesDTO.add(new PostulanteListaDTO(postulante.getId(), postulante.getNombre(), postulante.getApellido(), postulante.getDisponibilidad(), postulante.getNivelIngles(), expTotal, postulante.getTecnologias(),postulante.getEstadoPostulante(),postulante.getPostulaciones())); - } - - model.addAttribute("pages", postulantesPag.getTotalPages()); - model.addAttribute("postulantes", postulantesDTO); - return "postulantes"; - } - @RequestMapping("/postulante") + @RequestMapping(value = "/work-with-us",method = RequestMethod.GET) public String getFormPostulante(Model model){ model.addAttribute("tecnologias", tecRepo.findAll()); model.addAttribute("disponibilidades", Disponibilidad.values()); @@ -131,7 +80,7 @@ public class PostulanteController { model.addAttribute("estadosCiviles", EstadoCivil.values()); model.addAttribute("nacionalidades", Nacionalidad.values()); model.addAttribute("tiposExperencia", TipoExperiencia.values()); - model.addAttribute("CargosDisponibles", cargoRepo.f1ndByCargoAndEstado(new TypedParameterValue(LongType.INSTANCE, null), new Date(), new TypedParameterValue(IntegerType.INSTANCE, 1))); + model.addAttribute("CargosDisponibles", convoRepo.f1ndByCargoAndEstado(new TypedParameterValue(LongType.INSTANCE, null), new Date(), new TypedParameterValue(IntegerType.INSTANCE, 1))); try { model.addAttribute("ciudades", new ObjectMapper().writeValueAsString(ciuRepo.findAll())); } catch (JsonProcessingException er) { @@ -142,42 +91,76 @@ public class PostulanteController { return "postulante-form"; } - - @PostMapping(value = "/postulante",consumes = "application/json") - public String guardarPostulante(@RequestBody Postulante postulante){ + + /* @PostMapping("/uploadCVPostulante") + public String uploadFile(@RequestParam("file") MultipartFile file) { + dbFileRepository.save(storeFile(file)); + DBFile dbFile = dbFileRepository.save(storeFile(file)); + return "{\"id\": "+dbFile.getId()+"}"; + } */ + + private DBFile createFile(MultipartFile file) { + // Normalize file name + String fileName = StringUtils.cleanPath(file.getOriginalFilename()); + + try { + // Check if the file's name contains invalid characters + if(fileName.contains("..")) { + throw new Exception("Sorry! Filename contains invalid path sequence " + fileName); + } + if(file.getSize()==0) throw new Exception("Sorry! File cant be void");; + + DBFile dbFile = new DBFile(fileName, file.getContentType(), file.getBytes()); + + return dbFile; + } catch (IOException ex) { + ex.printStackTrace(); + return null; + } + catch(Exception ex){ + ex.printStackTrace(); + return null; + } + } + + @PostMapping(value = "/work-with-us",consumes = "multipart/form-data") + public String guardarPostulante(@RequestPart(name = "file",required = false) MultipartFile file,@RequestPart("postulante") Postulante postulante){ //Codigo encargado de modificar postulacion si se envia mismo CI - Postulante postulantex = post.findByNroDocument(postulante.getnroDocument()); + Postulante postulantex = post.findByNroDocument(postulante.getNroDocument()); if(postulantex != null){ estudioRepository.findByPostulante(postulantex).forEach(x -> estudioRepository.delete(x)); expRepo.findByPostulante(postulantex).forEach(x -> expRepo.delete(x)); postulanteTecnologiaRepository.findByPostulante(postulantex).forEach(x -> postulanteTecnologiaRepository.delete(x)); postulante.setId(postulantex.getId()); } + if(file!=null){ + DBFile cv = 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 (int i = 0; i < postulante.getPostulaciones().size(); i++) { - postulante.getPostulaciones().set(i, cargoRepo.getById(postulante.getPostulaciones().get(i).getId())); - } - */ - for(Estudio estudio: postulante.getEstudios()){ - String nombreIns = ""; - nombreIns = estudio.getInstitucion().getNombre().toLowerCase(); - Institucion institucion = institucionRepository.findByNombre(nombreIns); - if(institucion==null){ - institucionRepository.save(estudio.getInstitucion()); - }else{ - estudio.setInstitucion(institucion); - } - } - post.save(postulante); - return "redirect:/postulacion-correcta"; + for(Estudio estudio: postulante.getEstudios()){ + String nombreIns = ""; + nombreIns = estudio.getInstitucion().getNombre().toLowerCase(); + Institucion institucion = institucionRepository.findByNombre(nombreIns); + if(institucion==null){ + institucionRepository.save(estudio.getInstitucion()); + }else{ + estudio.setInstitucion(institucion); } + } + post.save(postulante); + return "redirect:/work-with-us/postulacion-correcta"; + } - @GetMapping("/postulacion-correcta") + + + @GetMapping("/work-with-us/postulacion-correcta") public String successPostulation(Model model){ model.addAttribute("mensaje1", "Tu informacion se ha recibido correctamente!"); model.addAttribute("mensaje2", " espera por que nos pongamos en contacto!"); @@ -202,23 +185,6 @@ public class PostulanteController { - @GetMapping({"/postulante/{postulanteId}"}) - public String getPostulanteDetalle(Model model, @PathVariable("postulanteId") Long postulanteId) { - Postulante p = post.findById(postulanteId).orElse(null); - model.addAttribute("postulante",p); - model.addAttribute("estadoP", EstadoPostulante.values()); - return "detallepostulante"; - - } - @PostMapping({"/postulante/{postulanteId}"}) - public String setPostulanteEstado(@ModelAttribute Postulante postulante, BindingResult result, @PathVariable("postulanteId") Long postulanteId) { - //post.setPostulanteEstadoAndComentario(postulante.getEstadoPostulante(),postulante.getComentarioRRHH(), postulante.getId()); - Postulante postulanteVd = post.getById(postulanteId); - postulanteVd.setEstadoPostulante(postulante.getEstadoPostulante()); - postulanteVd.setComentarioRRHH(postulante.getComentarioRRHH()); - post.setPostulanteEstadoAndComentario(postulante.getEstadoPostulante(), postulante.getComentarioRRHH(), postulanteId); - //post.save(postulanteVd); - return "redirect:/postulante/"+postulanteId; - } + } \ No newline at end of file diff --git a/curriculumsearch/src/main/java/com/roshka/controller/PostulanteRRHHController.java b/curriculumsearch/src/main/java/com/roshka/controller/PostulanteRRHHController.java new file mode 100644 index 0000000..3d4cf94 --- /dev/null +++ b/curriculumsearch/src/main/java/com/roshka/controller/PostulanteRRHHController.java @@ -0,0 +1,162 @@ +package com.roshka.controller; + + +import java.util.ArrayList; + +import java.util.List; + + + + +import com.roshka.DTO.PostulanteListaDTO; +import com.roshka.modelo.*; +import com.roshka.modelo.Disponibilidad; +import com.roshka.modelo.EstadoPostulante; +import com.roshka.modelo.Postulante; +import com.roshka.repositorio.*; +import com.roshka.repositorio.CiudadRepository; +import com.roshka.repositorio.ConvocatoriaRepository; +import com.roshka.repositorio.DepartamentoRepository; +import com.roshka.repositorio.ExperienciaRepository; +import com.roshka.repositorio.InstitucionRepository; +import com.roshka.repositorio.PostulanteRepository; +import com.roshka.repositorio.TecnologiaRepository; +import com.roshka.utils.Helper; + + +import org.hibernate.jpa.TypedParameterValue; +import org.hibernate.type.StringType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + + + +@Controller +public class PostulanteRRHHController { + PostulanteRepository post; + TecnologiaRepository tecRepo; + ExperienciaRepository expRepo; + InstitucionRepository institucionRepository; + DepartamentoRepository depRepo; + CiudadRepository ciuRepo; + EstudioRepository estudioRepository; + PostulanteTecnologiaRepository postulanteTecnologiaRepository; + ConvocatoriaRepository cargoRepo; + CargoRepository carRepo; + DBFileRepository fileRepo; + + @Autowired + public PostulanteRRHHController( + PostulanteRepository post, TecnologiaRepository tecRepo, ExperienciaRepository expRepo, + InstitucionRepository institucionRepository, DepartamentoRepository depRepo, + CiudadRepository ciuRepo, EstudioRepository estudioRepository, + PostulanteTecnologiaRepository postulanteTecnologiaRepository, + ConvocatoriaRepository cargoRepo, CargoRepository carRepo, DBFileRepository fileRepo) { + this.post = post; + this.tecRepo = tecRepo; + this.expRepo = expRepo; + this.institucionRepository = institucionRepository; + this.depRepo = depRepo; + this.ciuRepo = ciuRepo; + this.estudioRepository = estudioRepository; + this.postulanteTecnologiaRepository = postulanteTecnologiaRepository; + this.cargoRepo =cargoRepo; + this.carRepo=carRepo; + this.fileRepo = fileRepo; + } + + @RequestMapping("/postulantes") + public String postulantes(Model model, + @RequestParam(required = false)Long tecId, + @RequestParam(required = false)String nombre, + @RequestParam(required = false)EstadoPostulante estado, + @RequestParam(required = false)Disponibilidad dispo, + @RequestParam(required = false)Long lvlEng, + @RequestParam(required = false)Long lvlTec, + @RequestParam(required = false)Long instId, + @RequestParam(required = false)Long expInMonths, + @RequestParam(required = false)Long cargoId, + @RequestParam(required = false)Long convId, + @RequestParam(defaultValue = "0")Integer nroPagina + ) { + final Integer CANTIDAD_POR_PAGINA = 5; + Pageable page = PageRequest.of(nroPagina,CANTIDAD_POR_PAGINA,Sort.by("id")); + model.addAttribute("tecnologias", tecRepo.findAll()); + model.addAttribute("disponibilidades", Disponibilidad.values()); + model.addAttribute("institucionesEducativas", institucionRepository.findAll()); + model.addAttribute("estadoP", EstadoPostulante.values()); + model.addAttribute("convocatoriaC", cargoRepo.findAll()); + Page postulantesPag = post.postulantesMultiFiltro(nombre == null || nombre.trim().isEmpty() ? new TypedParameterValue(StringType.INSTANCE,null) : new TypedParameterValue(StringType.INSTANCE,"%"+nombre+"%"),dispo, lvlEng, lvlTec, tecId, instId,cargoId,page,estado,convId); + List postulantes = postulantesPag.getContent(); + List postulantesDTO = new ArrayList<>(); + + for (Postulante postulante : postulantes) { + long expTotal = 0; + //Sumamos el tiempo de experiencia total en meses de cada postulante + //expTotal = postulante.getExperiencias().stream().mapToLong(e -> Helper.getMonthsDifference(e.getFechaDesde(), e.getFechaHasta())).sum(); + for (Experiencia experiencia : postulante.getExperiencias()) { + expTotal += Helper.getMonthsDifference(experiencia.getFechaDesde(), experiencia.getFechaHasta()); + } + if(expInMonths != null && expInMonths > expTotal) continue; + postulantesDTO.add(new PostulanteListaDTO(postulante.getId(), postulante.getNombre(), postulante.getApellido(), postulante.getDisponibilidad(), postulante.getNivelIngles(), expTotal, postulante.getTecnologias(),postulante.getEstadoPostulante(),postulante.getPostulaciones())); + } + + model.addAttribute("pages", postulantesPag.getTotalPages()); + model.addAttribute("postulantes", postulantesDTO); + return "postulantes"; + } + + + + @GetMapping({"/postulantes/{postulanteId}"}) + public String getPostulanteDetalle(Model model, @PathVariable("postulanteId") Long postulanteId) { + Postulante p = post.findById(postulanteId).orElse(null); + model.addAttribute("postulante",p); + model.addAttribute("cvId", fileRepo.getIdByPostulante(p)); + model.addAttribute("estadoP", EstadoPostulante.values()); + return "detallepostulante"; + + } + @PostMapping({"/postulantes/{postulanteId}"}) + public String setPostulanteEstado(@ModelAttribute Postulante postulante, BindingResult result, @PathVariable("postulanteId") Long postulanteId) { + //post.setPostulanteEstadoAndComentario(postulante.getEstadoPostulante(),postulante.getComentarioRRHH(), postulante.getId()); + Postulante postulanteVd = post.getById(postulanteId); + postulanteVd.setEstadoPostulante(postulante.getEstadoPostulante()); + postulanteVd.setComentarioRRHH(postulante.getComentarioRRHH()); + post.setPostulanteEstadoAndComentario(postulante.getEstadoPostulante(), postulante.getComentarioRRHH(), postulanteId); + //post.save(postulanteVd); + return "redirect:/postulante/"+postulanteId; + } + + @GetMapping("/postulantes/cvFile/{fileId}") + public ResponseEntity downloadFile(@PathVariable String fileId) { + // Load file from database + DBFile dbFile; + try { + dbFile = fileRepo.findById(fileId) + .orElseThrow(() -> new Exception("File not found with id " + fileId)); + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType(dbFile.getFileType())) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + dbFile.getFileName() + "\"") + .body(new ByteArrayResource(dbFile.getData())); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return ResponseEntity.notFound().build(); + } + + } +} + \ No newline at end of file diff --git a/curriculumsearch/src/main/java/com/roshka/modelo/DBFile.java b/curriculumsearch/src/main/java/com/roshka/modelo/DBFile.java new file mode 100644 index 0000000..2eb7919 --- /dev/null +++ b/curriculumsearch/src/main/java/com/roshka/modelo/DBFile.java @@ -0,0 +1,70 @@ +package com.roshka.modelo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +@Entity +@Table(name = "files") +public class DBFile { + @Id + @GeneratedValue(generator = "uuid") + @GenericGenerator(name = "uuid", strategy = "uuid2") + private String id; + + private String fileName; + + private String fileType; + + @Lob + private byte[] data; + + @OneToOne(mappedBy = "cvFile") + private Postulante postulante; + + public DBFile() { + + } + + public DBFile(String fileName, String fileType, byte[] data) { + this.fileName = fileName; + this.fileType = fileType; + this.data = data; + } + + public byte[] getData() { + return data; + } + public String getFileName() { + return fileName; + } + public String getFileType() { + return fileType; + } + public void setData(byte[] data) { + this.data = data; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + public void setFileType(String fileType) { + this.fileType = fileType; + } + public void setId(String id) { + this.id = id; + } + public String getId() { + return id; + } + public Postulante getPostulante() { + return postulante; + } + public void setPostulante(Postulante postulante) { + this.postulante = postulante; + } +} diff --git a/curriculumsearch/src/main/java/com/roshka/modelo/Postulante.java b/curriculumsearch/src/main/java/com/roshka/modelo/Postulante.java index 92b61cd..8f8569a 100644 --- a/curriculumsearch/src/main/java/com/roshka/modelo/Postulante.java +++ b/curriculumsearch/src/main/java/com/roshka/modelo/Postulante.java @@ -66,8 +66,6 @@ public class Postulante { @Max(value = 5) private Long nivelIngles; - @Column(name = "curriculum") - private String curriculum; @Column(name="estado_civil") @NotNull @@ -115,6 +113,11 @@ public class Postulante { ) private List postulaciones; + @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY) + @JoinColumn(name = "cvfile_id",referencedColumnName = "id") + @JsonIgnore + private DBFile cvFile; + public long getId() { return id; @@ -140,9 +143,6 @@ public class Postulante { this.apellido = apellido; } - public String getnroDocument() { - return nroDocument; - } public void setnroDocument(String nroDocument) { this.nroDocument = nroDocument; @@ -192,16 +192,6 @@ public class Postulante { this.nivelIngles = nivelIngles; } - public String getCurriculum() { - return curriculum; - } - - public void setCurriculum(String curriculum) { - this.curriculum = curriculum; - } - - - public Disponibilidad getDisponibilidad() { return disponibilidad; } @@ -291,4 +281,13 @@ public class Postulante { public void setComentarioRRHH(String comentarioRRHH){ this.comentarioRRHH=comentarioRRHH; } + public DBFile getCvFile() { + return cvFile; + } + public String getNroDocument() { + return nroDocument; + } + public void setCvFile(DBFile cvFile) { + this.cvFile = cvFile; + } } diff --git a/curriculumsearch/src/main/java/com/roshka/repositorio/DBFileRepository.java b/curriculumsearch/src/main/java/com/roshka/repositorio/DBFileRepository.java new file mode 100644 index 0000000..8ba8b40 --- /dev/null +++ b/curriculumsearch/src/main/java/com/roshka/repositorio/DBFileRepository.java @@ -0,0 +1,15 @@ +package com.roshka.repositorio; + +import com.roshka.modelo.DBFile; +import com.roshka.modelo.Postulante; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface DBFileRepository extends JpaRepository { + + @Query("select db.id from DBFile db where db.postulante = ?1") + public String getIdByPostulante(Postulante postulante); +} \ No newline at end of file diff --git a/curriculumsearch/src/main/resources/application.properties b/curriculumsearch/src/main/resources/application.properties index e1e0dad..e718a77 100644 --- a/curriculumsearch/src/main/resources/application.properties +++ b/curriculumsearch/src/main/resources/application.properties @@ -26,3 +26,13 @@ spring.mail.properties.mail.smtp.starttls.enable=true jsp-inheritance-prefix=/jsp/layouts/ jsp-inheritance-suffix=.jsp + +## MULTIPART (MultipartProperties) +# Enable multipart uploads +spring.servlet.multipart.enabled=true +# Threshold after which files are written to disk. +spring.servlet.multipart.file-size-threshold=2KB +# Max file size. +spring.servlet.multipart.max-file-size=10MB +# Max Request Size +spring.servlet.multipart.max-request-size=10MB \ No newline at end of file diff --git a/curriculumsearch/src/main/resources/static/main.js b/curriculumsearch/src/main/resources/static/main.js index 81c57ef..722651f 100644 --- a/curriculumsearch/src/main/resources/static/main.js +++ b/curriculumsearch/src/main/resources/static/main.js @@ -211,6 +211,12 @@ function serializeJSON (form) { return JSON.stringify(pairs, null, 2); } +function obtenerCV(){ + let input = document.querySelector('#cvFile') + return input.files[0]; + +} + async function postData(url = '', data = {}) { var token = document.querySelector("meta[name='_csrf']").content; var headerxs = document.querySelector("meta[name='_csrf_header']").content; @@ -221,7 +227,7 @@ async function postData(url = '', data = {}) { cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'same-origin', // include, *same-origin, omit headers: { - 'Content-Type': 'application/json', + //'Content-Type': undefined//'application/json', // 'Content-Type': 'application/x-www-form-urlencoded', }, redirect: 'follow', // manual, *follow, error @@ -232,6 +238,16 @@ async function postData(url = '', data = {}) { const response = await fetch(url, senddata); return response; // parses JSON response into native JavaScript objects } + +function formatearJsonWithFile(json, file){ + formData = new FormData(); + + formData.append("file", file); + formData.append('postulante', new Blob([json], { + type: "application/json" + })); + return formData +} formValidator() form = document.querySelector("form"); form.addEventListener("submit",(evt)=>{ @@ -241,7 +257,7 @@ form.addEventListener("submit",(evt)=>{ // } // form.classList.add('was-validated') if(!noValidateFlag){ - postData('postulante', serializeJSON(form)) + postData('work-with-us', formatearJsonWithFile(serializeJSON(form),obtenerCV())) .then(response => { if(response.status==200 || response.status==302){ location.replace(response.url); diff --git a/curriculumsearch/src/main/webapp/jsp/detallepostulante.jsp b/curriculumsearch/src/main/webapp/jsp/detallepostulante.jsp index a5a625a..0791ec2 100644 --- a/curriculumsearch/src/main/webapp/jsp/detallepostulante.jsp +++ b/curriculumsearch/src/main/webapp/jsp/detallepostulante.jsp @@ -130,11 +130,18 @@
- -
-
- Descargar CV +
+ + + + + + + +
diff --git a/curriculumsearch/src/main/webapp/jsp/index.jsp b/curriculumsearch/src/main/webapp/jsp/index.jsp index 1ec98fe..a44f6bc 100644 --- a/curriculumsearch/src/main/webapp/jsp/index.jsp +++ b/curriculumsearch/src/main/webapp/jsp/index.jsp @@ -1,24 +1,10 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> - - - - - - - - RRHH - +<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%> + + + + - - - - -
- -
- - - - \ No newline at end of file +
\ No newline at end of file diff --git a/curriculumsearch/src/main/webapp/jsp/layouts/base.jsp b/curriculumsearch/src/main/webapp/jsp/layouts/base.jsp index deaba95..d90023f 100644 --- a/curriculumsearch/src/main/webapp/jsp/layouts/base.jsp +++ b/curriculumsearch/src/main/webapp/jsp/layouts/base.jsp @@ -9,7 +9,9 @@ - + + + RRHH @@ -54,7 +56,7 @@ Postulantes diff --git a/curriculumsearch/src/main/webapp/jsp/postulante-form.jsp b/curriculumsearch/src/main/webapp/jsp/postulante-form.jsp index 1bf5127..6de666b 100644 --- a/curriculumsearch/src/main/webapp/jsp/postulante-form.jsp +++ b/curriculumsearch/src/main/webapp/jsp/postulante-form.jsp @@ -145,6 +145,11 @@ +
+ + +
+
 Cargo al que postulas

diff --git a/curriculumsearch/src/main/webapp/jsp/postulantes.jsp b/curriculumsearch/src/main/webapp/jsp/postulantes.jsp index 4806afa..7ae93a8 100644 --- a/curriculumsearch/src/main/webapp/jsp/postulantes.jsp +++ b/curriculumsearch/src/main/webapp/jsp/postulantes.jsp @@ -99,7 +99,7 @@ ${postulante.estado.getEstado()} - Ver + Ver -- libgit2 0.26.0