Resolved conflicts
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
FROM amazoncorretto:17.0.8-alpine3.17
|
||||
ENV TZ="Europe/Rome"
|
||||
EXPOSE 8080
|
||||
ADD /target/tendermanagement-0.0.1-SNAPSHOT.jar tendermanagement-0.0.1-SNAPSHOT.jar
|
||||
ENTRYPOINT ["java", "-jar","tendermanagement-0.0.1-SNAPSHOT.jar"]
|
||||
|
||||
26
pom.xml
26
pom.xml
@@ -179,12 +179,38 @@
|
||||
<version>5.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mailgun</groupId>
|
||||
<artifactId>mailgun-java</artifactId>
|
||||
<version>1.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.santuario</groupId>
|
||||
<artifactId>xmlsec</artifactId>
|
||||
<version>2.3.0</version> <!-- or latest -->
|
||||
</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>
|
||||
<repositories>
|
||||
|
||||
@@ -199,6 +199,8 @@ public class GepafinConstant {
|
||||
public static final String DELEGATION_NOT_FOUND = "delegation.not.found";
|
||||
public static final String USER_COMPANY_RELATION_NOT_FOUND = "user.company.relation.not.found";
|
||||
public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success";
|
||||
public static final String HH_MM_SS = "HH:mm:ss";
|
||||
|
||||
public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application";
|
||||
public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change";
|
||||
public static final String CALL_DOCUMENTS_FETCH_SUCCESS_MSG = "call.documents.fetch.success";
|
||||
@@ -215,5 +217,11 @@ public class GepafinConstant {
|
||||
public static final String USER_ID_AND_BENEFICIARY_ID_ERROR = "userId.and.beneficiaryId.error";
|
||||
public static final String EITHER_USER_OR_BENEFICIARY_ID_REQUIRED = "either.user.or.beneficiary.id.required";
|
||||
public static final String USER_NOT_FOUND_WITH_BENEFICIARYID_MSG = "User.not.found.with.the.given.beneficiaryID";
|
||||
public static final String PERMISSION_DENIED = "permission.denied";
|
||||
public static final String SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS = "signed.document.file.upload.success";
|
||||
public static final String GET_SIGNED_DOCUMENT_FILE_SUCCESS = "get.signed.document.file.success";
|
||||
public static final String APPLICATION_SIGNED_DOCUMENT_NOT_FOUND = "application.signed.document.not.found";
|
||||
public static final String DELETE_SIGNED_DOCUMENT_FILE_SUCCESS = "delete.signed.document.file.success";
|
||||
public static final String DD_MM_YYYY = "dd/MM/yyyy";
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package net.gepafin.tendermanagement.dao;
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.entities.*;
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum;
|
||||
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
|
||||
@@ -12,24 +14,31 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequest;
|
||||
import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||
import net.gepafin.tendermanagement.model.response.*;
|
||||
import net.gepafin.tendermanagement.repositories.*;
|
||||
import net.gepafin.tendermanagement.service.AmazonS3Service;
|
||||
import net.gepafin.tendermanagement.service.CallService;
|
||||
import net.gepafin.tendermanagement.service.CompanyService;
|
||||
import net.gepafin.tendermanagement.service.DocumentService;
|
||||
import net.gepafin.tendermanagement.service.FormService;
|
||||
import net.gepafin.tendermanagement.service.SystemEmailTemplatesService;
|
||||
import net.gepafin.tendermanagement.util.DateTimeUtil;
|
||||
import net.gepafin.tendermanagement.util.FieldValidator;
|
||||
import net.gepafin.tendermanagement.util.MailUtil;
|
||||
import net.gepafin.tendermanagement.util.Utils;
|
||||
import net.gepafin.tendermanagement.util.Validator;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -71,18 +80,46 @@ public class ApplicationDao {
|
||||
|
||||
@Autowired
|
||||
private FlowDataRepository flowDataRepository;
|
||||
@Autowired
|
||||
private UserWithCompanyRepository userWithCompanyRepository;
|
||||
|
||||
@Autowired
|
||||
private UserCompanyDelegationRepository userCompanyDelegationRepository;
|
||||
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
|
||||
@Autowired
|
||||
private CompanyService companyService;
|
||||
|
||||
@Autowired
|
||||
private ProtocolRepository protocolRepository;
|
||||
|
||||
@Autowired
|
||||
private SystemEmailTemplatesService systemEmailTemplatesService;
|
||||
|
||||
@Autowired
|
||||
private MailUtil mailUtil;
|
||||
|
||||
@Value("${default_System_Receiver_Email}")
|
||||
private String defaultSystemReceiverEmail;
|
||||
|
||||
@Value("${gepafin_email}")
|
||||
private String gepafinEmail;
|
||||
|
||||
@Value("${rinaldo_email}")
|
||||
private String rinaldoEmail;
|
||||
|
||||
@Value("${carlo_email}")
|
||||
private String carloEmail;
|
||||
|
||||
@Autowired
|
||||
private AmazonS3Service amazonS3Service;
|
||||
|
||||
@Autowired
|
||||
private ApplicationSignedDocumentRepository applicationSignedDocumentRepository;
|
||||
|
||||
@Value("${aws.s3.url.folder.signed.document}")
|
||||
private String signedDocumentS3Folder;
|
||||
|
||||
|
||||
public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId, Long applicationId) {
|
||||
FormEntity formEntity = formService.validateForm(formId);
|
||||
@@ -523,21 +560,21 @@ public class ApplicationDao {
|
||||
ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) {
|
||||
CallEntity call = callService.validateCall(callId);
|
||||
// call = callService.validatePublishedCall(call.getId());
|
||||
checkIfApplicationExists(call, companyEntity);
|
||||
checkIfApplicationExists(call, companyEntity, userEntity);
|
||||
ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity);
|
||||
applicationEntity.setComments(applicationRequest.getComments());
|
||||
applicationEntity = saveApplicationEntity(applicationEntity);
|
||||
ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity);
|
||||
return applicationResponse;
|
||||
}
|
||||
public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity){
|
||||
Optional<ApplicationEntity> applicationEntity=applicationRepository.findByCompanyIdAndCallIdAndIsDeletedFalse(companyEntity.getId(),call.getId());
|
||||
public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){
|
||||
Optional<ApplicationEntity> applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId());
|
||||
if(applicationEntity.isPresent()){
|
||||
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS));
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationResponse updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) {
|
||||
public ApplicationResponse updateApplicationStatus(UserEntity userEntity, Long applicationId, ApplicationStatusTypeEnum status) {
|
||||
ApplicationEntity applicationEntity = validateApplication(applicationId);
|
||||
if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) {
|
||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE));
|
||||
@@ -566,11 +603,13 @@ public class ApplicationDao {
|
||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG));
|
||||
}
|
||||
Integer maxProtocolNumber=protocolRepository.findMaxProtocolNumber();
|
||||
Integer protocolNumber = (maxProtocolNumber != null) ? maxProtocolNumber + 1 : 10000;
|
||||
Integer protocolNumber = (maxProtocolNumber != null) ? maxProtocolNumber + 1 : 1;
|
||||
ProtocolEntity protocolEntity=createProtocolEntity(applicationEntity,protocolNumber);
|
||||
applicationEntity.setProtocol(protocolEntity);
|
||||
applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue());
|
||||
applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
|
||||
sendMailToUserAndCompany(userEntity, applicationEntity);
|
||||
sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity);
|
||||
} else {
|
||||
applicationEntity.setStatus(status.getValue());
|
||||
}
|
||||
@@ -663,4 +702,143 @@ public class ApplicationDao {
|
||||
protocolRepository.save(protocolEntity);
|
||||
return protocolEntity;
|
||||
}
|
||||
private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) {
|
||||
CallEntity call =applicationEntity.getCall();
|
||||
CompanyEntity company = applicationEntity.getCompany();
|
||||
ProtocolEntity protocol = applicationEntity.getProtocol();
|
||||
SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService
|
||||
.retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY,
|
||||
call, null);
|
||||
|
||||
// Create the map for subject placeholders
|
||||
Map<String, String> subjectPlaceholders = new HashMap<>();
|
||||
subjectPlaceholders.put("{{call_name}}", call.getName());
|
||||
subjectPlaceholders.put("{{company_name}}", company.getCompanyName());
|
||||
|
||||
// Create the map for body placeholders
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", call.getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY));
|
||||
bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS));
|
||||
|
||||
// Replace placeholders in the subject and body
|
||||
String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders);
|
||||
String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders);
|
||||
|
||||
String email = userEntity.getEmail();
|
||||
if (userEntity.getBeneficiary() != null) {
|
||||
email = userEntity.getBeneficiary().getEmail();
|
||||
}
|
||||
mailUtil.sendByMailGun(subject, body, List.of(email), null);
|
||||
mailUtil.sendByMailGun(subject, body, List.of(applicationEntity.getCompany().getEmail()), null);
|
||||
|
||||
}
|
||||
|
||||
private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) {
|
||||
CallEntity call = applicationEntity.getCall();
|
||||
CompanyEntity company = applicationEntity.getCompany();
|
||||
ProtocolEntity protocol = applicationEntity.getProtocol();
|
||||
SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService
|
||||
.retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN,
|
||||
call, null);
|
||||
|
||||
// Create the map for subject placeholders
|
||||
Map<String, String> subjectPlaceholders = new HashMap<>();
|
||||
subjectPlaceholders.put("{{call_name}}", call.getName());
|
||||
subjectPlaceholders.put("{{company_name}}", company.getCompanyName());
|
||||
|
||||
// Create the map for body placeholders
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", call.getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY));
|
||||
bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS));
|
||||
|
||||
// Replace placeholders in the subject and body
|
||||
String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders);
|
||||
String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders);
|
||||
|
||||
|
||||
mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null);
|
||||
mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null);
|
||||
mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null);
|
||||
mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null);
|
||||
|
||||
}
|
||||
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId,
|
||||
MultipartFile file) {
|
||||
ApplicationEntity applicationEntity = validateApplication(applicationId);
|
||||
validator.validateUserWithCompany(request, applicationEntity.getCompany().getId());
|
||||
validateFileType(file);
|
||||
ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository
|
||||
.findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
|
||||
if (applicationSignedDocument != null) {
|
||||
applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue());
|
||||
applicationSignedDocumentRepository.save(applicationSignedDocument);
|
||||
}
|
||||
UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = amazonS3Service.uploadFileOnAmazonS3(signedDocumentS3Folder,
|
||||
file);
|
||||
applicationSignedDocument = new ApplicationSignedDocumentEntity();
|
||||
applicationSignedDocument.setApplication(applicationEntity);
|
||||
applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName());
|
||||
applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath());
|
||||
applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
|
||||
applicationSignedDocumentRepository.save(applicationSignedDocument);
|
||||
return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument);
|
||||
}
|
||||
|
||||
private ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse(
|
||||
ApplicationSignedDocumentEntity applicationSignedDocument) {
|
||||
ApplicationSignedDocumentResponse applicationSignedDocumentResponse = new ApplicationSignedDocumentResponse();
|
||||
applicationSignedDocumentResponse.setId(applicationSignedDocument.getId());
|
||||
applicationSignedDocumentResponse.setApplicationId(applicationSignedDocument.getApplication().getId());
|
||||
applicationSignedDocumentResponse.setFileName(applicationSignedDocument.getFileName());
|
||||
applicationSignedDocumentResponse.setFilePath(applicationSignedDocument.getFilePath());
|
||||
applicationSignedDocumentResponse
|
||||
.setStatus(ApplicationSignedDocumentStatusEnum.valueOf(applicationSignedDocument.getStatus()));
|
||||
applicationSignedDocumentResponse.setCreatedDate(applicationSignedDocument.getCreatedDate());
|
||||
applicationSignedDocumentResponse.setUpdatedDate(applicationSignedDocument.getUpdatedDate());
|
||||
return applicationSignedDocumentResponse;
|
||||
}
|
||||
|
||||
private void validateFileType(MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
||||
Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY));
|
||||
}
|
||||
String filename = file.getOriginalFilename();
|
||||
if (filename == null || !filename.endsWith(".p7m")) {
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
||||
Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE));
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) {
|
||||
|
||||
ApplicationEntity applicationEntity = validateApplication(applicationId);
|
||||
validator.validateUserWithCompany(request, applicationEntity.getCompany().getId());
|
||||
|
||||
ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository
|
||||
.findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
|
||||
if(applicationSignedDocument == null) {
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND,
|
||||
Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND));
|
||||
}
|
||||
return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument);
|
||||
}
|
||||
|
||||
public void deleteSignedDocument(HttpServletRequest request, Long applicationId) {
|
||||
ApplicationEntity applicationEntity = validateApplication(applicationId);
|
||||
validator.validateUserWithCompany(request, applicationEntity.getCompany().getId());
|
||||
|
||||
ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository
|
||||
.findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
|
||||
if(applicationSignedDocument == null) {
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND,
|
||||
Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND));
|
||||
}
|
||||
applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue());
|
||||
applicationSignedDocumentRepository.save(applicationSignedDocument);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository;
|
||||
import net.gepafin.tendermanagement.service.UserService;
|
||||
import net.gepafin.tendermanagement.util.Utils;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ForbiddenAccessException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
|
||||
@@ -190,8 +191,8 @@ public class CompanyDao {
|
||||
}
|
||||
|
||||
public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) {
|
||||
return userWithCompanyRepository.findByUserIdAndCompanyId(userId, companyId).orElseThrow(() -> new CustomValidationException(Status.UNAUTHORIZED,
|
||||
Translator.toLocale(GepafinConstant.UNAUTHORIZED)));
|
||||
return userWithCompanyRepository.findByUserIdAndCompanyId(userId, companyId).orElseThrow(() -> new ForbiddenAccessException(Status.FORBIDDEN,
|
||||
Translator.toLocale(GepafinConstant.PERMISSION_DENIED)));
|
||||
}
|
||||
|
||||
public UserWithCompanyEntity getUserWithCompany(Long userId, Long compnayId) {
|
||||
|
||||
640
src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java
Normal file
640
src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java
Normal file
@@ -0,0 +1,640 @@
|
||||
package net.gepafin.tendermanagement.dao;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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 jakarta.servlet.http.HttpServletRequest;
|
||||
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.util.Validator;
|
||||
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.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class PdfDao {
|
||||
|
||||
@Autowired
|
||||
private CallService callService;
|
||||
|
||||
@Autowired
|
||||
private ApplicationDao applicationDao;
|
||||
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
|
||||
|
||||
public byte[] generatePdf(HttpServletRequest request,Long applicationId) {
|
||||
try {
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId);
|
||||
validator.validateUserWithCompany(request, applicationEntity.getCompany().getId());
|
||||
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());
|
||||
String protocolNumber="XX00";
|
||||
if(applicationEntity.getProtocol()!=null) {
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
Paragraph appId = new Paragraph("ID domanda :" +protocolNumber);
|
||||
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();
|
||||
// pageEvent.setTotalPages(writer.getPageNumber());
|
||||
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);
|
||||
|
||||
// System.out.println(writer.getPageSize());
|
||||
// System.out.println(document.getPageSize());
|
||||
// System.out.println(document.getPageNumber());
|
||||
// System.out.println(writer.getPageNumber());
|
||||
// document.setPageCount(100);
|
||||
// document.setPageCount(writer.getPageNumber());
|
||||
// System.out.println(document.getPageNumber());
|
||||
|
||||
// Close the document
|
||||
document.close();
|
||||
|
||||
// Convert to byte array for response
|
||||
byte[] pdfBytes =PdfPageNumberInserter.addPageNumbers(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%
|
||||
table.setTableEvent(new RoundedBorderEvent());
|
||||
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
|
||||
float[] columnWidths = {0.7f, 0.3f};
|
||||
table.setWidths(columnWidths);
|
||||
|
||||
|
||||
// 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]; // 1st part (number)
|
||||
String description = combinedValues[1]; // 2nd part (description)
|
||||
String amount = "";
|
||||
if (combinedValues.length == 3) {
|
||||
amount = combinedValues[2]; // 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.setMinimumHeight(20f); // Set minimum height for better appearance
|
||||
cellDescription.setMinimumHeight(20f); // Set minimum height for better appearance
|
||||
cellAmount.setMinimumHeight(20f); // Set minimum height for better appearance
|
||||
|
||||
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));
|
||||
|
||||
cellKey.setPadding(7f);
|
||||
cellValue.setPadding(7f);
|
||||
// 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 static class RoundedBorderEvent implements PdfPTableEvent {
|
||||
@Override
|
||||
public void tableLayout(PdfPTable table, float[][] widths, float[] heights,
|
||||
int headerRows, int rowStart, PdfContentByte[] canvases) {
|
||||
PdfContentByte canvas = canvases[PdfPTable.BASECANVAS];
|
||||
|
||||
// Get the table boundaries
|
||||
float left = widths[0][0];
|
||||
float right = widths[0][widths[0].length - 1];
|
||||
float top = heights[0];
|
||||
float bottom = heights[heights.length - 1];
|
||||
|
||||
// Define the corner radius
|
||||
float radius = 20f;
|
||||
|
||||
// Draw a rounded rectangle around the table
|
||||
canvas.roundRectangle(left, bottom, right - left, top - bottom, radius);
|
||||
canvas.stroke();
|
||||
}
|
||||
}
|
||||
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()) {
|
||||
fieldValue = findLabelInOptions(matchingContent.get().getSettings(), fieldValue);
|
||||
labelValuePairs.add(new FieldLabelValuePairRequest(label, fieldValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return labelValuePairs;
|
||||
}
|
||||
|
||||
public static Object findLabelInOptions(List<SettingResponseBean> settings, Object valueToFind) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
try {
|
||||
if (valueToFind instanceof String) {
|
||||
String searchValue = (String) valueToFind;
|
||||
for (SettingResponseBean setting : settings) {
|
||||
Object value = setting.getValue();
|
||||
if (value instanceof List) {
|
||||
List<?> options = (List<?>) value;
|
||||
for (Object option : options) {
|
||||
JsonNode optionNode = objectMapper.convertValue(option, JsonNode.class);
|
||||
if (optionNode.get("name").asText().equals(searchValue)) {
|
||||
return optionNode.get("label").asText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return valueToFind;
|
||||
}
|
||||
|
||||
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.DocumentException;
|
||||
import com.itextpdf.text.Font;
|
||||
import com.itextpdf.text.FontFactory;
|
||||
import com.itextpdf.text.pdf.BaseFont;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.itextpdf.text.pdf.PdfStamper;
|
||||
import com.itextpdf.text.pdf.PdfContentByte;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PdfPageNumberInserter {
|
||||
|
||||
public static byte[] addPageNumbers(byte[] pdfData) throws IOException, DocumentException {
|
||||
PdfReader reader = new PdfReader(pdfData); // Read the generated PDF
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
BaseColor darkGreenColor = new BaseColor(1, 50, 32); // Adjust RGB values as needed
|
||||
Font baseFont = FontFactory.getFont(FontFactory.HELVETICA, 4,darkGreenColor);
|
||||
BaseFont font = baseFont.getBaseFont();
|
||||
|
||||
// PdfStamper allows us to modify the existing PDF
|
||||
PdfStamper stamper = new PdfStamper(reader, outputStream);
|
||||
int totalPages = reader.getNumberOfPages();
|
||||
|
||||
// Set the font for page numbers
|
||||
|
||||
for (int i = 1; i <= totalPages; i++) {
|
||||
// Get the content of the current page
|
||||
PdfContentByte over = stamper.getOverContent(i);
|
||||
over.beginText();
|
||||
over.setFontAndSize(font, 12);
|
||||
|
||||
// Add the page number at the bottom center of the page
|
||||
over.showTextAligned(PdfContentByte.ALIGN_CENTER, "Page " + i + " of " + totalPages, 300, 30, 0);
|
||||
|
||||
over.endText();
|
||||
}
|
||||
|
||||
stamper.close();
|
||||
reader.close();
|
||||
|
||||
return outputStream.toByteArray(); // Return the modified PDF with page numbers
|
||||
}
|
||||
}
|
||||
@@ -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,116 @@
|
||||
package net.gepafin.tendermanagement.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.CallEntity;
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity;
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
||||
import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse;
|
||||
import net.gepafin.tendermanagement.repositories.SystemEmailTemplatesRespository;
|
||||
import net.gepafin.tendermanagement.util.Utils;
|
||||
|
||||
@Component
|
||||
public class SystemEmailTemplatesDao {
|
||||
|
||||
@Autowired
|
||||
private SystemEmailTemplatesRespository systemEmailTemplatesRespository;
|
||||
|
||||
@Value("${fe.base.url}")
|
||||
private String feBaseUrl;
|
||||
|
||||
|
||||
public SystemEmailTemplateResponse retrieveTemplate(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) {
|
||||
SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity = null;
|
||||
if(call != null){
|
||||
// dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository
|
||||
// .findByTypeAndCallId(type.getValue(), call.getId());
|
||||
}
|
||||
if(dbSystemEmailTemplatesEntity == null){
|
||||
dbSystemEmailTemplatesEntity = systemEmailTemplatesRespository
|
||||
.findByType(type.getValue());
|
||||
}
|
||||
|
||||
SystemEmailTemplateResponse systemEmailTemplateResponse = replaceHtmlContant(dbSystemEmailTemplatesEntity, call, language, Boolean.TRUE);
|
||||
return systemEmailTemplateResponse;
|
||||
}
|
||||
|
||||
private SystemEmailTemplateResponse replaceHtmlContant(SystemEmailTemplatesEntity dbSystemEmailTemplatesEntity,
|
||||
CallEntity call, Locale language1, Boolean isDefaultReplace) {
|
||||
String language = null;
|
||||
String htmlContent = dbSystemEmailTemplatesEntity.getHtmlContent();
|
||||
String subject = dbSystemEmailTemplatesEntity.getSubject();
|
||||
|
||||
if (language1 == null) {
|
||||
// language = getLanguage(LocaleContextHolder.getLocale());
|
||||
language="italian";
|
||||
}else{
|
||||
language="italian";
|
||||
}
|
||||
Map<String, String> languageMap = new HashMap<>();
|
||||
String jsonContent = dbSystemEmailTemplatesEntity.getJson();
|
||||
if (Boolean.FALSE.equals(StringUtils.isEmpty(jsonContent))) {
|
||||
Map<String, Map<String, String>> jsonMap = Utils.parseJsonContent(jsonContent);
|
||||
if (jsonMap != null && jsonMap.containsKey(language)) {
|
||||
languageMap = jsonMap.get(language);
|
||||
htmlContent = replacePlaceholders(htmlContent, languageMap);
|
||||
subject = replaceSubjectPlaceholders(subject, languageMap);
|
||||
|
||||
}
|
||||
}
|
||||
if(Boolean.TRUE.equals(StringUtils.isEmpty(subject))){
|
||||
subject = "";
|
||||
}
|
||||
|
||||
|
||||
htmlContent = replacePlatformLinkPlaceholder(call, htmlContent, languageMap);
|
||||
SystemEmailTemplateResponse systemEmailTemplateResponse = new SystemEmailTemplateResponse();
|
||||
systemEmailTemplateResponse.setHtmlContent(htmlContent);
|
||||
systemEmailTemplateResponse.setSubject(subject);
|
||||
systemEmailTemplateResponse.setJsonMap(languageMap);
|
||||
return systemEmailTemplateResponse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// private String getLanguage(Locale locale) {
|
||||
// return switch (locale.getLanguage()) {
|
||||
// case "en" -> "english";
|
||||
// case "it" -> "italian";
|
||||
// default -> "italian";
|
||||
// };
|
||||
// }
|
||||
|
||||
private String replacePlaceholders(String htmlContent, Map<String, String> languageMap) {
|
||||
for (Map.Entry<String, String> entry : languageMap.entrySet()) {
|
||||
htmlContent = htmlContent.replace("{{" + entry.getKey() + "}}", entry.getValue());
|
||||
}
|
||||
return htmlContent;
|
||||
}
|
||||
|
||||
private String replaceSubjectPlaceholders(String subject, Map<String, String> languageMap) {
|
||||
if(languageMap.containsKey("subject") && subject != null){
|
||||
String value = languageMap.get("subject");
|
||||
subject = subject.replace("{{subject}}", value);
|
||||
return subject;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
private String replacePlatformLinkPlaceholder(CallEntity call, String htmlContent,
|
||||
Map<String, String> languageMap) {
|
||||
String platformLink = feBaseUrl;
|
||||
|
||||
// if(hubEntity != null && Boolean.FALSE.equals(isEmpty(hubEntity.getDomainName()))){
|
||||
// platformLink = hubEntity.getDomainName();
|
||||
// }
|
||||
htmlContent = htmlContent.replace("{{platform_link}}", platformLink);
|
||||
return htmlContent;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.gepafin.tendermanagement.entities;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "application_signed_document")
|
||||
public class ApplicationSignedDocumentEntity extends BaseEntity {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "APPLICATION_ID")
|
||||
private ApplicationEntity application;
|
||||
|
||||
@Column(name = "FILE_NAME")
|
||||
private String fileName;
|
||||
|
||||
@Column(name = "FILE_PATH")
|
||||
private String filePath;
|
||||
|
||||
@Column(name="STATUS")
|
||||
private String status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.gepafin.tendermanagement.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Table(name = "system_email_template")
|
||||
@Data
|
||||
public class SystemEmailTemplatesEntity extends BaseEntity {
|
||||
|
||||
|
||||
@Column(name = "TEMPLATE_NAME")
|
||||
private String templateName;
|
||||
|
||||
@Column(name = "TYPE")
|
||||
private String type;
|
||||
|
||||
@Column(name = "HTML_CONTENT", columnDefinition = "TEXT")
|
||||
private String htmlContent;
|
||||
|
||||
@Column(name = "SUBJECT")
|
||||
private String subject;
|
||||
|
||||
@Column(name = "JSON", columnDefinition = "TEXT")
|
||||
private String json;
|
||||
|
||||
@Column(name = "SYSTEM")
|
||||
private Boolean system;
|
||||
|
||||
@Column(name ="IS_DELETED", nullable = false)
|
||||
private Boolean isDeleted = false;
|
||||
|
||||
public enum SystemEmailTemplatesEntityTypeEnum {
|
||||
|
||||
APPLICATION_SUBMISSION_TO_USER_AND_COMPANY("APPLICATION_SUBMISSION_TO_USER_AND_COMPANY"),
|
||||
APPLICATION_SUBMISSION_TO_GEPAFIN("APPLICATION_SUBMISSION_TO_GEPAFIN");
|
||||
|
||||
private String value;
|
||||
|
||||
SystemEmailTemplatesEntityTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.gepafin.tendermanagement.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum ApplicationSignedDocumentStatusEnum {
|
||||
ACTIVE("ACTIVE"), INACTIVE("INACTIVE");
|
||||
|
||||
private String value;
|
||||
|
||||
ApplicationSignedDocumentStatusEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -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,14 @@
|
||||
package net.gepafin.tendermanagement.model.response;
|
||||
|
||||
import lombok.Data;
|
||||
import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.BaseBean;
|
||||
|
||||
@Data
|
||||
public class ApplicationSignedDocumentResponse extends BaseBean{
|
||||
|
||||
private Long applicationId;
|
||||
private String fileName;
|
||||
private String filePath;
|
||||
private ApplicationSignedDocumentStatusEnum status;
|
||||
}
|
||||
@@ -3,9 +3,10 @@ package net.gepafin.tendermanagement.model.response;
|
||||
import lombok.Data;
|
||||
import net.gepafin.tendermanagement.entities.BaseEntity;
|
||||
import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.BaseBean;
|
||||
|
||||
@Data
|
||||
public class CompanyDelegationResponse extends BaseEntity{
|
||||
public class CompanyDelegationResponse extends BaseBean{
|
||||
private Long userId;
|
||||
private Long companyId;
|
||||
private Long beneficiaryId;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.gepafin.tendermanagement.model.response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SystemEmailTemplateResponse {
|
||||
|
||||
String htmlContent;
|
||||
|
||||
String subject;
|
||||
|
||||
Map<String, String> jsonMap;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.gepafin.tendermanagement.model.response;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class UploadFileOnAmazonS3Response {
|
||||
|
||||
private String fileName;
|
||||
|
||||
private String filePath;
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.gepafin.tendermanagement.repositories;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.ApplicationEntity;
|
||||
import net.gepafin.tendermanagement.entities.FaqEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
@@ -25,7 +24,7 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
|
||||
|
||||
public Optional<ApplicationEntity> findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId);
|
||||
|
||||
Optional<ApplicationEntity> findByCompanyIdAndCallIdAndIsDeletedFalse(Long companyId, Long callId);
|
||||
Optional<ApplicationEntity> findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long companyId, Long callId);
|
||||
|
||||
public Optional<ApplicationEntity> findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId,
|
||||
Long callId);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.gepafin.tendermanagement.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.ApplicationSignedDocumentEntity;
|
||||
|
||||
@Repository
|
||||
public interface ApplicationSignedDocumentRepository extends JpaRepository<ApplicationSignedDocumentEntity, Long> {
|
||||
|
||||
ApplicationSignedDocumentEntity findByApplicationIdAndStatus(Long applicationId, String status);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.gepafin.tendermanagement.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity;
|
||||
|
||||
public interface SystemEmailTemplatesRespository extends JpaRepository<SystemEmailTemplatesEntity, Long> {
|
||||
|
||||
// @Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.call.id=:callId and s.isDeleted =false and s.system = false")
|
||||
// SystemEmailTemplatesEntity findByTypeAndCallId(@Param("type") String type, @Param("callId") Long callId);
|
||||
|
||||
@Query("select s from SystemEmailTemplatesEntity s where s.type=:type and s.isDeleted =false and s.system = true")
|
||||
SystemEmailTemplatesEntity findByType(@Param("type") String type);
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package net.gepafin.tendermanagement.service;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -14,4 +16,6 @@ public interface AmazonS3Service {
|
||||
public Boolean delete(String s3Folder, String fileName);
|
||||
|
||||
InputStream getFile(String s3Folder, String filePath) throws IOException;
|
||||
|
||||
public UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file);
|
||||
}
|
||||
@@ -9,10 +9,13 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface ApplicationService {
|
||||
|
||||
public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId);
|
||||
@@ -31,4 +34,10 @@ public interface ApplicationService {
|
||||
|
||||
public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status);
|
||||
|
||||
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file);
|
||||
|
||||
public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId);
|
||||
|
||||
public void deleteSignedDocument(HttpServletRequest request, Long applicationId);
|
||||
|
||||
}
|
||||
|
||||
@@ -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,13 @@
|
||||
package net.gepafin.tendermanagement.service;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.CallEntity;
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
||||
import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse;
|
||||
|
||||
public interface SystemEmailTemplatesService {
|
||||
|
||||
SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language);
|
||||
|
||||
}
|
||||
@@ -2,7 +2,16 @@ package net.gepafin.tendermanagement.service.impl;
|
||||
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.model.*;
|
||||
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response;
|
||||
import net.gepafin.tendermanagement.service.AmazonS3Service;
|
||||
import net.gepafin.tendermanagement.util.Utils;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.env.Environment;
|
||||
@@ -86,4 +95,20 @@ public class AmazonS3ServiceImpl implements AmazonS3Service {
|
||||
throw new IOException("Error getting file from Amazon S3", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file) {
|
||||
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||
String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename());
|
||||
String firstNameContain = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
firstNameContain+=Utils.randomKey(5);
|
||||
fileName = (firstNameContain + "." + extension);
|
||||
try {
|
||||
String filepath = upload(fileName, s3Folder, file);
|
||||
return UploadFileOnAmazonS3Response.builder().fileName(fileName).filePath(filepath).build();
|
||||
} catch (Exception e) {
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
||||
Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,14 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
||||
import net.gepafin.tendermanagement.service.ApplicationService;
|
||||
import net.gepafin.tendermanagement.util.Validator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -64,7 +66,7 @@ public class ApplicationServiceImpl implements ApplicationService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ApplicationResponse createApplication(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) {
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
CompanyEntity companyEntity = validator.validateUSerWithCompany(request, companyId);
|
||||
CompanyEntity companyEntity = validator.validateUserWithCompany(request, companyId);
|
||||
return applicationDao.createApplicationByCallId(companyEntity, applicationRequest, callId, userEntity);
|
||||
}
|
||||
|
||||
@@ -78,7 +80,8 @@ public class ApplicationServiceImpl implements ApplicationService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) {
|
||||
return applicationDao.updateApplicationStatus(applicationId, status);
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
return applicationDao.updateApplicationStatus(userEntity, applicationId, status);
|
||||
|
||||
}
|
||||
|
||||
@@ -87,8 +90,26 @@ public class ApplicationServiceImpl implements ApplicationService {
|
||||
public List<ApplicationResponse> getAllApplications(HttpServletRequest request, Long callId, Long companyId) {
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
if (companyId != null) {
|
||||
validator.validateUSerWithCompany(request, companyId);
|
||||
validator.validateUserWithCompany(request, companyId);
|
||||
}
|
||||
return applicationDao.getAllApplications(userEntity, callId, companyId);
|
||||
}
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) {
|
||||
return applicationDao.uploadSignedDocument(request, applicationId, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) {
|
||||
return applicationDao.getSignedDocument(request, applicationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteSignedDocument(HttpServletRequest request, Long applicationId) {
|
||||
applicationDao.deleteSignedDocument(request, applicationId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ public class CompanyServiceImpl implements CompanyService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file) {
|
||||
UserEntity userEntity =validator.validateUser(request);
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
validator.validateUserWithCompany(request, companyId);
|
||||
return delegationDao.uploadCompanyDelegation(userEntity, companyId, file);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
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) {
|
||||
return pdfDao.generatePdf(request, applicationId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.gepafin.tendermanagement.service.impl;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import net.gepafin.tendermanagement.dao.SystemEmailTemplatesDao;
|
||||
import net.gepafin.tendermanagement.entities.CallEntity;
|
||||
import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
|
||||
import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse;
|
||||
import net.gepafin.tendermanagement.service.SystemEmailTemplatesService;
|
||||
|
||||
@Service
|
||||
public class SystemEmailTemplatesServiceImpl implements SystemEmailTemplatesService {
|
||||
|
||||
@Autowired
|
||||
private SystemEmailTemplatesDao systemEmailTemplatesDao;
|
||||
|
||||
|
||||
@Override
|
||||
public SystemEmailTemplateResponse retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum type, CallEntity call, Locale language) {
|
||||
return systemEmailTemplatesDao.retrieveTemplate(type, call, language);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class DateTimeUtil {
|
||||
public static LocalDateTime DateServerToUTC(LocalDateTime systemDate) {
|
||||
|
||||
ZonedDateTime ldtZoned = systemDate.atZone(ZoneId.systemDefault());
|
||||
LocalDateTime localDatetime = ldtZoned.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
|
||||
LocalDateTime localDatetime = ldtZoned.withZoneSameInstant(ZoneId.of("Europe/Rome")).toLocalDateTime();
|
||||
return localDatetime;
|
||||
}
|
||||
|
||||
@@ -92,4 +92,20 @@ public class DateTimeUtil {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return LocalDateTime.parse(dateTimeStr, formatter);
|
||||
}
|
||||
|
||||
public static String parseLocalTimeToString(LocalTime time, String format) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
||||
return time.format(formatter);
|
||||
}
|
||||
|
||||
// Method 2: Convert String and format to LocalTime
|
||||
public static LocalTime parseStringToLocalTime(String timeString, String format) {
|
||||
try {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
||||
return LocalTime.parse(timeString, formatter);
|
||||
} catch (DateTimeParseException e) {
|
||||
System.out.println("Invalid time format: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.gepafin.tendermanagement.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.mailgun.api.v3.MailgunMessagesApi;
|
||||
import com.mailgun.client.MailgunClient;
|
||||
|
||||
@Component
|
||||
public class MailUtil {
|
||||
|
||||
@Value("${apiKey}")
|
||||
private String apiKeyValue;
|
||||
|
||||
@Value("${mailGun_user}")
|
||||
private String mailGunUser;
|
||||
|
||||
@Value("${mailGun_apiKey}")
|
||||
private String mailGunApiKey;
|
||||
|
||||
@Value("${mailGun_domainName}")
|
||||
private String mailGunDomainName;
|
||||
|
||||
@Value("${mailGun_base_url}")
|
||||
private String mailGunBaseUrl;
|
||||
|
||||
@Value("${isMailSendingEnabled}")
|
||||
private String isEmailSendingEnabled;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
public Boolean isTestProfileActivated() {
|
||||
String[] activeProfiles = environment.getActiveProfiles();
|
||||
return Arrays.stream(activeProfiles).anyMatch("test"::equals);
|
||||
}
|
||||
|
||||
public void sendMailByMailGunAPI(List<String> recipents, List<String> CC, List<String> BCC, String subject,
|
||||
String body, String replyTo) {
|
||||
if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) {
|
||||
return;
|
||||
}
|
||||
|
||||
MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey)
|
||||
.createApi(MailgunMessagesApi.class);
|
||||
|
||||
String mailFrom = mailGunUser;
|
||||
|
||||
com.mailgun.model.message.Message.MessageBuilder temp = com.mailgun.model.message.Message.builder()
|
||||
.replyTo(replyTo).from(mailFrom).to(recipents).subject(subject).html(body);
|
||||
|
||||
if (Boolean.FALSE.equals(CollectionUtils.isEmpty(CC))) {
|
||||
temp.cc(CC);
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(CollectionUtils.isEmpty(BCC))) {
|
||||
temp.bcc(BCC);
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(isTestProfileActivated())) {
|
||||
com.mailgun.model.message.Message message = temp.build();
|
||||
mailgunMessagesApi.sendMessage(mailGunDomainName, message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sendByMailGun(String subject, String body, List<String> receiverEmails, String replyTo) {
|
||||
sendMailByMailGunAPI(receiverEmails, null, null, subject, body, replyTo);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
@@ -276,4 +277,30 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Map<String, String>> parseJsonContent(String jsonContent) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
return mapper.readValue(jsonContent, HashMap.class);
|
||||
} catch (Exception exception) {
|
||||
log.error(exception.getMessage());
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
// Utility method to replace placeholders with their values, handling nulls
|
||||
public static String replacePlaceholders(String text, Map<String, String> placeholders) {
|
||||
if (text == null) {
|
||||
return "";
|
||||
}
|
||||
for (Map.Entry<String, String> entry : placeholders.entrySet()) {
|
||||
text = replaceNull(text, entry.getKey(), entry.getValue());
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// Method to safely replace nulls with an empty string or a default value
|
||||
private static String replaceNull(String text, String target, String replacement) {
|
||||
return text.replace(target, replacement != null ? replacement : "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
|
||||
import net.gepafin.tendermanagement.service.CompanyService;
|
||||
import net.gepafin.tendermanagement.service.UserService;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ForbiddenAccessException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException;
|
||||
|
||||
@@ -60,7 +61,7 @@ public class Validator {
|
||||
}
|
||||
}
|
||||
|
||||
public CompanyEntity validateUSerWithCompany(HttpServletRequest request, Long companyId) {
|
||||
public CompanyEntity validateUserWithCompany(HttpServletRequest request, Long companyId) {
|
||||
if (checkIsSuperAdmin()) {
|
||||
return companyService.validateCompany(companyId);
|
||||
}
|
||||
@@ -89,7 +90,7 @@ public class Validator {
|
||||
public UserEntity validateUserId(HttpServletRequest request, Long userId) {
|
||||
UserEntity user = validateUser(request);
|
||||
if(user.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue()) && Boolean.FALSE.equals(user.getId().equals(userId))) {
|
||||
throw new UnauthorizedAccessException(Status.UNAUTHORIZED, Translator.toLocale(GepafinConstant.INVALID_REQUEST));
|
||||
throw new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
|
||||
}
|
||||
return userService.validateUser(userId);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -21,6 +22,8 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse;
|
||||
import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
||||
import net.gepafin.tendermanagement.model.util.Response;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
|
||||
@@ -131,6 +134,58 @@ public interface ApplicationApi {
|
||||
@Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId,
|
||||
@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"),
|
||||
@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}/signedDocument/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
ResponseEntity<Response<ApplicationSignedDocumentResponse>> uploadSignedDocument(HttpServletRequest request,
|
||||
@Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId,
|
||||
@Parameter(description = "The signed document", required = true) @RequestParam("file") MultipartFile file);
|
||||
|
||||
|
||||
@Operation(summary = "Api to get signed document", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
||||
@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) })) })
|
||||
@GetMapping(value = "{applicationId}/signedDocument", produces = "application/json")
|
||||
ResponseEntity<Response<ApplicationSignedDocumentResponse>> getSignedDocument(HttpServletRequest request,
|
||||
@Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId);
|
||||
|
||||
@Operation(summary = "Api to delete signed document", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
||||
@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) })) })
|
||||
@DeleteMapping(value = "{applicationId}/signedDocument", produces = "application/json")
|
||||
ResponseEntity<Response<Void>> deleteSignedDocument(HttpServletRequest request,
|
||||
@Parameter(description = "The applicationId id", required = true) @PathVariable("applicationId") Long applicationId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -10,17 +10,22 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.ApplicationSignedDocumentResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse;
|
||||
import net.gepafin.tendermanagement.model.util.Response;
|
||||
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.errors.Status;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
@@ -35,17 +40,21 @@ public class ApplicationApiController implements ApplicationApi {
|
||||
@Autowired
|
||||
private ApplicationService applicationService;
|
||||
|
||||
@Autowired
|
||||
private PdfService pdfService;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<ApplicationResponseBean>> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean,Long applicationId, Long formId) {
|
||||
ApplicationResponseBean applicationResponseBean= applicationService.createApplication(request,applicationRequestBean,applicationId,formId);
|
||||
public ResponseEntity<Response<ApplicationResponseBean>> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long applicationId, Long formId) {
|
||||
ApplicationResponseBean applicationResponseBean = applicationService.createApplication(request, applicationRequestBean, applicationId, formId);
|
||||
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
|
||||
public ResponseEntity<Response<ApplicationGetResponseBean>> getApplicationByFormId(HttpServletRequest request
|
||||
, Long applicationId,Long formId) {
|
||||
, Long applicationId, Long formId) {
|
||||
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)
|
||||
.body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
||||
}
|
||||
@@ -54,27 +63,28 @@ public class ApplicationApiController implements ApplicationApi {
|
||||
public ResponseEntity<Response<Void>> deleteApplication(HttpServletRequest request,
|
||||
Long applicationId) {
|
||||
log.info("Delete Application - Application ID: {}", applicationId);
|
||||
applicationService.deleteApplication(request,applicationId);
|
||||
applicationService.deleteApplication(request, applicationId);
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG)));
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
.body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request,Long callId,Long companyId) {
|
||||
List<ApplicationResponse> applications = applicationService.getAllApplications(request,callId,companyId);
|
||||
public ResponseEntity<Response<List<ApplicationResponse>>> getAllApplications(HttpServletRequest request, Long callId, Long companyId) {
|
||||
List<ApplicationResponse> applications = applicationService.getAllApplications(request, callId, companyId);
|
||||
log.info("Get All Applications");
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<NextOrPreviousFormResponse>> getNextOrPreviousForm(HttpServletRequest request,Long applicationId,
|
||||
public ResponseEntity<Response<NextOrPreviousFormResponse>> getNextOrPreviousForm(HttpServletRequest request, Long applicationId,
|
||||
Long formId, FormActionEnum action) {
|
||||
NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action);
|
||||
log.info("Get Next Or Previous Form ");
|
||||
@@ -89,4 +99,47 @@ public class ApplicationApiController implements ApplicationApi {
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.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
|
||||
public ResponseEntity<Response<ApplicationSignedDocumentResponse>> uploadSignedDocument(HttpServletRequest request,
|
||||
Long applicationId, MultipartFile file) {
|
||||
log.info("upload signed document applicationId: {}", applicationId);
|
||||
ApplicationSignedDocumentResponse response = applicationService.uploadSignedDocument(request, applicationId, file);
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<ApplicationSignedDocumentResponse>> getSignedDocument(HttpServletRequest request,
|
||||
Long applicationId) {
|
||||
ApplicationSignedDocumentResponse response = applicationService.getSignedDocument(request, applicationId);
|
||||
log.info("get signed document applicationId: {}", applicationId);
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_SIGNED_DOCUMENT_FILE_SUCCESS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<Void>> deleteSignedDocument(HttpServletRequest request,
|
||||
Long applicationId) {
|
||||
applicationService.deleteSignedDocument(request, applicationId);
|
||||
log.info("delete signed document applicationId: {}", applicationId);
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_SIGNED_DOCUMENT_FILE_SUCCESS)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
||||
spring.h2.console.enabled=true
|
||||
|
||||
isVatCheckGloballyDisabled = false
|
||||
isMailSendingEnabled = true
|
||||
|
||||
@@ -6,11 +6,12 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
||||
|
||||
# JPA Configuration
|
||||
spring.h2.console.enabled=true
|
||||
base-url=http://bandi-api.gepafin.it
|
||||
base-url=https://bandi-api.gepafin.it
|
||||
|
||||
isVatCheckGloballyDisabled = false
|
||||
#fe.base.url=http://gepafin-production-fe.s3-website.eu-central-1.amazonaws.com
|
||||
fe.base.url=http://bandi.gepafin.it
|
||||
fe.base.url=https://bandi.gepafin.it
|
||||
#SPID configuration
|
||||
spid.ipd.base.url=https://login.regione.umbria.it
|
||||
active.profile.folder=production
|
||||
isMailSendingEnabled = true
|
||||
|
||||
@@ -32,6 +32,7 @@ aws.s3.bucket.name=mementoresources
|
||||
aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/
|
||||
aws.s3.url.folder=gepafin
|
||||
aws.s3.url.folder.delegation=gepafin/delegation
|
||||
aws.s3.url.folder.signed.document=gepafin/signed-document
|
||||
# JWT configuration
|
||||
# Ensure these values match your expectations
|
||||
security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key
|
||||
@@ -50,3 +51,17 @@ vatCheckNewToken: 66026bd891a51044e90e08c4
|
||||
spid.ipd.base.url=https://federatest.umbriadigitale.it
|
||||
active.profile.folder=dev
|
||||
|
||||
# MailGun API Key
|
||||
mailGun_apiKey= 398e3dea1911fe941af261906ec99362-07e2c238-8094421f
|
||||
mailGun_user=comunicazione@paghiamoci.ai
|
||||
mailGun_domainName=paghiamoci.ai
|
||||
mailGun_base_url=https://api.eu.mailgun.net/
|
||||
# SendinBlue API key
|
||||
apiKey=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
|
||||
#senderEmail=mailer@bflows.net
|
||||
isMailSendingEnabled = false
|
||||
default_System_Receiver_Email=antonio.manca@bflows.net
|
||||
gepafin_email=bandi@pec.gepafin.it
|
||||
rinaldo_email=rinaldo.bonazzo@bflows.net
|
||||
carlo_email=carlo.mancosu@bflows.net
|
||||
|
||||
|
||||
@@ -993,4 +993,63 @@
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="10-10-2024_1" author="Rajesh Khore">
|
||||
<createTable tableName="system_email_template">
|
||||
<column name="id" type="INTEGER" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"
|
||||
primaryKeyName="system_email_template_pkey" />
|
||||
</column>
|
||||
<column name="TEMPLATE_NAME" type="VARCHAR(255)"/>
|
||||
<column name="TYPE" type="VARCHAR(255)"/>
|
||||
<column name="HTML_CONTENT" type="TEXT"/>
|
||||
<column name="SUBJECT" type="TEXT"/>
|
||||
<column name="JSON" type="TEXT"/>
|
||||
<column name="SYSTEM" type="BOOLEAN"/>
|
||||
<column name="IS_DELETED" type="BOOLEAN" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="10-10-2024_2" author="Rajesh Khore">
|
||||
<sqlFile dbms="postgresql"
|
||||
path="db/dump/insert_system_email_template_for_application_submission.sql" />
|
||||
</changeSet>
|
||||
<changeSet id="12-10-2024_1" author="Rajesh Khore">
|
||||
|
||||
<createTable tableName="application_signed_document">
|
||||
<column name="id" type="INTEGER" autoIncrement="true">
|
||||
<constraints primaryKey="true" primaryKeyName="application_signed_document_pkey" nullable="false"/>
|
||||
</column>
|
||||
<column name="APPLICATION_ID" type="INTEGER">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="FILE_NAME" type="VARCHAR(255)"/>
|
||||
<column name="FILE_PATH" type="VARCHAR(255)"/>
|
||||
<column name="STATUS" type="VARCHAR(64)"/>
|
||||
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="application_signed_document"
|
||||
baseColumnNames="APPLICATION_ID"
|
||||
referencedTableName="application"
|
||||
referencedColumnNames="ID"
|
||||
constraintName="fk_application_signed_document_application"/>
|
||||
|
||||
</changeSet>
|
||||
<changeSet id="13-10-2024_1" author="Rajesh Khore">
|
||||
<update tableName="form_field">
|
||||
<column name="validators" value='{"custom": "nonEmptyTables"}' />
|
||||
<where>name='table'</where>
|
||||
</update>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="14-10-2024_1" author="Harish Bagora">
|
||||
<sqlFile dbms="postgresql"
|
||||
path="db/dump/update_system_email_template_of_application_submission.sql" />
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(1, 'Application submission template to beneficiary and company', 'APPLICATION_SUBMISSION_TO_USER_AND_COMPANY', '<html>
|
||||
<body style="font-family: Arial, sans-serif; color: #333; line-height: 1.6;">
|
||||
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
|
||||
<p>Buongiorno,</p>
|
||||
<p>
|
||||
Si comunica che, in riferimento alla domanda di concessione di
|
||||
Finanziamento agevolato a valere sul Fondo prestiti
|
||||
<strong>{{call_name}}</strong> di cui all''oggetto, la stessa è stata
|
||||
regolarmente acquisita ed è stata registrata con Protocollo n.
|
||||
<strong>{{protocol_number}}</strong> del <strong>{{date}}</strong> alle
|
||||
<strong>{{time}}</strong>.
|
||||
</p>
|
||||
<p>Distinti Saluti,</p>
|
||||
<p>
|
||||
<strong>Gepafin S.p.a.</strong>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:23.037');
|
||||
INSERT INTO gepafin_schema.system_email_template (id, template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date) VALUES(2, 'Application submission template to gepafin', 'APPLICATION_SUBMISSION_TO_GEPAFIN', '<html>
|
||||
<body style="font-family: Arial, sans-serif; color: #333; line-height: 1.6;">
|
||||
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
|
||||
<p>
|
||||
In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti
|
||||
<strong>{{call_name}}</strong> di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata
|
||||
registrata con Protocollo n. <strong>{{protocol_number}}</strong> del <strong>{{date}}</strong> e <strong>{{time}}</strong>.
|
||||
</p>
|
||||
<p>Distinti Saluti,</p>
|
||||
<p>
|
||||
<strong>Gepafin S.p.a.</strong>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>', 'BANDO {{call_name}} - Domanda di concessione di finanziamento agevolato {{company_name}}', NULL, true, false, '2024-10-10 16:10:31.035', '2024-10-11 10:09:57.224');
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
UPDATE gepafin_schema.system_email_template
|
||||
SET html_content = '<html>
|
||||
<body style="font-family: Arial, sans-serif; color: #333; line-height: 1.6;">
|
||||
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px; max-width: 600px; margin: auto;">
|
||||
<p>
|
||||
In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti
|
||||
<strong>{{call_name}}</strong> di cui all’oggetto, la stessa è stata regolarmente acquisita ed è stata
|
||||
registrata con Protocollo n. <strong>{{protocol_number}}</strong> del <strong>{{date}}</strong> alle <strong>{{time}}</strong>.
|
||||
</p>
|
||||
<p>Distinti Saluti,</p>
|
||||
<p>
|
||||
<strong>Gepafin S.p.a.</strong>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>',
|
||||
updated_date = '2024-10-14 10:00:00'
|
||||
WHERE type = 'APPLICATION_SUBMISSION_TO_GEPAFIN';
|
||||
@@ -241,4 +241,10 @@ beneficiary.preferred.call.not.found=Beneficiary preferred call not found.
|
||||
either.user.or.beneficiary.id.required = User ID or Beneficiary ID not present.
|
||||
userId.and.beneficiaryId.error = Both userId and beneficiaryId cannot be provided at the same time.
|
||||
User.not.found.with.the.given.beneficiaryID=User not found with the given beneficiary ID.
|
||||
permission.denied=You are not authorized to access this data.
|
||||
signed.document.file.upload.success=Signed document file uploaded successfully.
|
||||
get.signed.document.file.success=Signed document file retrieved successfully.
|
||||
application.signed.document.not.found=Signed document for the application not found.
|
||||
delete.signed.document.file.success=Signed document deleted successfully.
|
||||
|
||||
|
||||
|
||||
@@ -220,13 +220,13 @@ delegation.not.found=Delega non trovata.
|
||||
user.company.relation.not.found=Relazione utente con l'azienda specificata non trovata.
|
||||
delegation.delete.success=Delega eliminata con successo.
|
||||
user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega.
|
||||
application.submitted.cannot.change=La domanda inviata non può essere modificata.
|
||||
application.submitted.cannot.change=La domanda inviata non pu<EFBFBD> essere modificata.
|
||||
|
||||
# Call Document Messages
|
||||
call.documents.fetch.success=Documenti recuperati con successo.
|
||||
call.documents.not.found=Nessun documento trovato per la chiamata specificata.
|
||||
# Beneficiary Preferred Call messages
|
||||
beneficiary.preferred.call.status.updated.success=Lo stato della chiamata preferita del beneficiario è stato aggiornato con successo.
|
||||
beneficiary.preferred.call.status.updated.success=Lo stato della chiamata preferita del beneficiario <EFBFBD> stato aggiornato con successo.
|
||||
beneficiary.preferred.calls.get.all.success=Tutte le chiamate preferite del beneficiario sono state recuperate con successo.
|
||||
beneficiary.preferred.call.created.success=Chiamata preferita del beneficiario creata con successo.
|
||||
beneficiary.preferred.call.get.success=Chiamata preferita del beneficiario recuperata con successo.
|
||||
@@ -235,5 +235,12 @@ beneficiary.preferred.calls.get.success=Tutte le chiamate preferite del benefici
|
||||
beneficiary.preferred.call.updated.success=Chiamata preferita del beneficiario aggiornata con successo.
|
||||
beneficiary.preferred.call.not.found=Chiamata preferita del beneficiario non trovata.
|
||||
either.user.or.beneficiary.id.required = ID utente o ID beneficiario non presente.
|
||||
userId.and.beneficiaryId.error = Non è possibile fornire contemporaneamente sia userId che beneficiaryId.
|
||||
userId.and.beneficiaryId.error = Non <EFBFBD> possibile fornire contemporaneamente sia userId che beneficiaryId.
|
||||
User.not.found.with.the.given.beneficiaryID=Utente non trovato con l'ID beneficiario fornito.
|
||||
permission.denied=Non sei autorizzato ad accedere a questi dati.
|
||||
signed.document.file.upload.success=File del documento firmato caricato con successo.
|
||||
get.signed.document.file.success=File del documento firmato recuperato con successo.
|
||||
application.signed.document.not.found=Documento firmato per l'applicazione non trovato.
|
||||
delete.signed.document.file.success=Documento firmato eliminato con successo.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user