diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index ee165f63..080ed3d1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -35,6 +35,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; @@ -578,54 +579,57 @@ public class ApplicationAmendmentRequestDao { private Map getApplicationFormFieldEntityMap( ApplicationAmendmentRequestEntity entity, List amendmentFormFields) { - List fieldIds = amendmentFormFields.stream() - .map(AmendmentFormField::getFieldId) - .toList(); - return getApplicationFormFieldList(entity, fieldIds).stream() - .collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); + if(amendmentFormFields!=null) { + List fieldIds = amendmentFormFields.stream() + .map(AmendmentFormField::getFieldId) + .toList(); + return getApplicationFormFieldList(entity, fieldIds).stream() + .collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); + } + return null; } private void processFormFields(List amendmentFormFields, Map fieldIdToLabelMap, Map formFieldEntityMap, ApplicationAmendmentRequestResponse response) { List formFields = new ArrayList<>(); List fileDetails = new ArrayList<>(); + if (amendmentFormFields != null){ + for (AmendmentFormField amendmentFormField : amendmentFormFields) { + // Create form field response + createFormField(formFields, fieldIdToLabelMap, amendmentFormField); - for (AmendmentFormField amendmentFormField : amendmentFormFields) { - // Create form field response - createFormField(formFields, fieldIdToLabelMap, amendmentFormField); + // Create document responses + List documentIds = extractIds(amendmentFormField.getFieldValue()); + List documentResponseBeans = documentIds.stream() + .map(id -> { + DocumentEntity documentEntity = documentService.validateDocument(id); + DocumentResponseBean responseBean = new DocumentResponseBean(); + responseBean.setId(documentEntity.getId()); + responseBean.setName(documentEntity.getFileName()); + responseBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType())); + responseBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource())); + responseBean.setSourceId(documentEntity.getSourceId()); + responseBean.setFilePath(documentEntity.getFilePath()); + responseBean.setCreatedDate(documentEntity.getCreatedDate()); + responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); + responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId()); + return responseBean; + }) + .toList(); - // Create document responses - List documentIds = extractIds(amendmentFormField.getFieldValue()); - List documentResponseBeans = documentIds.stream() - .map(id -> { - DocumentEntity documentEntity = documentService.validateDocument(id); - DocumentResponseBean responseBean = new DocumentResponseBean(); - responseBean.setId(documentEntity.getId()); - responseBean.setName(documentEntity.getFileName()); - responseBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType())); - responseBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource())); - responseBean.setSourceId(documentEntity.getSourceId()); - responseBean.setFilePath(documentEntity.getFilePath()); - responseBean.setCreatedDate(documentEntity.getCreatedDate()); - responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); - responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId()); - return responseBean; - }) - .toList(); - - // Map to application form field response bean - ApplicationFormFieldEntity formFieldEntity = formFieldEntityMap.get(amendmentFormField.getFieldId()); - ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean(); - responseBean.setApplicationFormId(formFieldEntity.getApplicationForm().getId()); - responseBean.setId(formFieldEntity.getId()); - responseBean.setFieldId(amendmentFormField.getFieldId()); - responseBean.setCreatedDate(formFieldEntity.getCreatedDate()); - responseBean.setUpdatedDate(formFieldEntity.getUpdatedDate()); - responseBean.setFieldValue(documentResponseBeans); - - fileDetails.add(responseBean); - } + // Map to application form field response bean + ApplicationFormFieldEntity formFieldEntity = formFieldEntityMap.get(amendmentFormField.getFieldId()); + ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean(); + responseBean.setApplicationFormId(formFieldEntity.getApplicationForm().getId()); + responseBean.setId(formFieldEntity.getId()); + responseBean.setFieldId(amendmentFormField.getFieldId()); + responseBean.setCreatedDate(formFieldEntity.getCreatedDate()); + responseBean.setUpdatedDate(formFieldEntity.getUpdatedDate()); + responseBean.setFieldValue(documentResponseBeans); + fileDetails.add(responseBean); + } + } response.setFormFields(formFields); response.setApplicationFormFields(fileDetails); } @@ -1774,5 +1778,87 @@ public class ApplicationAmendmentRequestDao { return totalDays; } + public ApplicationAmendmentRequestResponse createSpecialApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentSpecialRequest applicationAmendmentRequest) { + log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); + ApplicationEntity applicationEntity=applicationDao.validateApplication(applicationEvaluationEntity.getApplicationId()); + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + + if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS)); + } + ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); + applicationAmendmentRequestEntity.setResponseDays(20l); + applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(20)); + applicationAmendmentRequestEntity.setIsEmail(Boolean.TRUE); + applicationAmendmentRequestEntity.setIsNotification(Boolean.FALSE); + applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue()); +// if ( applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) { +// Long initialDays = applicationEvaluationEntity.getInitialDays(); +// LocalDateTime startDate = applicationEvaluationEntity.getStartDate(); +// LocalDateTime nowInUTC = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); +// // Calculate remaining days +// Long remainingDays = initialDays - DAYS.between(startDate, nowInUTC); +// // Set remaining days in the entity +// applicationEvaluationEntity.setRemainingDays(remainingDays); +// //Set stop date time in the entity becuase amendment has started +// applicationEvaluationEntity.setStopDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); +// } + applicationAmendmentRequestEntity.setApplicationEvaluationEntity(applicationEvaluationEntity); + applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); + + Long applicationId = applicationEvaluationEntity.getApplicationId(); + Long assignedApplicationId = applicationEvaluationEntity.getAssignedApplicationsEntity().getId(); + // add here the changing status of assigned application + AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); + AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue()); + assignedApplicationsRepository.save(assignedApplicationsEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); + + + BigDecimal amountAccepted = applicationEntity.getAmountAccepted(); + if (applicationAmendmentRequest.getAmount() != null && (amountAccepted==null || applicationAmendmentRequest.getAmount().compareTo(amountAccepted) == 0)) { + applicationEntity.setAmountAccepted(applicationAmendmentRequest.getAmount()); + } + if(Boolean.FALSE.equals(applicationAmendmentRequest.getPec().equals(applicationEntity.getPecEmail()))){ + applicationEntity.setPecEmail(applicationAmendmentRequest.getPec()); + } + applicationEvaluationDao.processTechnicalEvaluation(applicationEntity.getId(),applicationEntity,ApplicationStatusForEvaluation.AWAITING_TECHNICAL_EVALUATION,applicationEvaluationEntity); + applicationRepository.save(applicationEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + + applicationAmendmentRequestEntity.setType(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue()); + applicationAmendmentRequestEntity.setApplicationId(applicationId); + UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); + Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); + ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( + applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, + userEntity.getHub().getId(),false); + protocolDao.saveProtocolEntity(protocolEntity); + applicationAmendmentRequestEntity.setProtocol(protocolEntity); + applicationAmendmentRequestEntity.setAmendmentDocumentType(applicationAmendmentRequest.getAmendmentDocumentType().getValue()); + ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); + log.info("Amendment request saved with ID={}", applicationAmendment.getId()); + + emailNotificationDao.sendMailforSpecialAmendment(applicationAmendmentRequestEntity,applicationEntity); + EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); + List responses = List.of(emailSendResponse); + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity,false); + + if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){ + saveEmailSendResponse(emailSendResponse, applicationAmendmentRequestEntity); + applicationAmendmentRequestResponse.setEmailSendResponse(responses); + } + else{ + applicationAmendmentRequestResponse.setEmailSendResponse(Collections.emptyList()); + } + log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); + return applicationAmendmentRequestResponse; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index fec8882c..0d11aee0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1934,7 +1934,7 @@ public class ApplicationEvaluationDao { if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION)){ log.info("Processing technical evaluation for applicationId: {}", application.getId()); - processTechnicalEvaluation(application.getId(), application, newStatus); + application.setStatus(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue()); } if((newStatus.equals(ApplicationStatusForEvaluation.APPROVED) || newStatus.equals(ApplicationStatusForEvaluation.REJECTED))) { @@ -2566,24 +2566,20 @@ public class ApplicationEvaluationDao { } return false; } - private void processTechnicalEvaluation(Long applicationId, ApplicationEntity applicationEntity, ApplicationStatusForEvaluation status){ - log.info("Starting technical evaluation processing for applicationId: {}", applicationId); - Optional evaluationEntityOpt = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId); - if (evaluationEntityOpt.isPresent()){ - ApplicationEvaluationEntity evaluationEntity = evaluationEntityOpt.get(); + public void processTechnicalEvaluation(Long applicationId, ApplicationEntity applicationEntity, ApplicationStatusForEvaluation status, ApplicationEvaluationEntity evaluationEntity){ + log.info("Starting process for checking scores for applicationId: {}", applicationId); String criteriaJson = evaluationEntity.getCriteria(); if (criteriaJson != null){ BigDecimal totalScore = calculateTotalScore(evaluationEntity.getCriteria()); if (totalScore.compareTo(new BigDecimal("40")) > 0) { applicationEntity.setStatus(status.getValue()); - log.info("Status updated to TECHNICAL_EVALUATION for applicationId: {}", applicationId); + log.info("Status updated to AWAITING_TECHNICAL_EVALUATION for applicationId: {}", applicationId); } else{ log.warn("Insufficient score ({}) for applicationId: {}. Throwing validation exception.", totalScore, applicationId); throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.INSUFFICIENT_SCORE_MESSAGE)); } } - } } public BigDecimal calculateTotalScore(String criteriaJson){ diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index a556d042..b22ece00 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -1,11 +1,13 @@ package net.gepafin.tendermanagement.dao; +import com.amazonaws.services.s3.AmazonS3Client; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; -import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; -import net.gepafin.tendermanagement.enums.RecipientTypeEnum; +import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; +import net.gepafin.tendermanagement.model.request.AttachmentRequest; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse; @@ -17,6 +19,7 @@ import net.gepafin.tendermanagement.service.impl.EmailService; import net.gepafin.tendermanagement.service.impl.EmailServiceFactory; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.service.impl.SystemEmailService; +import net.gepafin.tendermanagement.util.S3DocxProcessor; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.slf4j.Logger; @@ -25,8 +28,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.io.IOException; import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; import static net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao.filterByName; @@ -80,7 +85,16 @@ public class EmailNotificationDao { @Autowired private Validator validator; - private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, + @Autowired + private AmazonS3Client s3Client; + + @Autowired + private DocumentRepository documentRepository; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + public void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId) { HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); @@ -117,6 +131,34 @@ public class EmailNotificationDao { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + ApplicationAmendmentRequestEntity applicationAmendmentRequest=applicationAmendmentRequestDao.validateApplicationAmendmentRequest(amendmentId); + List attachmentRequests =new ArrayList<>(); + if(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED)) { + S3DocxProcessor processor = new S3DocxProcessor(s3Client); + List urls=new ArrayList<>(); + Map replacements = Map.of( + "{call_name}", applicationEntity.getCall().getName(), + "{amount_accepted}", String.valueOf(applicationEntity.getAmountAccepted()), + "{pec}", "bandi.gepafin@legalmail.it" + ); + List documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); + urls = documentEntities.stream() + .map(DocumentEntity::getFilePath) // or getUrl() + .collect(Collectors.toList()); + + Map processedFiles = null; + try { + processedFiles = processor.processFiles(urls, replacements); + } catch (IOException e) { + throw new RuntimeException(e); + } + for (Map.Entry entry : processedFiles.entrySet()) { + AttachmentRequest attachmentRequest = new AttachmentRequest(); + attachmentRequest.setName(entry.getKey()); // e.g. "path/file1.docx" + attachmentRequest.setFile(entry.getValue().getFile()); // updated file content + attachmentRequests.add(attachmentRequest); + } + } UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId()); String companyEmail = userWithCompany.getEmail(); @@ -130,17 +172,20 @@ public class EmailNotificationDao { } EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY,company.getId() , String.valueOf(recipientEmails), userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, recipientEmails, emailLogRequest); } else { if (companyEmail != null && !companyEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY, company.getId(), companyEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, List.of(companyEmail), emailLogRequest); } if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY, company.getId(), contactEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, List.of(contactEmail), emailLogRequest); } } @@ -154,6 +199,7 @@ public class EmailNotificationDao { } EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY,userEntity.getBeneficiary().getId() , beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogRequest); } if(userEntity.getHub().getEmail() != null){ @@ -164,6 +210,7 @@ public class EmailNotificationDao { if (!hubEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null, hubEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, List.of(hubEmail), emailLogRequest); } } @@ -173,6 +220,7 @@ public class EmailNotificationDao { rinaldoEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); //SMTP + emailLogRequest.setAttachments(attachmentRequests); sendMail(null, subject, body, List.of(rinaldoEmail), emailLogRequest); } if (applicationEvaluationEntity.isPresent()) { @@ -182,6 +230,7 @@ public class EmailNotificationDao { if (preInstructorEmail != null && !preInstructorEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.INSTRUCTOR, instructorUser.getId(), preInstructorEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + emailLogRequest.setAttachments(attachmentRequests); sendMail(applicationEntity.getHubId(), subject, body, List.of(preInstructorEmail), emailLogRequest); } } @@ -390,4 +439,10 @@ public class EmailNotificationDao { return bodyPlaceholders; } + public void sendMailforSpecialAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,ApplicationEntity applicationEntity) { + + Map bodyPlaceholders = prepareEmailPlaceholders(applicationEntity, applicationAmendmentRequestEntity); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, bodyPlaceholders, null, + applicationAmendmentRequestEntity.getId()); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java index e5361e83..abd35d6a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationFormDao.java @@ -145,7 +145,7 @@ public class EvaluationFormDao { } - public EvaluationFormResponseBean getEvaluationFormByCallId(CallEntity callEntity) { + public EvaluationFormResponseBean getEvaluationFormByCallId(CallEntity callEntity) { if (callEntity == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.CALL_NOT_FOUND)); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index b9af1ca8..7195e1cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -68,4 +68,10 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @Column(name = "EXTENSION_DATE") private LocalDateTime extensionDate; + @Column(name = "TYPE") + private String type; + + @Column(name = "AMENDMENT_DOCUMENT_TYPE") + private String amendmentDocumentType; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java index 1ac63bae..0cc3c6fb 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -56,7 +56,8 @@ public class SystemEmailTemplatesEntity extends BaseEntity { PASSWORD_RESET("PASSWORD_RESET"), INADMISSIBILITY_TEMPLATE("INADMISSIBILITY_NOTIFICATION"), APPLICATION_SUBMISSION_FAILURE_NOTIFICATION("APPLICATION_SUBMISSION_FAILURE_NOTIFICATION"), - INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE"); + INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE"), + SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"); private String value; SystemEmailTemplatesEntityTypeEnum(String value) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/AmendmentDocumentTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/AmendmentDocumentTypeEnum.java new file mode 100644 index 00000000..e1e97b63 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/AmendmentDocumentTypeEnum.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum AmendmentDocumentTypeEnum { + + NESSUNA_GARANZIA("NESSUNA_GARANZIA"), + + GARANZIA_MCC("GARANZIA_MCC"), + + MCC_START_UP("MCC_START_UP"), + + ALTRE_GARANZIE("ALTRE_GARANZIE"); + + + private final String value; + + AmendmentDocumentTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationAmendmentRequestTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationAmendmentRequestTypeEnum.java new file mode 100644 index 00000000..c336c9da --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationAmendmentRequestTypeEnum.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ApplicationAmendmentRequestTypeEnum { + + REGULAR ("REGULAR"), + + SPECIAL("SPECIAL"); + + + private final String value; + + ApplicationAmendmentRequestTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java index d9c3c45e..1a03e846 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java @@ -7,6 +7,7 @@ public enum ApplicationStatusForEvaluation { REJECTED("REJECTED"), ADMISSIBLE("ADMISSIBLE"), TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"), + AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION"), TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java index ab25ad25..c459239d 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java @@ -13,7 +13,8 @@ public enum EmailScenarioTypeEnum { PASSWORD_RESET_REQUEST("PASSWORD_RESET_REQUEST"), APPLICATION_REJECTED("APPLICATION_REJECTED"), APPLICATION_SUBMISSION_FAILURE("APPLICATION_SUBMISSION_FAILURE"), - APPLICATION_TECHNICAL_EVALUATION_REJECTED("APPLICATION_TECHNICAL_EVALUATION_REJECTED"); + APPLICATION_TECHNICAL_EVALUATION_REJECTED("APPLICATION_TECHNICAL_EVALUATION_REJECTED"), + SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 4200e361..8d512478 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -222,7 +222,8 @@ public enum UserActionContextEnum { UPDATE_CALL_END_DATE_AND_TIME("UPDATE_CALL_END_DATE_AND_TIME"), UPDATE_EXPIRED_CALL("UPDATE_EXPIRED_CALL"), RESEND_EMAIL("RESEND_EMAIL"), - SEND_REMINDER_EMAIL("SEND_REMINDER_EMAIL"); + SEND_REMINDER_EMAIL("SEND_REMINDER_EMAIL"), + CREATE_SPECIAL_AMENDMENT("CREATE_SPECIAL_AMENDMENT"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentSpecialRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentSpecialRequest.java new file mode 100644 index 00000000..3a971a7c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentSpecialRequest.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.AmendmentDocumentTypeEnum; + +import java.math.BigDecimal; + +@Data +public class ApplicationAmendmentSpecialRequest { + + private BigDecimal amount; + + private AmendmentDocumentTypeEnum amendmentDocumentType; + + private String pec; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AttachmentRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AttachmentRequest.java new file mode 100644 index 00000000..3fa1c5b1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/AttachmentRequest.java @@ -0,0 +1,11 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class AttachmentRequest { + + private String name; + + private String file; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/EmailLogRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/EmailLogRequest.java index 7cae845c..eccb412f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/EmailLogRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/EmailLogRequest.java @@ -6,6 +6,8 @@ import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum; import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; import net.gepafin.tendermanagement.enums.RecipientTypeEnum; +import java.util.List; + @Data public class EmailLogRequest { @@ -39,4 +41,6 @@ public class EmailLogRequest { private Long userActionId; + private List attachments; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/PecEmailRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/PecEmailRequest.java index a066dce0..cf903121 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/PecEmailRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/PecEmailRequest.java @@ -12,4 +12,5 @@ public class PecEmailRequest { private String body; private String username; private String password; + private List attachments; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 0ca46f8e..17e5ba03 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -35,5 +35,7 @@ public interface DocumentRepository extends JpaRepository List findAllByIdInAndIsDeletedFalse(Set documentIds); List findBySourceIdInAndSourceAndIsDeletedFalse(Set sourceId, String type); + + List findBySourceInAndIsDeletedFalse(List type); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java index b19f77c4..5e698107 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java @@ -4,10 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentPaginationRequestBean; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; -import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import java.util.List; @@ -28,4 +25,6 @@ public interface ApplicationAmendmentRequestService { EmailReminderResponse sendReminderEmail(HttpServletRequest request, Long amendmentId); PageableResponseBean> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean); + public ApplicationAmendmentRequestResponse createSpecialApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentSpecialRequest applicationAmendmentRequest); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java index a680ec1b..8926971f 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -8,10 +8,7 @@ import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentPaginationRequestBean; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; -import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; @@ -169,4 +166,10 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm return applicationAmendmentRequestDao.getApplicationAmendmentByPaginationByView(userId,amendmentPaginationRequestBean); } + + @Override + @Transactional(rollbackFor = Exception.class) + public ApplicationAmendmentRequestResponse createSpecialApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, ApplicationAmendmentSpecialRequest applicationAmendmentRequest) { + return applicationAmendmentRequestDao.createSpecialApplicationAmendmentRequest(applicationEvaluationId, applicationAmendmentRequest); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java index 19742a8c..85153e91 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.io.ByteArrayInputStream; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,6 +64,7 @@ public class PecEmailService implements EmailService { emailRequest.setBody(body); emailRequest.setUsername(emailConfig.getUsername()); emailRequest.setPassword(emailConfig.getPassword()); + emailRequest.setAttachments(emailLogRequest.getAttachments()); emailRequest.setRecipient(recipientEmails); String url=emailConfig.getUrl()+ GepafinConstant.PEC_SERVICE_SEND_MAIL; String authToken = emailConfig.getAuthToken(); @@ -88,7 +90,7 @@ public class PecEmailService implements EmailService { emailLogRequest.setErrorMessage(errorMsg); sendNotificationOnFailure(emailLogRequest.getUserId(),emailLogRequest.getEmailType()); - if (EmailScenarioTypeEnum.APPLICATION_SUBMITTED.equals(emailLogRequest.getEmailType())) { + if (EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.equals(emailLogRequest.getEmailType())) { applicationDao.sendApplicationSubmissionFailureEmail(emailLogRequest); } } @@ -98,7 +100,7 @@ public class PecEmailService implements EmailService { emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE); emailLogRequest.setErrorMessage(e.getMessage()); sendNotificationOnFailure(emailLogRequest.getUserId(),emailLogRequest.getEmailType()); - if (EmailScenarioTypeEnum.APPLICATION_SUBMITTED.equals(emailLogRequest.getEmailType())) { + if (EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.equals(emailLogRequest.getEmailType())) { applicationDao.sendApplicationSubmissionFailureEmail(emailLogRequest); } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java b/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java new file mode 100644 index 00000000..9175eec1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java @@ -0,0 +1,140 @@ +package net.gepafin.tendermanagement.util; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3URI; +import com.amazonaws.services.s3.model.S3Object; +import net.gepafin.tendermanagement.model.request.AttachmentRequest; +import org.apache.poi.xwpf.usermodel.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.Base64; + +public class S3DocxProcessor { + + private final AmazonS3 s3Client; + + public static final Logger log = LoggerFactory.getLogger(S3DocxProcessor.class); + + + public S3DocxProcessor(AmazonS3 s3Client) { + this.s3Client = s3Client; + } + + /** + * Fetches DOCX files from S3, replaces placeholders, and returns updated files + * as AttachmentRequest objects (ready for PEC API). + * + * @param s3Urls List of S3 file URLs + * @param replacements Map of placeholder -> value + * @return Map of original file name -> AttachmentRequest + * @throws IOException + */ + public Map processFiles(List s3Urls, + Map replacements) throws IOException { + Map processedFiles = new HashMap<>(); + + for (String s3Url : s3Urls) { + // Extract bucket & key from URL + AmazonS3URI s3Uri = new AmazonS3URI(s3Url); + String bucket = s3Uri.getBucket(); + String key = s3Uri.getKey(); + try (S3Object s3Object = s3Client.getObject(bucket, key); + InputStream originalStream = new BufferedInputStream(s3Object.getObjectContent())) { + byte[] updatedBytes=null; + if (isDocxFile(originalStream)) { + log.warn("Skipping non-DOCX file from S3: bucket={}, key={}", bucket, key); + updatedBytes = replacePlaceholders(originalStream, replacements); + }else { + // non-DOCX → just copy raw stream + updatedBytes = originalStream.readAllBytes(); + log.info("Skipped placeholder replacement, copied file as-is: {}", key); + } + + // convert to base64 + String base64 = Base64.getEncoder().encodeToString(updatedBytes); + String fileString = "data:application/octet-stream;base64," + base64; + + // create attachment request + AttachmentRequest attachment = new AttachmentRequest(); + attachment.setName(extractFileName(key)); + attachment.setFile(fileString); + + processedFiles.put(key, attachment); + } + } + + return processedFiles; + } + + + private byte[] replacePlaceholders(InputStream docInputStream, + Map replacements) throws IOException { + try (XWPFDocument document = new XWPFDocument(docInputStream); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + + // replace in body paragraphs + replaceInParagraphs(document.getParagraphs(), replacements); + + // replace inside tables + for (XWPFTable table : document.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + replaceInParagraphs(cell.getParagraphs(), replacements); + } + } + } + + document.write(out); + return out.toByteArray(); + } + } + + private void replaceInParagraphs(List paragraphs, Map replacements) { + for (XWPFParagraph paragraph : paragraphs) { + String paragraphText = paragraph.getText(); + + if (paragraphText != null && !paragraphText.isEmpty()) { + // Apply all replacements + for (Map.Entry entry : replacements.entrySet()) { + paragraphText = paragraphText.replace(entry.getKey(), entry.getValue()); + } + + // Remove old runs + int runCount = paragraph.getRuns().size(); + for (int i = runCount - 1; i >= 0; i--) { + paragraph.removeRun(i); + } + + // Add one new run with replaced text + XWPFRun newRun = paragraph.createRun(); + newRun.setText(paragraphText); + } + } + } + + + private String extractFileName(String key) { + int lastSlash = key.lastIndexOf('/'); + if (lastSlash >= 0 && lastSlash < key.length() - 1) { + return key.substring(lastSlash + 1); + } + return key; + } + + private boolean isDocxFile(InputStream inputStream) throws IOException { + inputStream.mark(4); + byte[] header = new byte[2]; + int read = inputStream.read(header, 0, 2); + inputStream.reset(); + + // DOCX = ZIP = should start with PK (0x50 0x4B) + return read == 2 && header[0] == 0x50 && header[1] == 0x4B; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 13cf6e87..28dca3d7 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -161,19 +161,22 @@ public class Utils { } public static List convertJsonStringToList(String jsonString, Class clazz) { - try { - TypeReference> typeRef = new TypeReference>() { - @Override - public Type getType() { - return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); - } - }; - return mapper.readValue(jsonString, typeRef); - } catch (Exception e) { - e.printStackTrace(); - // Handle the exception appropriately (e.g., throw a custom exception) - return null; + if(jsonString!=null) { + try { + TypeReference> typeRef = new TypeReference>() { + @Override + public Type getType() { + return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); + } + }; + return mapper.readValue(jsonString, typeRef); + } catch (Exception e) { + e.printStackTrace(); + // Handle the exception appropriately (e.g., throw a custom exception) + return null; + } } + return null; } public static String convertMapIntoJsonString(Map map) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java index 5d81ce7e..9fe94bb5 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java @@ -199,5 +199,18 @@ public interface ApplicationAmendmentRequestApi { @PostMapping(value = "/user/{userId}/pagination", produces = { "application/json" }) ResponseEntity>>> getApplicationAmendmentByPaginnation(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, @RequestBody ApplicationAmendmentPaginationRequestBean userActionPaginationRequest); + @Operation(summary = "Api to create special Amendment", + 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 = "/special", produces = "application/json") + ResponseEntity> createSpecialApplicationAmendmentRequest(HttpServletRequest request, + @Parameter(description = "Application Evaluation Id", required = true) @RequestParam Long applicationEvaluationId, + @Valid @RequestBody ApplicationAmendmentSpecialRequest applicationAmendmentRequest); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java index 0c8ef489..797cce3a 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java @@ -200,4 +200,15 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme } + @Override + public ResponseEntity> createSpecialApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, ApplicationAmendmentSpecialRequest applicationAmendmentRequest) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_SPECIAL_AMENDMENT).build()); + + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.createSpecialApplicationAmendmentRequest(request,applicationEvaluationId,applicationAmendmentRequest); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationAmendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_DATA_FOR_AMENDMENT_MSG))); + + } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f2db0c1e..e1d0cba5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.application.name=tendermanagement spring.servlet.multipart.max-file-size=300MB spring.servlet.multipart.max-request-size=300MB -spring.profiles.active=testing +spring.profiles.active=local # JPA Configuration diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index 6337ecde..d99cb334 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -3022,4 +3022,17 @@ + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_document_for_special_amendment.sql b/src/main/resources/db/dump/insert_document_for_special_amendment.sql new file mode 100644 index 00000000..4f9fb454 --- /dev/null +++ b/src/main/resources/db/dump/insert_document_for_special_amendment.sql @@ -0,0 +1,23 @@ +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('nessuna_garanzia.docx', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/nessuna_garanzia.docx', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'NESSUNA_GARANZIA', NULL, NULL); + +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('garanzia_MCC.docx', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/garanzia_MCC.docx', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'GARANZIA_MCC', NULL, NULL); + +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('garanzia_MCC_per_START_UP.docx', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/garanzia_MCC_per_START_UP.docx', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'MCC_START_UP', NULL, NULL); + +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('altre_garanzie__fideiussione.docx', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/altre_garanzie__fideiussione.docx', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'ALTRE_GARANZIE', NULL, NULL); + +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('Modello_privacy_-_agg.to_05092024.pdf', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/Modello_privacy_-_agg.to_05092024.pdf', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'MODELLO_PRIVACY', NULL, NULL); + +INSERT INTO gepafin_schema."document" +(file_name, file_path, source_id, "type", created_date, updated_date, is_deleted, "source", document_attachment_id, uploaded_by) +VALUES('Modello_SP1_Autocertificazione.docx', 'https://mementoresources.s3.amazonaws.com/gepafin/staging/template/Modello_SP1_Autocertificazione.docx', NULL, 'DOCUMENT', '2024-10-12 16:09:08.262', '2024-10-12 16:09:08.262', false, 'MODELLO_AUTOCERTIFICAZIONE', NULL, NULL); \ No newline at end of file diff --git a/src/main/resources/db/dump/insert_system_email_template_for_special_amendment_28-09-2025.sql b/src/main/resources/db/dump/insert_system_email_template_for_special_amendment_28-09-2025.sql new file mode 100644 index 00000000..39053eea --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_for_special_amendment_28-09-2025.sql @@ -0,0 +1,11 @@ +INSERT INTO gepafin_schema.system_email_template +( template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date, email_scenario, hub_id) +VALUES( 'Special Amendment Creation Email', 'SPECIAL_APPLICATION_AMENDMENT_REQUESTED', ' + +
+

Buongiorno, vi invitiamo a prendere visione del documento allegato con cui vi informiamo dell avvenuta delibera a valere sull Avviso in oggetto.

+

Distinti Saluti,

+

{{email_signature}}

+
+ +', 'Comunicazione esito valutazione tecnica ed economico-finanziaria– Avviso {{call_name}} ', NULL, true, false, '2025-09-29 20:00:00.000', '2025-09-29 20:00:00.000', 'SPECIAL_APPLICATION_AMENDMENT_REQUESTED', NULL); \ No newline at end of file