diff --git a/MyINPulse-back/build.gradle b/MyINPulse-back/build.gradle index e9d19ad..47b0dc2 100644 --- a/MyINPulse-back/build.gradle +++ b/MyINPulse-back/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+' implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+' implementation 'org.postgresql:postgresql' + implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.3' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'com.h2database:h2' diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/AdminApi.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/AdminApi.java index b5f3866..d3f432a 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/AdminApi.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/AdminApi.java @@ -81,7 +81,7 @@ public class AdminApi { */ @PostMapping("/admin/appoitements/report/{appointmentId}") public void createAppointmentReport( - @PathVariable String appointmentId, + @PathVariable long appointmentId, @RequestBody Report report, @AuthenticationPrincipal Jwt principal) { adminApiService.createAppointmentReport( diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/SharedApi.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/SharedApi.java index 3d17290..e35818c 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/SharedApi.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/controller/SharedApi.java @@ -1,5 +1,6 @@ package enseirb.myinpulse.controller; +import com.itextpdf.text.DocumentException; import enseirb.myinpulse.model.*; import enseirb.myinpulse.service.SharedApiService; @@ -9,6 +10,9 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.web.bind.annotation.*; +import java.io.File; +import java.io.FileNotFoundException; + @SpringBootApplication @RestController public class SharedApi { @@ -78,7 +82,11 @@ public class SharedApi { @GetMapping("/shared/projects/appointments/report/{appointmentId}") public void getPDFReport( @PathVariable int appointmentId, @AuthenticationPrincipal Jwt principal) { - sharedApiService.getPDFReport(appointmentId, principal.getClaimAsString("email")); + try { + sharedApiService.getPDFReport(appointmentId, principal.getClaimAsString("email")); + } catch (FileNotFoundException | DocumentException e) { + System.out.println(e); + } } /** diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Appointment.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Appointment.java index 2d501a4..352ab17 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Appointment.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Appointment.java @@ -115,4 +115,8 @@ public class Appointment { public Report getAppointmentReport() { return report; } + + public void setAppointmentReport(Report report) { + this.report = report; + } } diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Report.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Report.java index 055b134..40e3337 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Report.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/model/Report.java @@ -37,4 +37,12 @@ public class Report { public void setReportContent(String reportContent) { this.reportContent = reportContent; } + + public Appointment getAppointmentReport() { + return appointmentReport; + } + + public void setAppointmentReport(Appointment appointmentReport) { + this.appointmentReport = appointmentReport; + } } diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/service/AdminApiService.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/service/AdminApiService.java index 400c2b6..a9cb44f 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/service/AdminApiService.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/service/AdminApiService.java @@ -4,6 +4,12 @@ import enseirb.myinpulse.model.*; import enseirb.myinpulse.service.database.AdministratorService; import enseirb.myinpulse.service.database.ProjectService; import enseirb.myinpulse.service.database.UserService; +import enseirb.myinpulse.service.database.AppointmentService; +import enseirb.myinpulse.service.database.ReportService; +import enseirb.myinpulse.service.UtilsService; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -13,30 +19,41 @@ import org.springframework.web.server.ResponseStatusException; @Service public class AdminApiService { + protected static final Logger logger = LogManager.getLogger(); + private final ProjectService projectService; private final UserService userService; private final AdministratorService administratorService; + private final UtilsService utilsService; + private final AppointmentService appointmentService; + private final ReportService reportService; @Autowired AdminApiService( ProjectService projectService, UserService userService, - AdministratorService administratorService) { + AdministratorService administratorService, + UtilsService utilsService, + AppointmentService appointmentService, + ReportService reportService) { this.projectService = projectService; this.userService = userService; this.administratorService = administratorService; + this.utilsService = utilsService; + this.appointmentService = appointmentService; + this.reportService = reportService; } // TODO: test - public Iterable getProjectsOfAdmin(String email) { + public Iterable getProjectsOfAdmin(String mail) { return projectService.getProjectsByAdminId( administratorService.getAdministratorById( - this.userService.getUserByEmail(email).getIdUser())); + this.userService.getUserByEmail(mail).getIdUser())); } // TODO - public Iterable getUpcomingAppointments(String email) { - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet"); + public Iterable getUpcomingAppointments(String mail) { + logger.info("User {} check their upcoming appointments", mail); } // TODO: test @@ -60,9 +77,26 @@ public class AdminApiService { projectService.addNewProject(project); // TODO: how can the front know the ID ? } - // TODO - public void createAppointmentReport(String appointmentId, Report report, String email) { - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet"); + public void createAppointmentReport(long appointmentId, Report report, String mail) { + long projectId = + this.appointmentService + .getAppointmentById(appointmentId) + .getAppointmentListSectionCell() + .getFirst() + .getProjectSectionCell() + .getIdProject(); + if (!utilsService.isAllowedToCheckProject(mail, projectId)) { + logger.warn( + "User {} tried to add an report for appointment {} but is not allowed to.", + mail, + projectId); + throw new ResponseStatusException( + HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); + } + logger.info("User {} added a report for appointment {}", mail, projectId); + Report addedReport = this.reportService.addNewReport(report); + addedReport.setAppointmentReport(this.appointmentService.getAppointmentById(appointmentId)); + this.appointmentService.getAppointmentById(appointmentId).setAppointmentReport(addedReport); } // TODO: test diff --git a/MyINPulse-back/src/main/java/enseirb/myinpulse/service/SharedApiService.java b/MyINPulse-back/src/main/java/enseirb/myinpulse/service/SharedApiService.java index 98cd05b..869b278 100644 --- a/MyINPulse-back/src/main/java/enseirb/myinpulse/service/SharedApiService.java +++ b/MyINPulse-back/src/main/java/enseirb/myinpulse/service/SharedApiService.java @@ -10,6 +10,11 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.PdfWriter; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -118,8 +123,9 @@ public class SharedApiService { return appointments; } - // TODO - public void getPDFReport(long appointmentId, String mail) { + // + public void getPDFReport(long appointmentId, String mail) + throws FileNotFoundException, DocumentException { long projectId = this.appointmentService .getAppointmentById(appointmentId) @@ -139,15 +145,82 @@ public class SharedApiService { throw new ResponseStatusException( HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); } - /* return this.appointmentService - .getAppointmentById(appointmentId) - .getAppointmentReport().getReportContent(); */ - // generate pdf from this string, and format it to be decent looking - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet"); + logger.info( + "User {} generated the PDF report related to appointment {}", mail, appointmentId); + + String reportContent = + this.appointmentService + .getAppointmentById(appointmentId) + .getAppointmentReport() + .getReportContent(); + + // PDF generation + Document document = new Document(); + PdfWriter.getInstance(document, new FileOutputStream("Report" + appointmentId + ".pdf")); + document.open(); + + Paragraph title = + new Paragraph( + new Phrase( + "Compte Rendu - Réunion du " + + this.appointmentService + .getAppointmentById(appointmentId) + .getAppointmentDate() + .toString(), + FontFactory.getFont( + FontFactory.HELVETICA, + 20, + Font.BOLDITALIC, + BaseColor.BLACK))); + title.setAlignment(Element.ALIGN_CENTER); + document.add(title); + + Font subsection = + FontFactory.getFont(FontFactory.HELVETICA, 14, Font.UNDERLINE, BaseColor.DARK_GRAY); + Font body = FontFactory.getFont(FontFactory.COURIER, 12, BaseColor.BLACK); + + String[] split = reportContent.split(" "); + + String tmp = ""; + int counter = 1; + for (String s : split) { + if (s.equals("//")) { + Chunk chunk = new Chunk(tmp, body); + document.add(chunk); + document.add(new Paragraph("\n")); + tmp = ""; + Paragraph paragraph = new Paragraph("Point n°" + counter + " : ", subsection); + document.add(paragraph); + document.add(new Paragraph("\n")); + counter++; + } else { + tmp = tmp.concat(s + " "); + } + } + Chunk chunk = new Chunk(tmp, body); + document.add(chunk); + document.add(new Paragraph("\n")); + + document.close(); } // TODO public void createAppointmentRequest(Appointment appointment, String mail) { - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet"); + long projectId = + appointment + .getAppointmentListSectionCell() + .getFirst() + .getProjectSectionCell() + .getIdProject(); + if (!utilsService.isAllowedToCheckProject(mail, projectId)) { + logger.warn( + "User {} tried to create for the project {} but is not allowed to.", + mail, + projectId); + throw new ResponseStatusException( + HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); + } + logger.info("User {} tried to create an appointment for project {}", mail, projectId); + this.appointmentService.addNewAppointment(appointment); } } diff --git a/documentation/Doc.txt b/documentation/Doc.txt new file mode 100644 index 0000000..21b094a --- /dev/null +++ b/documentation/Doc.txt @@ -0,0 +1,12 @@ +Format des comptes rendus de réunion : +Texte organisé par bullet point, chaque bullet point est séparé par "//" pour pouvoir être correctement généré. + +Exemple : +Le texte "// blablabla // oui bonjour" +donne le résultat + +Point n°1 : + blablabla + +Point n°2 : + oui bonjour \ No newline at end of file