diff --git a/.gitea/workflows/deploy_in_prod.yml b/.gitea/workflows/deploy_in_prod.yml index 9e706ea..1c31f63 100644 --- a/.gitea/workflows/deploy_in_prod.yml +++ b/.gitea/workflows/deploy_in_prod.yml @@ -45,6 +45,12 @@ jobs: mkdir -p src/main/resources/META-INF/ mv src/main/webapp/dist src/main/resources/META-INF/resources + - name: Build backend make_pdf tool + run: | + cd src/main/pdf_gen + mvn clean compile assembly:single + cd ../../.. + - name: Build backend run: | chmod 740 mvnw @@ -57,7 +63,7 @@ jobs: username: ${{ secrets.SSH_USER }} port: ${{ secrets.SSH_PORT }} key: ${{ secrets.SSH_KEY }} - source: "target/*-runner,src/main/resources/cacerts,src/main/docker/Dockerfile.native,docker-compose.yml,.dockerignore" + source: "target/*-runner,src/main/resources/cacerts,src/main/docker/Dockerfile.native,docker-compose.yml,.dockerignore,src/main/pdf_gen/target/pdf_gen-*.jar" target: ${{ secrets.TARGET_DIR }} # Need to create it first on the VPS - name: Re-start ffsaf container diff --git a/pom.xml b/pom.xml index ed769d2..22a16d3 100644 --- a/pom.xml +++ b/pom.xml @@ -75,11 +75,6 @@ 2.0.4 - - io.quarkiverse.openpdf - quarkus-openpdf - 3.1.2 - io.quarkus quarkus-junit5 @@ -211,7 +206,7 @@ false - --initialize-at-run-time=com.fasterxml.jackson.databind.ext.DOMDeserializer\,com.lowagie + --initialize-at-run-time=com.fasterxml.jackson.databind.ext.DOMDeserializer true false diff --git a/src/main/docker/Dockerfile.native b/src/main/docker/Dockerfile.native index 06f4983..aae442e 100644 --- a/src/main/docker/Dockerfile.native +++ b/src/main/docker/Dockerfile.native @@ -14,13 +14,16 @@ # docker run -i --rm -p 8080:8080 quarkus/ffsaf-site # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 +# replace FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 for jvm need sub application (ie. make_pdf) +FROM registry.access.redhat.com/ubi8/openjdk-17:1.18 + WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ && chown 1001:root /work COPY --chown=1001:root target/*-runner /work/application COPY --chown=1001:root src/main/resources/cacerts /work/cacerts +COPY --chown=1001:root src/main/pdf_gen/target/pdf_gen-*.jar /work/make_pdf.jar RUN mkdir /work/media && chown -R 1001:root /work/media EXPOSE 8080 diff --git a/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java b/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java index af3415d..7d8e1a9 100644 --- a/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java +++ b/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java @@ -1,10 +1,5 @@ package fr.titionfire.ffsaf.domain.service; -import com.lowagie.text.*; -import com.lowagie.text.pdf.BaseFont; -import com.lowagie.text.pdf.PdfPCell; -import com.lowagie.text.pdf.PdfPTable; -import com.lowagie.text.pdf.PdfWriter; import fr.titionfire.ffsaf.data.model.ClubModel; import fr.titionfire.ffsaf.data.model.LicenceModel; import fr.titionfire.ffsaf.data.model.MembreModel; @@ -38,18 +33,20 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.hibernate.reactive.mutiny.Mutiny; +import org.jboss.logging.Logger; import java.io.*; -import java.nio.file.Files; -import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.List; -import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.TimeUnit; @WithSession @ApplicationScoped public class MembreService { + private static final Logger LOGGER = Logger.getLogger(MembreService.class); @Inject CombRepository repository; @@ -66,6 +63,9 @@ public class MembreService { @ConfigProperty(name = "upload_dir") String media; + @ConfigProperty(name = "pdf-maker.jar-path") + String pdfMakerJarPath; + public SimpleCombModel find(int licence, String np) throws Throwable { return VertxContextSupport.subscribeAndAwait(() -> Panache.withTransaction(() -> repository.find("licence = ?1 AND (lname ILIKE ?2 OR fname ILIKE ?2)", @@ -315,11 +315,11 @@ public class MembreService { .findFirst() .orElseThrow(() -> new DNotFoundException("Pas de licence pour la saison en cours")); - ByteArrayOutputStream out = new ByteArrayOutputStream(); try { - make_pdf(m, out, licence); + byte[] buff = make_pdf(m, licence); + if (buff == null) + throw new IOException("Error making pdf"); - byte[] buff = out.toByteArray(); String mimeType = "application/pdf"; Response.ResponseBuilder resp = Response.ok(buff); @@ -336,185 +336,79 @@ public class MembreService { })); } - private void make_pdf(MembreModel m, ByteArrayOutputStream out, LicenceModel licence) throws IOException { - SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); - Document document = new Document(); - PdfWriter.getInstance(document, out); - document.open(); + private byte[] make_pdf(MembreModel m, LicenceModel licence) throws IOException, InterruptedException { + List cmd = new ArrayList<>(); + cmd.add("java"); + cmd.add("-jar"); + cmd.add(pdfMakerJarPath); - document.addCreator("FFSAF"); - document.addTitle( - "Attestation d'adhésion " + Utils.getSaison() + "-" + (Utils.getSaison() + 1) + " de " + m.getLname() + " " + m.getFname()); - document.addCreationDate(); - document.addProducer("https://www.ffsaf.fr"); + UUID uuid = UUID.randomUUID(); - InputStream fontStream = MembreService.class.getClassLoader().getResourceAsStream("asset/DMSans-Regular.ttf"); - if (fontStream == null) { - throw new IOException("Font file not found"); - } - BaseFont customFont = BaseFont.createFont("asset/DMSans-Regular.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true, - null, fontStream.readAllBytes()); + cmd.add("/tmp/" + uuid + ".pdf"); + cmd.add(m.getFname()); + cmd.add(m.getLname()); + cmd.add(m.getGenre().str); + cmd.add(m.getCategorie().getName()); + cmd.add(licence.getCertificate() == null ? "" : licence.getCertificate()); + cmd.add(Utils.getSaison() + ""); + cmd.add(m.getLicence() + ""); + cmd.add(m.getClub().getName()); + cmd.add(m.getClub().getNo_affiliation() + ""); + cmd.add(m.getBirth_date() == null ? "--" : new SimpleDateFormat("dd/MM/yyyy").format(m.getBirth_date())); - // Adding font - Font headerFont = new Font(customFont, 26, Font.BOLD); - Font subHeaderFont = new Font(customFont, 16, Font.BOLD); - Font bigFont = new Font(customFont, 18, Font.BOLD); - Font bodyFont = new Font(customFont, 15, Font.BOLD); - Font smallFont = new Font(customFont, 10, Font.NORMAL); - - // Creating the main table - PdfPTable mainTable = new PdfPTable(2); - mainTable.setWidthPercentage(100); - mainTable.setSpacingBefore(20f); - mainTable.setSpacingAfter(0f); - mainTable.setWidths(new float[]{120, 300}); - mainTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER); - - // Adding logo - Image logo = Image.getInstance( - Objects.requireNonNull( - getClass().getClassLoader().getResource("asset/FFSSAF-bord-blanc-fond-transparent.png"))); - logo.scaleToFit(120, 120); - PdfPCell logoCell = new PdfPCell(logo); - logoCell.setHorizontalAlignment(Element.ALIGN_CENTER); - logoCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - logoCell.setPadding(0); - logoCell.setRowspan(1); - logoCell.setBorder(PdfPCell.NO_BORDER); - mainTable.addCell(logoCell); - - // Adding header - PdfPCell headerCell = new PdfPCell(new Phrase("FEDERATION FRANCE\nSOFT ARMORED FIGHTING", headerFont)); - headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); - headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - headerCell.setBorder(PdfPCell.NO_BORDER); - mainTable.addCell(headerCell); - - document.add(mainTable); - - Paragraph addr = new Paragraph("5 place de la Barreyre\n63320 Champeix", subHeaderFont); - addr.setAlignment(Element.ALIGN_CENTER); - addr.setSpacingAfter(2f); - document.add(addr); - - Paragraph association = new Paragraph("Association loi 1901 W633001595\nSIRET 829 458 355 00015", smallFont); - association.setAlignment(Element.ALIGN_CENTER); - document.add(association); - - // Adding spacing - document.add(new Paragraph("\n\n")); - - // Adding attestation - PdfPTable attestationTable = new PdfPTable(1); - attestationTable.setWidthPercentage(60); - PdfPCell attestationCell = new PdfPCell( - new Phrase("ATTESTATION D'ADHESION\nSaison " + Utils.getSaison() + "-" + (Utils.getSaison() + 1), - bigFont)); - attestationCell.setHorizontalAlignment(Element.ALIGN_CENTER); - attestationCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - attestationCell.setPadding(20f); - attestationTable.addCell(attestationCell); - document.add(attestationTable); - - // Adding spacing - document.add(new Paragraph("\n\n")); - - // Adding member details table - PdfPTable memberTable = new PdfPTable(2); - memberTable.setWidthPercentage(100); - memberTable.setWidths(new float[]{130, 300}); - memberTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER); - - // Adding member photo - Image memberPhoto; FilenameFilter filter = (directory, filename) -> filename.startsWith(m.getId() + "."); File[] files = new File(media, "ppMembre").listFiles(filter); if (files != null && files.length > 0) { File file = files[0]; - memberPhoto = Image.getInstance(Files.readAllBytes(file.toPath())); + cmd.add(file.getAbsolutePath()); } else { - memberPhoto = Image.getInstance( - Objects.requireNonNull(getClass().getClassLoader().getResource("asset/blank-profile-picture.png"))); + cmd.add("/dev/null"); } - memberPhoto.scaleToFit(120, 150); - PdfPCell photoCell = new PdfPCell(memberPhoto); - photoCell.setHorizontalAlignment(Element.ALIGN_CENTER); - photoCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - photoCell.setRowspan(5); - photoCell.setBorder(PdfPCell.NO_BORDER); - memberTable.addCell(photoCell); - String[] cert; - if (licence.getCertificate() != null && !licence.getCertificate().isBlank()) { - cert = licence.getCertificate().split("¤"); - if (cert.length <= 1){ - cert = new String[]{licence.getCertificate(), "--"}; - }else{ - try { - cert[1] = sdf.format(new SimpleDateFormat("yyyy-MM-dd").parse(cert[1])); - } catch (ParseException e) { - cert[1] = "--"; - } + ProcessBuilder processBuilder = new ProcessBuilder(cmd); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + + StringBuilder builder = new StringBuilder(); + Thread t = new Thread(() -> { + try { + String line; + while ((line = reader.readLine()) != null) + builder.append(line).append("\n"); + } catch (Exception ignored) { } + }); + t.start(); + + int code = -1; + if (!process.waitFor(30, TimeUnit.SECONDS)) { + process.destroy(); + builder.append("Timeout..."); } else { - cert = new String[]{"--", "--"}; + code = process.exitValue(); } - // Adding member details - memberTable.addCell(new Phrase("NOM : " + m.getLname().toUpperCase(), bodyFont)); - memberTable.addCell(new Phrase("Prénom : " + m.getFname(), bodyFont)); - memberTable.addCell(new Phrase("Licence n° : " + m.getLicence(), bodyFont)); - memberTable.addCell(new Phrase("Certificat médical par " + cert[0] + ", le " + cert[1], bodyFont)); - memberTable.addCell(new Phrase("")); // Empty cell for spacing + if (t.isAlive()) + t.interrupt(); - document.add(memberTable); + LOGGER.debug("PDF maker: " + builder); - // Adding spacing - document.add(new Paragraph("\n")); - - Paragraph memberClub = new Paragraph("CLUB : " + m.getClub().getName().toUpperCase(), bodyFont); - document.add(memberClub); - - Paragraph memberClubNumber = new Paragraph("N° club : " + m.getClub().getNo_affiliation(), bodyFont); - document.add(memberClubNumber); - - // Adding spacing - document.add(new Paragraph("\n")); - - Paragraph memberBirthdate = new Paragraph( - "Date de naissance : " + ((m.getBirth_date() == null) ? "--" : sdf.format(m.getBirth_date())), - bodyFont); - document.add(memberBirthdate); - - Paragraph memberGender = new Paragraph("Sexe : " + m.getGenre().str, bodyFont); - document.add(memberGender); - - Paragraph memberAgeCategory = new Paragraph("Catégorie d'âge : " + m.getCategorie().getName(), bodyFont); - document.add(memberAgeCategory); - - // Adding spacing - document.add(new Paragraph("\n\n")); - - // Adding attestation text - PdfPTable textTable = new PdfPTable(1); - textTable.setWidthPercentage(100); - PdfPCell textCell = new PdfPCell(new Phrase( - """ - Ce document atteste que l’adhérent - - est valablement enregistré auprès de la FFSAF, - - est assuré dans sa pratique du Béhourd Léger et du Battle Arc en entraînement et en compétition. - - Il peut donc s’inscrire à tout tournoi organisé sous l’égide de la FFSAF s’il remplit les éventuelles - conditions de qualification. - Il peut participer à tout entraînement dans un club affilié si celui ci autorise les visiteurs.""", - smallFont)); - textCell.setHorizontalAlignment(Element.ALIGN_LEFT); - textCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - textCell.setBorder(PdfPCell.NO_BORDER); - textTable.addCell(textCell); - document.add(textTable); - - // Close the document - document.close(); + if (code != 0) { + throw new IOException("Error code: " + code); + } else { + File file = new File("/tmp/" + uuid + ".pdf"); + try (FileInputStream fis = new FileInputStream(file)) { + byte[] buff = fis.readAllBytes(); + //noinspection ResultOfMethodCallIgnored + file.delete(); + return buff; + } catch (IOException e) { + //noinspection ResultOfMethodCallIgnored + file.delete(); + } + return null; + } } } diff --git a/src/main/pdf_gen/.gitignore b/src/main/pdf_gen/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/src/main/pdf_gen/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/src/main/pdf_gen/pom.xml b/src/main/pdf_gen/pom.xml new file mode 100644 index 0000000..7e4c3bf --- /dev/null +++ b/src/main/pdf_gen/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + fr.titionfire + pdf_gen + 1.0-SNAPSHOT + + + 17 + 17 + UTF-8 + + + + + com.github.librepdf + openpdf + 2.0.3 + + + + + + + maven-assembly-plugin + + + + fr.titionfire.Main + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + \ No newline at end of file diff --git a/src/main/pdf_gen/src/main/java/fr/titionfire/Main.java b/src/main/pdf_gen/src/main/java/fr/titionfire/Main.java new file mode 100644 index 0000000..e6ba272 --- /dev/null +++ b/src/main/pdf_gen/src/main/java/fr/titionfire/Main.java @@ -0,0 +1,223 @@ +package fr.titionfire; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.BaseFont; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfWriter; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Objects; + +public class Main { + public static void main(String[] args) { + PdfData pdfData = new PdfData(); + + File dest = new File(args[0]); + pdfData.fname = args[1]; + pdfData.lname = args[2]; + pdfData.genre = args[3]; + pdfData.categorie = args[4]; + pdfData.certificate = args[5]; + pdfData.saison = Integer.parseInt(args[6]); + pdfData.licence = Integer.parseInt(args[7]); + pdfData.club = args[8]; + pdfData.club_no = Integer.parseInt(args[9]); + pdfData.birth_date = args[10]; + pdfData.photo_file = new File(args[11]); + + try { + FileOutputStream out = new FileOutputStream(dest); + new Main().make_pdf(pdfData, out); + } catch (IOException ignored) { + ignored.printStackTrace(); + System.exit(1); + } + + System.out.println("PDF generated successfully"); + System.exit(0); + } + + private void make_pdf(PdfData pdfData, FileOutputStream out) throws IOException { + SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); + Document document = new Document(); + PdfWriter.getInstance(document, out); + document.open(); + + document.addCreator("FFSAF"); + document.addTitle( + "Attestation d'adhésion " + pdfData.saison + "-" + (pdfData.saison + 1) + " de " + pdfData.lname + " " + pdfData.fname); + document.addCreationDate(); + document.addProducer("https://www.ffsaf.fr"); + + InputStream fontStream = Main.class.getClassLoader().getResourceAsStream("DMSans-Regular.ttf"); + if (fontStream == null) { + throw new IOException("Font file not found"); + } + BaseFont customFont = BaseFont.createFont("DMSans-Regular.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true, + null, fontStream.readAllBytes()); + + // Adding font + Font headerFont = new Font(customFont, 26, Font.BOLD); + Font subHeaderFont = new Font(customFont, 16, Font.BOLD); + Font bigFont = new Font(customFont, 18, Font.BOLD); + Font bodyFont = new Font(customFont, 15, Font.BOLD); + Font smallFont = new Font(customFont, 10, Font.NORMAL); + + // Creating the main table + PdfPTable mainTable = new PdfPTable(2); + mainTable.setWidthPercentage(100); + mainTable.setSpacingBefore(20f); + mainTable.setSpacingAfter(0f); + mainTable.setWidths(new float[]{120, 300}); + mainTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER); + + // Adding logo + Image logo = Image.getInstance( + Objects.requireNonNull( + getClass().getClassLoader().getResource("FFSSAF-bord-blanc-fond-transparent.png"))); + logo.scaleToFit(120, 120); + PdfPCell logoCell = new PdfPCell(logo); + logoCell.setHorizontalAlignment(Element.ALIGN_CENTER); + logoCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + logoCell.setPadding(0); + logoCell.setRowspan(1); + logoCell.setBorder(PdfPCell.NO_BORDER); + mainTable.addCell(logoCell); + + // Adding header + PdfPCell headerCell = new PdfPCell(new Phrase("FEDERATION FRANCE\nSOFT ARMORED FIGHTING", headerFont)); + headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); + headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell.setBorder(PdfPCell.NO_BORDER); + mainTable.addCell(headerCell); + + document.add(mainTable); + + Paragraph addr = new Paragraph("5 place de la Barreyre\n63320 Champeix", subHeaderFont); + addr.setAlignment(Element.ALIGN_CENTER); + addr.setSpacingAfter(2f); + document.add(addr); + + Paragraph association = new Paragraph("Association loi 1901 W633001595\nSIRET 829 458 355 00015", smallFont); + association.setAlignment(Element.ALIGN_CENTER); + document.add(association); + + // Adding spacing + document.add(new Paragraph("\n\n")); + + // Adding attestation + PdfPTable attestationTable = new PdfPTable(1); + attestationTable.setWidthPercentage(60); + PdfPCell attestationCell = new PdfPCell( + new Phrase("ATTESTATION D'ADHESION\nSaison " + pdfData.saison + "-" + (pdfData.saison + 1), + bigFont)); + attestationCell.setHorizontalAlignment(Element.ALIGN_CENTER); + attestationCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + attestationCell.setPadding(20f); + attestationTable.addCell(attestationCell); + document.add(attestationTable); + + // Adding spacing + document.add(new Paragraph("\n\n")); + + // Adding member details table + PdfPTable memberTable = new PdfPTable(2); + memberTable.setWidthPercentage(100); + memberTable.setWidths(new float[]{130, 300}); + memberTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER); + + // Adding member photo + Image memberPhoto; + if (pdfData.photo_file != null && pdfData.photo_file.exists()) { + memberPhoto = Image.getInstance(Files.readAllBytes(pdfData.photo_file.toPath())); + } else { + memberPhoto = Image.getInstance( + Objects.requireNonNull(getClass().getClassLoader().getResource("blank-profile-picture.png"))); + } + memberPhoto.scaleToFit(120, 150); + PdfPCell photoCell = new PdfPCell(memberPhoto); + photoCell.setHorizontalAlignment(Element.ALIGN_CENTER); + photoCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + photoCell.setRowspan(5); + photoCell.setBorder(PdfPCell.NO_BORDER); + memberTable.addCell(photoCell); + + String[] cert; + if (pdfData.certificate != null && !pdfData.certificate.isBlank()) { + cert = pdfData.certificate.split("¤"); + if (cert.length <= 1) { + cert = new String[]{pdfData.certificate, "--"}; + } else { + try { + cert[1] = sdf.format(new SimpleDateFormat("yyyy-MM-dd").parse(cert[1])); + } catch (ParseException e) { + cert[1] = "--"; + } + } + } else { + cert = new String[]{"--", "--"}; + } + + // Adding member details + memberTable.addCell(new Phrase("NOM : " + pdfData.lname.toUpperCase(), bodyFont)); + memberTable.addCell(new Phrase("Prénom : " + pdfData.fname, bodyFont)); + memberTable.addCell(new Phrase("Licence n° : " + pdfData.licence, bodyFont)); + memberTable.addCell(new Phrase("Certificat médical par " + cert[0] + ", le " + cert[1], bodyFont)); + memberTable.addCell(new Phrase("")); // Empty cell for spacing + + document.add(memberTable); + + // Adding spacing + document.add(new Paragraph("\n")); + + Paragraph memberClub = new Paragraph("CLUB : " + pdfData.club.toUpperCase(), bodyFont); + document.add(memberClub); + + Paragraph memberClubNumber = new Paragraph("N° club : " + pdfData.club_no, bodyFont); + document.add(memberClubNumber); + + // Adding spacing + document.add(new Paragraph("\n")); + + Paragraph memberBirthdate = new Paragraph("Date de naissance : " + pdfData.birth_date, bodyFont); + document.add(memberBirthdate); + + Paragraph memberGender = new Paragraph("Sexe : " + pdfData.genre, bodyFont); + document.add(memberGender); + + Paragraph memberAgeCategory = new Paragraph("Catégorie d'âge : " + pdfData.categorie, bodyFont); + document.add(memberAgeCategory); + + // Adding spacing + document.add(new Paragraph("\n\n")); + + // Adding attestation text + PdfPTable textTable = new PdfPTable(1); + textTable.setWidthPercentage(100); + PdfPCell textCell = new PdfPCell(new Phrase( + """ + Ce document atteste que l’adhérent + - est valablement enregistré auprès de la FFSAF, + - est assuré dans sa pratique du Béhourd Léger et du Battle Arc en entraînement et en compétition. + + Il peut donc s’inscrire à tout tournoi organisé sous l’égide de la FFSAF s’il remplit les éventuelles + conditions de qualification. + Il peut participer à tout entraînement dans un club affilié si celui ci autorise les visiteurs.""", + smallFont)); + textCell.setHorizontalAlignment(Element.ALIGN_LEFT); + textCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + textCell.setBorder(PdfPCell.NO_BORDER); + textTable.addCell(textCell); + document.add(textTable); + + // Close the document + document.close(); + } +} \ No newline at end of file diff --git a/src/main/pdf_gen/src/main/java/fr/titionfire/PdfData.java b/src/main/pdf_gen/src/main/java/fr/titionfire/PdfData.java new file mode 100644 index 0000000..7e0a4f6 --- /dev/null +++ b/src/main/pdf_gen/src/main/java/fr/titionfire/PdfData.java @@ -0,0 +1,19 @@ +package fr.titionfire; + +import java.io.File; +import java.util.Date; + +public class PdfData { + int saison; + int licence; + String fname; + String lname; + String club; + int club_no; + String categorie; + String genre; + String birth_date; + String certificate; + + File photo_file; +} diff --git a/src/main/resources/asset/DMSans-Regular.ttf b/src/main/pdf_gen/src/main/resources/DMSans-Regular.ttf similarity index 100% rename from src/main/resources/asset/DMSans-Regular.ttf rename to src/main/pdf_gen/src/main/resources/DMSans-Regular.ttf diff --git a/src/main/resources/asset/FFSSAF-bord-blanc-fond-transparent.png b/src/main/pdf_gen/src/main/resources/FFSSAF-bord-blanc-fond-transparent.png similarity index 100% rename from src/main/resources/asset/FFSSAF-bord-blanc-fond-transparent.png rename to src/main/pdf_gen/src/main/resources/FFSSAF-bord-blanc-fond-transparent.png diff --git a/src/main/pdf_gen/src/main/resources/blank-profile-picture.png b/src/main/pdf_gen/src/main/resources/blank-profile-picture.png new file mode 100644 index 0000000..9e34293 Binary files /dev/null and b/src/main/pdf_gen/src/main/resources/blank-profile-picture.png differ diff --git a/src/main/resources/META-INF/native-image/com/lowagie/reflect-config.json b/src/main/resources/META-INF/native-image/com/lowagie/reflect-config.json deleted file mode 100644 index 25ed93f..0000000 --- a/src/main/resources/META-INF/native-image/com/lowagie/reflect-config.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "name": "com.lowagie.text.pdf.GrayColor", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - } -] diff --git a/src/main/resources/META-INF/native-image/fr/titionfire/reflect-config.json b/src/main/resources/META-INF/native-image/fr/titionfire/reflect-config.json deleted file mode 100644 index 6dabb2f..0000000 --- a/src/main/resources/META-INF/native-image/fr/titionfire/reflect-config.json +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "name": "fr.titionfire.ffsaf", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "sun.font.Font2D", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "sun.font.CompositeFont", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "sun.awt.SunHints", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "java.awt.RenderingHints", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "sun.font.FontUtilities", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true - } -] \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ee898d3..245f2f5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -14,6 +14,8 @@ quarkus.hibernate-orm.physical-naming-strategy=fr.titionfire.ffsaf.data.SafcaNam quarkus.http.cors=true quarkus.quartz.start-mode=forced +%dev.pdf-maker.jar-path=src\\main\\pdf_gen\\target\\pdf_gen-1.0-SNAPSHOT-jar-with-dependencies.jar +pdf-maker.jar-path=/work/make_pdf.jar %dev.quarkus.log.min-level=ALL %dev.quarkus.log.category."fr.titionfire.ffsaf".level=ALL diff --git a/src/main/webapp/src/pages/admin/member/LicenceCard.jsx b/src/main/webapp/src/pages/admin/member/LicenceCard.jsx index 5c677ed..fde03d3 100644 --- a/src/main/webapp/src/pages/admin/member/LicenceCard.jsx +++ b/src/main/webapp/src/pages/admin/member/LicenceCard.jsx @@ -92,6 +92,7 @@ function sendLicence(event, dispatch) { const formData = new FormData(event.target); formData.set('licence', event.target.licence?.value?.length > 0 ? event.target.licence?.value : null) + formData.set('certificate', `${event.target.certificateBy?.value}¤${event.target.certificateDate?.value}`) toast.promise( apiAxios.post(`/licence/${formData.get('membre')}`, formData),