Merge pull request #44 from Kitzanos/feature/GEPAFINBE-33
GEPAFINBE-33(Created an API to download PDF documentation for Beneficiaries)
This commit is contained in:
20
pom.xml
20
pom.xml
@@ -185,6 +185,26 @@
|
|||||||
<version>2.3.0</version> <!-- or latest -->
|
<version>2.3.0</version> <!-- or latest -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itextpdf</artifactId>
|
||||||
|
<version>5.5.13.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext7-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itext7-core</artifactId>
|
||||||
|
<version>8.0.5</version>
|
||||||
|
<type>pom</type>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.itextpdf/layout -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>layout</artifactId>
|
||||||
|
<version>8.0.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
|
|||||||
574
src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java
Normal file
574
src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
package net.gepafin.tendermanagement.dao;
|
||||||
|
|
||||||
|
import com.itextpdf.kernel.colors.ColorConstants;
|
||||||
|
import com.itextpdf.kernel.colors.DeviceRgb;
|
||||||
|
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
|
||||||
|
import com.itextpdf.layout.properties.UnitValue;
|
||||||
|
import com.itextpdf.layout.renderer.CellRenderer;
|
||||||
|
import com.itextpdf.layout.renderer.DrawContext;
|
||||||
|
import com.itextpdf.text.*;
|
||||||
|
import com.itextpdf.text.Element;
|
||||||
|
import com.itextpdf.text.Font;
|
||||||
|
import com.itextpdf.text.Image;
|
||||||
|
import com.itextpdf.text.Rectangle;
|
||||||
|
import com.itextpdf.text.pdf.*;
|
||||||
|
import net.gepafin.tendermanagement.config.Translator;
|
||||||
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
|
import net.gepafin.tendermanagement.entities.*;
|
||||||
|
import net.gepafin.tendermanagement.model.request.CustomPageEvent;
|
||||||
|
import net.gepafin.tendermanagement.model.request.FieldLabelValuePairRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.*;
|
||||||
|
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
|
||||||
|
import net.gepafin.tendermanagement.service.CallService;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import com.itextpdf.layout.element.Table;
|
||||||
|
import com.itextpdf.layout.element.Cell;
|
||||||
|
//import com.itextpdf.layout.element.
|
||||||
|
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PdfDao {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationRepository applicationRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CallService callService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationDao applicationDao;
|
||||||
|
|
||||||
|
|
||||||
|
public byte[] generatePdf(UserEntity userEntity,Long applicationId) {
|
||||||
|
try {
|
||||||
|
ApplicationEntity applicationEntity = applicationRepository
|
||||||
|
.findByIdAndUserIdAndIsDeletedFalse(applicationId, userEntity.getId())
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException(
|
||||||
|
Status.NOT_FOUND,
|
||||||
|
Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG)
|
||||||
|
));
|
||||||
|
|
||||||
|
CompanyEntity companyEntity=applicationEntity.getCompany();
|
||||||
|
CallEntity call=callService.validateCall(applicationEntity.getCall().getId());
|
||||||
|
|
||||||
|
// Create a byte stream to hold the PDF
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
float leftMargin = 50f; // Adjust this for the left margin
|
||||||
|
|
||||||
|
Document document = new Document(PageSize.A4, leftMargin, 36f, 50f, 35);
|
||||||
|
PdfWriter writer = PdfWriter.getInstance(document, out);
|
||||||
|
CustomPageEvent pageEvent = new CustomPageEvent(call.getName(), 0);
|
||||||
|
writer.setPageEvent(pageEvent);
|
||||||
|
document.open();
|
||||||
|
pageEvent.setTotalPages(writer.getPageNumber());
|
||||||
|
addLogo(document, "https://mementoresources.s3.eu-west-1.amazonaws.com/gepafin/logo.jpg"); // Add your image path here
|
||||||
|
|
||||||
|
|
||||||
|
BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed
|
||||||
|
// Define fonts and styles
|
||||||
|
BaseColor greenColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed
|
||||||
|
BaseColor darkGreenColor = new BaseColor(1, 50, 32); // Adjust RGB values as needed
|
||||||
|
Font titleFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 16, customColor);
|
||||||
|
Font sectionFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,darkGreenColor);
|
||||||
|
Font labelFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,new BaseColor(113,121,126)); // Light grey);
|
||||||
|
Font smallFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 8,new BaseColor(105, 105, 105));
|
||||||
|
Font valueFont=FontFactory.getFont(FontFactory.HELVETICA_BOLD,10,new BaseColor(178, 190, 181));
|
||||||
|
Paragraph title = new Paragraph(call.getName(), titleFont);
|
||||||
|
title.setAlignment(Element.ALIGN_LEFT);
|
||||||
|
document.add(title);
|
||||||
|
|
||||||
|
BaseColor greyColor=new BaseColor(178, 190, 181); // Very light grey color
|
||||||
|
addColoredLines(writer,document,greyColor);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
// Application ID section (Centered)
|
||||||
|
pageEvent.setTotalPages(writer.getPageNumber());
|
||||||
|
Paragraph appId = new Paragraph("ID domanda :" +"XX00");
|
||||||
|
appId.setAlignment(Element.ALIGN_RIGHT);
|
||||||
|
document.add(appId);
|
||||||
|
|
||||||
|
if(applicationEntity.getProtocol()!=null) {
|
||||||
|
appId = new Paragraph("ID domanda :"+String.valueOf(applicationEntity.getProtocol().getProtocolNumber()), valueFont);
|
||||||
|
appId.setAlignment(Element.ALIGN_RIGHT);
|
||||||
|
document.add(appId);
|
||||||
|
}
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
addColoredLines(writer,document,greenColor);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
document.add(new Paragraph("\n")); // Add line break
|
||||||
|
// String companyName= companyEntity.getCompanyName();
|
||||||
|
// String vatNumber=companyEntity.getVatNumber();
|
||||||
|
// String address=companyEntity.getAddress();
|
||||||
|
// // Section: Dati Anagrafici Azienda
|
||||||
|
// document.add(new Paragraph("Dati Anagrafici Azienda", sectionFont));
|
||||||
|
// addLabelValuePair(document, "Codice ATECO", "SEZIONE C “ATTIVITÀ MANUFATTURIERE”", regularFont);
|
||||||
|
// addLabelValuePair(document, "Ragione Sociale", companyName, regularFont);
|
||||||
|
// addLabelValuePair(document, "Partita IVA", vatNumber, regularFont);
|
||||||
|
// addLabelValuePair(document, "Indirizzo sede Legale", address, regularFont);
|
||||||
|
//
|
||||||
|
// document.add(new Paragraph("\n")); // Add line break
|
||||||
|
//
|
||||||
|
// // Section: Domanda presentata da
|
||||||
|
// document.add(new Paragraph("Domanda presentata da:", sectionFont));
|
||||||
|
// addLabelValuePair(document, "Nome e cognome", userEntity.getBeneficiary().getFirstName()+" "+userEntity.getBeneficiary().getLastName(), regularFont);
|
||||||
|
// addLabelValuePair(document, "Codice fiscale", userEntity.getBeneficiary().getCodiceFiscale(), regularFont);
|
||||||
|
// addLabelValuePair(document, "Telefono", userEntity.getBeneficiary().getPhoneNumber(), regularFont);
|
||||||
|
// addLabelValuePair(document, "Email", userEntity.getBeneficiary().getEmail(), regularFont);
|
||||||
|
// addLabelValuePair(document, "Con il titolo di", "Rappresentante legale", regularFont);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
ApplicationGetResponseBean applicationGetResponseBean=applicationDao.getApplicationByFormId(applicationId,null,userEntity);
|
||||||
|
for(FormApplicationResponse formApplicationResponse: applicationGetResponseBean.getForm()) {
|
||||||
|
document.add(new Paragraph(formApplicationResponse.getLabel(),sectionFont));
|
||||||
|
document.add(new Paragraph(" ")); // Add line break
|
||||||
|
List<FieldLabelValuePairRequest> fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse);
|
||||||
|
for (FieldLabelValuePairRequest pair : fieldLabelValuePairRequests) {
|
||||||
|
String label = pair.getLabel();
|
||||||
|
Object value = pair.getValue();
|
||||||
|
Integer pages=0;
|
||||||
|
pages=addLabelValuePair(writer,document, label, value, labelFont,valueFont,call.getName(),pages);
|
||||||
|
if(pages !=0 ){
|
||||||
|
pageEvent.setTotalPages(writer.getPageNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addColoredLines(writer,document,greenColor);
|
||||||
|
document.add(new Paragraph(" ")); // Add line break
|
||||||
|
}
|
||||||
|
document.add(new Paragraph("\n")); // Add line break
|
||||||
|
Font boldSmallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD,new BaseColor(105, 105, 105));
|
||||||
|
|
||||||
|
// Adding the "Documenti Allegati" section title
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
pageEvent.setTotalPages(writer.getPageNumber());
|
||||||
|
document.newPage();
|
||||||
|
document.add(new Paragraph("Documenti Allegati", sectionFont));
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 1. Autocertificazione possesso Requisiti
|
||||||
|
Paragraph p1 = new Paragraph();
|
||||||
|
p1.add(new Chunk("1. ", boldSmallFont));
|
||||||
|
p1.add(new Chunk("Autocertificazione possesso Requisiti ", boldSmallFont));
|
||||||
|
p1.add(new Chunk("ai sensi degli artt. 46 e 47 del DPR 445/2000", smallFont));
|
||||||
|
document.add(p1);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Informativa Privacy relativa al trattamento dei dati personali
|
||||||
|
Paragraph p2 = new Paragraph();
|
||||||
|
p2.add(new Chunk("2. ", boldSmallFont));
|
||||||
|
p2.add(new Chunk("Informativa Privacy relativa al trattamento dei dati personali", boldSmallFont));
|
||||||
|
document.add(p2);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari
|
||||||
|
Paragraph p3 = new Paragraph();
|
||||||
|
p3.add(new Chunk("3. ", boldSmallFont));
|
||||||
|
p3.add(new Chunk("Dati richiesti per la valutazione dell’adeguatezza dei flussi finanziari prospettici come da tabella di cui all’Appendice 9", boldSmallFont));
|
||||||
|
document.add(p3);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 4. Rilevazione Centrale dei Rischi
|
||||||
|
Paragraph p4 = new Paragraph();
|
||||||
|
p4.add(new Chunk("4. ", boldSmallFont));
|
||||||
|
p4.add(new Chunk("Rilevazione Centrale dei Rischi riferita agli ultimi 36 mesi disponibili alla data di presentazione della Domanda", boldSmallFont));
|
||||||
|
document.add(p4);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 5. Schema di presentazione dei dati di bilancio
|
||||||
|
Paragraph p5 = new Paragraph();
|
||||||
|
p5.add(new Chunk("5. ", boldSmallFont));
|
||||||
|
p5.add(new Chunk("Schema di presentazione dei dati di bilancio", boldSmallFont));
|
||||||
|
document.add(p5);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 6. Dettagli bilanci in forma abbreviata
|
||||||
|
Paragraph p6 = new Paragraph();
|
||||||
|
p6.add(new Chunk("6. ", boldSmallFont));
|
||||||
|
p6.add(new Chunk("Dettagli bilanci in forma abbreviata", boldSmallFont));
|
||||||
|
document.add(p6);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
|
||||||
|
// 7. Relazione aziendale illustrativa
|
||||||
|
Paragraph p7 = new Paragraph();
|
||||||
|
p7.add(new Chunk("7. ", boldSmallFont));
|
||||||
|
p7.add(new Chunk("Relazione aziendale illustrativa", boldSmallFont));
|
||||||
|
document.add(p7);
|
||||||
|
document.add(new Paragraph(" "));
|
||||||
|
|
||||||
|
addColoredLines(writer,document,greenColor);
|
||||||
|
|
||||||
|
// Close the document
|
||||||
|
document.close();
|
||||||
|
|
||||||
|
// Convert to byte array for response
|
||||||
|
byte[] pdfBytes = out.toByteArray();
|
||||||
|
return pdfBytes;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,String title,Integer totalPages) throws DocumentException {
|
||||||
|
// Add label
|
||||||
|
Paragraph labelParagraph = new Paragraph(label, labelFont);
|
||||||
|
document.add(labelParagraph);
|
||||||
|
float leftMargin = 20f;
|
||||||
|
|
||||||
|
PdfContentByte canvas = writer.getDirectContent();
|
||||||
|
|
||||||
|
// Setting the color and width of the line
|
||||||
|
float lineWidth = 1.0f; // Thickness of the line
|
||||||
|
canvas.setLineWidth(lineWidth);
|
||||||
|
|
||||||
|
// Get the current vertical position in the document
|
||||||
|
float yPos = writer.getVerticalPosition(true) - 10f; // Adjust this to move line slightly below current content
|
||||||
|
|
||||||
|
// Define start and end points for the line (relative to the page size and margins)
|
||||||
|
|
||||||
|
if (yPos <= 140) {
|
||||||
|
// If xEnd is less than or equal to 200, generate a new page
|
||||||
|
|
||||||
|
totalPages++;
|
||||||
|
document.newPage();
|
||||||
|
} // Add a gap between the label and value
|
||||||
|
document.add(new Paragraph(" ")); // Adding an empty paragraph for spacing
|
||||||
|
// Create value cell with rounded corners
|
||||||
|
PdfPTable valueTable = new PdfPTable(1);
|
||||||
|
valueTable.setWidthPercentage(100);
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
// Further check if the list contains Strings
|
||||||
|
List<?> list = (List<?>) value;
|
||||||
|
if (!list.isEmpty() && list.get(0) instanceof String) {
|
||||||
|
// Cast to List<String>
|
||||||
|
List<String> values = (List<String>) value;
|
||||||
|
|
||||||
|
// Loop through the list of strings and create a cell for each string
|
||||||
|
for (String item : values) {
|
||||||
|
PdfPCell valueCell = new PdfPCell(new Phrase(item, valueFont));
|
||||||
|
valueCell.setPadding(5f); // Increase padding for better spacing
|
||||||
|
valueCell.setPaddingLeft(leftMargin); // Increase left margin for value
|
||||||
|
valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell
|
||||||
|
valueCell.setMinimumHeight(30f);
|
||||||
|
valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners
|
||||||
|
|
||||||
|
// Add the cell to the table
|
||||||
|
valueTable.addCell(valueCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, add the table to the document
|
||||||
|
document.add(valueTable);
|
||||||
|
} else {
|
||||||
|
boolean containsThreeValues = false; // Variable to track if any map contains three keys
|
||||||
|
List<Map<String, Object>> dataList = (List<Map<String, Object>>) value; // Cast Object to List of Maps
|
||||||
|
for (Map<String, Object> entry : dataList) {
|
||||||
|
if (entry.size() == 3) { // Check if the current map has three keys
|
||||||
|
containsThreeValues = true; // If found, set the variable to true
|
||||||
|
break; // No need to check further, exit loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> extractedData = new ArrayList<>(); // To hold extracted data
|
||||||
|
for (Map<String, Object> entry : dataList) {
|
||||||
|
Map<String, String> extractedMap = new HashMap<>(); // To hold the current extracted row of data
|
||||||
|
|
||||||
|
List<String> keys = new ArrayList<>(entry.keySet()); // Get all keys in the current map
|
||||||
|
|
||||||
|
// Handle based on the number of keys in the map
|
||||||
|
if (Boolean.FALSE.equals(containsThreeValues) && keys.size() == 2) {
|
||||||
|
// Treat the first key as the "key" and second key as the "value"
|
||||||
|
String heading = (String) entry.get(keys.get(0)); // Get value of first key
|
||||||
|
String value1 = (String) entry.get(keys.get(1)); // Get value of second key
|
||||||
|
extractedMap.put(heading,value1); // Store the first key's value as "heading"
|
||||||
|
} if (Boolean.TRUE.equals(containsThreeValues) ) {
|
||||||
|
String amount="";
|
||||||
|
// Treat the first as number, second as description, third as amount
|
||||||
|
if(keys.size()==3){
|
||||||
|
amount = (String) entry.get(keys.get(2)); // Third key's value
|
||||||
|
}
|
||||||
|
String number = (String) entry.get(keys.get(0)); // First key's value
|
||||||
|
String description = (String) entry.get(keys.get(1)); // Second key's value
|
||||||
|
|
||||||
|
// Store the combined result as a value in the map, with a suitable key
|
||||||
|
String combinedValue = number + ", " + description + ", " + amount; // Concatenate them as a single value
|
||||||
|
extractedMap.put("combined", combinedValue); // Store as a single entry, key as "combined"
|
||||||
|
}
|
||||||
|
|
||||||
|
extractedData.add(extractedMap); // Add each extracted map to the list
|
||||||
|
}
|
||||||
|
document=createPdfTable(extractedData,document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PdfPCell valueCell = new PdfPCell(new Phrase(String.valueOf(value), valueFont));
|
||||||
|
valueCell.setPadding(5f); // Increase padding for better spacing
|
||||||
|
valueCell.setPaddingLeft(leftMargin); // Increase left margin for value
|
||||||
|
valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell
|
||||||
|
valueCell.setMinimumHeight(30f);
|
||||||
|
valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners
|
||||||
|
|
||||||
|
valueTable.addCell(valueCell);
|
||||||
|
document.add(valueTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.add(new Paragraph("\n")); // Add line break after each value
|
||||||
|
return totalPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Document createPdfTable(List<Map<String, String>> extractedData,Document document) throws DocumentException { // Create a PdfPTable with 2 columns
|
||||||
|
PdfPTable table = new PdfPTable(2); // Initial assumption for 2 columns
|
||||||
|
table.setWidthPercentage(100); // Set table width to 100%
|
||||||
|
Font textFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new BaseColor(105, 105, 105)); // Gray text
|
||||||
|
boolean combinedHeaderAdded = false; // Flag to track if headers for combined have been added
|
||||||
|
float rowHeight = 50f; // Example row height, adjust as necessary
|
||||||
|
float maxTableHeight = 700f; // Maximum height of the table before a page break
|
||||||
|
int rowCount = 0; // Counter for rows
|
||||||
|
|
||||||
|
|
||||||
|
// Add table header
|
||||||
|
// Populate the table with extracted data and style rows
|
||||||
|
for (Map<String, String> row : extractedData) {
|
||||||
|
for (Map.Entry<String, String> entry : row.entrySet()) {
|
||||||
|
String key = entry.getKey(); // This will give you the key
|
||||||
|
String value = entry.getValue(); // This will give you the value
|
||||||
|
|
||||||
|
// Check if the current entry is for the combined section
|
||||||
|
if ("combined".equals(key)) {
|
||||||
|
// Ensure the combined header is added only once
|
||||||
|
if (!combinedHeaderAdded) {
|
||||||
|
// Create a new table for combined entries
|
||||||
|
table = new PdfPTable(3); // 3 columns for combined entries
|
||||||
|
|
||||||
|
PdfPCell headerCell1 = new PdfPCell(new Phrase("Number"));
|
||||||
|
headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
|
||||||
|
headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
|
||||||
|
table.addCell(headerCell1);
|
||||||
|
|
||||||
|
PdfPCell headerCell2 = new PdfPCell(new Phrase("Details"));
|
||||||
|
headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
|
||||||
|
headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
|
||||||
|
table.addCell(headerCell2);
|
||||||
|
|
||||||
|
PdfPCell headerCell3 = new PdfPCell(new Phrase("Amount"));
|
||||||
|
headerCell3.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
|
||||||
|
headerCell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
headerCell3.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
|
||||||
|
table.addCell(headerCell3);
|
||||||
|
|
||||||
|
combinedHeaderAdded = true; // Mark header as added
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the value for "combined" into separate parts
|
||||||
|
String[] combinedValues = value.split(", ");
|
||||||
|
|
||||||
|
// Check if we have 3 parts (number, description, amount)
|
||||||
|
String number = combinedValues[0].trim(); // 1st part (number)
|
||||||
|
String description = combinedValues[1].trim(); // 2nd part (description)
|
||||||
|
String amount = "";
|
||||||
|
if (combinedValues.length == 3) {
|
||||||
|
amount = combinedValues[2].trim(); // 3rd part (amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create PDF cells using the split values
|
||||||
|
PdfPCell cellNumber = new PdfPCell(new Phrase(number, textFont)); // Cell for number
|
||||||
|
PdfPCell cellDescription = new PdfPCell(new Phrase(description, textFont)); // Cell for description
|
||||||
|
PdfPCell cellAmount = new PdfPCell(new Phrase(amount, textFont)); // Cell for amount
|
||||||
|
|
||||||
|
// Set row background color for combined values
|
||||||
|
cellNumber.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for combined rows
|
||||||
|
cellDescription.setBackgroundColor(new BaseColor(239, 243, 248));
|
||||||
|
cellAmount.setBackgroundColor(new BaseColor(239, 243, 248));
|
||||||
|
|
||||||
|
// Set cell height and add rounded borders
|
||||||
|
cellNumber.setFixedHeight(rowHeight);
|
||||||
|
cellDescription.setFixedHeight(rowHeight);
|
||||||
|
cellAmount.setFixedHeight(rowHeight);
|
||||||
|
cellNumber.setPadding(7f);
|
||||||
|
cellDescription.setPadding(7f);
|
||||||
|
cellAmount.setPadding(7f);
|
||||||
|
|
||||||
|
// Add the cells to the table only once
|
||||||
|
table.addCell(cellNumber);
|
||||||
|
table.addCell(cellDescription);
|
||||||
|
table.addCell(cellAmount);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!combinedHeaderAdded) {
|
||||||
|
// Create a new table for combined entries
|
||||||
|
table= new PdfPTable(2); // 3 columns for combined entries
|
||||||
|
table.setWidthPercentage(100);
|
||||||
|
|
||||||
|
PdfPCell headerCell1 = new PdfPCell(new Phrase("Details"));
|
||||||
|
headerCell1.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
|
||||||
|
headerCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
headerCell1.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
|
||||||
|
table.addCell(headerCell1);
|
||||||
|
|
||||||
|
PdfPCell headerCell2 = new PdfPCell(new Phrase("Amount"));
|
||||||
|
headerCell2.setHorizontalAlignment(Element.ALIGN_CENTER); // Center align
|
||||||
|
headerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
||||||
|
headerCell2.setBackgroundColor(new BaseColor(178, 190, 181)); // Light gray background for header
|
||||||
|
table.addCell(headerCell2);
|
||||||
|
combinedHeaderAdded=true;
|
||||||
|
}
|
||||||
|
// Add cells for regular key-value pairs without headers
|
||||||
|
PdfPCell cellKey = new PdfPCell(new Phrase(key, textFont));
|
||||||
|
PdfPCell cellValue = new PdfPCell(new Phrase(value, textFont));
|
||||||
|
|
||||||
|
// Set background color for both cells
|
||||||
|
cellKey.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for other rows
|
||||||
|
cellValue.setBackgroundColor(new BaseColor(239, 243, 248));
|
||||||
|
|
||||||
|
// Set cell height and add rounded borders
|
||||||
|
cellKey.setFixedHeight(rowHeight);
|
||||||
|
cellValue.setFixedHeight(rowHeight);
|
||||||
|
|
||||||
|
// Add the cells to the table
|
||||||
|
table.addCell(cellKey);
|
||||||
|
table.addCell(cellValue);
|
||||||
|
}
|
||||||
|
if (table.getTotalHeight() + rowHeight > maxTableHeight) {
|
||||||
|
// Start a new page if needed
|
||||||
|
document.add(table);
|
||||||
|
table = new PdfPTable(2); // Reset table for new page
|
||||||
|
table.setWidthPercentage(100); // Reset width percentage
|
||||||
|
combinedHeaderAdded = false; // Reset header flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.add(table); // Add the last table before returning
|
||||||
|
|
||||||
|
|
||||||
|
// Check if adding a new row would exceed the maximum height
|
||||||
|
// Return the populated table
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FieldLabelValuePairRequest> getFormFieldsToLabels(FormApplicationResponse responseBean) {
|
||||||
|
List<FieldLabelValuePairRequest> labelValuePairs = new ArrayList<>();
|
||||||
|
|
||||||
|
// Iterate through each form in the application response
|
||||||
|
|
||||||
|
List<ApplicationFormFieldResponseBean> formFields = responseBean.getFormFields();
|
||||||
|
List<ContentResponseBean> contents = responseBean.getContent();
|
||||||
|
|
||||||
|
// Iterate through each formField in the current form
|
||||||
|
for (ApplicationFormFieldResponseBean formField : formFields) {
|
||||||
|
String fieldId = formField.getFieldId();
|
||||||
|
Object fieldValue = formField.getFieldValue();
|
||||||
|
|
||||||
|
// Find the content in the form that matches the fieldId
|
||||||
|
Optional<ContentResponseBean> matchingContent = contents.stream()
|
||||||
|
.filter(content -> content.getId().equals(fieldId))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
|
||||||
|
// If the content with the matching fieldId is found, create a label-value pair
|
||||||
|
if (matchingContent.isPresent()) {
|
||||||
|
String name = matchingContent.get().getName();
|
||||||
|
if (name.equals("fileupload")) {
|
||||||
|
|
||||||
|
// Step 1: Check if fieldValue is an instance of List<DocumentResponseBean>
|
||||||
|
if (fieldValue instanceof List<?> && ((List<?>) fieldValue).stream().allMatch(item -> item instanceof DocumentResponseBean)) {
|
||||||
|
// Step 2: Safely cast to List<DocumentResponseBean>
|
||||||
|
List<DocumentResponseBean> documentList = (List<DocumentResponseBean>) fieldValue;
|
||||||
|
|
||||||
|
// Step 3: Extract names from the document list
|
||||||
|
List<String> names = documentList.stream()
|
||||||
|
.map(DocumentResponseBean::getName) // Extract the name from each DocumentResponseBean
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
fieldValue=names;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(name.equals("checkboxes")) {
|
||||||
|
List<String> check = (List<String>) fieldValue;
|
||||||
|
List<SettingResponseBean> settingResponseBeans = matchingContent.get().getSettings();
|
||||||
|
for (SettingResponseBean settingResponseBean : settingResponseBeans) {
|
||||||
|
// Initialize a list to hold matched labels for each SettingResponseBean
|
||||||
|
List<String> matchedLabels = new ArrayList<>();
|
||||||
|
if (settingResponseBean.getValue() instanceof List<?>) {
|
||||||
|
|
||||||
|
List<?> valueList = (List<?>) settingResponseBean.getValue();
|
||||||
|
if (!valueList.isEmpty() && valueList.get(0) instanceof Map<?, ?>) {
|
||||||
|
// Cast to List<Map<String, String>>
|
||||||
|
List<Map<String, String>> options = (List<Map<String, String>>) valueList;
|
||||||
|
for (Map<String, String> field : options) {
|
||||||
|
for (String val : check) {
|
||||||
|
String name1=field.get("name");
|
||||||
|
if (val.equals(name1)) { // Check if the key exists in the current field map
|
||||||
|
String label = field.get("label"); // Extract the label
|
||||||
|
if (field != null) { // Check if the value is not null
|
||||||
|
matchedLabels.add(label); // Add the value to the matchedValues list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldValue = matchedLabels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String label = matchingContent.get().getLabel();
|
||||||
|
// Add the label-value pair to the list
|
||||||
|
if (fieldValue != null && !fieldValue.toString().trim().isEmpty()) {
|
||||||
|
labelValuePairs.add(new FieldLabelValuePairRequest(label, fieldValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return labelValuePairs;
|
||||||
|
}
|
||||||
|
public void addLogo(Document document, String logoPath) throws Exception {
|
||||||
|
Image logo = Image.getInstance(logoPath);
|
||||||
|
logo.scaleToFit(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin(), // Fit to document width
|
||||||
|
document.getPageSize().getHeight() / 4); // Adjust the height as needed (1/4th of the page height)
|
||||||
|
logo.setAlignment(Image.ALIGN_CENTER); // Align logo to center
|
||||||
|
document.add(logo);
|
||||||
|
|
||||||
|
// Add some space after logo
|
||||||
|
document.add(new Paragraph("\n")); // Adding space after the logo
|
||||||
|
}
|
||||||
|
public void addColoredLines(PdfWriter writer, Document document, BaseColor color){
|
||||||
|
PdfContentByte canvas = writer.getDirectContent();
|
||||||
|
|
||||||
|
// Setting the color and width of the line
|
||||||
|
canvas.setColorStroke(color);
|
||||||
|
float lineWidth = 1.0f; // Thickness of the line
|
||||||
|
canvas.setLineWidth(lineWidth);
|
||||||
|
|
||||||
|
// Get the current vertical position in the document
|
||||||
|
float yPos = writer.getVerticalPosition(true) - 10f; // Adjust this to move line slightly below current content
|
||||||
|
|
||||||
|
// Define start and end points for the line (relative to the page size and margins)
|
||||||
|
float xStart = document.leftMargin(); // Start from the left margin
|
||||||
|
float xEnd = document.getPageSize().getWidth() - document.rightMargin(); // End at the right margin
|
||||||
|
|
||||||
|
// Draw the line at the current Y position
|
||||||
|
canvas.moveTo(xStart, yPos); // Move to the starting point
|
||||||
|
canvas.lineTo(xEnd, yPos); // Draw the line to the end point
|
||||||
|
canvas.stroke(); // Apply the stroke (line)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package net.gepafin.tendermanagement.dao;
|
||||||
|
|
||||||
|
import com.itextpdf.text.BaseColor;
|
||||||
|
import com.itextpdf.text.Rectangle;
|
||||||
|
import com.itextpdf.text.pdf.PdfContentByte;
|
||||||
|
import com.itextpdf.text.pdf.PdfPCell;
|
||||||
|
import com.itextpdf.text.pdf.PdfPCellEvent;
|
||||||
|
import com.itextpdf.text.pdf.PdfPTable;
|
||||||
|
|
||||||
|
public class RoundedCorners implements PdfPCellEvent {
|
||||||
|
@Override
|
||||||
|
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvas) {
|
||||||
|
// Retrieve the canvas for drawing the background and border
|
||||||
|
PdfContentByte cbBackground = canvas[PdfPTable.BACKGROUNDCANVAS];
|
||||||
|
PdfContentByte cb = canvas[PdfPTable.LINECANVAS];
|
||||||
|
|
||||||
|
cbBackground.saveState();
|
||||||
|
cb.saveState();
|
||||||
|
|
||||||
|
// Define the rounded rectangle radius and padding
|
||||||
|
float radius = 10f;
|
||||||
|
float padding = 2f; // Small padding to avoid overlap
|
||||||
|
|
||||||
|
// Get position values with adjusted height and width
|
||||||
|
float x = position.getLeft() + padding;
|
||||||
|
float y = position.getBottom() + padding;
|
||||||
|
float width = position.getWidth() - 2 * padding;
|
||||||
|
float height = position.getHeight() - 2 * padding;
|
||||||
|
|
||||||
|
// Fill the rounded rectangle with lighter grey
|
||||||
|
cbBackground.setColorFill(new BaseColor(239, 243, 248)); // Very light grey color
|
||||||
|
cbBackground.roundRectangle(x, y, width, height, radius);
|
||||||
|
cbBackground.fill(); // Fill the background
|
||||||
|
|
||||||
|
// Set the border stroke to thin and draw the rounded rectangle with dark grey color
|
||||||
|
cb.setLineWidth(0.5f); // Thin border width
|
||||||
|
cb.setColorStroke(new BaseColor(105, 105, 105)); // Dark grey border
|
||||||
|
cb.roundRectangle(x, y, width, height, radius);
|
||||||
|
cb.stroke(); // Draw the border
|
||||||
|
|
||||||
|
// Restore the canvas states
|
||||||
|
cbBackground.restoreState();
|
||||||
|
cb.restoreState();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import com.itextpdf.text.*;
|
||||||
|
import com.itextpdf.text.pdf.ColumnText;
|
||||||
|
import com.itextpdf.text.pdf.PdfContentByte;
|
||||||
|
import com.itextpdf.text.pdf.PdfPageEventHelper;
|
||||||
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
|
|
||||||
|
public class CustomPageEvent extends PdfPageEventHelper {
|
||||||
|
private String title;
|
||||||
|
private int totalPages;
|
||||||
|
|
||||||
|
public CustomPageEvent(String title, int totalPages) {
|
||||||
|
this.title = title;
|
||||||
|
this.totalPages = totalPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEndPage(PdfWriter writer, Document document) {
|
||||||
|
PdfContentByte canvas = writer.getDirectContent();
|
||||||
|
|
||||||
|
// Header - Add a title to each page at the top
|
||||||
|
if (writer.getPageNumber() > 1) {
|
||||||
|
Font headerFont = new Font(Font.FontFamily.HELVETICA, 6, Font.BOLD, new BaseColor(113, 121, 126)); // Gray color for header
|
||||||
|
ColumnText.showTextAligned(
|
||||||
|
canvas,
|
||||||
|
Element.ALIGN_LEFT,
|
||||||
|
new Phrase(title, headerFont),
|
||||||
|
document.leftMargin(), // Use left margin to align fully to the left
|
||||||
|
document.getPageSize().getHeight() - 30, // Positioning header near top
|
||||||
|
0 // No rotation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Footer - Add page number at the bottom
|
||||||
|
String footerText = String.format("Page %d of %d", writer.getPageNumber(), totalPages);
|
||||||
|
|
||||||
|
// Set font for the footer
|
||||||
|
Font footerFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL, BaseColor.BLACK);
|
||||||
|
|
||||||
|
// Positioning footer near bottom
|
||||||
|
ColumnText.showTextAligned(writer.getDirectContent(),
|
||||||
|
Element.ALIGN_LEFT,
|
||||||
|
new Phrase(footerText, footerFont),
|
||||||
|
(document.right() + document.left()) / 2,
|
||||||
|
document.bottomMargin() - 10, // Positioning footer near bottom
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Draw a yellow line below header
|
||||||
|
if (writer.getPageNumber() > 1) {
|
||||||
|
canvas.setLineWidth(1.5f);
|
||||||
|
canvas.setColorStroke(new BaseColor(255, 219, 88)); // Yellow color
|
||||||
|
float yPos = document.getPageSize().getHeight() - 50f; // Position for the line below header
|
||||||
|
canvas.moveTo(0, yPos);
|
||||||
|
canvas.lineTo(document.getPageSize().getWidth(), yPos);
|
||||||
|
canvas.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw another line 50 points above the bottom of the document
|
||||||
|
canvas.setLineWidth(1.5f);
|
||||||
|
canvas.setColorStroke(new BaseColor(255, 219, 88)); // Yellow color
|
||||||
|
float lineYPos = document.bottomMargin() + 25f; // Position for the line above the bottom margin
|
||||||
|
canvas.moveTo(0, lineYPos);
|
||||||
|
canvas.lineTo(document.getPageSize().getWidth(), lineYPos);
|
||||||
|
canvas.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPages(int totalPages) {
|
||||||
|
this.totalPages = totalPages;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FieldLabelValuePairRequest {
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
private Object value;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package net.gepafin.tendermanagement.service;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
|
||||||
|
public interface PdfService {
|
||||||
|
|
||||||
|
public byte[] generatePdf(HttpServletRequest request, Long applicationId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package net.gepafin.tendermanagement.service.impl;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.dao.PdfDao;
|
||||||
|
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||||
|
import net.gepafin.tendermanagement.service.PdfService;
|
||||||
|
import net.gepafin.tendermanagement.util.Validator;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PdfServiceImpl implements PdfService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PdfDao pdfDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Validator validator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] generatePdf(HttpServletRequest request, Long applicationId) {
|
||||||
|
UserEntity userEntity = validator.validateUser(request);
|
||||||
|
return pdfDao.generatePdf(userEntity,applicationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -133,6 +133,23 @@ public interface ApplicationApi {
|
|||||||
ResponseEntity<Response<ApplicationResponse>> updateApplicationStatus(HttpServletRequest request,
|
ResponseEntity<Response<ApplicationResponse>> updateApplicationStatus(HttpServletRequest request,
|
||||||
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId,
|
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId,
|
||||||
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status);
|
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status);
|
||||||
|
|
||||||
|
@Operation(summary = "API to generate PDF for an application",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/pdf")),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
|
||||||
|
})
|
||||||
|
@PostMapping(value = "/{applicationId}/download-pdf",
|
||||||
|
produces = { "application/pdf" })
|
||||||
|
public ResponseEntity<byte[]> generateApplicationPdf(
|
||||||
|
HttpServletRequest request,
|
||||||
|
@Parameter(description = "The application id", required = true)
|
||||||
|
@PathVariable(value = "applicationId", required = true) Long applicationId);
|
||||||
|
|
||||||
@Operation(summary = "Api to upload signed document (only p7m file format is supported)", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
@Operation(summary = "Api to upload signed document (only p7m file format is supported)", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
||||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
@Validated
|
||||||
|
public interface PdfApi {
|
||||||
|
|
||||||
|
@Operation(summary = "API to generate PDF for an application",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/pdf")),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
|
||||||
|
})
|
||||||
|
@PostMapping(value = "/{applicationId}/generate-pdf",
|
||||||
|
produces = { "application/pdf" })
|
||||||
|
public ResponseEntity<byte[]> generateApplicationPdf(
|
||||||
|
HttpServletRequest request,
|
||||||
|
@Parameter(description = "The application id", required = true)
|
||||||
|
@PathVariable(value = "applicationId", required = true) Long applicationId);
|
||||||
|
}
|
||||||
@@ -15,11 +15,14 @@ import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse;
|
|||||||
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
||||||
import net.gepafin.tendermanagement.model.util.Response;
|
import net.gepafin.tendermanagement.model.util.Response;
|
||||||
import net.gepafin.tendermanagement.service.ApplicationService;
|
import net.gepafin.tendermanagement.service.ApplicationService;
|
||||||
|
import net.gepafin.tendermanagement.service.PdfService;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.ApplicationApi;
|
import net.gepafin.tendermanagement.web.rest.api.ApplicationApi;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -38,17 +41,21 @@ public class ApplicationApiController implements ApplicationApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationService applicationService;
|
private ApplicationService applicationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PdfService pdfService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<ApplicationResponseBean>> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId) {
|
public ResponseEntity<Response<ApplicationResponseBean>> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long applicationId, Long formId) {
|
||||||
ApplicationResponseBean applicationResponseBean= applicationService.createApplication(request,applicationRequestBean,applicationId,formId);
|
ApplicationResponseBean applicationResponseBean = applicationService.createApplication(request, applicationRequestBean, applicationId, formId);
|
||||||
return ResponseEntity.status(HttpStatus.CREATED)
|
return ResponseEntity.status(HttpStatus.CREATED)
|
||||||
.body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); }
|
.body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<ApplicationGetResponseBean>> getApplicationByFormId(HttpServletRequest request
|
public ResponseEntity<Response<ApplicationGetResponseBean>> getApplicationByFormId(HttpServletRequest request
|
||||||
, Long applicationId,Long formId) {
|
, Long applicationId, Long formId) {
|
||||||
log.info("Get Application by ID - Application ID: {}", applicationId);
|
log.info("Get Application by ID - Application ID: {}", applicationId);
|
||||||
ApplicationGetResponseBean application = applicationService.getApplicationByFormId(request,applicationId,formId);
|
ApplicationGetResponseBean application = applicationService.getApplicationByFormId(request, applicationId, formId);
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
.body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
@@ -57,41 +64,58 @@ public class ApplicationApiController implements ApplicationApi {
|
|||||||
public ResponseEntity<Response<Void>> deleteApplication(HttpServletRequest request,
|
public ResponseEntity<Response<Void>> deleteApplication(HttpServletRequest request,
|
||||||
Long applicationId) {
|
Long applicationId) {
|
||||||
log.info("Delete Application - Application ID: {}", applicationId);
|
log.info("Delete Application - Application ID: {}", applicationId);
|
||||||
applicationService.deleteApplication(request,applicationId);
|
applicationService.deleteApplication(request, applicationId);
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG)));
|
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<ApplicationResponse>> createApplicationByCallId(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) {
|
public ResponseEntity<Response<ApplicationResponse>> createApplicationByCallId(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) {
|
||||||
ApplicationResponse applicationResponseBean=applicationService.createApplication(request, companyId, applicationRequest, callId);
|
ApplicationResponse applicationResponseBean = applicationService.createApplication(request, companyId, applicationRequest, callId);
|
||||||
return ResponseEntity.status(HttpStatus.CREATED)
|
return ResponseEntity.status(HttpStatus.CREATED)
|
||||||
.body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG)));
|
.body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request,Long callId,Long companyId) {
|
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request, Long callId, Long companyId) {
|
||||||
List<ApplicationResponse> applications = applicationService.getAllApplications(request,callId,companyId);
|
List<ApplicationResponse> applications = applicationService.getAllApplications(request, callId, companyId);
|
||||||
log.info("Get All Applications");
|
log.info("Get All Applications");
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
.body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<NextOrPreviousFormResponse>> getNextOrPreviousForm(HttpServletRequest request,Long applicationId,
|
public ResponseEntity<Response<NextOrPreviousFormResponse>> getNextOrPreviousForm(HttpServletRequest request, Long applicationId,
|
||||||
Long formId, FormActionEnum action) {
|
Long formId, FormActionEnum action) {
|
||||||
NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action);
|
NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action);
|
||||||
log.info("Get Next Or Previous Form ");
|
log.info("Get Next Or Previous Form ");
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
.body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<ApplicationResponse>> updateApplicationStatus(HttpServletRequest request, Long applicationId,
|
public ResponseEntity<Response<ApplicationResponse>> updateApplicationStatus(HttpServletRequest request, Long applicationId,
|
||||||
ApplicationStatusTypeEnum status) {
|
ApplicationStatusTypeEnum status) {
|
||||||
ApplicationResponse applicationResponse = applicationService.updateApplicationStatus(request, applicationId, status);
|
ApplicationResponse applicationResponse = applicationService.updateApplicationStatus(request, applicationId, status);
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
|
.body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<byte[]> generateApplicationPdf(HttpServletRequest request, Long applicationId) {
|
||||||
|
byte[] pdfBytes = pdfService.generatePdf(request, applicationId);
|
||||||
|
|
||||||
|
// Prepare headers for downloading the PDF
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Content-Disposition", "attachment; filename=bando-preview.pdf");
|
||||||
|
|
||||||
|
// Return the PDF as a response
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(headers)
|
||||||
|
.contentType(MediaType.APPLICATION_PDF)
|
||||||
|
.body(pdfBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Response<ApplicationSignedDocumentResponse>> uploadSignedDocument(HttpServletRequest request,
|
public ResponseEntity<Response<ApplicationSignedDocumentResponse>> uploadSignedDocument(HttpServletRequest request,
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api.impl;
|
||||||
|
|
||||||
|
import com.itextpdf.text.*;
|
||||||
|
import com.itextpdf.text.pdf.*;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.dao.RoundedCorners;
|
||||||
|
import net.gepafin.tendermanagement.service.PdfService;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.PdfApi;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class PdfController implements PdfApi {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PdfService pdfService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<byte[]> generateApplicationPdf(HttpServletRequest request, Long applicationId) {
|
||||||
|
byte[] pdfBytes =pdfService.generatePdf(request,applicationId);
|
||||||
|
|
||||||
|
// Prepare headers for downloading the PDF
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Content-Disposition", "attachment; filename=bando-preview.pdf");
|
||||||
|
|
||||||
|
// Return the PDF as a response
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(headers)
|
||||||
|
.contentType(MediaType.APPLICATION_PDF)
|
||||||
|
.body(pdfBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user