diff --git a/src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java b/src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java index 86e4893..2e11519 100644 --- a/src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java +++ b/src/main/java/com/ffii/lioner/modules/lioner/pdf/service/PdfService.java @@ -1,5 +1,8 @@ package com.ffii.lioner.modules.lioner.pdf.service; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -14,17 +17,29 @@ import java.util.stream.Collectors; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; +import org.apache.pdfbox.pdmodel.interactive.form.PDField; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ClassPathResource; import com.ffii.lioner.modules.lioner.pdf.entity.Pdf; import com.ffii.lioner.modules.lioner.pdf.entity.PdfRepository; +import com.ffii.lioner.modules.lioner.commonField.entity.CommonField; +import com.ffii.lioner.modules.lioner.commonField.service.CommonFieldService; import com.ffii.lioner.modules.lioner.entity.ImpEvent; import com.ffii.lioner.modules.lioner.pdf.req.UpdatePdfReq; import com.ffii.lioner.modules.lioner.service.FileService; import com.ffii.lioner.modules.common.SecurityUtils; import com.ffii.lioner.modules.common.service.AuditLogService; import com.ffii.lioner.modules.master.entity.SubDivision; +import com.itextpdf.forms.PdfAcroForm; +import com.itextpdf.forms.fields.PdfFormField; +import com.itextpdf.io.source.ByteArrayOutputStream; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.PdfWriter; import com.fasterxml.jackson.databind.ObjectMapper; import com.ffii.core.exception.NotFoundException; import com.ffii.core.exception.UnprocessableEntityException; @@ -35,6 +50,7 @@ import com.ffii.core.utils.JsonUtils; import com.ffii.core.utils.Params; import jakarta.persistence.Table; +import com.ffii.lioner.modules.lioner.pdf.web.Pdf2Controller; @Service public class PdfService extends AbstractBaseEntityService { @@ -43,11 +59,13 @@ public class PdfService extends AbstractBaseEntityService getAuditLogObject(Map req){ @@ -130,10 +148,7 @@ public class PdfService extends AbstractBaseEntityService { + // logger.info(" - Field Name: '{}', Type: '{}'", fieldName, pdfFormField.getFormType()); + // }); + // } + // logger.info("--- End of form fields list ---"); + // --- END DEBUGGING CODE --- + + // Load common field data + Long commonFieldId = commonFieldService.getByClientId(clientId); + // logger.info("id? " + id); + CommonField commonField = commonFieldService.find(commonFieldId).orElse(null); + + if(commonField == null){ + logger.info("No common field data found for clientId: " + clientId); + // do nothing + } else { + // It's highly recommended to check if the field exists before setting its value + // This prevents NullPointerExceptions if a field is missing in a template + + if(templateId.intValue() == 1){ // This is IDA + logger.info("Processing IDA form (ID: 1)"); + setValueIfPresent(form, "fill_6", commonField.getName(), "commonField.getName()"); + setValueIfPresent(form, "fill_7", commonField.getNameChi(), "commonField.getNameChi()"); + setValueIfPresent(form, "fill_11", commonField.getIdCard(), "commonField.getIdCard()"); + + } else if(templateId.intValue() == 2){ // This is FNA + logger.info("Processing FNA form (ID: 2)"); + setValueIfPresent(form, "fna_a_name", commonField.getName(), "commonField.getName()"); + setValueIfPresent(form, "fna_a_birth", commonField.getDateOfBirth(), "commonField.getDateOfBirth()"); + setValueIfPresent(form, "fna_a_occupation", commonField.getOccupation(), "commonField.getOccupation()"); + + } else if(templateId.intValue() == 3){ // This is HSBCFIN + logger.info("Processing HSBCFIN form (ID: 3)"); + setValueIfPresent(form, "fill_3", commonField.getName(), "commonField.getName()"); + setValueIfPresent(form, "fill_4", commonField.getNameChi(), "commonField.getNameChi()"); + setValueIfPresent(form, "fill_5", commonField.getGender(), "commonField.getGender()"); + setValueIfPresent(form, "fill_6", commonField.getDateOfBirth(), "commonField.getDateOfBirth()"); // Note: fill_6 used here again + setValueIfPresent(form, "fill_9", commonField.getOccupation(), "commonField.getOccupation()"); + } + + // These fields are set unconditionally if commonField is not null + // Ensure these fields exist across all your templates or handle them conditionally + setValueIfPresent(form, "address", "123 Main St, Anytown, USA", "hardcoded address"); + setValueIfPresent(form, "dateOfBirth", "01/01/1990", "hardcoded dateOfBirth"); + } + + //form.flattenFields(); // Flatten fields after setting all values + + } else { + // logger.warn("No AcroForm found in PDF for ID: " + id + ". PDF might not have fillable fields."); + } + + pdfDoc.close(); + modifiedPdfBytes = outputStream.toByteArray(); + logger.info("Modified PDF byte array length: " + modifiedPdfBytes.length); + + } catch (IOException e) { + // logger.error("Error processing PDF with iText for ID: " + id, e); + } + + + + + if (!pdfFile.exists()) { + throw new UnprocessableEntityException("PDF template not found."); + } + // try (InputStream is = pdfFile.getInputStream()) { + // return pdfBytes; + // } catch (Exception e) { + // throw new UnprocessableEntityException("Fail to load PDF: " + e); + // } + return modifiedPdfBytes; // return fileService.getfileBlob((long) 2); } @@ -245,4 +378,100 @@ public class PdfService extends AbstractBaseEntityService 0){ + commonField = commonFieldService.find(id).orElse(new CommonField()); + }else{ + commonField = new CommonField(); + } + //logger.info("commonField? " + commonField.toString()); + commonField.setClientId(record.getClientId()); + + logger.info("commonField? " + commonField.getId()); + // Example: Iterate through fields and print values + for (PDField field : acroForm.getFields()) { + String fieldName = field.getPartialName(); + String fieldValue = field.getValueAsString(); + + if (record.getTemplateId().intValue() == 1) { + logger.info("IDA "); + + switch (fieldName) { + case "fill_6" -> commonField.setName(fieldValue); + case "fill_7" -> commonField.setNameChi(fieldValue); + case "fill_11" -> commonField.setIdCard(fieldValue); + + }; + } + + if(record.getTemplateId().intValue() == 2){ + logger.info("FNA "); + + switch (fieldName) { + case "fna_a_name" -> commonField.setName(fieldValue); + case "fna_a_birth" -> commonField.setDateOfBirth(fieldValue); + case "fna_a_occupation" -> commonField.setOccupation(fieldValue); + }; + } + + if(record.getTemplateId().intValue() == 3){ + logger.info("HSBCFIN "); + + switch (fieldName) { + case "fill_3" -> commonField.setName(fieldValue); + case "fill_4" -> commonField.setNameChi(fieldValue); + case "fill_5" -> commonField.setGender(fieldValue); + case "fill_6" -> commonField.setDateOfBirth(fieldValue); + + case "fill_9" -> commonField.setOccupation(fieldValue); + }; + } + + logger.info("end Field: " + field.getPartialName() + ", Value: " + field.getValueAsString()); + // You can save this data to a database, or perform other operations + } + + commonFieldService.save(commonField); + } + logger.info("ended"); + document.close(); + logger.info("closed"); + } + + private void setValueIfPresent(PdfAcroForm form, String fieldName, String value, String valueSource) { + PdfFormField field = form.getField(fieldName); + if (field != null) { + if (value != null) { + try { + field.setValue(value); + // logger.info("Set field '{}' to value '{}' (from {})", fieldName, value, valueSource); + } catch (Exception e) { + // logger.error("Error setting value for field '{}' with value '{}' (from {}): {}", fieldName, value, valueSource, e.getMessage()); + } + } else { + // logger.warn("Value for field '{}' (from {}) is null. Skipping setting value.", fieldName, valueSource); + } + } else { + // logger.warn("PDF field '{}' not found in the document. Skipping setting value.", fieldName); + } + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java b/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java index 0ccd172..9dc0995 100644 --- a/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java +++ b/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/Pdf2Controller.java @@ -39,6 +39,7 @@ import org.springframework.web.multipart.MultipartFile; import com.ffii.lioner.modules.lioner.commonField.entity.CommonField; import com.ffii.lioner.modules.lioner.commonField.service.CommonFieldService; +import com.ffii.lioner.modules.lioner.pdf.entity.Pdf; import com.ffii.lioner.modules.lioner.pdf.service.PdfService; import com.itextpdf.forms.PdfAcroForm; import com.itextpdf.forms.fields.PdfFormField; @@ -361,8 +362,82 @@ public class Pdf2Controller { return ResponseEntity.ok("PDF saved successfully at " + file.getAbsolutePath()); } catch (IOException e) { return ResponseEntity.status(500).body("Error saving PDF: " + e.getMessage()); - } + } + } - + public void saveCmField(File file, Pdf record) throws IOException { + // byte[] pdfBytes = Files.readAllBytes(file.toPath()); + + // try (FileOutputStream fos = new FileOutputStream(file)) { + // IOUtils.write(pdfBytes, fos); + // } + + //PDDocument document = PDDocument.load(targetLocation.toFile()); + PDDocument document = Loader.loadPDF(file); // Changed! + PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(); + + logger.info("acroForm? " + (acroForm != null) ); + if (acroForm != null) { + //create CommonField if not exists for this client Id + Long id = commonFieldService.getByClientId(record.getClientId()); + logger.info("id? " + id); + CommonField commonField = null; + if(id > 0){ + commonField = commonFieldService.find(id).orElse(new CommonField()); + }else{ + commonField = new CommonField(); + } + //logger.info("commonField? " + commonField.toString()); + commonField.setClientId(record.getClientId()); + + logger.info("commonField? " + commonField.getId()); + // Example: Iterate through fields and print values + for (PDField field : acroForm.getFields()) { + String fieldName = field.getPartialName(); + String fieldValue = field.getValueAsString(); + + if (record.getTemplateId().intValue() == 1) { + logger.info("IDA "); + + switch (fieldName) { + case "fill_6" -> commonField.setName(fieldValue); + case "fill_7" -> commonField.setNameChi(fieldValue); + case "fill_11" -> commonField.setIdCard(fieldValue); + + }; + } + + if(record.getTemplateId().intValue() == 2){ + logger.info("FNA "); + + switch (fieldName) { + case "fna_a_ name" -> commonField.setName(fieldValue); + case "fna_a_birth" -> commonField.setDateOfBirth(fieldValue); + case "fna_a_occupation" -> commonField.setOccupation(fieldValue); + }; + } + + if(record.getTemplateId().intValue() == 3){ + logger.info("HSBCFIN "); + + switch (fieldName) { + case "fill_3" -> commonField.setName(fieldValue); + case "fill_4" -> commonField.setNameChi(fieldValue); + case "fill_5" -> commonField.setGender(fieldValue); + case "fill_6" -> commonField.setDateOfBirth(fieldValue); + + case "fill_9" -> commonField.setOccupation(fieldValue); + }; + } + + logger.info("end Field: " + field.getPartialName() + ", Value: " + field.getValueAsString()); + // You can save this data to a database, or perform other operations + } + + commonFieldService.save(commonField); + } + logger.info("ended"); + document.close(); + logger.info("closed"); } } diff --git a/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java b/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java index 23c82ff..eac37d3 100644 --- a/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java +++ b/src/main/java/com/ffii/lioner/modules/lioner/pdf/web/PdfController.java @@ -80,9 +80,21 @@ public class PdfController { // Endpoint to serve the initial template PDF @GetMapping(value = "/template", produces = MediaType.APPLICATION_PDF_VALUE) - public ResponseEntity getPdfTemplate() throws IOException { + public ResponseEntity getPdfTemplate(@RequestParam Long templateId, @RequestParam Long clientId) throws IOException { - byte[] pdfBytes = pdfService.getTemplateForm(); + byte[] pdfBytes = pdfService.getTemplateForm(templateId, clientId); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentDispositionFormData("inline", "template_form.pdf"); + headers.setContentType(MediaType.APPLICATION_PDF); + return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK); + } + + // Get template by template id (Unused now) + @GetMapping(value = "/template/{id}", produces = MediaType.APPLICATION_PDF_VALUE) + public ResponseEntity getPdfTemplateById(@PathVariable Long id) throws IOException { + + byte[] pdfBytes = pdfService.getTemplateForm(id, (long) 0); HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("inline", "template_form.pdf");